From d24c8453db1035f382e1b0853be00ebd281bbbdd Mon Sep 17 00:00:00 2001 From: M4xw Date: Tue, 22 Mar 2022 02:52:44 +0100 Subject: [PATCH] git subrepo clone https://github.com/HarbourMasters/libultraship.git subrepo: subdir: "libultraship" merged: "a484cda98" upstream: origin: "https://github.com/HarbourMasters/libultraship.git" branch: "main" commit: "a484cda98" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libultraship/.gitignore | 356 + libultraship/.gitrepo | 12 + libultraship/LICENSE | 9 + libultraship/Makefile | 28 + libultraship/TestApp/Main.cpp | 29 + libultraship/TestApp/StormLibDUS.lib | Bin 0 -> 2923852 bytes libultraship/TestApp/TestApp.vcxproj | 152 + libultraship/TestApp/TestApp.vcxproj.filters | 22 + libultraship/libultraship.sln | 64 + libultraship/libultraship/Animation.cpp | 72 + libultraship/libultraship/Animation.h | 63 + libultraship/libultraship/Archive.cpp | 357 + libultraship/libultraship/Archive.h | 55 + libultraship/libultraship/Array.cpp | 61 + libultraship/libultraship/Array.h | 85 + libultraship/libultraship/AudioPlayer.h | 15 + libultraship/libultraship/Blob.cpp | 18 + libultraship/libultraship/Blob.h | 19 + libultraship/libultraship/CollisionHeader.cpp | 99 + libultraship/libultraship/CollisionHeader.h | 85 + libultraship/libultraship/ConfigFile.cpp | 159 + libultraship/libultraship/ConfigFile.h | 37 + libultraship/libultraship/Controller.cpp | 96 + libultraship/libultraship/Controller.h | 45 + .../libultraship/ControllerAttachment.cpp | 5 + .../libultraship/ControllerAttachment.h | 8 + libultraship/libultraship/Cutscene.cpp | 21 + libultraship/libultraship/Cutscene.h | 28 + libultraship/libultraship/Cvar.cpp | 100 + libultraship/libultraship/Cvar.h | 49 + libultraship/libultraship/DisplayList.cpp | 31 + libultraship/libultraship/DisplayList.h | 23 + libultraship/libultraship/Environment.cpp | 15 + libultraship/libultraship/Environment.h | 8 + .../Factories/AnimationFactory.cpp | 25 + .../libultraship/Factories/AnimationFactory.h | 11 + .../libultraship/Factories/ArrayFactory.cpp | 25 + .../libultraship/Factories/ArrayFactory.h | 11 + .../libultraship/Factories/BlobFactory.cpp | 26 + .../libultraship/Factories/BlobFactory.h | 11 + .../Factories/CollisionHeaderFactory.cpp | 26 + .../Factories/CollisionHeaderFactory.h | 11 + .../Factories/CutsceneFactory.cpp | 25 + .../libultraship/Factories/CutsceneFactory.h | 11 + .../Factories/DisplayListFactory.cpp | 27 + .../Factories/DisplayListFactory.h | 11 + .../Factories/MaterialFactory.cpp | 26 + .../libultraship/Factories/MaterialFactory.h | 11 + .../libultraship/Factories/MtxFactory.cpp | 22 + .../libultraship/Factories/MtxFactory.h | 12 + .../Factories/OTRResourceLoader.cpp | 71 + .../libultraship/Factories/PathFactory.cpp | 25 + .../libultraship/Factories/PathFactory.h | 11 + .../Factories/PlayerAnimationFactory.cpp | 27 + .../Factories/PlayerAnimationFactory.h | 11 + .../libultraship/Factories/ResourceLoader.cpp | 105 + .../libultraship/Factories/ResourceLoader.h | 11 + .../libultraship/Factories/SceneFactory.cpp | 26 + .../libultraship/Factories/SceneFactory.h | 11 + .../Factories/SkeletonFactory.cpp | 26 + .../libultraship/Factories/SkeletonFactory.h | 11 + .../Factories/SkeletonLimbFactory.cpp | 26 + .../Factories/SkeletonLimbFactory.h | 11 + .../libultraship/Factories/TextFactory.cpp | 26 + .../libultraship/Factories/TextFactory.h | 11 + .../libultraship/Factories/TextureFactory.cpp | 26 + .../libultraship/Factories/TextureFactory.h | 11 + .../libultraship/Factories/VtxFactory.cpp | 22 + .../libultraship/Factories/VtxFactory.h | 12 + libultraship/libultraship/File.cpp | 1 + libultraship/libultraship/File.h | 22 + libultraship/libultraship/GameSettings.cpp | 133 + libultraship/libultraship/GameSettings.h | 56 + libultraship/libultraship/GlobalCtx2.cpp | 85 + libultraship/libultraship/GlobalCtx2.h | 41 + .../libultraship/KeyboardController.cpp | 56 + .../libultraship/KeyboardController.h | 23 + libultraship/libultraship/LUSMacros.h | 3 + libultraship/libultraship/Lib/Fast3D/.gitrepo | 12 + .../libultraship/Lib/Fast3D/LICENSE.txt | 19 + .../libultraship/Lib/Fast3D/README.md | 33 + .../Lib/Fast3D/U64/PR/ultra64/abi.h | 491 + .../Lib/Fast3D/U64/PR/ultra64/controller.h | 177 + .../Lib/Fast3D/U64/PR/ultra64/convert.h | 18 + .../Lib/Fast3D/U64/PR/ultra64/exception.h | 45 + .../Lib/Fast3D/U64/PR/ultra64/gbi.h | 4637 +++ .../Lib/Fast3D/U64/PR/ultra64/gs2dex.h | 379 + .../Lib/Fast3D/U64/PR/ultra64/gu.h | 8 + .../Lib/Fast3D/U64/PR/ultra64/hardware.h | 90 + .../Lib/Fast3D/U64/PR/ultra64/internal.h | 24 + .../Lib/Fast3D/U64/PR/ultra64/interrupt.h | 6 + .../Lib/Fast3D/U64/PR/ultra64/mbi.h | 44 + .../Lib/Fast3D/U64/PR/ultra64/message.h | 39 + .../Lib/Fast3D/U64/PR/ultra64/motor.h | 15 + .../Lib/Fast3D/U64/PR/ultra64/pfs.h | 137 + .../Lib/Fast3D/U64/PR/ultra64/pi.h | 83 + .../Lib/Fast3D/U64/PR/ultra64/printf.h | 33 + .../Lib/Fast3D/U64/PR/ultra64/r4300.h | 367 + .../Lib/Fast3D/U64/PR/ultra64/rcp.h | 95 + .../Lib/Fast3D/U64/PR/ultra64/rdp.h | 51 + .../Lib/Fast3D/U64/PR/ultra64/rsp.h | 50 + .../Lib/Fast3D/U64/PR/ultra64/sptask.h | 68 + .../Lib/Fast3D/U64/PR/ultra64/thread.h | 64 + .../Lib/Fast3D/U64/PR/ultra64/time.h | 17 + .../Lib/Fast3D/U64/PR/ultra64/types.h | 54 + .../Lib/Fast3D/U64/PR/ultra64/vi.h | 137 + .../libultraship/Lib/Fast3D/dxsdk/d3d12.h | 17258 +++++++++++ .../Lib/Fast3D/dxsdk/d3d12sdklayers.h | 3230 +++ .../libultraship/Lib/Fast3D/dxsdk/d3dcommon.h | 1009 + .../libultraship/Lib/Fast3D/dxsdk/d3dx12.h | 3440 +++ .../libultraship/Lib/Fast3D/gfx_cc.cpp | 56 + libultraship/libultraship/Lib/Fast3D/gfx_cc.h | 68 + .../Lib/Fast3D/gfx_direct3d11.cpp | 1015 + .../libultraship/Lib/Fast3D/gfx_direct3d11.h | 12 + .../Lib/Fast3D/gfx_direct3d12.cpp | 972 + .../libultraship/Lib/Fast3D/gfx_direct3d12.h | 12 + .../Lib/Fast3D/gfx_direct3d12_guids.h | 62 + .../Lib/Fast3D/gfx_direct3d_common.cpp | 322 + .../Lib/Fast3D/gfx_direct3d_common.h | 14 + .../libultraship/Lib/Fast3D/gfx_dxgi.cpp | 673 + .../libultraship/Lib/Fast3D/gfx_dxgi.h | 16 + .../libultraship/Lib/Fast3D/gfx_glx.cpp | 618 + .../libultraship/Lib/Fast3D/gfx_glx.h | 8 + .../libultraship/Lib/Fast3D/gfx_opengl.cpp | 739 + .../libultraship/Lib/Fast3D/gfx_opengl.h | 8 + .../libultraship/Lib/Fast3D/gfx_pc.cpp | 2731 ++ libultraship/libultraship/Lib/Fast3D/gfx_pc.h | 67 + .../Lib/Fast3D/gfx_rendering_api.h | 41 + .../Lib/Fast3D/gfx_screen_config.h | 7 + .../libultraship/Lib/Fast3D/gfx_sdl.h | 8 + .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 317 + .../Lib/Fast3D/gfx_window_manager_api.h | 23 + libultraship/libultraship/Lib/GLEW/GL/eglew.h | 2618 ++ libultraship/libultraship/Lib/GLEW/GL/glew.h | 23686 ++++++++++++++++ libultraship/libultraship/Lib/GLEW/GL/glxew.h | 1775 ++ libultraship/libultraship/Lib/GLEW/GL/wglew.h | 1447 + .../libultraship/Lib/GLEW/x64/glew32.dll | Bin 0 -> 464896 bytes .../libultraship/Lib/GLEW/x64/glew32.lib | Bin 0 -> 757468 bytes .../libultraship/Lib/GLEW/x64/glew32s.lib | Bin 0 -> 2845622 bytes .../libultraship/Lib/GLEW/x86/glew32.dll | Bin 0 -> 424960 bytes .../libultraship/Lib/GLEW/x86/glew32.lib | Bin 0 -> 769106 bytes .../libultraship/Lib/GLEW/x86/glew32s.lib | Bin 0 -> 2693038 bytes .../libultraship/Lib/GLFW/GLFW/glfw3.h | 5874 ++++ .../libultraship/Lib/GLFW/GLFW/glfw3native.h | 525 + .../libultraship/Lib/GLFW/GLFW/glfw_config.h | 60 + libultraship/libultraship/Lib/GLFW/glfw3.dll | Bin 0 -> 196608 bytes .../libultraship/Lib/GLFW/glfw3dll.exp | Bin 0 -> 18558 bytes .../libultraship/Lib/GLFW/glfw3dll.lib | Bin 0 -> 30922 bytes .../libultraship/Lib/ImGui/.editorconfig | 24 + .../libultraship/Lib/ImGui/.gitattributes | 30 + .../libultraship/Lib/ImGui/.gitignore | 53 + .../libultraship/Lib/ImGui/LICENSE.txt | 21 + .../ImGui/backends/imgui_impl_allegro5.cpp | 580 + .../Lib/ImGui/backends/imgui_impl_allegro5.h | 32 + .../Lib/ImGui/backends/imgui_impl_android.cpp | 276 + .../Lib/ImGui/backends/imgui_impl_android.h | 28 + .../Lib/ImGui/backends/imgui_impl_dx10.cpp | 712 + .../Lib/ImGui/backends/imgui_impl_dx10.h | 26 + .../Lib/ImGui/backends/imgui_impl_dx11.cpp | 728 + .../Lib/ImGui/backends/imgui_impl_dx11.h | 27 + .../Lib/ImGui/backends/imgui_impl_dx12.cpp | 1073 + .../Lib/ImGui/backends/imgui_impl_dx12.h | 39 + .../Lib/ImGui/backends/imgui_impl_dx9.cpp | 540 + .../Lib/ImGui/backends/imgui_impl_dx9.h | 26 + .../Lib/ImGui/backends/imgui_impl_glfw.cpp | 1135 + .../Lib/ImGui/backends/imgui_impl_glfw.h | 51 + .../Lib/ImGui/backends/imgui_impl_glut.cpp | 297 + .../Lib/ImGui/backends/imgui_impl_glut.h | 39 + .../Lib/ImGui/backends/imgui_impl_metal.h | 69 + .../Lib/ImGui/backends/imgui_impl_metal.mm | 598 + .../Lib/ImGui/backends/imgui_impl_opengl2.cpp | 324 + .../Lib/ImGui/backends/imgui_impl_opengl2.h | 33 + .../Lib/ImGui/backends/imgui_impl_opengl3.cpp | 838 + .../Lib/ImGui/backends/imgui_impl_opengl3.h | 56 + .../backends/imgui_impl_opengl3_loader.h | 757 + .../Lib/ImGui/backends/imgui_impl_osx.h | 27 + .../Lib/ImGui/backends/imgui_impl_osx.mm | 712 + .../Lib/ImGui/backends/imgui_impl_sdl.cpp | 917 + .../Lib/ImGui/backends/imgui_impl_sdl.h | 38 + .../ImGui/backends/imgui_impl_sdlrenderer.cpp | 249 + .../ImGui/backends/imgui_impl_sdlrenderer.h | 31 + .../Lib/ImGui/backends/imgui_impl_vulkan.cpp | 1758 ++ .../Lib/ImGui/backends/imgui_impl_vulkan.h | 156 + .../Lib/ImGui/backends/imgui_impl_wgpu.cpp | 718 + .../Lib/ImGui/backends/imgui_impl_wgpu.h | 25 + .../Lib/ImGui/backends/imgui_impl_win32.cpp | 1195 + .../Lib/ImGui/backends/imgui_impl_win32.h | 43 + .../Lib/ImGui/backends/vulkan/generate_spv.sh | 6 + .../ImGui/backends/vulkan/glsl_shader.frag | 14 + .../ImGui/backends/vulkan/glsl_shader.vert | 25 + .../libultraship/Lib/ImGui/docs/BACKENDS.md | 144 + .../libultraship/Lib/ImGui/docs/CHANGELOG.txt | 3847 +++ .../libultraship/Lib/ImGui/docs/EXAMPLES.md | 242 + .../libultraship/Lib/ImGui/docs/FAQ.md | 676 + .../libultraship/Lib/ImGui/docs/FONTS.md | 397 + .../libultraship/Lib/ImGui/docs/README.md | 243 + .../libultraship/Lib/ImGui/docs/TODO.txt | 445 + .../Lib/ImGui/examples/README.txt | 9 + .../ImGui/examples/example_allegro5/README.md | 36 + .../example_allegro5/example_allegro5.vcxproj | 180 + .../example_allegro5.vcxproj.filters | 58 + .../example_allegro5/imconfig_allegro5.h | 11 + .../ImGui/examples/example_allegro5/main.cpp | 145 + .../example_android_opengl3/CMakeLists.txt | 40 + .../android/.gitignore | 12 + .../android/app/build.gradle | 34 + .../android/app/src/main/AndroidManifest.xml | 24 + .../android/app/src/main/java/MainActivity.kt | 40 + .../android/build.gradle | 24 + .../android/settings.gradle | 1 + .../examples/example_android_opengl3/main.cpp | 369 + .../examples/example_apple_metal/README.md | 10 + .../project.pbxproj | 503 + .../example_apple_metal/iOS/Info-iOS.plist | 49 + .../iOS/LaunchScreen.storyboard | 27 + .../macOS/Info-macOS.plist | 30 + .../macOS/MainMenu.storyboard | 93 + .../examples/example_apple_metal/main.mm | 343 + .../project.pbxproj | 332 + .../examples/example_apple_opengl2/main.mm | 271 + .../example_emscripten_opengl3/Makefile | 91 + .../example_emscripten_opengl3/README.md | 26 + .../example_emscripten_opengl3/main.cpp | 175 + .../shell_minimal.html | 64 + .../examples/example_emscripten_wgpu/Makefile | 88 + .../example_emscripten_wgpu/README.md | 24 + .../examples/example_emscripten_wgpu/main.cpp | 245 + .../examples/example_glfw_metal/Makefile | 46 + .../ImGui/examples/example_glfw_metal/main.mm | 172 + .../examples/example_glfw_opengl2/Makefile | 81 + .../example_glfw_opengl2/build_win32.bat | 8 + .../example_glfw_opengl2.vcxproj | 181 + .../example_glfw_opengl2.vcxproj.filters | 61 + .../examples/example_glfw_opengl2/main.cpp | 181 + .../examples/example_glfw_opengl3/Makefile | 89 + .../example_glfw_opengl3/build_win32.bat | 8 + .../example_glfw_opengl3.vcxproj | 182 + .../example_glfw_opengl3.vcxproj.filters | 64 + .../examples/example_glfw_opengl3/main.cpp | 195 + .../example_glfw_vulkan/CMakeLists.txt | 44 + .../example_glfw_vulkan/build_win32.bat | 14 + .../example_glfw_vulkan/build_win64.bat | 13 + .../example_glfw_vulkan.vcxproj | 185 + .../example_glfw_vulkan.vcxproj.filters | 61 + .../examples/example_glfw_vulkan/main.cpp | 580 + .../examples/example_glut_opengl2/Makefile | 75 + .../example_glut_opengl2.vcxproj | 181 + .../example_glut_opengl2.vcxproj.filters | 61 + .../examples/example_glut_opengl2/main.cpp | 156 + .../Lib/ImGui/examples/example_null/Makefile | 92 + .../examples/example_null/build_win32.bat | 3 + .../Lib/ImGui/examples/example_null/main.cpp | 37 + .../example_sdl_directx11/build_win32.bat | 8 + .../example_sdl_directx11.vcxproj | 182 + .../example_sdl_directx11.vcxproj.filters | 60 + .../examples/example_sdl_directx11/main.cpp | 249 + .../ImGui/examples/example_sdl_metal/Makefile | 47 + .../ImGui/examples/example_sdl_metal/main.mm | 181 + .../examples/example_sdl_opengl2/Makefile | 79 + .../examples/example_sdl_opengl2/README.md | 29 + .../example_sdl_opengl2/build_win32.bat | 8 + .../example_sdl_opengl2.vcxproj | 181 + .../example_sdl_opengl2.vcxproj.filters | 61 + .../examples/example_sdl_opengl2/main.cpp | 182 + .../examples/example_sdl_opengl3/Makefile | 91 + .../examples/example_sdl_opengl3/README.md | 29 + .../example_sdl_opengl3/build_win32.bat | 8 + .../example_sdl_opengl3.vcxproj | 182 + .../example_sdl_opengl3.vcxproj.filters | 64 + .../examples/example_sdl_opengl3/main.cpp | 203 + .../examples/example_sdl_sdlrenderer/Makefile | 79 + .../example_sdl_sdlrenderer/README.md | 25 + .../example_sdl_sdlrenderer/build_win32.bat | 8 + .../example_sdl_sdlrenderer.vcxproj | 181 + .../example_sdl_sdlrenderer.vcxproj.filters | 61 + .../examples/example_sdl_sdlrenderer/main.cpp | 161 + .../example_sdl_vulkan/build_win32.bat | 10 + .../example_sdl_vulkan.vcxproj | 185 + .../example_sdl_vulkan.vcxproj.filters | 61 + .../examples/example_sdl_vulkan/main.cpp | 581 + .../example_win32_directx10/build_win32.bat | 8 + .../example_win32_directx10.vcxproj | 171 + .../example_win32_directx10.vcxproj.filters | 60 + .../examples/example_win32_directx10/main.cpp | 261 + .../example_win32_directx11/build_win32.bat | 9 + .../example_win32_directx11.vcxproj | 170 + .../example_win32_directx11.vcxproj.filters | 60 + .../examples/example_win32_directx11/main.cpp | 283 + .../example_win32_directx12/build_win32.bat | 9 + .../example_win32_directx12.vcxproj | 172 + .../example_win32_directx12.vcxproj.filters | 57 + .../examples/example_win32_directx12/main.cpp | 483 + .../example_win32_directx9/build_win32.bat | 8 + .../example_win32_directx9.vcxproj | 171 + .../example_win32_directx9.vcxproj.filters | 61 + .../examples/example_win32_directx9/main.cpp | 269 + .../Lib/ImGui/examples/imgui_examples.sln | 128 + .../Lib/ImGui/examples/libs/glfw/COPYING.txt | 22 + .../examples/libs/glfw/include/GLFW/glfw3.h | 4227 +++ .../libs/glfw/include/GLFW/glfw3native.h | 456 + .../libs/glfw/lib-vc2010-32/glfw3.lib | Bin 0 -> 187376 bytes .../libs/glfw/lib-vc2010-64/glfw3.lib | Bin 0 -> 291120 bytes .../ImGui/examples/libs/usynergy/README.txt | 8 + .../ImGui/examples/libs/usynergy/uSynergy.c | 636 + .../ImGui/examples/libs/usynergy/uSynergy.h | 420 + .../libultraship/Lib/ImGui/imconfig.h | 124 + libultraship/libultraship/Lib/ImGui/imgui.cpp | 18796 ++++++++++++ libultraship/libultraship/Lib/ImGui/imgui.h | 3300 +++ .../libultraship/Lib/ImGui/imgui_demo.cpp | 8212 ++++++ .../libultraship/Lib/ImGui/imgui_draw.cpp | 4190 +++ .../libultraship/Lib/ImGui/imgui_internal.h | 3220 +++ .../libultraship/Lib/ImGui/imgui_tables.cpp | 4054 +++ .../libultraship/Lib/ImGui/imgui_widgets.cpp | 8428 ++++++ .../libultraship/Lib/ImGui/imstb_rectpack.h | 639 + .../libultraship/Lib/ImGui/imstb_textedit.h | 1449 + .../libultraship/Lib/ImGui/imstb_truetype.h | 4903 ++++ .../libultraship/Lib/ImGui/misc/README.txt | 23 + .../Lib/ImGui/misc/cpp/README.txt | 13 + .../Lib/ImGui/misc/cpp/imgui_stdlib.cpp | 72 + .../Lib/ImGui/misc/cpp/imgui_stdlib.h | 18 + .../Lib/ImGui/misc/debuggers/README.txt | 16 + .../Lib/ImGui/misc/debuggers/imgui.gdb | 12 + .../ImGui/misc/debuggers/imgui.natstepfilter | 30 + .../Lib/ImGui/misc/debuggers/imgui.natvis | 62 + .../Lib/ImGui/misc/fonts/Cousine-Regular.ttf | Bin 0 -> 43912 bytes .../Lib/ImGui/misc/fonts/DroidSans.ttf | Bin 0 -> 190044 bytes .../Lib/ImGui/misc/fonts/Karla-Regular.ttf | Bin 0 -> 16848 bytes .../Lib/ImGui/misc/fonts/ProggyClean.ttf | Bin 0 -> 41208 bytes .../Lib/ImGui/misc/fonts/ProggyTiny.ttf | Bin 0 -> 35656 bytes .../Lib/ImGui/misc/fonts/Roboto-Medium.ttf | Bin 0 -> 162588 bytes .../misc/fonts/binary_to_compressed_c.cpp | 385 + .../Lib/ImGui/misc/freetype/README.md | 37 + .../ImGui/misc/freetype/imgui_freetype.cpp | 779 + .../Lib/ImGui/misc/freetype/imgui_freetype.h | 50 + .../misc/single_file/imgui_single_file.h | 18 + libultraship/libultraship/Lib/SDL/BUGS.txt | 16 + libultraship/libultraship/Lib/SDL/COPYING.txt | 20 + .../libultraship/Lib/SDL/README-SDL.txt | 13 + libultraship/libultraship/Lib/SDL/README.txt | 21 + libultraship/libultraship/Lib/SDL/SDL2/SDL.h | 232 + .../libultraship/Lib/SDL/SDL2/SDL_assert.h | 324 + .../libultraship/Lib/SDL/SDL2/SDL_atomic.h | 395 + .../libultraship/Lib/SDL/SDL2/SDL_audio.h | 1464 + .../libultraship/Lib/SDL/SDL2/SDL_bits.h | 126 + .../libultraship/Lib/SDL/SDL2/SDL_blendmode.h | 200 + .../libultraship/Lib/SDL/SDL2/SDL_clipboard.h | 94 + .../libultraship/Lib/SDL/SDL2/SDL_config.h | 57 + .../Lib/SDL/SDL2/SDL_config.h.cmake | 575 + .../libultraship/Lib/SDL/SDL2/SDL_config.h.in | 480 + .../Lib/SDL/SDL2/SDL_config_android.h | 192 + .../Lib/SDL/SDL2/SDL_config_emscripten.h | 216 + .../Lib/SDL/SDL2/SDL_config_iphoneos.h | 215 + .../Lib/SDL/SDL2/SDL_config_macosx.h | 280 + .../Lib/SDL/SDL2/SDL_config_minimal.h | 88 + .../Lib/SDL/SDL2/SDL_config_os2.h | 205 + .../Lib/SDL/SDL2/SDL_config_pandora.h | 140 + .../Lib/SDL/SDL2/SDL_config_psp.h | 165 + .../Lib/SDL/SDL2/SDL_config_windows.h | 305 + .../Lib/SDL/SDL2/SDL_config_winrt.h | 258 + .../Lib/SDL/SDL2/SDL_config_wiz.h | 154 + .../libultraship/Lib/SDL/SDL2/SDL_copying.h | 20 + .../libultraship/Lib/SDL/SDL2/SDL_cpuinfo.h | 559 + .../libultraship/Lib/SDL/SDL2/SDL_egl.h | 2302 ++ .../libultraship/Lib/SDL/SDL2/SDL_endian.h | 317 + .../libultraship/Lib/SDL/SDL2/SDL_error.h | 163 + .../libultraship/Lib/SDL/SDL2/SDL_events.h | 1135 + .../Lib/SDL/SDL2/SDL_filesystem.h | 145 + .../Lib/SDL/SDL2/SDL_gamecontroller.h | 1001 + .../libultraship/Lib/SDL/SDL2/SDL_gesture.h | 117 + .../libultraship/Lib/SDL/SDL2/SDL_haptic.h | 1341 + .../libultraship/Lib/SDL/SDL2/SDL_hidapi.h | 451 + .../libultraship/Lib/SDL/SDL2/SDL_hints.h | 1967 ++ .../libultraship/Lib/SDL/SDL2/SDL_joystick.h | 946 + .../libultraship/Lib/SDL/SDL2/SDL_keyboard.h | 316 + .../libultraship/Lib/SDL/SDL2/SDL_keycode.h | 353 + .../libultraship/Lib/SDL/SDL2/SDL_loadso.h | 115 + .../libultraship/Lib/SDL/SDL2/SDL_locale.h | 103 + .../libultraship/Lib/SDL/SDL2/SDL_log.h | 404 + .../libultraship/Lib/SDL/SDL2/SDL_main.h | 235 + .../Lib/SDL/SDL2/SDL_messagebox.h | 193 + .../libultraship/Lib/SDL/SDL2/SDL_metal.h | 112 + .../libultraship/Lib/SDL/SDL2/SDL_misc.h | 79 + .../libultraship/Lib/SDL/SDL2/SDL_mouse.h | 454 + .../libultraship/Lib/SDL/SDL2/SDL_mutex.h | 471 + .../libultraship/Lib/SDL/SDL2/SDL_name.h | 33 + .../libultraship/Lib/SDL/SDL2/SDL_opengl.h | 2183 ++ .../Lib/SDL/SDL2/SDL_opengl_glext.h | 11180 ++++++++ .../libultraship/Lib/SDL/SDL2/SDL_opengles.h | 39 + .../libultraship/Lib/SDL/SDL2/SDL_opengles2.h | 52 + .../Lib/SDL/SDL2/SDL_opengles2_gl2.h | 621 + .../Lib/SDL/SDL2/SDL_opengles2_gl2ext.h | 2050 ++ .../Lib/SDL/SDL2/SDL_opengles2_gl2platform.h | 30 + .../Lib/SDL/SDL2/SDL_opengles2_khrplatform.h | 282 + .../libultraship/Lib/SDL/SDL2/SDL_pixels.h | 644 + .../libultraship/Lib/SDL/SDL2/SDL_platform.h | 235 + .../libultraship/Lib/SDL/SDL2/SDL_power.h | 88 + .../libultraship/Lib/SDL/SDL2/SDL_quit.h | 58 + .../libultraship/Lib/SDL/SDL2/SDL_rect.h | 224 + .../libultraship/Lib/SDL/SDL2/SDL_render.h | 1890 ++ .../libultraship/Lib/SDL/SDL2/SDL_revision.h | 2 + .../Lib/SDL/SDL2/SDL_revision.h.cmake | 6 + .../libultraship/Lib/SDL/SDL2/SDL_rwops.h | 855 + .../libultraship/Lib/SDL/SDL2/SDL_scancode.h | 413 + .../libultraship/Lib/SDL/SDL2/SDL_sensor.h | 301 + .../libultraship/Lib/SDL/SDL2/SDL_shape.h | 155 + .../libultraship/Lib/SDL/SDL2/SDL_stdinc.h | 719 + .../libultraship/Lib/SDL/SDL2/SDL_surface.h | 995 + .../libultraship/Lib/SDL/SDL2/SDL_system.h | 563 + .../libultraship/Lib/SDL/SDL2/SDL_syswm.h | 384 + .../libultraship/Lib/SDL/SDL2/SDL_test.h | 69 + .../Lib/SDL/SDL2/SDL_test_assert.h | 105 + .../Lib/SDL/SDL2/SDL_test_common.h | 235 + .../Lib/SDL/SDL2/SDL_test_compare.h | 69 + .../Lib/SDL/SDL2/SDL_test_crc32.h | 124 + .../libultraship/Lib/SDL/SDL2/SDL_test_font.h | 81 + .../Lib/SDL/SDL2/SDL_test_fuzzer.h | 386 + .../Lib/SDL/SDL2/SDL_test_harness.h | 134 + .../Lib/SDL/SDL2/SDL_test_images.h | 78 + .../libultraship/Lib/SDL/SDL2/SDL_test_log.h | 67 + .../libultraship/Lib/SDL/SDL2/SDL_test_md5.h | 129 + .../Lib/SDL/SDL2/SDL_test_memory.h | 63 + .../Lib/SDL/SDL2/SDL_test_random.h | 115 + .../libultraship/Lib/SDL/SDL2/SDL_thread.h | 464 + .../libultraship/Lib/SDL/SDL2/SDL_timer.h | 222 + .../libultraship/Lib/SDL/SDL2/SDL_touch.h | 142 + .../libultraship/Lib/SDL/SDL2/SDL_types.h | 29 + .../libultraship/Lib/SDL/SDL2/SDL_version.h | 188 + .../libultraship/Lib/SDL/SDL2/SDL_video.h | 2088 ++ .../libultraship/Lib/SDL/SDL2/SDL_vulkan.h | 215 + .../libultraship/Lib/SDL/SDL2/begin_code.h | 187 + .../libultraship/Lib/SDL/SDL2/close_code.h | 40 + .../libultraship/Lib/SDL/WhatsNew.txt | 643 + .../libultraship/Lib/SDL/lib/x64/SDL2.lib | Bin 0 -> 16880106 bytes .../libultraship/Lib/SDL/lib/x64/SDL2main.lib | Bin 0 -> 35306 bytes .../libultraship/Lib/SDL/lib/x86/SDL2.lib | Bin 0 -> 18352314 bytes .../libultraship/Lib/SDL/lib/x86/SDL2main.lib | Bin 0 -> 55438 bytes .../libultraship/Lib/StormLib/StormLib.h | 1140 + .../libultraship/Lib/StormLib/StormPort.h | 445 + libultraship/libultraship/Lib/StrHash64.cpp | 250 + libultraship/libultraship/Lib/StrHash64.h | 99 + libultraship/libultraship/Lib/mINI/.gitignore | 7 + libultraship/libultraship/Lib/mINI/.gitrepo | 12 + .../libultraship/Lib/mINI/CHANGELOG.md | 41 + libultraship/libultraship/Lib/mINI/LICENSE | 19 + libultraship/libultraship/Lib/mINI/README.md | 332 + .../libultraship/Lib/mINI/src/mini/ini.h | 761 + .../libultraship/Lib/mINI/tests/build.bat | 7 + .../libultraship/Lib/mINI/tests/build.sh | 6 + .../libultraship/Lib/mINI/tests/building.txt | 25 + .../libultraship/Lib/mINI/tests/clean.bat | 3 + .../libultraship/Lib/mINI/tests/clean.sh | 3 + .../Lib/mINI/tests/lest/LICENSE.txt | 23 + .../libultraship/Lib/mINI/tests/lest/lest.hpp | 1392 + .../libultraship/Lib/mINI/tests/run.bat | 7 + .../libultraship/Lib/mINI/tests/run.sh | 6 + .../Lib/mINI/tests/testcasesens.cpp | 100 + .../libultraship/Lib/mINI/tests/testcopy.cpp | 77 + .../Lib/mINI/tests/testgenerate.cpp | 287 + .../libultraship/Lib/mINI/tests/testhuge.cpp | 59 + .../libultraship/Lib/mINI/tests/testread.cpp | 454 + .../libultraship/Lib/mINI/tests/testutf8.cpp | 68 + .../libultraship/Lib/mINI/tests/testwrite.cpp | 747 + .../libultraship/Lib/spdlog/.clang-format | 109 + .../libultraship/Lib/spdlog/.clang-tidy | 54 + .../libultraship/Lib/spdlog/.gitattributes | 1 + .../libultraship/Lib/spdlog/.gitignore | 83 + libultraship/libultraship/Lib/spdlog/.gitrepo | 12 + .../libultraship/Lib/spdlog/.travis.yml | 152 + .../libultraship/Lib/spdlog/CMakeLists.txt | 313 + libultraship/libultraship/Lib/spdlog/INSTALL | 24 + libultraship/libultraship/Lib/spdlog/LICENSE | 26 + .../libultraship/Lib/spdlog/README.md | 437 + .../libultraship/Lib/spdlog/appveyor.yml | 78 + .../Lib/spdlog/bench/CMakeLists.txt | 40 + .../Lib/spdlog/bench/async_bench.cpp | 184 + .../libultraship/Lib/spdlog/bench/bench.cpp | 246 + .../Lib/spdlog/bench/formatter-bench.cpp | 80 + .../libultraship/Lib/spdlog/bench/latency.cpp | 177 + .../libultraship/Lib/spdlog/bench/utils.h | 34 + .../libultraship/Lib/spdlog/cmake/ide.cmake | 18 + .../libultraship/Lib/spdlog/cmake/pch.h.in | 258 + .../Lib/spdlog/cmake/spdlog.pc.in | 13 + .../Lib/spdlog/cmake/spdlogCPack.cmake | 60 + .../Lib/spdlog/cmake/spdlogConfig.cmake.in | 19 + .../libultraship/Lib/spdlog/cmake/utils.cmake | 62 + .../Lib/spdlog/cmake/version.rc.in | 42 + .../Lib/spdlog/example/CMakeLists.txt | 23 + .../Lib/spdlog/example/example.cpp | 306 + .../Lib/spdlog/include/spdlog/async.h | 93 + .../spdlog/include/spdlog/async_logger-inl.h | 92 + .../Lib/spdlog/include/spdlog/async_logger.h | 68 + .../Lib/spdlog/include/spdlog/cfg/argv.h | 44 + .../Lib/spdlog/include/spdlog/cfg/env.h | 38 + .../spdlog/include/spdlog/cfg/helpers-inl.h | 120 + .../Lib/spdlog/include/spdlog/cfg/helpers.h | 29 + .../Lib/spdlog/include/spdlog/common-inl.h | 78 + .../Lib/spdlog/include/spdlog/common.h | 276 + .../include/spdlog/details/backtracer-inl.h | 69 + .../include/spdlog/details/backtracer.h | 45 + .../include/spdlog/details/circular_q.h | 141 + .../include/spdlog/details/console_globals.h | 32 + .../include/spdlog/details/file_helper-inl.h | 147 + .../include/spdlog/details/file_helper.h | 59 + .../include/spdlog/details/fmt_helper.h | 117 + .../include/spdlog/details/log_msg-inl.h | 37 + .../spdlog/include/spdlog/details/log_msg.h | 37 + .../spdlog/details/log_msg_buffer-inl.h | 58 + .../include/spdlog/details/log_msg_buffer.h | 33 + .../include/spdlog/details/mpmc_blocking_q.h | 126 + .../include/spdlog/details/null_mutex.h | 49 + .../spdlog/include/spdlog/details/os-inl.h | 599 + .../Lib/spdlog/include/spdlog/details/os.h | 118 + .../spdlog/details/periodic_worker-inl.h | 49 + .../include/spdlog/details/periodic_worker.h | 40 + .../include/spdlog/details/registry-inl.h | 313 + .../spdlog/include/spdlog/details/registry.h | 115 + .../spdlog/details/synchronous_factory.h | 24 + .../spdlog/details/tcp_client-windows.h | 162 + .../include/spdlog/details/tcp_client.h | 146 + .../include/spdlog/details/thread_pool-inl.h | 129 + .../include/spdlog/details/thread_pool.h | 120 + .../spdlog/details/udp_client-windows.h | 110 + .../include/spdlog/details/udp_client.h | 93 + .../include/spdlog/details/windows_include.h | 11 + .../spdlog/include/spdlog/fmt/bin_to_hex.h | 217 + .../spdlog/include/spdlog/fmt/bundled/args.h | 232 + .../include/spdlog/fmt/bundled/chrono.h | 1308 + .../spdlog/include/spdlog/fmt/bundled/color.h | 627 + .../include/spdlog/fmt/bundled/compile.h | 639 + .../spdlog/include/spdlog/fmt/bundled/core.h | 3002 ++ .../include/spdlog/fmt/bundled/format-inl.h | 2620 ++ .../include/spdlog/fmt/bundled/format.h | 2830 ++ .../include/spdlog/fmt/bundled/locale.h | 2 + .../spdlog/include/spdlog/fmt/bundled/os.h | 515 + .../include/spdlog/fmt/bundled/ostream.h | 181 + .../include/spdlog/fmt/bundled/printf.h | 652 + .../include/spdlog/fmt/bundled/ranges.h | 468 + .../spdlog/include/spdlog/fmt/bundled/xchar.h | 236 + .../Lib/spdlog/include/spdlog/fmt/chrono.h | 20 + .../Lib/spdlog/include/spdlog/fmt/compile.h | 20 + .../Lib/spdlog/include/spdlog/fmt/fmt.h | 27 + .../Lib/spdlog/include/spdlog/fmt/ostr.h | 20 + .../Lib/spdlog/include/spdlog/fmt/xchar.h | 20 + .../Lib/spdlog/include/spdlog/formatter.h | 18 + .../Lib/spdlog/include/spdlog/fwd.h | 14 + .../Lib/spdlog/include/spdlog/logger-inl.h | 257 + .../Lib/spdlog/include/spdlog/logger.h | 410 + .../include/spdlog/pattern_formatter-inl.h | 1395 + .../spdlog/include/spdlog/pattern_formatter.h | 126 + .../include/spdlog/sinks/android_sink.h | 119 + .../include/spdlog/sinks/ansicolor_sink-inl.h | 145 + .../include/spdlog/sinks/ansicolor_sink.h | 118 + .../include/spdlog/sinks/base_sink-inl.h | 63 + .../spdlog/include/spdlog/sinks/base_sink.h | 52 + .../spdlog/sinks/basic_file_sink-inl.h | 43 + .../include/spdlog/sinks/basic_file_sink.h | 58 + .../include/spdlog/sinks/daily_file_sink.h | 242 + .../spdlog/include/spdlog/sinks/dist_sink.h | 97 + .../include/spdlog/sinks/dup_filter_sink.h | 94 + .../include/spdlog/sinks/hourly_file_sink.h | 194 + .../spdlog/include/spdlog/sinks/mongo_sink.h | 99 + .../spdlog/include/spdlog/sinks/msvc_sink.h | 48 + .../spdlog/include/spdlog/sinks/null_sink.h | 44 + .../include/spdlog/sinks/ostream_sink.h | 50 + .../spdlog/include/spdlog/sinks/qt_sinks.h | 93 + .../include/spdlog/sinks/ringbuffer_sink.h | 74 + .../spdlog/sinks/rotating_file_sink-inl.h | 131 + .../include/spdlog/sinks/rotating_file_sink.h | 78 + .../spdlog/include/spdlog/sinks/sink-inl.h | 25 + .../Lib/spdlog/include/spdlog/sinks/sink.h | 35 + .../include/spdlog/sinks/sohconsole_sink.h | 80 + .../spdlog/sinks/stdout_color_sinks-inl.h | 38 + .../include/spdlog/sinks/stdout_color_sinks.h | 45 + .../include/spdlog/sinks/stdout_sinks-inl.h | 139 + .../include/spdlog/sinks/stdout_sinks.h | 87 + .../spdlog/include/spdlog/sinks/syslog_sink.h | 109 + .../include/spdlog/sinks/systemd_sink.h | 103 + .../spdlog/include/spdlog/sinks/tcp_sink.h | 81 + .../spdlog/include/spdlog/sinks/udp_sink.h | 74 + .../include/spdlog/sinks/win_eventlog_sink.h | 276 + .../include/spdlog/sinks/wincolor_sink-inl.h | 175 + .../include/spdlog/sinks/wincolor_sink.h | 85 + .../Lib/spdlog/include/spdlog/spdlog-inl.h | 125 + .../Lib/spdlog/include/spdlog/spdlog.h | 345 + .../Lib/spdlog/include/spdlog/stopwatch.h | 61 + .../Lib/spdlog/include/spdlog/tweakme.h | 124 + .../Lib/spdlog/include/spdlog/version.h | 10 + .../Lib/spdlog/logos/jetbrains-variant-4.svg | 43 + .../Lib/spdlog/scripts/extract_version.py | 17 + .../libultraship/Lib/spdlog/scripts/format.sh | 16 + .../libultraship/Lib/spdlog/src/async.cpp | 13 + .../libultraship/Lib/spdlog/src/cfg.cpp | 8 + .../Lib/spdlog/src/color_sinks.cpp | 51 + .../Lib/spdlog/src/file_sinks.cpp | 20 + .../libultraship/Lib/spdlog/src/fmt.cpp | 68 + .../libultraship/Lib/spdlog/src/spdlog.cpp | 26 + .../Lib/spdlog/src/stdout_sinks.cpp | 29 + .../Lib/spdlog/tests/CMakeLists.txt | 70 + .../libultraship/Lib/spdlog/tests/catch.hpp | 17959 ++++++++++++ .../Lib/spdlog/tests/catch.license | 23 + .../libultraship/Lib/spdlog/tests/includes.h | 26 + .../libultraship/Lib/spdlog/tests/main.cpp | 2 + .../Lib/spdlog/tests/test_async.cpp | 190 + .../Lib/spdlog/tests/test_backtrace.cpp | 65 + .../Lib/spdlog/tests/test_cfg.cpp | 183 + .../Lib/spdlog/tests/test_create_dir.cpp | 75 + .../Lib/spdlog/tests/test_daily_logger.cpp | 168 + .../Lib/spdlog/tests/test_dup_filter.cpp | 90 + .../Lib/spdlog/tests/test_errors.cpp | 121 + .../Lib/spdlog/tests/test_eventlog.cpp | 71 + .../Lib/spdlog/tests/test_file_helper.cpp | 101 + .../Lib/spdlog/tests/test_file_logging.cpp | 100 + .../Lib/spdlog/tests/test_fmt_helper.cpp | 86 + .../Lib/spdlog/tests/test_macros.cpp | 62 + .../Lib/spdlog/tests/test_misc.cpp | 271 + .../Lib/spdlog/tests/test_mpmc_q.cpp | 106 + .../spdlog/tests/test_pattern_formatter.cpp | 458 + .../Lib/spdlog/tests/test_registry.cpp | 116 + .../libultraship/Lib/spdlog/tests/test_sink.h | 79 + .../Lib/spdlog/tests/test_stdout_api.cpp | 98 + .../Lib/spdlog/tests/test_stopwatch.cpp | 35 + .../Lib/spdlog/tests/test_systemd.cpp | 15 + .../Lib/spdlog/tests/test_time_point.cpp | 36 + .../libultraship/Lib/spdlog/tests/utils.cpp | 127 + .../libultraship/Lib/spdlog/tests/utils.h | 18 + libultraship/libultraship/Lib/stb/stb_image.h | 7897 ++++++ .../libultraship/Lib/stb/stb_image_write.h | 1724 ++ libultraship/libultraship/Lib/stb/stb_impl.c | 2 + .../libultraship/Lib/tinyxml2/tinyxml2.cpp | 2837 ++ .../libultraship/Lib/tinyxml2/tinyxml2.h | 2309 ++ libultraship/libultraship/Material.cpp | 72 + libultraship/libultraship/Material.h | 48 + libultraship/libultraship/Matrix.cpp | 13 + libultraship/libultraship/Matrix.h | 18 + libultraship/libultraship/MemoryPack.cpp | 5 + libultraship/libultraship/MemoryPack.h | 7 + libultraship/libultraship/ModManager.cpp | 23 + libultraship/libultraship/ModManager.h | 12 + libultraship/libultraship/ModModule.h | 19 + libultraship/libultraship/Model.cpp | 93 + libultraship/libultraship/Model.h | 69 + libultraship/libultraship/Path.cpp | 33 + libultraship/libultraship/Path.h | 23 + libultraship/libultraship/PlayerAnimation.cpp | 19 + libultraship/libultraship/PlayerAnimation.h | 23 + libultraship/libultraship/Resource.cpp | 61 + libultraship/libultraship/Resource.h | 110 + libultraship/libultraship/ResourceMgr.cpp | 307 + libultraship/libultraship/ResourceMgr.h | 62 + libultraship/libultraship/RumblePack.cpp | 5 + libultraship/libultraship/RumblePack.h | 7 + libultraship/libultraship/SDLAudioPlayer.cpp | 41 + libultraship/libultraship/SDLAudioPlayer.h | 18 + libultraship/libultraship/SDLController.cpp | 434 + libultraship/libultraship/SDLController.h | 36 + libultraship/libultraship/Scene.cpp | 439 + libultraship/libultraship/Scene.h | 398 + libultraship/libultraship/Skeleton.cpp | 29 + libultraship/libultraship/Skeleton.h | 31 + libultraship/libultraship/SkeletonLimb.cpp | 81 + libultraship/libultraship/SkeletonLimb.h | 84 + libultraship/libultraship/SohConsole.cpp | 328 + libultraship/libultraship/SohConsole.h | 81 + libultraship/libultraship/SohHooks.cpp | 125 + libultraship/libultraship/SohHooks.h | 79 + libultraship/libultraship/SohImGuiImpl.cpp | 481 + libultraship/libultraship/SohImGuiImpl.h | 57 + libultraship/libultraship/StormLibDUS32.lib | Bin 0 -> 2605152 bytes libultraship/libultraship/StormLibDUS64.lib | Bin 0 -> 2923852 bytes libultraship/libultraship/StormLibRUS32.lib | Bin 0 -> 3035064 bytes libultraship/libultraship/StormLibRUS64.lib | Bin 0 -> 3248440 bytes libultraship/libultraship/Text.cpp | 22 + libultraship/libultraship/Text.h | 27 + libultraship/libultraship/Texture.cpp | 23 + libultraship/libultraship/Texture.h | 41 + libultraship/libultraship/TextureMod.cpp | 124 + libultraship/libultraship/TextureMod.h | 60 + libultraship/libultraship/UltraController.h | 183 + libultraship/libultraship/Utils.cpp | 49 + libultraship/libultraship/Utils.h | 8 + libultraship/libultraship/Vertex.cpp | 27 + libultraship/libultraship/Vertex.h | 27 + .../libultraship/WasapiAudioPlayer.cpp | 172 + libultraship/libultraship/WasapiAudioPlayer.h | 41 + libultraship/libultraship/Window.cpp | 387 + libultraship/libultraship/Window.h | 53 + libultraship/libultraship/WindowShim.cpp | 59 + libultraship/libultraship/WindowShim.h | 1 + libultraship/libultraship/abi.h | 493 + .../libultraship/libultraship.vcxproj | 422 + .../libultraship/libultraship.vcxproj.filters | 630 + libultraship/libultraship/luslog.cpp | 22 + libultraship/libultraship/luslog.h | 14 + libultraship/libultraship/mixer.c | 518 + libultraship/libultraship/mixer.h | 92 + libultraship/libultraship/stb_image_write.h | 1743 ++ libultraship/libultraship/stox.cpp | 63 + libultraship/libultraship/stox.h | 9 + 698 files changed, 302994 insertions(+) create mode 100644 libultraship/.gitignore create mode 100644 libultraship/.gitrepo create mode 100644 libultraship/LICENSE create mode 100644 libultraship/Makefile create mode 100644 libultraship/TestApp/Main.cpp create mode 100644 libultraship/TestApp/StormLibDUS.lib create mode 100644 libultraship/TestApp/TestApp.vcxproj create mode 100644 libultraship/TestApp/TestApp.vcxproj.filters create mode 100644 libultraship/libultraship.sln create mode 100644 libultraship/libultraship/Animation.cpp create mode 100644 libultraship/libultraship/Animation.h create mode 100644 libultraship/libultraship/Archive.cpp create mode 100644 libultraship/libultraship/Archive.h create mode 100644 libultraship/libultraship/Array.cpp create mode 100644 libultraship/libultraship/Array.h create mode 100644 libultraship/libultraship/AudioPlayer.h create mode 100644 libultraship/libultraship/Blob.cpp create mode 100644 libultraship/libultraship/Blob.h create mode 100644 libultraship/libultraship/CollisionHeader.cpp create mode 100644 libultraship/libultraship/CollisionHeader.h create mode 100644 libultraship/libultraship/ConfigFile.cpp create mode 100644 libultraship/libultraship/ConfigFile.h create mode 100644 libultraship/libultraship/Controller.cpp create mode 100644 libultraship/libultraship/Controller.h create mode 100644 libultraship/libultraship/ControllerAttachment.cpp create mode 100644 libultraship/libultraship/ControllerAttachment.h create mode 100644 libultraship/libultraship/Cutscene.cpp create mode 100644 libultraship/libultraship/Cutscene.h create mode 100644 libultraship/libultraship/Cvar.cpp create mode 100644 libultraship/libultraship/Cvar.h create mode 100644 libultraship/libultraship/DisplayList.cpp create mode 100644 libultraship/libultraship/DisplayList.h create mode 100644 libultraship/libultraship/Environment.cpp create mode 100644 libultraship/libultraship/Environment.h create mode 100644 libultraship/libultraship/Factories/AnimationFactory.cpp create mode 100644 libultraship/libultraship/Factories/AnimationFactory.h create mode 100644 libultraship/libultraship/Factories/ArrayFactory.cpp create mode 100644 libultraship/libultraship/Factories/ArrayFactory.h create mode 100644 libultraship/libultraship/Factories/BlobFactory.cpp create mode 100644 libultraship/libultraship/Factories/BlobFactory.h create mode 100644 libultraship/libultraship/Factories/CollisionHeaderFactory.cpp create mode 100644 libultraship/libultraship/Factories/CollisionHeaderFactory.h create mode 100644 libultraship/libultraship/Factories/CutsceneFactory.cpp create mode 100644 libultraship/libultraship/Factories/CutsceneFactory.h create mode 100644 libultraship/libultraship/Factories/DisplayListFactory.cpp create mode 100644 libultraship/libultraship/Factories/DisplayListFactory.h create mode 100644 libultraship/libultraship/Factories/MaterialFactory.cpp create mode 100644 libultraship/libultraship/Factories/MaterialFactory.h create mode 100644 libultraship/libultraship/Factories/MtxFactory.cpp create mode 100644 libultraship/libultraship/Factories/MtxFactory.h create mode 100644 libultraship/libultraship/Factories/OTRResourceLoader.cpp create mode 100644 libultraship/libultraship/Factories/PathFactory.cpp create mode 100644 libultraship/libultraship/Factories/PathFactory.h create mode 100644 libultraship/libultraship/Factories/PlayerAnimationFactory.cpp create mode 100644 libultraship/libultraship/Factories/PlayerAnimationFactory.h create mode 100644 libultraship/libultraship/Factories/ResourceLoader.cpp create mode 100644 libultraship/libultraship/Factories/ResourceLoader.h create mode 100644 libultraship/libultraship/Factories/SceneFactory.cpp create mode 100644 libultraship/libultraship/Factories/SceneFactory.h create mode 100644 libultraship/libultraship/Factories/SkeletonFactory.cpp create mode 100644 libultraship/libultraship/Factories/SkeletonFactory.h create mode 100644 libultraship/libultraship/Factories/SkeletonLimbFactory.cpp create mode 100644 libultraship/libultraship/Factories/SkeletonLimbFactory.h create mode 100644 libultraship/libultraship/Factories/TextFactory.cpp create mode 100644 libultraship/libultraship/Factories/TextFactory.h create mode 100644 libultraship/libultraship/Factories/TextureFactory.cpp create mode 100644 libultraship/libultraship/Factories/TextureFactory.h create mode 100644 libultraship/libultraship/Factories/VtxFactory.cpp create mode 100644 libultraship/libultraship/Factories/VtxFactory.h create mode 100644 libultraship/libultraship/File.cpp create mode 100644 libultraship/libultraship/File.h create mode 100644 libultraship/libultraship/GameSettings.cpp create mode 100644 libultraship/libultraship/GameSettings.h create mode 100644 libultraship/libultraship/GlobalCtx2.cpp create mode 100644 libultraship/libultraship/GlobalCtx2.h create mode 100644 libultraship/libultraship/KeyboardController.cpp create mode 100644 libultraship/libultraship/KeyboardController.h create mode 100644 libultraship/libultraship/LUSMacros.h create mode 100644 libultraship/libultraship/Lib/Fast3D/.gitrepo create mode 100644 libultraship/libultraship/Lib/Fast3D/LICENSE.txt create mode 100644 libultraship/libultraship/Lib/Fast3D/README.md create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/abi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/convert.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/exception.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gs2dex.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gu.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/hardware.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/internal.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/interrupt.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/message.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/motor.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pfs.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/printf.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/r4300.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rcp.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rdp.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rsp.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/sptask.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/thread.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/time.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/types.h create mode 100644 libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/vi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12.h create mode 100644 libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12sdklayers.h create mode 100644 libultraship/libultraship/Lib/Fast3D/dxsdk/d3dcommon.h create mode 100644 libultraship/libultraship/Lib/Fast3D/dxsdk/d3dx12.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_cc.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_cc.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d12_guids.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_dxgi.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_glx.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_glx.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_opengl.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_pc.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_rendering_api.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_screen_config.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_sdl.h create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp create mode 100644 libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h create mode 100644 libultraship/libultraship/Lib/GLEW/GL/eglew.h create mode 100644 libultraship/libultraship/Lib/GLEW/GL/glew.h create mode 100644 libultraship/libultraship/Lib/GLEW/GL/glxew.h create mode 100644 libultraship/libultraship/Lib/GLEW/GL/wglew.h create mode 100644 libultraship/libultraship/Lib/GLEW/x64/glew32.dll create mode 100644 libultraship/libultraship/Lib/GLEW/x64/glew32.lib create mode 100644 libultraship/libultraship/Lib/GLEW/x64/glew32s.lib create mode 100644 libultraship/libultraship/Lib/GLEW/x86/glew32.dll create mode 100644 libultraship/libultraship/Lib/GLEW/x86/glew32.lib create mode 100644 libultraship/libultraship/Lib/GLEW/x86/glew32s.lib create mode 100644 libultraship/libultraship/Lib/GLFW/GLFW/glfw3.h create mode 100644 libultraship/libultraship/Lib/GLFW/GLFW/glfw3native.h create mode 100644 libultraship/libultraship/Lib/GLFW/GLFW/glfw_config.h create mode 100644 libultraship/libultraship/Lib/GLFW/glfw3.dll create mode 100644 libultraship/libultraship/Lib/GLFW/glfw3dll.exp create mode 100644 libultraship/libultraship/Lib/GLFW/glfw3dll.lib create mode 100644 libultraship/libultraship/Lib/ImGui/.editorconfig create mode 100644 libultraship/libultraship/Lib/ImGui/.gitattributes create mode 100644 libultraship/libultraship/Lib/ImGui/.gitignore create mode 100644 libultraship/libultraship/Lib/ImGui/LICENSE.txt create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.mm create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3_loader.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.mm create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.h create mode 100644 libultraship/libultraship/Lib/ImGui/backends/vulkan/generate_spv.sh create mode 100644 libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.frag create mode 100644 libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.vert create mode 100644 libultraship/libultraship/Lib/ImGui/docs/BACKENDS.md create mode 100644 libultraship/libultraship/Lib/ImGui/docs/CHANGELOG.txt create mode 100644 libultraship/libultraship/Lib/ImGui/docs/EXAMPLES.md create mode 100644 libultraship/libultraship/Lib/ImGui/docs/FAQ.md create mode 100644 libultraship/libultraship/Lib/ImGui/docs/FONTS.md create mode 100644 libultraship/libultraship/Lib/ImGui/docs/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/docs/TODO.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/README.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_allegro5/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_allegro5/imconfig_allegro5.h create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_allegro5/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/.gitignore create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/build.gradle create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/AndroidManifest.xml create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/java/MainActivity.kt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/build.gradle create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/settings.gradle create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/Info-iOS.plist create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/LaunchScreen.storyboard create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/Info-macOS.plist create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/MainMenu.storyboard create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/main.mm create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/main.mm create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/shell_minimal.html create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/main.mm create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win64.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_null/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_null/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_null/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/main.mm create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/Makefile create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/build_win32.bat create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters create mode 100644 libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/main.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/examples/imgui_examples.sln create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/glfw/COPYING.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3.h create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3native.h create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/glfw/lib-vc2010-32/glfw3.lib create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/glfw/lib-vc2010-64/glfw3.lib create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/README.txt create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.c create mode 100644 libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.h create mode 100644 libultraship/libultraship/Lib/ImGui/imconfig.h create mode 100644 libultraship/libultraship/Lib/ImGui/imgui.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/imgui.h create mode 100644 libultraship/libultraship/Lib/ImGui/imgui_demo.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/imgui_draw.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/imgui_internal.h create mode 100644 libultraship/libultraship/Lib/ImGui/imgui_tables.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/imstb_rectpack.h create mode 100644 libultraship/libultraship/Lib/ImGui/imstb_textedit.h create mode 100644 libultraship/libultraship/Lib/ImGui/imstb_truetype.h create mode 100644 libultraship/libultraship/Lib/ImGui/misc/README.txt create mode 100644 libultraship/libultraship/Lib/ImGui/misc/cpp/README.txt create mode 100644 libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.h create mode 100644 libultraship/libultraship/Lib/ImGui/misc/debuggers/README.txt create mode 100644 libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.gdb create mode 100644 libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natstepfilter create mode 100644 libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natvis create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/Cousine-Regular.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/DroidSans.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/Karla-Regular.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/ProggyClean.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/ProggyTiny.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/Roboto-Medium.ttf create mode 100644 libultraship/libultraship/Lib/ImGui/misc/fonts/binary_to_compressed_c.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/misc/freetype/README.md create mode 100644 libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.cpp create mode 100644 libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.h create mode 100644 libultraship/libultraship/Lib/ImGui/misc/single_file/imgui_single_file.h create mode 100644 libultraship/libultraship/Lib/SDL/BUGS.txt create mode 100644 libultraship/libultraship/Lib/SDL/COPYING.txt create mode 100644 libultraship/libultraship/Lib/SDL/README-SDL.txt create mode 100644 libultraship/libultraship/Lib/SDL/README.txt create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_assert.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_atomic.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_audio.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_bits.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_blendmode.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_clipboard.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.cmake create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.in create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_android.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_emscripten.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_iphoneos.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_macosx.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_minimal.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_os2.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_pandora.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_psp.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_windows.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_winrt.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_config_wiz.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_copying.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_cpuinfo.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_egl.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_endian.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_error.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_events.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_filesystem.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_gamecontroller.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_gesture.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_haptic.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_hidapi.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_hints.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_joystick.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_keyboard.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_keycode.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_loadso.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_locale.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_log.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_main.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_messagebox.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_metal.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_misc.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_mouse.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_mutex.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_name.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl_glext.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2ext.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2platform.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_khrplatform.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_pixels.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_platform.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_power.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_quit.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_rect.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_render.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h.cmake create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_rwops.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_scancode.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_sensor.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_shape.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_stdinc.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_surface.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_system.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_syswm.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_assert.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_common.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_compare.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_crc32.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_font.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_fuzzer.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_harness.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_images.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_log.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_md5.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_memory.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_test_random.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_thread.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_timer.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_touch.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_types.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_version.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_video.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/SDL_vulkan.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/begin_code.h create mode 100644 libultraship/libultraship/Lib/SDL/SDL2/close_code.h create mode 100644 libultraship/libultraship/Lib/SDL/WhatsNew.txt create mode 100644 libultraship/libultraship/Lib/SDL/lib/x64/SDL2.lib create mode 100644 libultraship/libultraship/Lib/SDL/lib/x64/SDL2main.lib create mode 100644 libultraship/libultraship/Lib/SDL/lib/x86/SDL2.lib create mode 100644 libultraship/libultraship/Lib/SDL/lib/x86/SDL2main.lib create mode 100644 libultraship/libultraship/Lib/StormLib/StormLib.h create mode 100644 libultraship/libultraship/Lib/StormLib/StormPort.h create mode 100644 libultraship/libultraship/Lib/StrHash64.cpp create mode 100644 libultraship/libultraship/Lib/StrHash64.h create mode 100644 libultraship/libultraship/Lib/mINI/.gitignore create mode 100644 libultraship/libultraship/Lib/mINI/.gitrepo create mode 100644 libultraship/libultraship/Lib/mINI/CHANGELOG.md create mode 100644 libultraship/libultraship/Lib/mINI/LICENSE create mode 100644 libultraship/libultraship/Lib/mINI/README.md create mode 100644 libultraship/libultraship/Lib/mINI/src/mini/ini.h create mode 100644 libultraship/libultraship/Lib/mINI/tests/build.bat create mode 100644 libultraship/libultraship/Lib/mINI/tests/build.sh create mode 100644 libultraship/libultraship/Lib/mINI/tests/building.txt create mode 100644 libultraship/libultraship/Lib/mINI/tests/clean.bat create mode 100644 libultraship/libultraship/Lib/mINI/tests/clean.sh create mode 100644 libultraship/libultraship/Lib/mINI/tests/lest/LICENSE.txt create mode 100644 libultraship/libultraship/Lib/mINI/tests/lest/lest.hpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/run.bat create mode 100644 libultraship/libultraship/Lib/mINI/tests/run.sh create mode 100644 libultraship/libultraship/Lib/mINI/tests/testcasesens.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testcopy.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testgenerate.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testhuge.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testread.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testutf8.cpp create mode 100644 libultraship/libultraship/Lib/mINI/tests/testwrite.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/.clang-format create mode 100644 libultraship/libultraship/Lib/spdlog/.clang-tidy create mode 100644 libultraship/libultraship/Lib/spdlog/.gitattributes create mode 100644 libultraship/libultraship/Lib/spdlog/.gitignore create mode 100644 libultraship/libultraship/Lib/spdlog/.gitrepo create mode 100644 libultraship/libultraship/Lib/spdlog/.travis.yml create mode 100644 libultraship/libultraship/Lib/spdlog/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/spdlog/INSTALL create mode 100644 libultraship/libultraship/Lib/spdlog/LICENSE create mode 100644 libultraship/libultraship/Lib/spdlog/README.md create mode 100644 libultraship/libultraship/Lib/spdlog/appveyor.yml create mode 100644 libultraship/libultraship/Lib/spdlog/bench/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/spdlog/bench/async_bench.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/bench/bench.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/bench/formatter-bench.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/bench/latency.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/bench/utils.h create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/ide.cmake create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/pch.h.in create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/spdlog.pc.in create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/spdlogCPack.cmake create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/spdlogConfig.cmake.in create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/utils.cmake create mode 100644 libultraship/libultraship/Lib/spdlog/cmake/version.rc.in create mode 100644 libultraship/libultraship/Lib/spdlog/example/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/spdlog/example/example.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/async.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/async_logger-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/async_logger.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/cfg/argv.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/cfg/env.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/cfg/helpers-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/cfg/helpers.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/common-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/common.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/backtracer-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/backtracer.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/circular_q.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/console_globals.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/file_helper-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/file_helper.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/fmt_helper.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/log_msg-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/log_msg.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/log_msg_buffer-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/log_msg_buffer.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/mpmc_blocking_q.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/null_mutex.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/os-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/os.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/periodic_worker-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/periodic_worker.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/registry-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/registry.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/synchronous_factory.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/tcp_client-windows.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/tcp_client.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/thread_pool-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/thread_pool.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/udp_client-windows.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/udp_client.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/details/windows_include.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bin_to_hex.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/args.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/chrono.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/color.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/compile.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/core.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/format-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/format.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/locale.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/os.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/ostream.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/printf.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/ranges.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/bundled/xchar.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/chrono.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/compile.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/fmt.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/ostr.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fmt/xchar.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/formatter.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/fwd.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/logger-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/logger.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/pattern_formatter-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/pattern_formatter.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/android_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/ansicolor_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/base_sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/base_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/basic_file_sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/basic_file_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/daily_file_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/dist_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/dup_filter_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/hourly_file_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/mongo_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/msvc_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/null_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/ostream_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/qt_sinks.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/ringbuffer_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/rotating_file_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/stdout_color_sinks.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/stdout_sinks-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/stdout_sinks.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/syslog_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/systemd_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/tcp_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/udp_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/win_eventlog_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/wincolor_sink-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/wincolor_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/spdlog-inl.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/spdlog.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/stopwatch.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/tweakme.h create mode 100644 libultraship/libultraship/Lib/spdlog/include/spdlog/version.h create mode 100644 libultraship/libultraship/Lib/spdlog/logos/jetbrains-variant-4.svg create mode 100644 libultraship/libultraship/Lib/spdlog/scripts/extract_version.py create mode 100644 libultraship/libultraship/Lib/spdlog/scripts/format.sh create mode 100644 libultraship/libultraship/Lib/spdlog/src/async.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/cfg.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/color_sinks.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/file_sinks.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/fmt.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/spdlog.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/src/stdout_sinks.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/CMakeLists.txt create mode 100644 libultraship/libultraship/Lib/spdlog/tests/catch.hpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/catch.license create mode 100644 libultraship/libultraship/Lib/spdlog/tests/includes.h create mode 100644 libultraship/libultraship/Lib/spdlog/tests/main.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_async.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_backtrace.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_cfg.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_create_dir.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_daily_logger.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_dup_filter.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_errors.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_eventlog.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_file_helper.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_file_logging.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_fmt_helper.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_macros.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_misc.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_mpmc_q.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_pattern_formatter.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_registry.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_sink.h create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_stdout_api.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_stopwatch.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_systemd.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/test_time_point.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/utils.cpp create mode 100644 libultraship/libultraship/Lib/spdlog/tests/utils.h create mode 100644 libultraship/libultraship/Lib/stb/stb_image.h create mode 100644 libultraship/libultraship/Lib/stb/stb_image_write.h create mode 100644 libultraship/libultraship/Lib/stb/stb_impl.c create mode 100644 libultraship/libultraship/Lib/tinyxml2/tinyxml2.cpp create mode 100644 libultraship/libultraship/Lib/tinyxml2/tinyxml2.h create mode 100644 libultraship/libultraship/Material.cpp create mode 100644 libultraship/libultraship/Material.h create mode 100644 libultraship/libultraship/Matrix.cpp create mode 100644 libultraship/libultraship/Matrix.h create mode 100644 libultraship/libultraship/MemoryPack.cpp create mode 100644 libultraship/libultraship/MemoryPack.h create mode 100644 libultraship/libultraship/ModManager.cpp create mode 100644 libultraship/libultraship/ModManager.h create mode 100644 libultraship/libultraship/ModModule.h create mode 100644 libultraship/libultraship/Model.cpp create mode 100644 libultraship/libultraship/Model.h create mode 100644 libultraship/libultraship/Path.cpp create mode 100644 libultraship/libultraship/Path.h create mode 100644 libultraship/libultraship/PlayerAnimation.cpp create mode 100644 libultraship/libultraship/PlayerAnimation.h create mode 100644 libultraship/libultraship/Resource.cpp create mode 100644 libultraship/libultraship/Resource.h create mode 100644 libultraship/libultraship/ResourceMgr.cpp create mode 100644 libultraship/libultraship/ResourceMgr.h create mode 100644 libultraship/libultraship/RumblePack.cpp create mode 100644 libultraship/libultraship/RumblePack.h create mode 100644 libultraship/libultraship/SDLAudioPlayer.cpp create mode 100644 libultraship/libultraship/SDLAudioPlayer.h create mode 100644 libultraship/libultraship/SDLController.cpp create mode 100644 libultraship/libultraship/SDLController.h create mode 100644 libultraship/libultraship/Scene.cpp create mode 100644 libultraship/libultraship/Scene.h create mode 100644 libultraship/libultraship/Skeleton.cpp create mode 100644 libultraship/libultraship/Skeleton.h create mode 100644 libultraship/libultraship/SkeletonLimb.cpp create mode 100644 libultraship/libultraship/SkeletonLimb.h create mode 100644 libultraship/libultraship/SohConsole.cpp create mode 100644 libultraship/libultraship/SohConsole.h create mode 100644 libultraship/libultraship/SohHooks.cpp create mode 100644 libultraship/libultraship/SohHooks.h create mode 100644 libultraship/libultraship/SohImGuiImpl.cpp create mode 100644 libultraship/libultraship/SohImGuiImpl.h create mode 100644 libultraship/libultraship/StormLibDUS32.lib create mode 100644 libultraship/libultraship/StormLibDUS64.lib create mode 100644 libultraship/libultraship/StormLibRUS32.lib create mode 100644 libultraship/libultraship/StormLibRUS64.lib create mode 100644 libultraship/libultraship/Text.cpp create mode 100644 libultraship/libultraship/Text.h create mode 100644 libultraship/libultraship/Texture.cpp create mode 100644 libultraship/libultraship/Texture.h create mode 100644 libultraship/libultraship/TextureMod.cpp create mode 100644 libultraship/libultraship/TextureMod.h create mode 100644 libultraship/libultraship/UltraController.h create mode 100644 libultraship/libultraship/Utils.cpp create mode 100644 libultraship/libultraship/Utils.h create mode 100644 libultraship/libultraship/Vertex.cpp create mode 100644 libultraship/libultraship/Vertex.h create mode 100644 libultraship/libultraship/WasapiAudioPlayer.cpp create mode 100644 libultraship/libultraship/WasapiAudioPlayer.h create mode 100644 libultraship/libultraship/Window.cpp create mode 100644 libultraship/libultraship/Window.h create mode 100644 libultraship/libultraship/WindowShim.cpp create mode 100644 libultraship/libultraship/WindowShim.h create mode 100644 libultraship/libultraship/abi.h create mode 100644 libultraship/libultraship/libultraship.vcxproj create mode 100644 libultraship/libultraship/libultraship.vcxproj.filters create mode 100644 libultraship/libultraship/luslog.cpp create mode 100644 libultraship/libultraship/luslog.h create mode 100644 libultraship/libultraship/mixer.c create mode 100644 libultraship/libultraship/mixer.h create mode 100644 libultraship/libultraship/stb_image_write.h create mode 100644 libultraship/libultraship/stox.cpp create mode 100644 libultraship/libultraship/stox.h diff --git a/libultraship/.gitignore b/libultraship/.gitignore new file mode 100644 index 000000000..da0a72409 --- /dev/null +++ b/libultraship/.gitignore @@ -0,0 +1,356 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +!otrlib/Lib/SDL/lib/x64 +!otrlib/Lib/SDL/lib/x86 + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +!libultraship/Lib/** +libultraship/DebugObj/* \ No newline at end of file diff --git a/libultraship/.gitrepo b/libultraship/.gitrepo new file mode 100644 index 000000000..ff8c50c9d --- /dev/null +++ b/libultraship/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/HarbourMasters/libultraship.git + branch = main + commit = a484cda9802ed9c39b29e11a703fd0997f42a6af + parent = 39cc86c2608e2f75ace33fc7f43bc4f2ad743f1a + method = rebase + cmdver = 0.4.1 diff --git a/libultraship/LICENSE b/libultraship/LICENSE new file mode 100644 index 000000000..59ddd97bc --- /dev/null +++ b/libultraship/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2022 Harbour Masters + +MIT License + +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. \ No newline at end of file diff --git a/libultraship/Makefile b/libultraship/Makefile new file mode 100644 index 000000000..d7aafd65f --- /dev/null +++ b/libultraship/Makefile @@ -0,0 +1,28 @@ +# Only used for standalone compilation, usually inherits these from the main makefile +CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 + +SRC_DIRS := $(shell find -type d -not -path "*build*") +CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) +H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) + +O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f) +LIB := otrlib.a + +# create build directories +$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir))) + +all: $(LIB) + +clean: + rm -rf build $(LIB) + +format: + clang-format-11 -i $(CPP_FILES) $(H_FILES) + +.PHONY: all clean format + +build/%.o: %.cpp + $(CXX) $(CXXFLAGS) $(OPTFLAGS) -I ./ -I ../ZAPD/ZAPD -I ../ZAPD/ZAPDUtils -I ../../ZAPD/lib/tinyxml2 -I otrlib/Lib/spdlog/include -c $(OUTPUT_OPTION) $< + +$(LIB): $(O_FILES) + $(AR) rcs $@ $^ diff --git a/libultraship/TestApp/Main.cpp b/libultraship/TestApp/Main.cpp new file mode 100644 index 000000000..cde078458 --- /dev/null +++ b/libultraship/TestApp/Main.cpp @@ -0,0 +1,29 @@ +#include "OTRArchive.h" + +void SaveTest() +{ + auto archPtr = OtrLib::OTRArchive::CreateArchive("myarch.mpq"); + auto arch = archPtr.get(); + + char data[] = "ABCDEFG!"; + + arch->AddFile("test.txt", (uintptr_t)data, sizeof(data)); +} + +void LoadTest() +{ + std::shared_ptr archPtr(new OtrLib::OTRArchive("myarch.mpq")); + + archPtr->LoadFile("(crcfile)"); + + int bp = 0; + +} + +int main() +{ + LoadTest(); + //SaveTest(); + + return 0; +} \ No newline at end of file diff --git a/libultraship/TestApp/StormLibDUS.lib b/libultraship/TestApp/StormLibDUS.lib new file mode 100644 index 0000000000000000000000000000000000000000..79de4e0f4277dd6859d7a3b29e30f4a6ac9b1552 GIT binary patch literal 2923852 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�yINBo;_=rk z;oYn$58Vx_L3sCR%0o|pnkl@eHRYj~LCp}}tD5rAd!VKZkF{t_dFV4xUg04bgz^xt zc}){uxu(z`fjUNbta)R~Lx+PpT6hyRc_;|#OyPwz<)P)E28Fju zQyw}W)Hj5;MpGWT3e*|GyH-;k`VpwF3-8C8LYo7M=U9dGfTqyqfMPvLAw8ohv^k(w z32(Ee(B^1GOT4yYBv8=)z*IiPsdT}V}$LYo6BA-qYNLYo6B zF1$ufq0Ipm6W$_Cq0IrcOn5z-LYo7sPk1Xeg*FEi&n*k-LQSE~0TmJ6HJU=%0M#qJ zTQr3>2UJ*i_iGAm4ydKV`?aRf=72g?c&}*+Z4RiA@V06SVL^wd%Fu5!s!>g=+p5Z%R<~5;FKRmT{k8DEY0YQ%Q~~dP3dhGcH?6s->UzHX;DH~% z3i?JC$=wL*c2F1R<-?cpYj6UqfK|ZCrZwk?qb6L`Puy_shSGCR!0gq|ZfZLFKJl!m z^gOI|(A|0L@zM#M)uFRnPapJK4BpFL7I?-SWNhd_%jfF?A^vKqr~la?UwJ!bF^F2FK3v`*t?Be%C;xWBRFUqw-j$rm^rNwW|dY$ zhMBWgipJUR6g92ZG$Mv<-T(%OEroyo;tNv@oW7>BPp|4LDm{O4E^_{2ln*W;EmeJM zF1kSI+{eFoeVdtU+}vidNLiq^JUGlMa%RC9_r(`q5GS)y0(Rg5{vjTKeIH-W11R+a zkaAzr1F%oTtd-l5!aU(iNI%Vj`I-4IUL;7C7 z@d)#_5mmEEc<=aBG7=R_=CBkpDyWuB0qWKGEstV6v4ux+s(oGUYF`)I+E<>HLbGVK zuZv6X%FDS&ah^clwpD>scYNds{ugZS?@!>V2JU^?;+T&OY;ZpomFDa}=>5 z3-T5$aq~7ZsQ?}>n(d`O&&%1kS^8A7u}=!VqaoFIx1%y-6H;tqGeeqhhV-8hkUCpH zb~OW{k}RpZTZw{@Cf&^{{@l{)oRUUFa%u;CeeYDmO9`kg^UX%pD2P^A@l5mXdj}aF z$bBPB)_v6^PsFOj7T(=!AL#bj8sg!oJr19GxE$J_WZabwSMI7&qxmR9Kw_c=xELo1 zpp9;+(gLGW2}tr90kASnCqCM1(|JC~BmpTDwg4mv>}KEr*jsE( z4K5O{qsP&Ob;z7H3RBv$lD4#MyRfD$>uGCC+WNNb>YBE;r)@9Nwm8!C8P(NnZr)Q( zUp;aH)k@~Pws|e)yd_-qH*OiO=DfD~@Oa#?&%H4(FXURfamz?G$FQn- zlhdJT%_mK3o@%-nni<)F#Qn!(O=mvL+8EzM{QEC^u#U($TA)R$Y{AGebEOjZldMKs zL-&Y!X`NOtJ(JvHhX8Ql}*cBlcAl;CVPdD%A`~8KTg?n zymJEcl_;CA3&&JJNIT5>O+!CmmSbb)FAcHQfLddwZK+4MVC!tk2Z(av%Xk2!Duc z#!!d!pQ?xAy<|o}zCt~etQzR}e`$KCEoX7Vt$melbURd0(+v-#RZmt$ZM(G&u!@S` zakGz_cdDqM3*M=s;whFfhquks|0CC}GgndJb#tpH+Nq*aDrd|JtkJG+@cwx!s%l0+#Jr|v_OP;xz zN#?+EtEDPW>uT~0cQSO)H}myPc^>?chC7edI{9j!Q@+}}Q>3;k$sJa4TJFHYGjxNW zw8aiw*t!1VsErNete!(AqIOS`X`S6n;VMIfF#Na^MkCwXJEWkTxNx^-X8LliP%xtmmt0W9g!L%fYgriTSu$#`#;8 zlb9zsEOD@4Zeo`$cGX16j5Bg|n^`V{J!etj6z5bkQ(1C=+bqOOsif_>!+9s7M&V#( zJCdB0?N+f-Ib~)!7lu70iItw+Dkdo(&bf$(D?R%*A1)y`N~Tc~Qarpw9!TdRd$M5a(v-L3R(etWU9LJ2yik)g0dnxoP+!&q{vn&8 zbqZ&gh^aS2>qN}ZkJOu?bvk9}$98Ro)=@Q!M5@iuIx3b-ip|hEsFsY{esVCYHTkm= z_QqD0o^-34wDWGU+5yUgM$*8!02P__Uh3CQY&EdWUZvL(w1fO$7{ zYtCZgC6LICc7(P|4Gfe)#*TK#dY=11SE+LM}ZFiodLoOOJ!%Es44G6ezrM3ThK5yq*i{c~E$58PtoQ z@DJ)0z#&3y26eDdZ-P2VsCPh(7wUab{Pl}m;_v?*Ak?2hjT7nH44-bLhS=;vQU+vCJDuFX4eVDZ)Q&v>QGR% zLREvR5vmSUwNUk-_&XxVEl?AL@`5@{sLzp5Dpw1Tc>H|^q$v_!@iu{K7T#P$Lh()p z#ov3#r4B^IGwFvb*sM$ij2lL8%-Z1*%`}?gJ_zR3)gmP*tE} zLX8KtOsGRa^$ArCDk>E0D99V;xl|9TS9nuFg@y8h;&;e%sR7ifLN$Tn_r-Im1=QI> z%?EXsP;H>j6lyW3L7|p_`i4;Lp!nVYTgYQ zkqu~{jAMh1=I@dk2Y)BiIQUz8#&IMF)DQeBiu3Iv;jvIqs4|m6^GBBpkK@=S6!%4n zss!~d;Z@VWy34*KZBC#v_(ty?}Wyy@WTv%mP-?8Vc5 z@$~13Rm~rtU9s-RuaqTj{QRYhx|-Gp-=FZ4AMXF7$M+j?+rqxTeDBP{RR+@2AAI`# zjgS8fL6gJFW&$UKI$uiUb)^gon+kP!Ku=?QiU16#YWI9zhs?uEsf1kPLs zhr`UaFf17kGh4;5I2>lSk705qahQ3m#hhG@DNM$o$3?|7WnfhXUtx4`ID~B1!jj<- z@)xr$4u_C!T38$oA%8X7;&2FOIyf9c{&Kb@!y#nb7A6PQcJQ@G2ZzJV-~6#;ILvJ6 z!s2k4+17>0nZ(cHQ66(7?yv=f97Ho<%D_4SzF_I#a4gvNgeAkVU@H_Bhka&y6c&eL z!ImjZ&LoZn+o-TO91FHqVR1MXY`4PVa4gt@g~j18vn>mY!(nEt78ZxY%yunI&SZWT z9~Othlc-W0Ne!t5!$;a=V1frD2M32^`iz6aF|FR+=1OY8r49~1eUpR3F|F9c?uui& z*umkLUhCj+OdoJ?IHqqnI7fi9>nOX=9Oi@V9H|97Hs#c?YQal;*<492Sb;{!Ofi^W z!dG7%91h_abWxTJhj5yM!y&xM!Ql}8%E93fj===X@`qD(nw=xHV1M|= zgTrBd(aw=tz@uU_?otc7#@L=NwcvaQhhuT0gTt|S!olHK{K3KDSmckj`7E{IAP0wI zah!w0vFLGdI2NlN98US092`#hUpY7&=J)IzsRgRvG1_^4y6SiA9G-TXc_As!BXKju zYB+><9Bz}r_m=TBSyU<06+X#~@wbD+A>8EPa0qJ<1j`ktYM+C{sd}e_!>Rg-og+1F zDgtHt0|Q)`oj5og=5IJS9OnOWa5&75**P$5hS`-p?l2FASuX-^J&R+pz`@~I#2p-t z#X1Lveg2u9gO7R>{kMa|vG}ut!?73%@6D%6t(@%Oa4gy!91e58g9A_L3I_)lbdQ|_ zvv24xWW2#;!)|{Ooi#=~WjV~}ne~S61N5;_qsRz-Dt^mwTAV>#%{MuAi;d{4ZR4@S zes$@2VCds2jUq#K`;8om+?=WSMOQ%!N{+l)ivkQ%WQ2V`e%oPJ} zAu>XJY^~E1HZL*Yfee=t=K&imcB7AWdsD_hx|Vzk+GhG@ z_5=eZ-M;KY@=nM{FKeA-Z$@y}_z#7ZZLo1mgi0w-KL# z4mPl1(yIQ*3VZ^($_fxwiHT7=$GTaY@(s~gUsUk@@HGg6|ofdY(GJzszR07hYK?fuJ>NH zXX~<4%O$u7g?R}VXdDb)wo~ggKTB7Dzd_5e93NitZkW&!kE<*7i$^9MgH*P`J{x6$ z{UOLU?pCrY4F|Uqm25}XWgnMYjPGd~mgB=qsqN!F0l8gRZGeMYT9Hd(ANLx_{Fj#F zr1X}hwvYQ`$gq7KK1{h3_HloyWt1d87wK$kE12Jo^AHY{{Xlvm@3+f7?lLvM}m4VxB!Tuuh;}V1h@*<(5#6a3=D(@&&Txy;AOzWf!6?Q zfcFA1G8?=Ph*9O>V?d0;2A=~?0{#w&q1E80z587^;AAT-}pQC6Lfhh?~Qkh$q#mdRzmD^ z6u}?|SG4|?Xhhu|gDb;82pjX@a4nC9I{UiBF_$C5{0HA=&$M4+%cC9FD9*5{v3lL_ z?>pnLJO29AVJECV`hmqkwGLL66F;Tm>OD7)o;j@U@=2fVG43L42Nn6e*1|KUP5;dg z4l3FF$dW&d{1a@r2>+!A$L%`h|IQvZ_1&T;etJ*+^U5~IA^eaXw#{K0n20B0uuQIO zR%C2qf*ZCas;v*~cv$Q~*fEPEMyz^+y@9@!zBr=guzgXB0`xGFZ%>?sZ2e3qkLbG< zFCVGPl(I{)m&mn)$CQWd&}th6Jmb*3VTLUO{y-eJ7U+yoSee3iz%}Ke#h}oKfVV_b z9(u&&Jz?@To4hwoo)?vOw76~16u$Rw^4N+H-}TUDQ28SFrlwp2E!_Ju4(=~=n~V`eMWCysGyqK%Ko|7?TA;=7NOteC<46InP(l^Yas> z?~QtIv`FSz?(;48Maq2<7YsbGNVzXk?u+d1%PjYmmiubuzDz&AOt~*p?#tNyUhnNM z&-b#UQ6P62#IyLKkS{i<3y{t&^{cVtevy1t@eqDH>Z+!Tiy?_!O?ewrrm*b3w|$H} zIk9<1BVNBc9h2I`s5NR+zn5Pf0>55wnyUxDzVtS}xna%Y@5mFAclvXN+CO|g)U()Q zn;$%Az(5F{Z2%1fr+6O0$g6C+$)i2dK=9Bkk8+0P(6Bxf`jN02UpuTXXO|q>g|81B zMk8uV`*JX=DXlF8hZ_v*;DMiU@W915xRW;y?l6smdpNZ)t0)c;27cgi#ob@1GLzy8 z$=zwLRAVl;SUSe9qAEdQFbE!BV|WQ_yh-uU0z*Xbs_~0KC#X7;;_A-fLW^cQDnZ*K zgsU;a;ga@MFU;QX^7Qo^Px^fQ*P=hW#Q*8BC$?|=y!$Up205B?Jh-#g%;+b@1; zzrqD`_xSznMR$#?xa`P{?ZyJFfnVK1El$fy|i)xoZM)r7#tG3E$^rmIx}QxM=5Pfi^>jN&J)JprCCYA)&CTH&&&P^H z=Ld@7-=j4tG7gnBw>Xx{`sDYozD|n*j@P8f2;GTazEb`$>+3kVt+Hgkg)2^dOJ+T; zxF%RKcW90!^B_1?4w+|hRf*G**^Dc0y_7#vT576gn+@lGu2KoCfOKkPPNUqMcKkYzy-shHsKV_pG(8K2_<7OMi=9~ zEJe~3h=w&097t64vSLaO|4ht?y+q$RTU~SKD;iOk92e@R&s8$UZ)F)Yr%E%~YVg*9 zcouTO^Av~OdCQ=gbZJ;`1pi{lOgdl5q2wVR$r{$J;7^0h;TI^msfL`(Kdy%7U#Mh^ zUvF8me_Zsx3At;uEO%=nXY1J5eLK#3AhYKhzET~Kmo?8RG`q7Q)2ihp9z$q$Plim; zEtf*G8`U!E$(%09n%x21{GCgVCzB|0|9s6ZW?;eim!sM3Ks?>n+kX!p&yHF1@zMVH zQHL)P^M$aKl}3$bSa1KtE7~!#w5EgFBL;p3cN09zNZ{n-9B7XCx#t4;vF8Ji1YQ7~ z1H2H}30wnQ0fg1m!ApRb0KW%Z3%m_@DewW{Wx%I_-v)AAt_FSxfkshFjiP8k>;K*#Q~)nN4gTXj7YPJa6GR2an8%>RCaBZdQq{$0hKTxL4eDe zad0>|UAP{FHFMWIr6Jr6cr19BeGZ-hEC6zoQ3$*VSOnzw7Xu#ymIAqBtpM`dh$Dgg zd5eRA9M8jnoE|>}J;|l*{Vp07ZUVmz-0Ca?UE%(CkFNs?)uoauUWlbQbgIn9EhAM} z%eWZVZ0>hn4kr9~iJ`o_9h|W^p-RO*&0wc59E?C)QC{8yCYKGE$@arA@F<<8iq-2M zKp3$2861#1oM(nFP#Of-mkua1RKBP?(Y}Pi&Mk+$9Dc;U2`3H?-=RSLPy}NnS%TbD zo@xnJn}W;zVPxj6a@rlR&yNm+nDV*Kbifg`3$oAeSc3JYpxtMy9=(J6#=-f-3_f&UA{Zsfrd#PKEIp}<#xoRXV?KSFd~2W|wu1>|&i8+ahX`v>46;1=K+z>k0z z0RIg9Ch#vnE_a^+xqSW#e!A=HLKGoxE9L?J;w+#3aHw0YJ#pDfap;oSj$1~_wC6@A z9>-qe-~v$zOkE)Uh&x`KI9RX>s08iVX7?El5}k!pJKzQ)wa)}0c{|TtCWrEw!|cs9 zeYVP`yQp!Pc}Fb{4zpDzhw_=jydIgM9av@4?K6k@WlN9;63M9{g_zqsuG_}JdC6rM z-K)Ik!Tht3_nZl513Agg0ahT~7cd`q36LZFO&|wvEpRgYS;u_f6+kWAS(|X}Y~;8oj>VbO$Snp_7XohN z?8W6o9X?2;FNpIXr3F(LM63PaJTwkY15SI+IBxp*2qVonU3!7%;eHIrX%yFK$-%9r zMzaNFH_(|$rTGH%J{$mb@OZ)2Rg@WgC+bwJ1lLGK?oe4sB~1iv>%4L8o}j;PI|m1MbZ~j#!JLdAtV+97t~pCo^iP#*TpBe>l7l!s2AHc4 z4kxEa5zesYJ%f00*f#;WN1^8FsYd}1WHUoD7 zz7FJccmv4k6^D#Fz0iJ(I`aeIepY&Q2P3|YP=ebH-Wb3&BE^xSaW=*R6#-7KPTmm3 z#e<8hQ9SsXqp7ZYq~G_N*HJ7VbcLfUh6Sd-H9G~a;15rgLi}R76Yyjpz!qreBW1)N? z5%assMz59keMo!b;5284hv4MSfR7K6NBaXm0v-;;-Z`7g$aoJOzk+9^?t@ z-+*TTKL?%%#ICo&yMTGa)NTS;RUh0He(wg{8<-EQ2NnR^fF58suo$=;SPJ|OundU$ zNaesMfWv{m1C9W4nW_LD1BCv4a3*kf;5^{Iz!QP{0Z#*>d=GvfSP9$&90U9ta2#+L z;(q|J7>F0D1`h>J0L}m&4rE*8)j+guR0A9U)&egA)&ViLp~=AC0qcPnv#=%j!FPd2 z0=X<71>`c%aX;ME{&~UUg21~mM?1?r7ZkPKWDo)=j#=gC`i?B;syr_zM~cc?(6&O# zrSB@RtYRglkJ;CQy$l^4#?xVx$^J+}3d|ByT8*U_o7YmDcZW-^FTXj4T}DvQRC(sw z&<6e(obz(@L#!ci7uY|=iGzEjcAyFpS86o`#-1K-m-=uT2d52}%|e`=n%RuBi zoC#b223y z1g-^M4!jh|?ZIWhKLOVP(KgYyfV|W8YT#7V>+b>^fZqf1(j@Bs;IqK>z+F)ve*ioR zcq6bIh&jjL^T3;dm^;ugyNAF+y1rNMThE<&8t_9Dbt=PC%l z>S|C|P;td`y~P!k7!SPhA)jd6vgv0gS*YEdsQu9>(yQ;eGs;;iCUg)aih@BFb zf<5W@O$nq%OP!R(KH+YwsJcRgcE_Ww>NZ0zlj1nnB~jWE@s^}9-j-LCEYek7mhMSe z^O9EfA!#H*Jpd*3P>yFwQz^I4K}mq;q1=noeurepN`8i>!xy1EIDHu|g0H~k@L%vw z_!`^@Uxy#UH{hr6P52#r3#JklzTFZU0N;T#;Jc7{B5Mm=3EzWHz<7B5YK_FW;hal4CxoF7DyXreF~*adSt`ny%pErdqN?Fww+w+;(Mk`IKgbqr06dLWb+*Zs8TMTyx?fEKe9l1Ec9^$w=C!azX-IY-=0iI=K8L%Uw!-{}u*JY`eU>oaFD;Btjcmt3w9gXe ze}ydu9gFRyhNN?EnG(=G%Ye1*)R1(Z61JG@SZvQ{3G?kT7|}lGIS$$i^Rr=#`Hn@m z&*A%OcUvfRKDsU3K^r0E>jx;M;U_3<;m=Uo!e5}Yg*&0Ng^X!cTNnqgz#I?PK>9v4 z2I>f3$Lxhti#kF2Y%2lM_gbBy)B(oCAt|v*un(Er4N7U~4ttVtJ)op?Pw10y!~NjC z@F2J!90q&CBVivn8S-)A&=kmgOsD|*p|o)aL1_zXQNyCf$t}pFfA|1(a4J9g&|@)1 zu+DHy5~z*Cw1)vs*?p)(asX17%4+(?hjg*-gM%bS)OSlHX@sLd$ zLNeMN0?&p=z&}IA8*0V%SokRBaqvCJeMU&)GyzK74<_9+qT-&zFkPC9qhM+{?v>IH z@QgvlUEe538E)e+kuT(w9eL^CC2po_=z9$jmOH{?EtH00pT5Di|vJ(2T)ce6^TQ9Zoe6oyX4El76UkF9cEQJCEeU* zQ_4tm+2r0eB(u5Uo4d#@ChgASB!^^Q3N-ej3bPC-SBo`mQSzg8 z_PKp-z-MMJYzOU+V}8a;Fl^C}ao0Y}9PlgQGAcRKc9=iq%y(gnl9#*oxeA{bQ(8DA zHQKL$a*KCk*y8Rh;BGho|c{)98*!xnd60hi(PGAS3ktAM{?qbY1LfU$LI z*mKHTIBOqL4@(qb7=Uu0oCVK>hmlp_5M$&5m9|o0^yW?FCHEmuJ^?yRV77L1+r+Ppz8E;{Z2^|_S!g1 zujJ>H-7Cq=M7SC*RMVp3vM)*|s(3xNV8P7Fd6v@#*2rmdNSGuKq`uELGTJxQKi9y1 z$dX>tlsGSgk~WQ~=y{`3WPVg3DlMEg zv*s3X8_a_A-KC1%x9WCHwOLZr((o=^A4Gz{G=8+T;WWt=xj7^(k|t7HvW@I=!tO_Z z1w0h;%rrC#UI~wZe}OW`&m2dn5MB)>u0^Qm`HlCGQM9agQHMpuRbDWz){i(i*VbVQ zfD{kA066)Y?{Xm5kT_68o#!?86DGOt126@yh37)%W7It0I`}x|hv8=U2$V23L5a&O z)ZnNxEz9i0&t9;9L|oL;1@-iS(`_B?MWxjkQm!F!p?W!E$eRe0T=!-u=Wc=Z@K$&! zybaz6Z-@87JK+29PPh~P6-t=zf)cl@QPE}cG|mq~J`WBE$E~Q0S8RTprS zD`O@ZPD(!NLdyfM;u8A>zEP)dZvoB|cMV*!ib9zj<~W)FGf)V9XT~L`jj36 zMTSkD51BZzyQe#B>Wms9?T5U3v}f}R)Z?)>&lT%)z1wm}=#|41UZ(pCb*i|8S6-`1 zcn;1lh1{F$CpD{!=J0Sqziwy0yVt|Gn7gp5q+;RB`NqjUh$VC;{t|tCg=9|r9AF(R z7Ue~vf=Y%T-sE*$)b4O9Y58~cLZEo@BVMRA+y$l83yYK&pHXUUU(0#epu;@=bQ6Jt zh(K;xr8*%cnE;oPS#1ZCP({6VC_yU6S<#%C6{X4(<6)_~_{GE6AMcC;Q#mA&TrpDC zr9MrP0LV!R0PjpKEGwu|&U+^FmW8B|6PxErkZ`Ic;>Mk7PV~rt0F&r!|=g(%o*P9#>K4K@)@pE31r&QU9xF9wp0VRqo_9|808G}lggE?VdxD{_>9}&sclS;~$W&%kd$}^Z)7Fmy%DFga5yJ`*IL{$CISFwAK3U zOWkTGd2CsV(fQO$BpDAUSdSnRozF^((Ygd{pwaoPjp+7M_GCg;bUy2rSX;*GGb4N6 zk-g-|tT@|VoYDEL{*G*rBg=PWGaT6*#>l|zM&syuq9(H6~9NAV!mQ07O-S#j# z9>qGcagJ=BBP(-cD;?P?NA?d#_Ov7W%#nTR$YdT)Usp!(qVrjQMJKn83D!ME=d%I~ zmb5I}=zP{(N4CI`t#V{nIkFw-WNe>c{bY1LE06aev@GA~eAdh84pjDDGdiDD%)my= z<`^As<}wxPSN6O{=d%hKq-$BR(fO<$UGxKFu4{BY>&33N>{X-lSwA^4d13V+eD+x@ z(e+i=SY>oRt0u{oEipQu+Qs@{Wlwfi6rIo7+D+>ctZhc;vrH9N7{_7II`aJF?py*{hE14M(=qk;V4ZSM#YI`%+byGaT7TMwein;>a#^ zWEVNI`yAO?N4C|GZF6K@_OauZY;-=zLbTBMUmR1&-`AM|O=PyTOrdaAeOqvK@}>Cr5S= zm0Vx9pV9fOsgCSKM|P$oJI9gT=E(l)$nNp$dBg;3jnVn6fmH1@l~(CS=d(7U>#t;+ zjgGdCimzqaMn^iMJ51So#OP>;sP0`SPxY8ijB@^ zZF6LwII=)b&j(wtzUb{K=-OaJzZjRo&KKiKm$Hm8Y;ONNVHAg3N_@a)4 zs6*0gSBIqKt`14(|KyN7`cDo@SaP>+-MdRRO4ixgWoJ`#_C#mLZjyh$T_=C<-hKYV zWB>o~pgQdG@Nm|xVlcZ^EM~Wg!|Yb^nB5BFE)V-!_BCw3Z9i?lI^c^a29ZihJ0?on zE>Y56={8I1yKa}HZIZS~)Ngf2I3yRSO^7ld@C2 zm$^YNJ85}or@hu+QS(usp!%S$Ld`(Eg&K=`1hoY96DkIEE^0jLaa3Q_4X9bDf1|j% zbt!5p>P6I0)M``(>Pr;U9M*-XV^Gha4ny66Iu-RXYCqJKsFP7|ppHO2ggOKD1F8e+ zeAH2>r%;EWZb6lzK1B6IU5+{t^(txv>H*Xu)VC-m2CR!v$D#g-8jQLNwGj0g>HyR= zs6V3KL5)K_iaHzh3rco@sYPX>)}szWU5}cHdJn}k0beZe@~XGjdI2>Abua2P)EB5u zs0P#|)YGW`sM}FMYdHsP4p|yQdS+IZ$vKoCaTlFTr7O7`zYO2Pr6JP>tgpKf6cr1JtJ_`rH z0q{Blr>A2krx}fLFlja60@K{1+SvN5ZvmEnEy2!|&jCFcBug zi{Zs^3Y-F;htI>q;oh&@P}iZFP+L%K9nsg9Ys+=znsPmv zCGw->8Ua)xDuil6kpOA~i--v9fd}E`=i*8DNJHxn8~0i#ad96@Nxb6`c&v@+rYc=f zZG6z> zEJe-vXfj{W6p#Ilp|6=&5Kl2T>_DHmHZL`;v>_#{jq@@Gk@!GfYWmU?zLw`W-`S)* zXs8vx*bOSpsy<95sCb*Ww!T)M=uw;%-G5JJjyoX$8`>M8lU(TG2gt4=)cD=Gz^mN1(YbA6zuS^l|U7j|udsZKj zt>4yBs=3wJ6nQpS#C}@#B_;cbP_U>oG7}+PBvf3slMXvKD%+z~qE!22Loz9>End+{ zAh}o^8+0YL+IuUT^6FQa7`Y=>Kypzks4Ew9@lEOwS(u%gTle5!MW1-lwYG#W-q+Ox zW2$>dU~)}aM;C1D)Q}Zaj)L*JsBd;#!LwkzF4z%r+Y`wa<+?FM`)1WO`POfXMMx>a zX=5nPElfq`ADx|=y4Z^@RjjpiM^{+a6pukpE1?#}jp6*_Lu6aAe5>k!Yyv(fTTV$z z=Z6E?Je7f`x?J6Z_YmK>s;<~l*GW9@Y|?r|cB;H0WIZTpHUNWiJGxeCR^mlpBE^FCV7&$QI>n5$^*g+K<|rJpV37*iLlU3hfER*|&%CrFB2-0oB#q7B@@&s` zWurmGx@EG7apKx0eepewYolt9Vr~DmcR9;d#}?F;PI;(GSo4EA^)uY5pP|mTPW?Di zf0V>=)ZT^YznJF=<=|*-^L@9lZmj=b~cy{B) zY*T7Yy;qgm?zwV6x!wBb8KTHRmMY72vieW=&pi=QB|KH~BfJXPgzMri!irI`YpTHTAS^WhAqu*{b+n#=^lg4HeJPea5PXNteVT;Wmf2r z?MYVXNVk_2C%2OVDy8*S`@ z)!hWBOs%_{fV;b)q0Og_OLZFcfV-*(qPm-atGnS`WOoxV-A%yN-2|NOCSbZ7+nMQZ zcJC-0vi5S&36*z8p8Hne~Fe9kE)Gb`y zlj-gZbH)QnZQXX74VqiLjb;bt+Oeqz;PqKO{oTp66SywS>f9oAdfl|fC* z+iltH-pa1rkhi?;Zu(WsBvSs;hGj8wUFoC!8`ND4Cfg`?IxeH!q`Hi9^Q(-}_jGOC z%C(s?K{Asv&COq9eeG?G;Tq!P)+qgjEfm){6{N<{RgAB=m5NKenC(q;z+A%R&k+LL z#BtBDN_iD5(te2{EpcsJZLlauJR`EfqGcD#WyHX#&KHhZpSbMY|ICBxDeYd}pZGw% z=O%*Rb_h7V%qOSEtUt%6JyFp%x81uB`;tQY7Jc`2t4G*&_aam=Ek{Te#Yyq9EH>Q!n=&UZUym&m>BB7V8G{tbE=%pB1iScta+XIa%_r-1<;_=B zAfH6ZPdq0>3RE5u$=~_3%BYp8*I|)}922|#g)PdpL^_|6mYPSU%}#5181H6aNqaX# zc{ii6K6Mo$5^u&ibHv4rV51I_s+)wOkSi9l7*q;gD44$r3@hokKyRfA;*tp5eHko^?oYb1&uua-f`(%g!xkn=EGZ9hW6)2R1 zlt&y+Lgo-6%0Z23GyTTkG@=w5bvBUH7)T-f=_JQkGH$2H%QvVl8UM&3Wt8?$nlWs( zYCy4(PKsrmb-JX1s*8Tl0o^ZQaW1;a#FJ!mP+q0E|C#x(rT>T zmDt{uKczcat0h@o!WmG}`ZibEfv$T{e2Ph2{u1FPo5seRB@^Of)dk0jj*tY^Ty@Zi znk!5>c9?R)VM3b7w0v3^o8p^s>fF@$Srz3Nl*2NB{=VCEajz^%iy3qJUH-)3wPdbR9-dI zipwmSG3Bg`%ABjWcg<187b$3}G0C-aBe!9x>U~LFWI8u8>=GiuF633|}zx-?} zyDR-@nIu7JqQdDnqs_*q>0i&KY96OK#5{ zC*1B1w;gnA&jBY~4(!Y#LSE7?PG?fL=uB!E=p>*zCr{=jUnK)uRF=APx;ZE}CUsBx zBTHE}7w8pPz6#swH1W7~`KtM~<*Ri;s!t6OY*m(?W12@|M#$V{NiMcWW$Di5A=(F3 zmJ*j=MagnXM7flwTgYa7?_*B}_K|!kx95$1CLodaCHJvUQ^Sw4>z+lz%ZTTO<*r#I z&PC25m77_la@Q{jooVVW zWA~Y+Mw)4R7lHp`rs7OnwZs^MiXE?O-;3fz;#){$&4v1PS`#MnG<-}AUS39S9s3Ecb{ciO7EPrUeR z?(giJR9(Ki_>Z--K#k>`EN~b9up3kS1Ck?wy(6af*Lr0_?x$l@QA#18J=MgNP5twXjaiLE2qUSj{}#b5hxivQ=XGOtFh z?lPZamw7!4V5hsg%!l2WGM_8iko&vM1|70J$p#(g_Oih#^N|U#cky=0yuOxG=JRAc zZ>PP!eYev-T;>xPsOC#z=kMJ`|BGc_hip$0TSv0J#5QF<;nz3$+J7g3)h#mp$ZvSp z)%z=T*X7*XJI_lQWVC*uEi(jx@Y3W!c4KW&%_MD>%naz60&T}$+9h^mL0GV{wH>_# z*(GP(;O|BuQWNZcH5~WT%lTuM^pnB1-(F9|!drDg`(}wL%a|7CcDb~FXVbi|GQi;qXzng?G<_^#r1k{azRHky3pH8%H)}=j8`tLG*)kuAhO0bS(d+969w#4|? zC$RS4Nnk(eYd2}~aM>>xU?$L?xcp+;1{ytfcMWHO8c8}?Ae;QQ)%H;Yor$7=6nr%- z{#|B_4%wa*d>!@nGKRdB#ykA-g{tayI_zD&ciI|#Nu5{CCo$(k=FHJgeG1L0)w6M8T}^CzS**mg))G^m;>3?R6dW~YnPT^0Davbm z*!I1IfJC<~tEB|Jq_p)?_I{7etPa_plr|mL_Db9FkrCg!_&UW)U&9oyMNENfU&CdX z_COv!bXG4CNkMbvO5_Bv(PG0RWRm<2_b?X1furiml>g>e(S5_wX&{FxQ8@kBKRMxsObxu`vNp)jV zl``!9NDrm#{^&Ewp14#j{2v*M9?gOrT_N_kt92@pPCDJNsbPeEzg8YWC!YJjclNV* z^QMmJchq}2k(0(w<&Y|PNsBy;sks)Y)oALjZmBl^uY{OsPnNl7%)XMuh?F=cM z`I;mdMXEbF8EbxZr#SWV9Q&N6onJASlrvU~EJkHHHuWctYV^XkhPYIwSK%g`{q@BjKJjWaBb#1)4tcTn(i(|hM7@b5Wg}AQt z&wk?18r}ry(^Wg#mk9c;sv{+-<((xdtrTQkT7!uXbTcKj_4`c0 zAZxksE7)=eRgqcU14$!xIke)~mPv0#7pFG$FHc!ZwW0{x;3;0{gv(obkmgXRdj=t?tOGalx_r@V@e9gS!*0! zI+4|~Rp|WsEV_e~?j0_5u+qignbz%xuCJ11q3fb_M-H`h6WQ8Y%bL)os_^rXJ4Nr(Fyr<5qu6I?W{(e`V#j_${SHj_sCw z`;rfSc=QK&q#P%xt#3r~DczFFJ$x}L@zR9yeaFUFJ-rBNx`!Dyp zG)2oVHFELSA7gdt)~VdXw}?96n?rN`ApWPLs2m(`t6%+dFSX7-u9ajl#|g4v&>Xk8 z?8s*{?1NAAI>$HKYh@0&?8qlc?IX`+Up|>;A1$^9$|sTRLq5-9AM%+H`zW(Tst;#qT`uOyN|wj3 zU+JXAXx$8SQ(A zCzJBJtMpOr9a2Vib-p|2>8hMVdK-`GMWyO^ROt}+9d|BA+S`7-uVQY_?MV-;iBzVZ@;8= z{NV5I%m4n_pKr-}IQ{4Db5b`|9lqeo`)^yl;gN*=9~P}%a9iB_x1D(R3FY5hUz>1- zP3yVOf4E`&#{2Ea2IRwMgXb2%UKQt&HSN^O(vq1~gVWPjcswC38C+b!HSTbAe zIFi9td}1Ya!9s+pKE!%vPS6|EJ@e=f(qMA9?Jy7{?shEyy!!U%bh^6JP`ZLxkF+PY zJ=tcD7rW^HRmZQ+_)YqphG~0*Z4OI{U8Pq$Y-HNm$OSU5=S4T)vbB>daSRInv9V{f$Nt--1k|7K>O`h5k>C<(d8p&{R zrSnuIgKNSyPTI;?&u#q5#W#%YemgM7{U$uhjzyE?)Kh80V?9!~#-hF%)V;ts0Z$oM z%8nAhibPD>9}#UsA}wy%&i6I z9Og%mNUDY7{!b(l!myq9kOU*_e1&9Ggq;ptJ}<(Kyvib z$Lv=`*paX6l}Ff-5By#gVP_l?xq3KWd@#_uEyB(`B%ug9^+?u4*x~bWYJ3;==WZlT z5q8!ikr0OMyo6*^gq^KORz=wP2FYs?cH(KwuZytL3&~c;&fstrPKvXdABgox*@`>{7tNVhIf5pgLq>419?9Lv<4^b+ z@iDZ5@aNCmA3W3gV)cnLtv4Svi}+rdG3YOpxxYyk{tB6Nyj6UN>vYuxtKPzVhfdDS zoIiK=LUpE+kzYx%ITdxYE*-ZyQ+`@;+2VzKMXTJJU9zx%@W}`0M5{kntiKa2-&?XO zi)JoVpG>yY2b7g8@-xy=A6Aa~mTjv~T)MvNh}L}e(Dh-xf~k2E3MR}cDVjH}iqY+f zGb<`BC7VR}$MeNDZJIWxx=JEp6%-sjEjV*w@%)ks7VGRYZ*)x5NZCTzHKgm%z3np9NQ?+O`rF7%P#*J>qKir_}9G zMb!njm*G#3+m@qhim@CmHGybVkBs%!ay!)F@2A>9c1gmPObra%u?1l(sz}>eVUJdw z%yQLTCkoDIGVO*=f0fW~=^{+_M-d|`xzkT5sa@Hfe!yMFb?rWU$dF-v*D++ou#6Gu zBQr*)yM$@G#!dWvu>Be|Ec_n`EN95OKwu#(2RZ$Cxur>D!NcPkbP9Q4uH%MG}1)kOXs{w>2! zT`w`|sb9a9Tj(BOiaZ7N5q5qw_9UnQD?Q*IPK!P1P~-RIrWPd!V;*hK)iH})24#n1 zXQZ*G{7VW1oGcJa9AYmEJCmaA>05Hu)rvjoXr~!FVwOXti>td8SuX0aD0{LUJ6U&l z_Qa#IPRPm2nKb^0zWhv>oR{44hWxrl!Ih;JVsG_X0thCCXHnqQhN_o}X1#{1syKuID0@EFH z>8J>cgiUUdhgnCfuwhh(Mw;>&73t~e-ODax-e?H6O&1;Ba&t7 znJFF*8|5b_%U$BPv&5{vF)gARM5l3=KgC1GU&(g+$;lx^)%Y>RqZ?Y0Ek*XJcB!r_ zPFILMNPl7!2NkIOGRJ_E632ckx~%XTDls!QdAsN@DBN*-R(Z7ECJFzHB_m6qzPU5ZFw zPYptqHMup^4(FGY>R<&B=?hj@mJ}=R{f+DfuF(<|2ttF>=>hN2t$40d6?z_1o#BxYxOem9y$eXgeCB4xBxx_tKqYdFS5%G zVrV&h4qgWT3HeGnUmUSQe}|jl2KW;E9KHg-hi|}6-0Hju`$F#gLWjb);aK<%90%Wp z)8Q7l7`_Kr!GFUm;Z}Gp`~cnp$@|bh;m1(k=xu@D!cSobnwHOCKlnKu2)~5K!LQ&S z;n(m~_zjd+>|0m|DNCV0!5#22_yfEe{tR!0zrc6kPWUObJXWX+_tJ522F_-`1UAE=P#&KTgYvD;E4Ew1z*JC|oVL(*qVT39r{y0`@G;Pk;mMhzP=ba48N>Y|FO8AaUg!-B

Nhvwchf0YCSw^-6M%P5bcIi@$yO+mFBA{Pp2)fBpjesZkXE=#d#; z%9Ozh2Z`L~u??x;b>_Axb1`PRtl#Y+sdN+$#DeUvVTWt*-q z&*(**wVxDXLDtUYW65kV##WEzN=nbkN!fj}UTrzavQoc@%%R~4_Wi$S|#Y5r&gL%osYrS9OdhpAYQD%L8FC#vQgSVnQc{JHv4lD z=7F9H*%XnFA!r}X8_#cwjBBSa@`_G85X)BelBcp$iv#?Wc=R@$rE(cbU3QivEX571 zV{`<;x~4b@w>sazyVcH_J+Uf*-#{)(qBVE*sy7?kT4uW>d_ zqERW)NHggmj|=7PNXejf@^Gx$)mS!(lm*8stqJj1^J30e(qgQ2mhVB?d9JyNCaUEj zB|5t|`7LF}s_Li`x60Vb#ZGWTeX0bXmQR%n(MOjHkx9AOwyO|U$_8jETw;xIp#+kXXQVzYHD*Q3A);TZ-`0u_RLCvlPFU{?Xn>dSI+dVIZ-yaV(`vB|6C?rOxjv`Le3C z2DxmxnSs4g#(u827rEL+v|(8)gGx)j2vM(eFKxkofb#*hvNg{XG*7jU1?_=6TJ_2l zBa5j{5m_!#uJAo5>Ds(GPOU{BCB;Ju@lq-ahO3$|Bs%4^bDl;!j9L{-ZxBcvkEjQ}oU%1Z3Wr@B!R`L)`%?3%11Gln(PiS_f45{*$-wKSkoWJf`@j=CneJg(L*%uZfmLv|#0 z@+2r1Q-xS`D$S%-75f%Y$~Nctz?^(3Fk@*-Z5!hBrFpgPE>E(&COBYY zkS)~L?~r}O@o1&#JG)T_E{ti;|7qt=)x+YSlcrKxO|>8|vRSbI5*0^fOVt>6_$1G& z`ftD~=OyHlVXfMp#0L}a)B_6BjDFIf}bFuM?A!4nyzNE#|mCb86W=QvANdB~V3&e}rz$$hol zGSE`WtxTLX5}iC_U^PBExowHFUc^#wrTZ5;nOBapK1SC=>Gquv%ZGCZS}EliIV2$B zE(N8B-7=YHA1t6!HwYGkdC__KJwWOBagJ{2@WypWXXoL%|NYgA(>*E)nu+5U z9e?SBy1@gl-1pj-VjrJ&OXvF2hbJ8J{BhsSe!S=EK7M;OqRs!_sziA>)YX+%OyRUz zmFOqeCH1~Jzy7YURguUc`Gf@y$(3}JNObN=8Ir6GOOD5MPlTil({@MVe%K^ei1kPb zkn(lJQ(rJqVIRwEjb*PqyVXeI90`-1=CJKNZ3`Sb|7s=qpp}HlJadRYtVJ6+!k8t5 zGHa(M;$+gx6;qiumTos3cP6uB0?Q>i5tG!mupN0NR~mjTaX(U%aaycLY6hpR4hO1x zQ*?4%C?XDJCt}T(gf6^hE0jN?Q0(dBI^#;&A>YI6U>JPkO6r%ff==f#Q^-c7>}XeJ z9gNs-&(*WWm9m39rewoj?4K$>2vnsd-a@s*yzzCNBiZF z=j;jUIeWiGy+BUNQd`g2H@OO{DsOE(XWu-~vVOwerop;IUIzkgJZG1M(w&E6cbv8- z)vvAR>={`!AelU?3Tb<%g0`NsOH;U_UfZ#M+j`EviIaWKV+krsj$tTe&$YBp zxhQ+mLy)1r>UsPn_&4o0d>%i4W>v}H|NL>hnp^He4>Kt0dHhz&R~lg!`cl#8!&E6I zG`l4QBrjSYfn=stJIf%;xBi;Q8dVllK;EQYpnHMEthA+5rk-YU$k zQa&TS)wR;2eI7P?NK{ORwMxTbBcuHpHX=HGhOxLbGT(=dXmzdOt?XnBW1t=`Efhdj zpw8sI7+IYlH$I=yKTq-SAZP&-^2uriNEIb-ibpTs;^9KFROV_WV}*pc3p#>1;+3o@ zxDAnZS5czZ1r$1#K?NCM)eNi|pn_sMgo{sT#WlI)}>0r%3rh{H)t|)=jeyL{(5*@j*)WLGrTI4wH z)H(-QPZCpvOdVwv#Vp1Vmvb;{m!%bD3sf9$LZq+gUi z3ce4og!|AA6UNZ7@G3YHUJXm(bx_`1z8*dgZ-DQ?8{yaRCMYBGn_)a8j-j6LHrOAs zZX+}t-T{w*e}%F{{crFO@GiI>-VOf+?}6{b)i6MbzYof*vTNWBct6|$AAnsMrIVJS z{UG0!4lRZc!8-UbTm^Y8BXlQx6efFF;{gwaO>h`|90uVN@MicVychlh$}|6`;B#;T z9LCsYBb)@EhR4EZpghxm7S4g2U=`%$k5B`A9$p4F!&~7Ca5a1pz6xK4U%^*kG5!4O zuo}JrSHd@;Y##j(jN3ygt1snfCWP#6b~g7NS~*a6C`)E(jJ&kh&D=*_DYM*dHdrv5<8`p&;xAC&Lt21bf0VxDRZAynGY-Go&tto`b#N z>#z@e2ObE=Fl*$8SHXkeYS2y!3>xWhr<<+HX?KtJOW+=+4D1W8_a}jU;sV}v)~(WJbV{s z!}nkiehMeS&*8B!hFPZ^*cBcJ4}(+S;qZ7k15SnO;57IW z`WViGGV?Yc#=|n049j6pSOF_xCA%_Jw0gm;r@_UsY2;+ z2^+f%n3`a5X$1-Usi7Yv4ohez*}n0JlQ=xKJ}(2PZQ(`w(0NABMH?5qL5DJG>J< z248?pa4TF7x5LNbm+(oL+=u=E9t$_XT=)zug3rMa{3rYqd>&p4H^ZCYtMFm?FDNg- zz6Rfdufy@YIsYcifp5VA_%@se-+|?D3p@|L2QPvDhH=abZ-rgq2k;>HAshrhf;{`4Yhgpr!yfQW*b{Dnz2GNsU$_(Q2NU|zj>9ClKlH-`;6UhyW8gvXTG$u9 z4iARjgK5v)b!S4NN&*4}&22O`#VG%qME`q!k89Enc!V6#)TnWd+o8Sa^51a@e zgFM6t9efCD3gIa*2$#W0@D4Z)J^)XEkHZt;i*P#J3iIK&@FW;_D4S!zZtxGVADjV) zz*FD|$U50jHe3kvVHsQm%V7*Eo(a3A(cZ$5 z@N5`_=fDCOg2nJ$SPtvpa##914KSrY?JrD)jc^=X2B$*S_l8b^ ze6K6?9$W#NA?tlZQxBuPg(dI`cp6*<7r`sxGI$MK1+Rk-!0Tc60ko^|Ab2CpfH%Pa zycv#%x59jQCoG14gJtk8cpAJ1E`j&Lv*CSkDSQB43fICbU=#cru7?KCl!XqIs(1x<%%kT?} z{s)yFH3xJXGMXgo22=udz#L`{XyU?RH4T(*%Oe@!_L3XS0Me*CbU&ikXUUzfzRm4w zjZR*KOpcxmb;P_v8-^*HPtI!Aq5;nPVCsZCvj@O8bg!c_N4!#K|!nfcw_%=Kp zz61XR--Xw~_n^e_-%!$GBkG8#w7ATp=ff_Bom-{Fw34dqxkXiT%NEY8IDPL^WgikM z$VE@1;g9eQ_!ImP z{tUOno$wdPeQHRS(ZoPmJrN6!g50-;s$oYc_xh~C4=slYP^CMR{CNU3Br1P~#OSg* z04BE1pVJo>scb34X&Z+rtmT|?6;?@5@yaCVLNz@SPGOmlkr}5TR^0g@vq>4q^t6!7 z3W>yzL}#Ntt)j}bq>Ft>9MUl`+_APA;RNC=W%?L679I!UN@$&?@6P^g=-IM9CAIyh`!js?#cru&@{|Mz>lLB}NEQB}1nNSuY6vKbQ z68Ir3h1=n5=p{aLU<#ZId%{zpbzVmOXyXLC5bP`j{)6+eWXlbvyViPLs~f1qN(>gtSw5Yeh@bl5XnVuXCWJQ;2^_Pib$X-=UOz?TcLIRpZ)D&!NA* zb0S7gEf~)m8mfEuBQz%}*i}IiKU}fG-TNz8lOtUCr9Zz%$@GteUGkzk>Lw#6eM1tT z3t<2@!sFmY@C0}_fsRZo8nwy&U9BNWxA0)mVwXA~Y2<{dedj z_$DldZ$W8q-iDNM_3j(#ZEeAPKYR~Lx&AklG<+XQT5N@qmXzmK?fu`7NnN`Y)xA}k z$!jCOUGKEvrQ)?KJh* z>e4DMN0(FuOJ>SLm%VP!>@tu~r^B-%eA#7w=W~7gkT6Lcy{H@`OePKz&K__a>*50p6V4<+t@Mn$*dMNr8&DpYv@TrtC{dUF~=Z zg_VsWvy!d1v5;if%qU@kON12rH{u4@= zpEqUnd-Tz5YOzOe%J@eZZ+qa3NhEGVb>!R^#UJ}HkqcmUMa~}Z>uBhag=$kJ*16bi z9c#(h*0Hunmiml5xoocq{si}O{20*VlVgaG9N{KejYsd%QuQlwmuR`$Wa>?5AhLU5 z3A_(VyRZh}73Ecr7gfbqX-%{CuGD%oCGnJkY9A6ViDyStwh`V#Jo=))4;~5Ez+>S3@HDs%GOn>6 zf)bxcpu~G6YKV1IGH{Lnx(+C5v%KMWm(HyzDORiODpfXewylF&D0!B|Irq4*J5R+w zpJhAXz6|epIMF%zGe;;JT#3}amk!#tVE`p@mT-+l$w9h=#N5Nf{SNF2B@N_V=%KI| zlsN1QC9eNK4ULNHX)!vFWgOip9M@{ux2eS3hNuNNxNYMwO^)P_tI3g;LfVjO)D(}s zm_Tw|OVnMEbT(4EwMgQw(#?;^oo+HiGas28(w?~5UW+bk|fsA@mXfgfQG!EYe*1)(&qeJ+%_g*uoG z>!IwOa6T-67eKCMErs{O2Dl!wxHYs9HbPn6xeUtsg5^-|doF^>a0ToKFM$)_rI57^ z7V|3VzUOi%`Fam3Jt|+HL?#LTD5`5XUn^;dDobWo6wTSgmPl_y;;dW|Fa4A`w$(6m z4U(`r3uUfBavp(^%r<+F#5oeRX2dSvOU0%+B)sBPSCow3RH}SzT5#jrcU5B25sTU%S(c4z^f5D%t0|aA($j462ZCRF~ne6o|6Q}Dx+AC+>$iR$()>( zHzDZwH#swBQuyp~nG=E&CmieeKSlgMIxpz>pPQLI<+zEC>*F)Wlb3ebre;o_IN7l} zEpysQ$4y|E;#C(m^F;*Sk*QiM&+j>Pd`~qz#ugnr3kq`$XJ+bI*>&Ers8Hxb=b~U)%BB=j#3( z`!Dw0a7p4Z@6MZi;;RQ|aYM&P5anlmc&dhq{=Kfu`{A0#PJw8)?C-S!UkD&kf z-RvKs1|Pq2?+LYj_xHc`ge7gT7bSa7^rX+)h`tL-?>!+ppPI{+J|ThK6Lb&fv%Khn zO4ixve6s(G+L}H=Z9{*waw~I>M=5(U+83Qq_G7UoD%p6W^I5s*vXv~)=zP{JbQ6@U z)aZONez3+X86ya#^GV-tWhoiGywdrsRpW`E;^qj^Wt(JkYMd+ zbUrH$9W@%+K%--OGjt=BY@E^gtQ>SBlq}cieAXY)4Og;RM(4B2(Pb!EmC>>HA3B;I zuEFX@rSr);MaH8dTV-@U>lSoFl#JDbO6Rj4L?>f|1X3p(&iXA`1Ei0y!&Sza5C%%g8Pe$jH=cJ}QZ#Ft)-Sn6z!P;zeKI_o# zwrqgW`K*zSY>Xqzb!2&t>@{?W>bh?kosW-k*|KFu=d)^h(5@ z#_pqEa!jxSM(4Ad9oeUj?0ZM{vm@)&%XZtv=(vU>OLJrc_vQXlg(cnSC>xG!l_OiS zpPnB`VEL2Q`K%7TZJE#Le3svlr8=@5=!iV|@srW{tolB-Y^l-ttbyD>kRaGgH#(oS z!jY|XWINEwJs18N9qqvZwyehJeAd_KhyeC>7#(SUpe_JDi>>&MYFTq-2bUtf`Bm2pb74~J`&64XD8y)S7Biri8@(W^hI$K8 ze$3ZFu^&POFmK^}2lV+UifX47R`-r$(AS_wVcu*dcVwvKor6lld=JC}?^09{^LE_F zq0d9HH<0&z+|$B%t56x7--vtqG;cAAsCBvxiv4<2Hs)=(7yo9U$e~WFtdx$^&@Vxa z#rzuap{jZ3qXuGr5Ozi_L*-!Jf%{nWQ&HWx{*7Fp-kGf+ohewpjj#CT6d9fo-gl=Qq1bqwaOanDSY_e4}r zD?n7bcN~U(5o!eIH*tMhDsL%@EbH`FDCvDZ>L|>g;GUA?{UeI1)9EU%UxfZ_)Huv< zaebim+;O+Q5`zn06nN$ zR2Jrcb6&!85{eq!=~9#br(+(C`9+ieb20bFyc$Y)8&H!le~Ej^&l6BRtR!!YN9TVv z=HZ-w#^iqq=6;y(fRbM4p(bMf826I@r=VzJI$de<|18W$Vt&Kq{{qZ|Fh2yPJS|5} z#{2{BCI6+&bSM5#nEbEAOg?ma%H+SK>A{$9fnvW7H39R7xR?C@1B!I+bh*j@Gck|B z{Hn?Sd6+5JogRQvo*GfdV*VEQ5})a)eO&p!81qQZ|I_6EY|MvZz6;9rE|YNpR0tKo z{2u2e|MOA3FkfQwzXtOt%rBVypMyCK^Sw~=Ybh#-`3u}j{Gw#K|8K^#(|7`Mq3FfhwUpM(bAM-%W>tJWpGE@%c?{P2r*-IyJKRfr+N=N1oBW@RokOvIHjwCn%1CjagF|E|gZGVC0V{l{P; z>SELs%sZ{5cn{ASJ)Z8o($_oQlaw4EZ|xiJiR%%c#WO}vASpi9>J{&aNr^v*XOA9# zxA;yxlk|9d#@AW_f}Ru~gZotSEL-3RGWu^m2E zMwzRk%we0q4;`f`;*cq0_mP3Y9Y6QEJ<(HJBM#Z8mDY+>eGMJ;7Tq>q z=x#$dTc1TYN9p8i&gP55wVwp=S#|=X>#%nMlwDl+vQ2e0UW*;!eqpPd=I5xjwmc}Gre&)hKHkeuZH+gRF0Q(>GHnQW1DIS^ z2`RgP*@DJEFN`_1kzM%Y^eEfh81P~YDz6#?a*9odxJY9_w#CXD*2Jb!HzJTT`B0=Y z*wE}YA}NQl>}C6@CovLf!JrI+WJDy1hz?A=VBBHYFVZ%G%V~|oeyt!FyME^ukgm)?= zcd|8;lq%UCE>EbWAKR%hoJ4Jo?QeY85MbP4^uanQWJ$`R6qXHvfb13*j+lqN$5JJ9 z>if#;w|HfDsrAj?*!9C+Tz4SeeD_7;<6_4y7bbs#4MD$s`QzpC^=Uembz2hac6fJh zKhM}-zb%f0m))`Q>XcUJ!Bz>A_(i_dr`}}8r>-X5E(O#q5jOt8C7wtB* z@_qnCQan(3!mfE6(d!MzME4Sf_F1g0hK|`f|&ZUZq35s?mf<&Nc*PlepY| zG}RU<*M&;48S#;%QcHp{NIkWEk&_KUZ`)biJdlt^74icl@V{{(C)XQ-v^T1T_fmyn zkFs(3A$CLpz4}>ORE&3<`uVmaT|9e8a#1_@-n~k6zO$Vsdw!a*m~=ehf1zTHAe$ud z{oxko`hLH8;zw6fse%o`xTpk3tiOPQvNwsKlQqe1bYe`Sqs6^!ajer8#o_;M+oHtt zPNxBByRfPd(>jkd$>wU9Pfh(FO13nKj`MMNIzq}$mRHBo8!k>+x>Kanv+L#mMtPEL zY{J<}dP}z=Ym1_4_}GJg^VHIXO84Py7r1ck|6izaE&Ho<(IL~_yc*nW2qaM|b)r$S zMz@uKCy;<9RdeY}3d#H+ds7ywEr?}&Qb_U^T8Z_2Y>VnLiS;+wKC4T~2qUqc`#|lP zl1U%XI4PH6Ghn^xhw#17^gS|~aEjQNtUikl(2<~{H8vUpeU!tO@wFvEoZ^cZ=zIi@ zYxZ-L&L|jrJe~D3*|Mo(Uh1fAi0r621^2*g@kgE4v5p!sr~u}qvSDQ7dLl1&u${xu zE>>+JiHuR6G_E~OE0A_&1SA1SNf@aI5|TgbdKk1y$omTYW!A}9(RVbAdogXE4OlJ*p|r{ zZ1@u&&}p|ch5D}gj9dnGVu2_z$dq)os=9JYm5Ri3OT#0e-!xI3YsEL8c_8`SZjts& zh*Vgk5_e2Q;!^UZeQ+o4!T9^1C2o2fi94#@#7+M_Chh^u>$IP^>8`}}j*UoAH6Tl@ zzXKal4eql{l}G{kP4650{p35@v_!eP9}Z6>0K4c^buBr}l%dKKSLWGFR61K#<4D-Nx-A{`Ce^twZKJ){w^v&_ zN~lb?pl`EYvh(~n$@3;AY$eZQ!^7Rxh<@8Vw+n7Vmh5?*tMlr1}k#TjIzAAk03V)nLwQt+@&9v&WqVi$wp-TJo}|FE#EHzP@EL6td%@&8hP2RHstLjzwzE^J`^;jtc&D8 zjj8Xdg9~Y~c5^KZmE8V?I*hQ+ zoWs>l8gf1BHiXDoB67Vw#^}j4n%%A0))BFV;T6obJ8NBAXfH`#ZrweyuQ{yh+3Pkd z^m^K1RVIz4m~ZAPi2C09Yd0Ne-gu+l2mL%Kc5lLfR#w0@1~1WQ_MI`t=jGNxVsKgz zgWl{~i)FEiuaPs?If=Nh#5?cJwuZU9rwQ22<%xP^yWOJDFrERC`&xZ9(*%vZCF@8} zhrVjx$p`S~UNo%#Ttv$TF?W)-S1wb1ODOH~+v_Si?|uoS(Ghr22m2P?gg?|4))~r;4tdSynIYxwdw9^49lO zVFl}zXJG%QEm7C+U7}poiaK9X^4`aQAdwA7$z~HR?vb!uK$LH!%v7OKM!GhuA~))7 zmrBEjl_9RcN0+bP8VVez>Fhag^nXkCF#D_o>2Zk~kxJAq+N^u9?n`+@IvM)>+9?yyExfN#hAyRv+;ajaC1S_toi*Lvm1f%eptaEIOSB5O zcm2e;I4vr=LbulJyR{CsT?`fJjzQhpsl=&Xo}7J^tLWQv5*gliM#3mZ;j1Isr~HcN35zAi`eABUuK1IWi7g)!|5tsWN?n*AmaHv_ zadqg;zWS@jmK9;qy4+=qeOZrQb7$YQQ6aO8N77y1CAxWSym8&UsF%^rKg!ONSKfZP zZXPwFL(_FrEmFK3Dcu9k`V1UG=|IS?g{51UJ|w(tW90`8uQh)0{oll5^vG{|@85YJ zCDAbcq2Bvhm>gvuUhD1N&rGp6kNmOsex^n?TPu@NXS%)3`pV8?U6YhjY<^Srs-(C^ zip^~yq-~_mPc#H3(wWvb9ttKF;o^0_vq=l;V2_b|+{2s2UHGAn*Nm9>l|9O%uw~#( zYE_@^Za0&z?HSf)GXsRqz4{q2eS6p2&F;wx_!R~F2(waF>!!6C&&&>rY}cB3QF(Vi zD2wSKi~ z@>ok)vL=f&uqGFh7V6iKHF@l-lgR&>HCdInYx^EmyODJJrgD4Ho$KrDpgQ>GAZjmF z2k&Mq{mR8>S9MT}kgn4bm6UE@bLNJGgzEO{)j=v;J-L8#!6k*m`+i(v36&}|-%krS zxOC0k&nHZuuvzAQdUzui zje}y*o1H!(?&XSW(Rk`AoBQ25s~q%ZXAL&@J~o*DVd3AV7yHqeE$)`dS%0aX{0wfC zKCBFwXN03!#CV3#*|zWpte<98dd=mx?YqGi1+spV8EggOcAPcKJ3n&J%5>-V%s;KX z7B=rm3+$WBa66RNQ8ra$JNRf>%Ws?AFdzs;+kB0e49t%|hEc9t;MS+o@G`llB6c{G#%tFg zY6YD42b~9g{Tua4npXdWy|C;&*k}&Zi!buZ?c}nZjlO`0%YJy@Kv3Efj->0aO%Gc2GlH=)y z-KV92v@qJ&K#_Du{crFu|3d%lKV%b^UheGE=}xybmYX1=zOEl@80|#PiOj3Kn&(Af zdeq5!5RC~V7_FXNIxB?AZV?hczhlCn;S_4*Ys?J|@f_T^1UzqY;9|_STf}^xZwFDL z0(&g%&`2Ztfjx@4gRPBL!&p))nCwYq^GT7Ie4Om{b?+KTZ-Tt*x>N#mAu!OW*nJhO zA~F3__uh>KNGNiju8EH0+O)1UtZ-^am*O9KfH;dN`zOz(QJ^!uG1Bu7)b?wF{H2*(zlc zm%Db|TfN{rA zCe@65(%Z$4>1upe=PVk$;n0PbD}IRGWePgeJ7;=sg4<{YPest1b1SC)ja8oB+0%P+ zHT}9O82650j&r?pvd%BfQv`oVkR`?iOPDw|dTUk#xj}_PA;t34D0yNLHz`l8lBZTL zL%bkQp;Uh6Gr2XCilwzx=Oj80QkdATFKsW|q;Ae0Klk+;;FBHGH7W-r1%Unya2#Z92)|xARbOXwwDfWGtT_l-rgoDq{IF>{Z{S*} z=A8}IZt9yrOiE2N`M%^1iKq?|;oG@JIi{LcyBUxA%2{rRH|vq@wVPB^oMub7Y46!A zxfahlDTTSNy+~TAaoWUN@t}6oJbaNYEHFy3ymyiJ^*1y;7L&r_Kqfb{wz18&(PVPN zf8poojC&DYNdV%dW@0hB(T||GmRtc<<*w>p7nY(~2dH%^O}lA+2{%K8<5sZa8_+NsNX5yEv z*?LKfb6cvTRgU!5<)dnY=N=|iNET@HstWAs1+u0<&MJ_(0$CqOU!qj*QuC1RAdbgk68T=`{Qoms4M)V5_57(0km zMS62HbJZP3Ig?$fGgXvB)@3Lj;3#7Q6-Og~)yg>EC8v~{pxl6_-=s2WF9q?_K9e%8 zjVsakyDGXAO-#}=u;{04?(dL=ipvS6q>>JkKB21Xxy)*x8E;iygjTK8)w)tY$5pNU z7i1>sGN;b8T3zd?%3}4bqbjX~jXic8Hc_I~4VDdM!(P|F5u3Q=VQ2r!L6r~HKzq?T z_j9q+Y*A_d4835YNwdyF^r9%~KtNuT*ftwBs$WO9tjdvi^?g<)dQG&qY_A}PN_P|g z!U58*C-=1Md}g0GC=smE*;&P)YBRb~l+`fPf|)pancGF44xuk2886&XikNIthX3{7 zj+9z8Tf9aF3a)B#HQ+E9LX zNs$Q@$0p;gSa**qJ7J3rv*yi1RsN@xygw@*2xm6#zkg{lQv;A_G_%&-ciP_kY+)ZK zF>)5OmI`|@U4Sx?fjgB-F4hdt0kWZ!&JNH4Mp$>;f1Y!nDuYn*>7SAMP|3-q4DqMK z7$5iVN#CtkQ(CGNMPijnk9A&VebAxeeoiG@XQ+l!5@S-YO|+e3^nxNwt|I1IXN^qY zB@v25TDDWAyqDs9dMXaq4h zTeH5uw;_(^m%_A@wG@6BS=Gi=xkVfw3PV7mIft1b4JS>N8fpxg3@o^%0`+NX)g{Pz zILjvad+I7D5>ORG*NLl3MS0FdY!M?3G~+N$i|w5=OHEK_b}>2}CF7JjiwSkbjdUkzz0=t%QS7R8WQ*McrJZF|G4!I6%Kjtqq+rM_#J*cgOl9pKxk-UcD5=DnESVlv z(*ItUH2U>Yb86kVj_Z8}+a=L_C^crq(FlfGV~zLLnBuqqsv-cWmI6 z+X^H0RYN^V&>M|9f=YXpQD1>_{{4pKK}YRm!PHSlQ1Knr$aV-$-r&myD98IHn?fA* zMmFU*YC3z5-e>kc1?6}(RDBnN8`;e_&P@La^?susX9J|B?n2$e>2__ zPy~pnHbFb89M3YwI~GcluqDwK*!2Gaqcj%N?vawHmyvqUpUiW-#blIoyC0eIT65b5wZW)+pb#=b z>xVkrs2o{#piy5wQD3u>>HSdq8a0M2b3T7OrhXMuMODSo=%T8qtd+sy>xV^UbM|R1 z;)A1O=2W!W``36MKP)Q0W~6&RfcJ5H8)r^gYtd1|q5}^oFYsmW0PM;ARNPM-7LA=V zreH322jFg>qG%t5r}sAAW&eN*INT9KNrdO7K!AKxJ$`gIT6lC%R(Q@y*x4^Z|0!4i zzm%ZYC1}Y(c$OsGUL2Uu;2HdiDT_dekstWn-!iYNhdV{B1Bw zp*u={Ta7oDzvmb=FQ(>0wHdFGzjKUQ5>w4k9mZ4W=Ncuy93_+0##_T*`A!QIQ+X)y zX@U6r7Na)A)JCXFjCVDE-)hvgF?Ai3d@9!MPSM+px*?`+gu2XlH}Q9zQ8&lbEl_#m z-O69p`eNNz;;Fl!t}xza{#F`wZ%l22>Neh#$x|n*HC(=O@v64Aro|l@_d)N>;^wBs z7ohB~ykO<3i&kb9uUgUC*3_=+Y%(jFI+|B4!I8P+HmBuFGVX$hj9qFY{!6(F=03Eg zEen^mXLNO%e?lzU7H3v0Z(p&nW3kFe@pR!W;>+b1WI8Txm8d27?H#MynwDgoG4}{? z?PR;mJ65gAtXR16;*8^ER<&hxQN+TPi<>g-7q3{fs>Q6u{x9Y;?A~rFUUB%#JAzkj zO|4A}L&W#g-29(3Nr`J;zH(WnY2}hhtCmi(cqh}-vb>|IZDGr?J}Ge)g>XV5LL>t} z?T+GG;xa0j2Y10_5MLR#bYWX&(L#wqLO!_8V_}evB;RMOmm8(QKW_jN?G$fl7jR1W zyEHoJpbfX*^!(S`me+rw;+uC|x^m`)KZbwG8|S~Jo!gVsBr9T+y_$qkaDA z%R6$Ni{_t8DX*wszG(iUYi3NJU)Qv#bJ<(YjhT~Mmn@3@^2~kJhZav?ePqi; z51p9(#UGcxal#90uiyXAP2U^QyXoJbe&p8YYgS#o|NgT_biV)jC!hY%S*J|D|J}!a z?5dCMtpCbeTL1G?>qcG@F#5rt|M}@H+rB{*?a8WMOkTd^ryV6lIxSfoWtSohldG$* zE-K19&g3PkSF0`ml@G;5)!uahCNELEE7jiUOB>jEaAFkQpx5}B+@`E|uf;%d(bM#s z=(5qxWy5|MTeE!Co7pk;5&B!2C%t9D62gF zll(@PL>Y^vYqFl6ELVZE2pcz`n-w@0!O5b86gXXQ^3#$WDag{r3U<^WHXfhkd{M4y zlAPPcK}RdN`VO2dx|-uGT+-6iHf<_AJ&NJtw#D(geD|8>ypKGze0+m>kyK5MC-(qdqN%_K8U033^(|&RIVtg zaGp+aPKDE&b@6d_8V32ZWDut<#i^`6>$qu@%n~b8$p@Ti)8RB>Pc?QQ;~Y1gy31>U zGXtUi?eG)_JFgv);!t|ikh+4a) z;RIJnY9;Rz14R#$~5IHXILhC7aAHIMA*+VFxM<&U12 zgD=RlmpYTNDHOYJNxaleA%eaoNpf6E;yJ{R$6AtLNB+2$#B<1H;$$s}=a7SN_?wQ8 zYe~Evaxk&4OJHHF@RYDn)O)l<)*|9ImHN9pgMaHYrWM0AgFpQ6|m7d^mVCG|hX+;}ES!R!^Wj__r$YYZ;oOkod>GF56z3K= zhoyYJ7fxl$=bw0vOR0SBhodqpg#IF&iEs*b4kSBi<`Z_b$yVZ8uyZ1uT*}TI@2X&D z8JxK(JMV^5m-6TRa2iu~J`JZnW#>*fEh#&Xz>&{|uy(*%ld|&yocSp`2O!$rDLY5O zS(37og>!Yv&OA5@y%5%gaIR0;>4DRcvh#5`H>K>{0%vW?&UfM5nzHj#INd2bn#S84 z+nHPtRX&3&S$!L&r)S1-XKD6XHHQw%42qnbNtk)Qh!pM=}~3?rzXm#IcN&= z25_cZJ|}#xnPQV?3C_%#=$4eLn(C?1wlrtT^k~NbP7Rj_C1Y4Kb!Maug$18$rX6P& z$|N~8x{5AoXL_|=5|gkqeX4ySFu^%)M)Y9X)r{k#r_-F{kGF4lCtS^}w(DJzoa3S_ zCEz%d+d39k&OY-UB+K%;xJWsUr~dIp6}?EA>X9j}mR!wsuBhOY>CmpmNC0`vj#0;W zj$VdEUVm1#u&LAHB1vufnY_69g7z8HjX9FP#YHOJ^uq;k(MgPCxFjii(v*`%zA7$asp)$qUy z3s*N)9*4O5&?}LWvlgysVx!YQ&Xhr%IBVpJ0PC9C<4hInv^IRIQ?FOqxl+>>3R4$b zMU~bW7GBfFD!jA}VDB;svM?Z$j+Kt3$yPdYj+M6N z#4c^m^Mp^OelT#*om(un?p)V1OcD^Ds`{z1F6g|nn@dfPd809$XOtMkM z$;k;0nLN(mv4-Dk4t4g_mt>-b#^e->Od9#+uyd2Qr%o&zHDr^@HY`(w@A7u^t|uE+ zXOrr+c#76G>^xkJ5MAVa%TM)1xfPR%EkrDH+$< zn}?mof%e?AlXaW2s!sEKZ^t_&e&k=G>l9xd=YI^ar+$|rKDO@E(`w&RKevAN$!{FT zpHt49TQ@GvJ-fb67m=PjE+bvw8Gir9@7$=zNy#W{p-UKFG4u zVbM=JwEX1o%;k&QR<*BM+L5W6b9CnH){f;XmS3Wo*i)F%Th6?Z;-a`s8>ZF7(=Be| z>5=?Yfj-#!})! zWL*gT9IQ@$XBRPn&2`u1@D!U2!RV(Xuqer*GczluE zwAlQxcxz(b65}ZfH^&Ywo?@v&y5Q`p39%$Q&ih5nJK8Po&9KJtJG-cPRm&0!vpcr6 zWW~bv3yhb6m%ON1SO3<)a{=hm=L6w1#vFf{v;w^r<`b3#yZS;YXn^J7agnV?h?kFf zEf%Um$iZ_VF!yfpP&M!_?V4h_l%#u}-8d|lH^sbANVmj(Ep1!1BC?yM{{nBjS9T#y zX2yaa;rFQLpT=lcB}WQ0`=C{|d_A}XRDL#rd2lJHP?v%CgBO7R0b(cr8*l~q6u1(6 z0bB)YUlt{t*Ex#|!Eqo$ZTHi+gKy`Z`jEc@ycp~OF9B}>-woagt_6PsUJ7dBfEj`O ze#7kE`ut(w6}(r2UEnETH#i4e56%aBz%}4|!Arqj@crOM@Dt!w;8(!+f!_j|2F~9P zUJX72{u}rL_yO?vV%zPIe>3<&-rogY2R4D^X?`R4QSigy$H2S6>%sfLPk?>k4d8R& zr@&E^!KcB)!Owt`!5hIW_*w95@N-}z_<3*zNEzg>1-}4(68s`~Gx+b|BjC;88H)Bls)u5^y_sE%+PoBj9hrFM_`Ve+>Q}><9k;Rtx*MolouLhC5{1?Ed!JmWAfd2_n2lC~mQS_hS81Px}1n@cV&EP-4 zCE)Ymhrky=O@#dmydR8;qP%WkDFVwF`watUfqWl5zY;6~F9(N%-5|^L`S*b%z|A0a zAb&r&FZcpD5-cj??o9AdkUjVLGrhO1|9^C8j0Qj zz6LxP%z@kyn?D0Q6r2ZgA~$~(_&V?!kWV4zuLU#U=fNYuuY=Ud{3fsx{1$j5_-s{I1}6o&H{f1o(Mh#a;I(nO!~N!z%PTf;5WgO!S8`}AY~n`plt{ja{F7s!==~m z3hW_oxz?T0<8j^QuWkN+ms*n{88SpyZtwn5Yb^bZUn4)V9{KIL_Lp~EHtB1Be_+yE zZ#?ntc}-4-tSEYP>Q6uS=|6w;XMcI-{AUjQal^xIFWOM|SJS5K^8RY%%M`PQwpGg* zK4(rtL2A!bt*M!D^!&FmgkE(~d*;pb`tzq$&!4?=aZBftCdkRvlc&^7n=y5A_59Ao zZ5{L3VbBCFxQIK;(X?LX9n_}V{V%(Nx~S6KL9Hgu-9as?EP9c@R3mt_Y(|yYav)U? z9<7ay7|NpG(FZ!WJ3Pgmu7zU)>z>?>18w@O0pqR58!Ks#VRw6sHy{T_#QFXlTWZ-# z>sTB$@7gikeNv~Y@TFTe9S0|T^UJwmJ8f_?mNVM4=#e(mI=40cJQsdv6ZR(2jz_^p z@wOaSC14}xH@i-UWkHtWcY%fnWE@W_8a%zt=`*BfQef!pxi zY~TBC_B_03@jIVe^!+Vq(B2g%(&aen zD&c#Hp(|lg14>xY_a&T2$xD^6l0@UAOHk|->40Q+SIV#QD?d~c=MBxAcvgFS9??pL z3&y6(!%XU+UxN@aN$>Us#} z|7=PJ77$6Z?6#!6mjo+mX~FqF8=>7~{cVbl&s~3RN8QB#0;%y|LK#+mr4y^YmDIhL z?Y(#5OTKG|E})PM^qs~bx$q5_4i1m*ZLGc9B7H4wZ{7Bt?rOj;s^Q*y_+Q~-P!`7J z{+>7gH|AykN+Mc$>e8s^p`XIU(-8<2LQons`>uJI(oOH|tE9!;%?JFDA zx>KX7-5lpc*OXt8`Ac^~o3K%H6Ah+sEPn7_-ER!yOvc6atW?L;!mA*Jx&N z)7+E8t;RUy79W$#^*-P)lh}d9D7Wt3?ZATXe34im22~P$lKCK(#-OT4g%dRoFlao` zcn?9LePbH#e&)pdyg2xidM3*_j+!*1AY|_J?q1N*qWqmwTeIt)B^a}n~@GEfE^VSe^k}JGQ zad8oq&z=c=e?7>Pz$ZOvc81taDOZa9Q^T`u-YRgbCzVPzK_ymy8JH2)TyI`9Z-sgb z9^2SfbDYs;$2e2jvzvjJQhYDuX?0f0PP4!eCKX z4ScyOYI)I#cB?;%>Uigmfl8Pg)avRcWeucVKI_uJTt?GXEgV*W07+_<&g^ezs^ z+ndc4$4;F#C6jnwYX8La>Cq{;0RJ#xRR@f)DB~idc6eBq9 za+Ut~4Su(J{_J6H?*d!;^XgyE1{=Y1zze~-;H@BEZ^%Cm&I4IDjotyWz8Red>S7G` z3FK?R1z-cX5L^H*0#}2J!H<5>E`b_RJkmK1=Gf14GnIAMfkH ze}Gqj)yP;Ecs{ruycoO^{2aIe{2JH;-VOGGl1cVMWz7{M8KL{QI zeh54YBu)7#;77oj;77rF@MB;TcsP%V0goK8^e$kfRs*%fYXLcYp;pV|7Gyo;5Wg|;P=3Lz-{2Y;G^L8z~6#fK~=78U@;2E z1K=Ux55O7V55YF@K~QV^4}rbl!{EokN5Id5kAj~EIWCg_5AZRth+6kkP;31^1CIuO z4mN?m1Y5wz!8PEoz;5u@AX^!u--256|2_CA@DHGB@e|+{kV7c>pMXz-e*^ynYGn6k z@I>%wa5nf1cpmr{a54B-unGJ-crExW_-*hx@P6P7opVq#1b=B2@pGMzRXW=HgYIQLgSgt=(57XIh-HZAR zJ+C3H>TZ7PUgP(0{56=f*TkOiu6=5H^sesdFVJ~0{G+s}Z$d;ZaIx2scBQWyRIhs_ zSP!yCET0G82fi1)2HXUG0Q>`ZEhruHgCKicBKDHy^+lrVz~$gaLFL)UK;`Yz{N6Yq zZ@)laQw5)PHu}Y&yiFehP%bxMcZkR5awA5GTt1jwZiaQ?!RpAD6i$%HpcMnBAjqKJ zK7K%!j~+cSHdtxuQ+52_ys*7_fm9vSeiUuz0Rt$$oM4VKFoRAN^8Z12;Zb^(|HR1j zc=6G<^72gkh!mLi57mI$H?$6{1AD>KK&kyqXXkGObKrNtGr)(yH-o%o5TOpv`? zB%L-6L|-r+;v7&q#M?mW4)ee-fXGh%hu}NFtBB`$ApNYqGL`=n_)bve^e#~4$v!f^ zA#^&DR(Qq~yKidHzD2(uRGxNjLdBRZxJXjI7#rZZVqDV1R$oVfRcG7crg$5# z&+K+%WU%EJOWHY0>2}^;h?;PA(W=!=Z7mBgwo0`gYkHo~x=NXcsr;WlTF~4 zz&pTuz;A*-0`CIZBN%-PJe;uE!CdBwL49NF5s-c@`Z1_-{|PAhxR~F-z2L~2 z<;fiIm&y$H__oxYm)YyqRJAsPN6CuEtJ=Ps_=QJdt4!!7>`CEz%4ICu;=0-O$(f^P-)1!?P|GLW_`8UE>I&xG>X~oJ=k58+N6AgsYstC`kkxZKcI#jw8{=jr? zAij!I5BLV~z2Gdc7d#8x2r9l;fl8P3jDh915}w+CW`5rrlrDE1bZ?ZpU3NdJfsF*R zjP##fguJ9R-0iRH+*L!UnR;pmR0i!$hDfw|$-1$g(TN(3Kq*gnsD5C}B z2akNO0mtz>yJ&HzSDDrFI@WT&=s@SRk9AOR|H4l)5gw&qa(yhnZqGk-xEre+4ju!4 z9H=(@NN_Ir2Jj;AC~zHkG^mDwGj;iE!0F&^AfN5XOSe59lw8+<2NDMJ^?AxHss%OV zJsCU)tOFSjMW=$-gQtP$;!zGn=Z?+*zYo@fzX#6*UxS>T10DsQ3rbGk0-gab0eitF z@Uvhu$h>&89Aut3Iv49H4^ddZtHf`Gb#{>ydUuNXPy{TK;@ihC2lb1au@fG}Su%AH zzgs<%{a$(b{Vh;3#X4601aJ#@2DlZR2R;BU0)GHr2L1^AH<0s{`LBVGf?L3!fRBQY zfs(DCfs(DCgVIZX0W!{tehvN!{0;ctVXTjXtnEa<2UXU80F}2-fGPv|F?B#0e1?IF z>gz|r{=sEnpIuQSpSS|#9kiweb(f$5rt!n|N| z@$)94j5@7H&4IL!Blu||($25@W9Y`xNMqo7DBVzWnRHZo0Nksw%J8E(SzKs2)NZKV z36JtbWjv1GVV?h2@=*EoFHkMei{NZz55mC{au9pGu;h2+QSpkyQm zN|xG*`#@QG%P1#H_283(WvRVo)kRjD|C?m#-^e~qt?@`bRB8H-ixy$|N8R*sf{n zlGS_>fBd67m#j|W*Wvl+QbtPMyFkh60#LHr2rdH`f|Aw6U^loN+z7IUY_fU*C|PX< ze*@B&=l=$_gJ&VD$WeX;xEA~_cqRA~a3iP;z6w;vT?77%O#diYhAe&zq(6;54!#ro z1h^DgyaD_$_$lxU;HSYm!Ows{1wRYkNG5(BRAzn&ycya2GI%@q74RL%=2yWrAZyyb^#&k_6*QeVSs##lk> zlTxe}_a_uOk0d?|X85J0*y(De1Qj0To8(yf>I%iZF9{_&`@_mEo_u#L=KY)x+q9?#J2y+K`A^0b-iKPA++z37mei3{IWX(VN zJE*Mq2Y5b7dLGo_tQWw|;J?6!!52X#xo8CLkn3R}eQ{I_(jP>_!EN9^;19qN;1<$b z3QA7)1tm{+@*CKu4yPWCgTIq_JT+LJnmd;+eHAn$2}*`gQvGwXR2ll)NAv-eY9*NA zmo8PcP1o@YkK(Q}t>CBjMb81GRp~hxlxXtJhx{8s_M7B$AfNBepA8-gz7;$SJP$kq zJRckns@_$CXM#t9P2d|q=HH^DzyrW4@HgPmpz`h*PAl-=3-!b)hvJcE#>#yLfTt9 zJI-xh)z)$5xhGrtF&*mh=~n@V^h+I7LS5UmC^%7(Xwne493)>?%p0%I@{x?+WoZ4Rb*&?H$MdEd|QpAs$koW-g0SVxCD`-7>IT zB3v^!cpremRvPx>r<$W@I&oEejsquyjM+@CYrwg@zY$ywo&c&&%mTjzo(OIM-vs^y zJPG_yFbkFtPA#Z3o&rjauje;;KwfCxqzb{c4DuyA%};qtB@DU zs|GkOV{8I(*Lig{7Q>^sDX+@;b$jOTSmRWD8CTjI(-Yunyzc;&SAPUm=br?%e)uQw zW8hQZ$HAw;o55$mAA)}ap8)?8d>;He$h=SV9H=~Dp2hO+3h04y)Pf+6!_87~M{)^`wNfCK=uyjCz;oC3~iUn zWdf*pOay0x$Aa^~YH%4i1^hZV1Ka{KX3GBntOcI}PX>$e^AzwPupVTNEjkmN0nP!n zw!`O#^UdIUz{kK1;4i_eLDrX|kAm#!iTD;%{tMs@AbSd;8^P~@p9M9)_c`!q;OD_V zfd39Y58e#YZb!F(b>P>)^T4lzlD%6&)o=EOQB3=desB>l_FS@nMdKCi%c4VIKOD1t z@h`A%ryZO&(jeIxydHz^$8Lf)x_DLV#cj)%HLI9MjK0y#S2i^*SzuFn2YOynL;$UFbGfas8I1YF5Dn4_&tdq%g)+GD~Ud#Cc z%}=o5%ob?NN$Kd1!3dFbTZha1hiW<(YmZR+D?SJCuE_h@8{2ApkoRTzN^Ub*xv)j? zWC!xWuph#z-j*+3K&5J0!2X!UG;F1#|CMD=8y4N-2x?2|=sOg%js-d{L)1pW8AoAs z*3&FlG>+iyB9@2S7Ie@JBvWEOYR2BKWLRL!`|?q}ObDcvrLMyFcP!;!P=NmC8|O$V zS1=8$+9~>>qfguvdNIo7>Q&2^v@W%%w&F^0TWZ00KbBg$-am~+jZ17F7K>@h&_qhj zx+?r^g(*YTT%>R1Dw3&0XlI-*mT)mt5hn94P8EfvE~9j`7Tx0DT2VNBKDI1F@=8ai zV&n5ULy+#PM6&TCvL!AoY$)H9Ahzc(HShe3Wy5$3{0E+7Pbuk~y|QBuzhAUO$Aka1-!JmjX!8HE?-%`pLfoc&=jXm(B&sZ$TNHTnJXIEb zBIbQM=4me7x&2YhD;pMgnsIafY0bykJ2U2KZo}~|jCmVko<@q!Z7bcadgGCiX39jB zMGwTh2V>qZV&3+c_hig_I_A9)^R#`$`8Uc_BcqC#R~hrP%iV_yb%4d?K~I%MH=;~C z-c6n=i>_xr<3O`_gQv=(Da>g&-f^BPi)v%usWI=In5S7MxhRVk#yss5cf1Q@UT4hP z81t@kI;ca;-u0d$ zyNR6Rm3XQwYK4;8g}iu*hLFfP-Y8F%MU7B8e?2l<;;FLeEFvu3d1N%lQaeoMiUKc#1lWCCAHq3b}`|((K*fsj}$nP^*l0yQj*cA40Vn?_p0-=1`@^>-SVy zv|zHEml+u?_7pPd`^}79SI8%ty{4R*GIQo}lcrWrsm`3yv~cC5mQ|gtnbQ}tq<(Q` z;mRc$eK9^$t6RV_QMl=l;08S<%zTvE?1wWdiH6gwC}!b(pD4q>@W_6J^*fGJ3Y|39 zd!B#cDaDkxqVTS_VeW$j#>()NjWTKte;u_Urmln9&rENMsZBAp zEv6oesU0zu`hMWmu=V}GN-**Lz#GKoGc7{9gTC8HZZGG?>@oiPEyFJ_^Hg+c*(Ti` z-#48WTHnBsyKwP2U+jooS416L9Ufk5qR#!pTi2S>sB^5okWsa6P3cGJ-8-jy-%C1< z(UnM1?t;xF;d>^%*ZMF@igGTx%+R}tT1%Ga~@L5R5QS~GE2`FgekM5j*MJni9W_bI|G}Tx72hi;GWn$wU`XH)*G0+w-%yYHNYB$R?Wx7H1!!gN=71P z4sbRguK%N~b#1zt+}*cRca}FGDpCIoOIp{aTX-3EsgomTYuH-ZnhW3EY_6l8`h3@1 zO15E8hLqpN-SQj86a|CbXUfQ3SmQ%H7ZOU}*$i9E3U#5nt0wADRHQMxsLX>%n6H`T zEX=nQm11>%$^r#h5m}lW#kYIf8JC_&0T-T1$E!#`FHuJZX zJgqiZXj+@2cytcyf18gR;;($|olQ7=#8}N(@0_Z7$;O#5%5N(vt=&+9 z0StT_)Zo{|oSMF;P;z2#U;V@p11k!PZ+0xX>@}hR^NG%3CQ}yB+4cv&umM-QgfOevN`2zt63DHXLntguRO^X#?Ymwb@W2%>CNI!>77@; z{xhMZeCeUNb$11x6ZSfvGqJFjuis7S)ul>Lt*=!&Jb9(1Hz*!fdbwSfUbQd1+#Z%* zZdaw3+kNT1@+4Dwxu`R)Vark_rngXH%gWb36<$NlDewMKV3FHhn}?Z5o=`h>^?qSI zkZQjYHp<^~jX6!U>h^9${gNtJ>}v0N>D_e{zIQ5!tJGSbct(OWt*Hjt#h_~qL$3qP z*4Av60oKlGoBLkN(5V0H(6%G&QD-epZiX)y--Mr+4>8!={h;kWlqm}%3>RtNL-?gp zVaT|9U%Jefg1gSiE_Iu(CsI*oCJb=PyZwAR^V2~v{fDb z%e|Kxn-mXiX-&Ux3m4l`IwReRFkDqii*xsjT~HDu%(1qF71^~i7i zu#ORe;({1!P%T#EOor)m?;+)sSP=J6V$JA0vR+ia{$~W{bE2rTypX)U4-^cBmv^t{ z?bK=anLrgRd56WFE+2Zc9Xq$V@7N>JvzwPbgS*pAy6j>Tl3wbdG=f^yObw)S*ewDj6hD?V7T&HGcmfnY?GR^zIP^=4D(&V zyR7TY*6)={9=qDRN*YRv;LrhIZisuQ_J^qM-IybG^>Pz9>g6U7hkKJi%^8Hq?u}wS zK)9r-BPy32;6-@ivyYkV_tZ}GazsP9-`4KR4JMkjf+PKlM2i@R&*xvS1{Qqhfx%C% zr@pfEZMm)|X>DJ)Lo)J(k_s zKyzHM-5hnKY&Y-LcH;osjk~qoFu-=hu535Z-V7PXt=TG4r^YUGp(!zy|Dw~f`ISl; z;Hom$b#L{M#q&TN89O$Ym{sk1k|?}z#~55DN~#fGH1MxtAX+V7RdS@%n!ZLWxsKz+ zBd=_zOsY{Im{)XJ7ha1x4^cAwYw0nefH=k+#RfSQw%#(5&5pzC6u4AA%lO8^c)Px` zk;zFyttxI;^QQyR=B_ter;kIgJ|?^=>iAN{;H1??vYRF5&EYftOclx0hHyR@B9Lo{ z+irdMxT%H$Kf^!kik^q+~vYzPm&Z$>nOspG!Pi^mmy$@?3nqeT? zSblp+?b6zw5@bg)$kr>I@k|xCzEb&Oc8GQLAg{}BpIbRm{b=72NG`=$&0=^Ev}v0W z-iBCs)1sP{s8*2hgs3)14CgV?FQj@|<1#PRxah!vVlhubDru{#-K6PEr4b&NK3Kum zZpyG;`AsVzY?C(EJ~ZrXsCF_+2%56o^aAnjTjhPlo|SYCU*&;(rSifnh?519>nW|Z zbGR-?8f;9G4#oLY+pvfB8dLT<z`iN)pWr&%E$Y&9+_#g+8tDlD30B$-+n zXxf0Wfu`J<`Ox;>%~svW{9JDXu|#eLRJm+j&Xg&c$x>sm z)L6(!w63%z1l9ReP`r@Gv5ByJI(l;zu{Tyc{F#keHj|s+YG1BcUvRgwtR-#|?7Z@7 z+QWPmkSu%l8J9IzmDGA`>z?yj>21<36g#7WSL=2JJGtR^Ss_>m>#{7JxwsG4L6hL4 zF6Q%W?ZpV}R@hcGvT@b0&UcUcTPwY+RS8#mqN#LoKg`;e?>S%eVv^mOJq*&K0_x$BDkv`pZ;z zNkRv=L80|Zwm~#Z2?eLgR|X{C-*Bd8YiFk#zIiOnsY9O^tvyJv@8$agjnP^SiW*BU z^JOzG)Ti9wfmd%`QK_|TmNUJ14d3V|8aofmEmp&q7^9h0b(gNIZs=MwD(X1!n+$m) zNtqufW^Pmp^LmUq(D(A&>xyg+A=9(&CiyrZbUF@tK61Nf-K|3! z*A)JemD=r8V1%^Hr?AmhDmcD(isw*AdQ&(B4m}e99nV65lU1`_mefmD@r3Sf` z;Q8ohC*p1_&c;&qf})N?1j9ON`*daiskA!Zr%m`uaMva&LvGFQFy)+8OluP(3E%I7hdB9o`dBnQDPBpED0KQ6>=jV0vjW=r@G1trL7|Bkn%Ii z)F5lMm@$nuSi>(X%zDde`E78x9p%x4C)RWC-jgF#x+zbNNP1!u%vvrP#pIWwXel41 zI;(KH*5t}NS!EQpro3Z+StLQFDyjYnyydp+5F;+SEq(iQHw%m{eTSebj4FPx_a0I| zVo0U^6^rgEvFH*cB0B~Rg-BJI9@;aiQg@z|RQmf)s-?nN^`dXATH3R&0^380Z9MQx z>1S3@u6SJA=c|vYej@ushWZ?4{n6< zt{Iy)mb1GRtC7Siib)cgDFtiq(0;gD+n|xw{nD*QoIDr);6i9n_+#)Z(S9^4G-^wv zy(m|MQO601(ZWXKmET=b6ovrYcf+1O8rHiP)6$eWz@B!LS`g852t8tt*7?AT!Z)4(oPND*Oac+ z;C)T`;X0GRY6IG6FH*YWpzT0<;gNi;U$5eO+@-gF3iXvQfoejbVki^4pa; zm5MZKb7k8BqKH_fW|lC?nnIApd-K1l{C1`~m-dt@0Lv4b$&5O0l)Hf;(^|j$kn1eu zx>U$@y9${Yr*?BR=6WMr+8W-+Nm8FRwn!0jrNPga;j+;QO|E#0CWNS^4_a2{dP{dG zbfwDWZCwx6amL_CfaAZQO}{OMLnI-!Ylv)1qX~X0)T0t-MQp`M|gq zTY5;XQ!+?mjkDft@MKQtqccY&jT=q&E7jQ#ATM zO(HR?87`m9VCFg(KXsL9lL=;`pc4t|k!_0;!aHkqn2%Lj3r2FI82Fr(lOf{hb3>+- zu(RA_VeX=JdfVoV16XxU<&q?(v8Y9V4_JamwYCau9t zn=UTDVq5GAX0KJKxP6Li15!{~m|w;>wNBAm8;UgcT5uL8RSsVZ3A(C(-yE`3CA$`` zFE2R`A+e_E=e23eDCI&XdCN*<&xW`)3{}|sN3CFaRT=oLkXu6p;#jlm*7d1Mov@|+ zijRjV?O{@?T~cCgt8s`>3Q4Ip)0dr;zYw{;J6R`@c$CSbxLzs4xPGWgnW&HJp41>k zRk9L{2Qq$BxnFHew41pBYl&_-GGSpf`uk0I<-}*AO=>zzg(~>;2sav&wXmY;dxr8W z_%LJ442vi}I)m0xLS%Y-B+q_{BkZ#;bOp}2^#+c#4#vfbz9jf!DuCanFXjCP{5)05 z8rR78+VQsb;n)L~KO8go(>uG~)x+_&5)$$XF73 z!d^-<#8}BkD*rc|+z#pN(R_Hkyt7MNni1EIw<_B+mGny67elP&HPeYK746(+p=x@k z%4_XfbaOYJUKd<&CGNVri0RUuo25Qu(~YiKUR$@NNTRivRWK(aOMANCE4$|Zi8}If z>1&KmcuzvJ{jWFfmghzcm!;fw1I#tOnN3DOQ~5+7w^*y)iNM?xe@LpvLmK9}q|RKY zq*|*~M>@X zI#DP@t|uiuP70ExTW3SghD@aF(0P33Fty%er9jPYU{l~t zHZlr1r+gfkuYFrBJCjyI<`(;62_>H_hOJhcaT=GjE4JXapm2NF(z!z*d2{9rRD$!o z<~`4A-pLYl%J-f%x_uK;LgwP@gYg3Z8Xx-k5RoBTmazM37gj>EQvK4+3M~mix!?!1 z8}QR@L?KGMthSADwQVH(RBaoR)z($iWSvS@)S>GXLQ)x(ci(Bn;SwA)tD_1rlD-ns zkyaI(os!b5_yqgGW^a$&g%-V_Wi$CCw^G@$- zjkBsX8OUCxZH-IYnxqFI>glve4Qusk*qUJF6{l{3S9D4`wN)xlG#G2Rtx|f?gBa(5 z{-aY?mF=ddX;+nAlo?pHVjOZ;)qkD7_P8xP2T7BFMxDd^E~h_Z#F5c!5Tm%?_<#CZ zLSGBH6Qr!SM?G%Oh8q$&S1^-G)w5w^!pybW5+u|7%DW#+7#1Af1b3!+THbYA!UlrA zJN>ZyJv~_7D;;t8MQ;yja(jl0I^s=;UW@EJKG-NkFsUq_sKdgmnQ(DpRY+psbZxqU zXrYa2e@b8${E}hNT=W&iU?bh1xv44ELjOgh8>_FqdAW8vZ9-wSel}LUCahBtNW0v9 z&m*0-+HL)HN$DM^`G(GC;!Afv=(N>dr>&MwJ29bD?p~+G=AP-a)d`)pI^jJD^*U|! z{}i3pl~bW}bfu}O)gT995;5ewD_0f+T>ss(PK>l@*g|nG<}rcjCR^y4tC(HNmA_~A zZ5I=g$Ozio5L(awg=5V)qpZ%@ob|kzXL~&?&$UCPeEl^Ey>+Wy2u1eC`9HXh|DVxs z8l4W%m<&5eL|O+Z=r@hQ!YkGQG(Yww8l=8=*eqk{H8r7v(xyuz;_R~tKzE2>kh;qP zND%6mukKEN=@y4ZhMcUTb3UG7TT`(s`kH5~R@P#JY7ED(c$U)mjNBMhlC@d!gN$`!1dra8n2BQd_{dXmcY!X1aG88wazY zYG+~v_cmL>RgYffH;Yx-3%kg)q+7mTyS{g0tSj1fV=UPV2^lIf-TH1$r1+p_?lKNP zw#e_&*lGK_H2(1JTz9VBWw@OScWrdqu8k(_+NeTC)j2Y@s{D#k>|%0OsVmjF38+tWj8s8Ju9K_&q{btLhIZd_N-m$`*oVbX7`Y*&Wb={4jaB}*%Vlq!&cyKPma^t z^`4l+c8999=AFYp+JOW=6Y@KR5(lwLQ1Whk^1|dm}Rim)FBBl*&-KnT(=x(9br6iN?HGel^-A8pQ|;(k>n8iN*$} zwKZTZPC-a(goXjBZ66OHb@FwuAjmA!A?KWw5=RozWA&V%cg zQszO#QQNDu4IE_T%_El!>9k1`nCB-N8$&`~aq7nTPSmBS*>nI^tY)Q%!f)=^neRfH zTjE9F7Ns5=Ei3}JCN|Zk`g@9D@Ge$0*6c@+AVrVN*0hzf@CD#`!_m#SW1aLs1?xF1xtm>XxW<`t>e-!{L$*%%n*%>9i3V@ZwR{^RAAKpPhaA#(! z{h1ksF_blTbOu|udf^+=mOnv*wN1OXW(R4oc4M%X{zO4_@)HHbD7`0&*BfxBCdu+7 zIqzeZZ7w7>&AL&2*S(oUW5hPrLVHA_^~Ek_bcO#GTSej%ZWWvpaFwirFAvIc{9S>U zwq6J`E^kU@@L3zBB&!n%{0|jB%K;VJkY)!P^d=MQHCZ3IpA_N<>9Ga>+3rm7IlP-s z{>)*)hCdgW&GqQ4VF-=6`&_Zk#xdvV{lS9sq&It*HlCS5Pc3RNjrVSYtfwUOd`@+xBjLD^94PQ)?X8b^W3!GZ>$70#rqo&HOSGDci zTT;1Y$FQC_7u1KEp!mI>wx31GC7fn+AF`)HgA@ydLtZ6C+TT;lk(swABNUrtF*!+b zfMc0ORQH8vL)Q45SFm7*7Q%siZ0amd$MC*tn_sZAb$k?wNLdM`T$lQ(guy1MfVY*e zU*y%JJ$F&P*Dk`z-8~QE0kU7Yu;(s5x|c3GTlU8P&NuCqZEF>3G|f<2enpEdN?0jr ze|37Afzlf*uWNFXf+&|ta&S8KvNL3&a|WEqxQ_JkrWXD%Fe3|VhxNZpmiIvJu~sdQ z#I4wAf{T=HMU{k7#fC)cV4!dX{1=l|^!FD@2 zHxs*+{7RzdVrm(3a;Wii8=|8=$z+?3PM1VmW9qjt^=BwPt&Zu03tz-Vvh$H51C2j@d8px}h9z?EZoG7AVL25|m5FUt_A7gLzdJgR7v9 zGU|&^SRkgSS8#iqQ7uqM8ufK3eX+76dJ@X{oZ*YkF6FagYBrQJ9l@lxOZh4&KK+i{ z=COggJEp$I7wY-QKc>Hda`r~x&`}d(>a3VL=CF{;Sx_#FMNs3+mlmj_jT-;DkfO6< zssoAy5ZcW#?}3==kExLa?{Z@a-onPkb|{@_EQyXEA4M6X8ljFb>RoRL`P>QRQZ$^b z9b=}?Lb()uhR97c-tWmgm!~~snWJ8h5zYzYlu6vBXVg+Cm#6zr4!kK)j`#hT_f*XL z;IYA%L1mqc%hsdlJV3*!SZbK%EZd!dMnlZ_5V%x}cnY$DAB^Z-sKa+v@`Fw@{Av=~F|vkL5xb!)6ES zcqkXz+hS__n}aW->Vq$LL%H1jW6Znq%;578X9v?dC>QSIF|Vj0@a}_h<+dGaf6K`c z=LBj}OwEm{d*%c=D4!c-_hcyF3P3q2DXJ=tMi(6rm64btrsT`!?9*Dr5zsN$RJ0b2 z9~PCjjckqiT+4T0TX}2I#9`6c1IDx#jT;v2Kc}p;LUF~x!6cCUmT zn?3eM*A}cqqZ4j>6MV8Zepbd5w*!?FUam^ex+y$7x=}hjx;rI2PtbmcN4I5$N1sd& zPjeu^$^>6CW#MT_gj)@>m>SOAXhzW;L~k-m0aIZyt%#{HP*ezbG@0B!DvBn~QyHi_ z<5lu^no(-m9W@c^G~+3x=|<_Vqo~ReRS5s6w$X7$Wn)Udo?$%MnPC)F#ZwJXdMl3R z@|T7JYF(O#nF6lrbSgGF)ZWy=06iB(n?|lOg3A>KZa+p8oI8-uq0+^W6J9 z&-eTL{a*iP)jsdf`mE2IhrRY%dw-UMiUmbAsl=Ox-`)&0Lqdr_QH)Bw6#Qb~0X1Jj zEdn)$;Vs24jiXAu6%r~F6s1v#w+_FW43#aRHiPnHc-!%-#ZWsW)NW9eD<$53{NjcS zDqlhsf||teittPKQzhO>33V2f55v2FUvq{kl~C6~`7yj(`0dD0cO_IMC@MK6-b4J- z-ByWLEuo%)3S@XM@k`^B5_5(YOMQSnnBjfFZx@E59ZHr`1~r-Cse!^R27a|9lpd%s z)(3vY1~(XHi&JdJDSr${8NY!%L&Nz8w}0Lj9paLsclgjR5xu6|0DoX_uhBTUJH~6M zuYahQQ>1@fxG*9%#%pj$tRT+M%RM$SI@~41&&w|)LTZ_2+uh4a=oc3>+Fio5j0*7M zy?%Ah%2=uU)OKN?OY|4Ccw^A_{KqDzrynoAJ;1`fv%AyvYkKE9>pob}b=vAQWd+4s z->>c(9rbp@EX_nQ@-EhX+IakIo;VKr^Isz6#B+mT3IbsP!O>k z%YbO1f9zBt`9Z<(loYJQ-X&-mKtroa|9d*+ytdE=fJ6y}Ib0a-AC*8tWGEbPVuZ1*o#iC@Gv^0#ERsp|r<3<& zWpIokdr~pO6qgvCe99Uzr}YngH;$xD1 zP|Z>qZ^%?)ULxg$k}nLsEJu7Otq9FQDw6=2Y!6w^JaAYe&c#YOj+x5{Yilc3f?BT% zk2q8}Z2OVru|VA%E}=Fr`eZ9g1`Zev{g;W*uF!C~8vtPIq-}}W$N6Gp7;Z5*TA>MUxL z^uhTeC({O;LOGe9;Lv=9&6niFUC59@Gl6k|jM%W8@p2r?=vaTVA;W31$D=N%q@adh z1j-rK4{Dh6#mL~^4PPFtFOvV6uSCulBg5ln1=Q&1$Vm92HX&~;{eweeY`Zf|nhPk= z17u5``0f#nwRIm{^G=CM+_ZJG)o@TwnX}1n;SsnBk;f2YYLK zd(QWeh>+NB-VP4E9D0ev7!)B1+g%vz6yi^(1N%lNh~4SzH8DL(NcTrBEH~e1-|!f* z%_A;CD5eKQ#z_Npiw+5wxF7}r&O^tcw=xOxmbG;A=Ftt6Jwcv1Qkb#(hJ^%0Fce!H z-mFs~PJZ)_4~YmsF^CH&I!qFscW_)_ATKH|);%~fI(E4G0G|BG^z!G6dyn!M=uIUw zz&A$7V{Gohaj^(Hf@c;NLD86Tk?_ozp#HT)p|VMe3~%BVB!HeHwW2gOX9~h!!s*njE9g7XNu$E z^W1!7XS>9w8=5wrFnn>5p`<$StQ=(Lx5THrT_|MAI5}G9WaMP-!6Zj_%STu;dQQtm zFid!Q4i1t6XW5M0d&qpRFULN8Gxu2%rFhj*zOsfX7nyr4xzU|AuAUq{kfWlyIt_Am z9PQ%aGGsvSw)h!1+{3A@JlEC5X@ukOLGEq&nBMSS;aY-gBu_yf@b9mDFb}Pkk$#i0 z4Axhl=fmTb;s9q8UU@7XeWrLBnJ{4lPFz-!Bw!%8eR07wh9Dmphs#w#7!eTS8^Ke=6i<=o zO7gF9W#bYXN;e)0nLU;j9J30OWXj6}AUy*938dhk1D${`fYbzQfkD7mz?r~0;6mVA z;7Z^-;9Etg{sU4c`2eJK-;Y2o;3wcX;Adb65c5?LmETt&!epKSZ0eOWwmq0#G+HGs zHN_8Wm~!^U>JwJJgs4peJ-*mU9#P)-)2G^yl(#j*vXfgR`6PEkb6eD<6)KS9D+Z{*24*4Gbr z7s?N08ZyWaQ?vEcMd8*@S1HPs;<^E(`7>62m~<@z-QypW^A%~j4&5i@yDFtR4j0pKu$QIJq=V)7Gfj)e=u#i9dv}-CVJY}xL+PbDY=-M3$Hb~K z(>JlEEV2MkAJ_wE02~Tz45a$RN(i$pZwOoudo$p6pb>B%5c?^j<#_OGLGD0f;3l96 zkWSle37m}hp;1{B2gGWcC=tj9rU2UlQ-P+yYd|yLLts1LGhlllm2(FmwS9Vm?OLxs zB2WnJ!4C#rs9zs`Awf**`ae_|)SoJGi4CQd>Y_QW>m0K?@m1Ns4b0Ve~os>qCo zI6_lY40~VT1zHpDcX)Q9SqzD z#ODg4eBcn^X&_Fb5tRa6fMvkpz!pe1PBRd72D$=mfNnr4^N~P`cPTF0dUX>C9<}li zToAOiYX|VMG;eZa zyf;(BBAP<}Xa?z{K6>jTE~Hk08P}GAX6qKgus7CBSr&U^%?8T=;c++C`q`#Cv;&+k zqgFAAnTqKSm6aJ-Y}nCQe;`h!L?|*KK+jrzDl6H3I}K$*`JM?J3`Fi|VV;)^ z3<9PAslCksE(Fd6t^s0oo_QH^K5#4Ssla^TV&Hk;3gBHJ*6c-p0yBV$h<_Cj<1=p! z5aTNkpX7;1Q~i3N6)+3fABa*BjR$T3h5$DM3$Q}9gRv&pK2GYQ;9mZ;e1fRMmII8$KMI)%~E5s_SAV(~!i<+4$6F;Q4dB8EhepE_JVxR3>& zp2C6^_X?9N_P)DdF=lhWqvP;!nC zmX11=r@WpRViH=$@XL$asr34stl0NYt#kVh*t=jsOy6Vp z=F{wKJ9>>}7O-OY!$PoiYHj5;B*H%|E&c?QzrIlBle{`&uKNc2%-tjRQ z@*;vPga7h#NKCZ9S7I2pVwv7#>HqJiMK%flnOw0ua^5k>7LVE!ZV7l$aM8bp)^ZXw z%^@{;XE{oP*8^qB@^GhPC=D7*IbN`YhgV{l-4#t9y^5*@{~El_65e(R?+YkxHgqMH z(%|*wC{3P>r2e4kMSzQ5rlwWihV_M``eaLFqDb^o9sg8qD%L%TsP7=6wLA$H;x* zC=K2s49qNVDMxAWR^T3r;TQSK2Z_>ZyhKa%`|!09HqfCQWx_~I7)*@ zYT&6iY4T=plm^cUNo08fj?&by8SQhjyvli{jM>Ly3^ z*y3NaX=T9rZu9TxY|g)%(5mJ}<^1xit2(m2Q?p?MlxK5ftI5tg}kz|C_7 zcN{(z?)W3@R<}5>`-3iP-@H4%-<98YSe3W$&8rwG8d-L>sc-4Ayt@5uOi%6`vwG#> z%eq^RCa@802;M&|X73qN^f^XIyo z*CyA54E$0a(cO7|(9Y6)pW87O%1)13D%p6uX#93=hW5R_QyRJb=BU^~PfzpcT)x)1 zc6q^L_sxmqt6vX1l=aZ}lFrA9Ntx%$JGRX%-MxQ%*_mej_KlyVz2CBr*O7xe!wwhm zlk=Y+*mrD=)`J5|Yp(8z?KSwupS$9({%Y9%j&gF-yD)$FnUt8drcw6tn(0f6V_YZyiSbKEwz@rD7-B`Tar+U-Pn@P*BY&cnb%Wl-``>wBo z3a$i=E!=ufCC`4C?Ows{&f2$Jj5T(>8>(dMlc?-?qSojB==(w2YZpgYCmaoNUbN4* zq(yRIVfNL?cD4_KN3D$4x}Y>zv*1uu#kO7BHyVAk&*4+%nn(67^W5KAdGbE5ZQsj^ ztuL46rLHgU(lWPV!tUaLwe4T~KU=qHa-7EUaK#)I^>y~PI#1^WsYW**%WE`y=&_Ye z67wJAcHT4H&iH`V+QnCwX&=4u=wR*L8Ex+0(Y${3+S~yTuD|-Q?_O|3^6l0an;xAt zq5YwERq?wc;|Cu!dhDq-KWeh>_w#*J0=+a9^uMncE(yu?`*7`hsPCZ5VNIt!(8zvq zRlCe1S$Rb9KBZp1?SroiI%sI8b zpkn6by@PAM=UJJ&K5}GX@!|7U%lEl&-L&7Vk!|VW>|}l+G&1CC z)YRNi>t3~sfY|GHNl#$k0op-@YU|lvS)$dcpdH1S#kBJ3` z4a2fG-Ly}eze*<~-7T}MLOFbec9d zHPpQwWoNe5(X`*T(67SBo{wj=Q!g1CU{^X~Q*OG#gRF%{Z7yuH@%dWVX;+om&KITj z`z?|UvcmSN&;8v@aPCh-_tK8eNuPt`g%92(*mpfBFtd#{R&Uv(lY#QYrS>C>YOjymxnLXDUKaz;Q2<;)bY>bQDMhLj`6n!m)WjTd2F%xR32|j zN{Vq|i-nF;CKPxEXI94#EH4l9Y~^ZU=$&M%wa&u0!#xvTe*<3TA$RNK?4^FWsaM?d zmNh+9cW-Q6?a39}ifeCVl)tMfRL$LzxCxo8gA&9ybX*}_RWhdvV zD%*;{Y}HdU{XMEZ+6vzcfAnUr;^yKUVnp#<=HCF-Xu-hSu7kJkuC`9n(ZD}ZEMgwM^)W) zvWJ;kXQ93R!-Q=aTLgtm0*%u*cj&b6NM&Kk>kVn8PyH&s7Ma#QEnTd(k2)*f-L9_sw75iN?~F9%IZa&~<&SKvv!u@z-J5e(X;;;b z)(ZI8Lfw7&Ej0~`^&0&Kduc{(YHu?5+{2cw;y1SL*wUxf4$ZE{Yki-$D8B!@(c8R` z=4W5`F!-MNzVX)fd-T&?V)UAL_BAxM`qm_IaemX`4-=bJIuExi>$0TR;$`Rh9QvTy zyYCApd(D)&{YUjK>ML|p>^H92B-_Ye*7dYKal3~?j#2lNV`HuN-B@Y$XXv$V_Z0MP zmOctK+qNX9-8bvn4(BFVw09ZqXF9z@cH6eAAM*|0n6)wAKdn>iio>0qeZF*@qS4>H z&SZ+kiK+X#tU3GEa_7dLU5nDzM7@79Zc6U>Rxzt>?naxmTOQxpb>!6OSIuGvt-TR9 z?e2mk*8{_5HdWL9rH$X^8JlB83Cmjzn07u}Iq~cH)6;ib7KY7pN(!&|WEWYp^ixFG z+`P~U&*CR5jY<@Q)(_0f&{^2Bw8n2JuVE z1kE-W4jIwfeON+V`p_@_6|N=fCL@*|^mN&BFLQY2nv>4EUaAa!H^O1iakJS@PTej# z#*EW-==6BVfR>9=2f78n@(5D28Qs4yZmjyvgJTvIeQ+=Mt@o%0O=h^=NIE*Qy4M5G z`|kV+bDsx}-!pIXxbEpsCn|mJ=;b*ma#DELo!%nj9#sdYysvz5dC!CLEir$1?d$tE zwEWwXZbA8v8fhm!v>V#KR+s=|1mDt>w}<%_hx2t@$2^eQeNthb$+$NQN3s5(arU+2E35U3w(lBVl67hcYU&=d)T5$RoaU~QZFxg_N!>&o%aJ$XAe&{``P7$;WiY z&3?SQmFUXtyR$qlEKl*@I&w~Lqh|B8qi@X3E`5-*>M(!%CFQ{1K1OW*ea5t>xx)-P z?lRaBxwGBrojZ(Xz1r6Gsm<1@qvJL^+8^9y0J9oWZskJ zD*KOab2zZz;_QQ3cP{SjvqyKIpYD)7qlKxvgWHxBcnb^RI*QUhK*<7`w`ENw=33J@0ylwmW23_G_*A{!QMjt*e&zvsDjXj-NAc)uVn_=FJuEuk3x#({;&Zdvlxkxq1)({3CwcDD7L% z9fFUI{IKCe=a(n5RtY*;we@rzyZ*tu$RRVAtGzw*%QlA_Mnzx3N0esu=zP#L?UYeQ zR`$$J9hwjRdUyukQE}OlI=%PRg6;jrHCa2(e!J;`r7f+mz2C54^5v;bbhn@1QKdTb zXo}AXm8((NlMXgBc|1Npr>^gPLzg*Eimz0Pl0tO4mP`*7#Glxxt6g#?cu!2nGs?a$ z+4<#fGb5dre!uo5$u01OanIXhhIcrmWA4!C!0FoEn>WqZGHJ2<&a9bbLA}zaUF}@g zI%2uf`}TbTm##^kZ{Icj`MBjBJ$#(@TdRK1y1#vRtHYOHZGCos*|!Dxmd-)V)_N#L zb$C`FcsZq_tIIhn(Z@TZpA7O}mu(;V@l5iyX2G_{qjeW1l=PhVFxRch%i+7nh<2IP z?_%bs<~FVE+4O_MY~^1&^e;4PUDL*K+UV80$|_UO@Ak6kb71`QNmm|?-ksz&_(t<* z-^1GU@l$u6cl$|Ax3jYsFOIst{<-;{k0Y0Qk9jz|xAnN*$?8kCJ&v$xt#*8_cKFub zd7G;ojvSx+rBT<8Lz)d8@pjjnscpMu=&xTm?P%xBmgTGX!_L)Bv&7z!?Lx=k$mAzej#qY_}0~Ow*7ONNctjS9(cjg5bwka(A z)B67WC1d=pd_Uf7tGs^lnj>3}sNOoRaLhJh|4w&xHN!O{qFa9Ncxj9N-025ntIp_N zEZ1AM{pgNP&ic*mOs8%U#RZ~sAp4OcHxNp&hL7IL#FPp1|xNJB& za&6x`wjEM>tX`Jk_RZ3A^&yY;Un;8C8%&wFD86Y`_e++xIlm8Cs6Xhjy%K*`a>3N} z%0C*v^P2E=e9e%|{-a;DQJEd)gy*3md>UBCvLG&$W-J{ipW}3Fywh<#u7H?}B zIJbDp?fzXVBD)MZbZy1US<31wALs9xK16#{E6Y8`g8o+rT8xkQeB#}mnyu+UBU|U} zzL0oHD|UtNp}j8Mop_#SIg(CA8_fMv}eYVC;1ktOOLfoZ+TEJVDfJM>oE-;l`jT(S4O3UKyr*eehN7IbXMEu*NO*X#SsH4$Yt8cdzAr!`l`^7G0b1 z=JRzI;qbk_<9g?fytJv17kjcPd`=0iUb8d~M^zESN_}fuUJ-u^U{JCR;^V;zv=j=NacwPOH z@58J~6(4mvmY>VqU7FeUOxgDR+NP_m6kZ31s1$#D?>Ba$NElSoJj`}VM5xM>Z`X~dF1XgYQtx)6XVAT& z7d{@kAG!Ew?Z;*Zj}G+Nz4*q>o13aPTv?uEcdPiM>;2cGt`r2l+FCd^$UaZyo?x%- zuv^-lZ|~ADcCl3&`p!`~(dWKT?TPI{_eWbtEUtA9Ihs)7yKhlpU~-Fgkyo=v1wXL8 zpcTKeKy$ECTg9e_MmK8T_0-`$NB17lH1E9MbD7t^$;!oL-?!zJUbgO1zCLwAMQ+Qr z0mZwY`M+)-H+j=K#qi}C>(o_pp6b}zN2>3@7!-Q_uAF#udY8B5PWanht{`~BW4|Kdhy+%_7fs^$5$C092`Gi z&GYeh-N{jbDt*rDD`sQLz5h;Jue;TIGGOIdbH+ z$@#;@3*GlEw=&zmY3t!q+eR15RF->GjO}Pz9&~J9V4~$o-=X;vgN+qCMRs1XU-M|s z6IzQmcs9CkY@t|7OW?fb#@3GAZ2e|;ws1cY5OzxWm-xCtV?4Lbb#=@*bGCe;+Lhvh zA)jii7yeOKUa}+4RVyzyY54kNi^cOYO)d{DHW=w%ZmKt}F6x?Zt>ZGw+_KR<^By-b z$;>Njl$??=+cisb9$oc-se#sQ|dy6Rt25jyx(YDd|-h|dfZag?C#C73P0?R-n}qL^s|80LPZ|F*uA)=lmkF+oYW$L%id`+{-SIFvy~1#zLYhv2!&cMk(zts3D_w$DfCVFhj4l|seW`8q1LuXY* zS*F{W3px7FsyAAkv|pK5Xu{)`4jy?G<6Tp-n(7#g(={}0Ze|yCyPv7!TH)8w zZ8NX{Ft$X!-H1}V0EP72O-2i|9@uQV(56%2SD&3`RlD}vm%hj{NVb@(zBlZg!0h)@ zcf&tFCpmX~AdC<0YM=1V)=Y4)rMhvfvO%XF!`usBj}oNqOAuB>`6Sg^KY9G-+qbX9 z$8MCS&$v*M-7k5e?WZ;Ass(!rJ*I8nChXNGIdfRs%p48%yie!!a!clW*G_bGt_#x% zFSoxKTdcF_jijwUw4_l6MDVi*@~ZCif0y@(i+*t=&^|{gy7vbH8%0?o`v0wRK}_i?^+K zSDtYrSGBO_ph?>Hb=DQ3bFct#J~ZL^wJ5=k4-<_etDHMo23FWs%{--=jmLlg;ctX( z75Bb*WSmpH*(xPHsAE=k`-i7;^S@SPeZ2YRLhsAfU#E+5LJL>#_58XwOTGW^DRwiv zn3(PEp=$W5RVU|es@Cx_f~czfBSTByCORkE`cK>&U-GGJ#MP?Dx*xFsP+69ewkyM6 z=z%m-&0n*l&ZZPNE>JR^=-k3COx4=Z{-n8%&YU3E%mGOrIZC4wJ{7t6mCTxDcdB)! zY2BoKI@^Bz%`oHcBM+YO7guY~GC#l7mlE7>4XJW%=JqLR%=9vgm3|jYu3MxnY}`Gg zU{vdZ>U5Rt^3q93Z=MYn7Viubq({WLXLs#wU|Vgfu9~A}<}q2{Uf4NfTf)O7g@P@c z(~Sd4tqhn>6`mW!f}Zj-? zw4Ky!T+emCME1CS!nV6nj)L{rV<}cEZ|v)KE%Z+teT92wp^uif%UQCmL#_3<_7)S) znfeWPX`9_)I{)$Nwr$Mb7?KBm?9+~~VDtK*lqGnqQlwR3Eh2$k7LDrtTY=k*CJ#m)O}gRvpjY(-zWe?0fzRiT+dOa2#HZ=q zy*hqYniM(6(|c#v@TwlhqRRJE4nEj(`NbbGTgo5z-RJe>TY2cC{Ge_R6SW)FwjXNu z;vrx6*~ax_p8M4KR(E~yu;%&vYfpc-UHE5+*O9M{^Iv|sa`nu&RblJDk5M)vr@`T=BM~^QQM{D?hz+{eH20+C-mQ zhkK5_{bhm9o&JCHs+jV&@czE6)O&B+T)o?K*rT#gty?#90&B0=-a2r@V(+X{zs<^5 zvMlrRpVQQTb-_tB_Tt>|ftQP}wYa2s$Rd4LhQreEFY(Jd53pQbW8OStYyWkt z0z7_S+4j%ZD=I~&vI@_9Sf8}>@;bZ58NYr?*pQhQX|_7PQRB7N1w+@ox$;Zef*w|j zhIy+l)~=eg5ehXB-^!w(BkGW5$&Dhn^VA#&c9R@pgo^H48)hwf} zHcz{5jvGC7%Rzg`><=AJZsGsjg?$4?J=NASE ze^Wo3YLK_<#S*_&V|!M-?A9*S`|hu0c85;wH?RFg&2?eqk;;HFEC39>c`X0+`@qsGPm;qd&H_J@(jf?sz2utBgY>!fE} zt4dSL2;2kUb3 z$GaHb?|Y^A$()cRQRVcKt~w{;1)(L{x*KEm1fTI$KGU&0KikDAGV|@1Yu}f?2y{yt zbGxUp&Y=#&4>WQx-@Lo_w29XIO|$OoZqX~KY-Z=H)6$nmw65#Z{=HK2nx%p1UG3+0 zTt4pkekUIftq-c!t%h&EzxCDS!{3(Of97nNzrbT{v!G`kq7?^>TAQsNJc^5dS_565`-9%tQq+Y;0{D?!<=0;!U9&a|JW7l18 zM-1)OcIumj>-94-J0G3KUsc|6THU!}MS@(*t6vq0COZahd7m-K#I;kego#-hs~(xY zdObX}d84;wNj^{ft}OPhIPkPseetNoyqccDJm>OKEC9^EZ~dp0|Cl9hZ+`S$GkLwT zDi#2aDICAGbAN=bp_;mT%jgknwp{A?{owSu`nqSTVwdTaU+lEw=ytp2`p%*)Q%!H3 z4vh0jRM3mQocry3%(=B=H@|9IYm_ng>&{*|gY+j|m^%E0%B5Ee{O>xoPYd|qSpBhU z!br#Et-8Cn-*fxvnw!V=eLP*GIcUS8<}Y>pHn@bS_FX&jXi5j$I~mJX_pr45=GNZh z(CYQo6<-!joMOq>Cg+qQ#NcIGs9-9 zw7K5j*XeZXrQecz=3Krx)6p*CMEi*|rY_ib^8AaN<6GX0tlF?g<4u!R4~K0}nANx> zr0n;2oxO*OH+U%|o$j?R=bOmPaP=eGY+KF6CL<%}1~%Q+|MryPE|C>oR$MzYL|u8- z%RTvzS8mcCGTnHOWvhW#`wKotjJK${^X|mRp!BU5cIUK?)w+}zc*u7}MI)70%u7%h z1L!>`GL^VQxWvW*gh*`pUqHONA!m&EtQHLgo;fIMxGC^5LD?{rR2Lu4Wm6jqg>%r@ zCa1&@%BLIzP)#UckKpWs7d>o>l0PWK4usNJK3*+>&S?-hL9bxsrN* zRu%LZ&;g9ZIR2+vs`7lBVhV|rTnRWmYJ&fU_22TU-zKP;CReMWt+>_9VNdXNubYg`X4EL6n8&9bw7H?h|?L1o@7P6#{t!7M;4}AA((nf zPoejejKf$#8eW~kE4L?DM!nzvbbLRKA5fw9Oa@5zB7cFh8PwFhF9o7Vta!10 z)KAR?$(2e13?3doFMV_B^i9m9eLnRZtdbtjs(v&VpTU4Yt(cOxdb)~@0rjj#QSxPRS~MWF$!um!I>dT7r@(367bsm3q@HK8pf~FQNvB@5QBD_&Vbn7O zk0&E$#0ZF!`rouOE&RXb{@*skO%(pyS847e9zgzoKF-h$Ai0{4vD~Vr(I-Y3y_K@= zZ2HdU|K*{d&6YBgt&ZFQIBImqGG}k6J5|$IBpy6Y|L#Nh}1`m+bgWZ{Pf_0t5^ zpFK4CyR!$CAEyNk%^p;L6qBDl{5S1?Z}#xtaz}3vPmcfF-v81}|G#bK|JgS4&t?z* zk9LKIXAg4ST4pXGc^LnX+*jFY#18R|94MI!Xqm}Q1?U-@W(Dj_K>WnbOay+IcyQ|) zv~(glf2ID?11&@H&nTPG(=-xc&Wp80IhZF`Dqz7upT;u2?6WkvU8%<1-<)w0*EIj> z2_*R^2@uF7p#It^vkpqjq?CfE8WbUOiZmao;q!lKPbW}d!3QUXq&AtwAiKKbk95=Y z#bJT+!l&mDwUv0%#mu)TPIkR$)-w@SU}?q02Qi43j24;EN2!8T=0+#5IVo6>VipAs z&h^Ts1>2cgIH!t!Gk{D?!o+O-QpDNs5JVBax9axZt+z8SZF>E%IKgb|alsvY2jBt=0lM6`@$OJJssVg5~ zXT-To#VI}=|6?q2VH!)qlu5@w308NGJ0{x*hCY@~WlNS>HLFxr=>cwU+ z^$Z=^76o4dn+q&!)=3ep-Y4iYdHVEGnKu=`^l_syZv%eS7>afjS&Ba9WT`n4>WYMF ziIsBJHAF(?Nhl*FvFkoi^dX}%?}mhDiaKX`8KBruTA{hHl)Z$Cl2EH8)NKj%SweNe zrwsKqa;*}gxV~jN+gsH#91F*C6teZnkS*oOQ@$3iazy( z1!XW$Ld}&>+a%O23H4n<4Zt^^tY135f~8hSr~(PqocknHnb%uFg-WPp5~@r>mEa3p zHastFG4+dt%9T(zBorNe!TRVWp(abHbP07`LcNtx?a|~|zr!WeQVF$3LOqaB>S&s* z4;Kj)E}_;-s8bS34PW50J~~P$PYE?kLY&CNLk0}G=|s`-M~YF{iWA$(oenV&BONYapurx3 zFiJD3c|Rqdp@J1p2Y$%Vu;Kzl1dM_sR?QW;kfGd&4H}!o$nr^rjo6S16|spF6Trzb z^eMzBHl(sa3Hf7{Hz+YB-^|3QdBes4Pqw9+d^DMq^d`vlJipb_~x9za|W2 zE}^=B>cH@<@Qa2Czf{UBWe2Jw!|RJ*iVL*oF4%ISYwZG5ZJ$b=&??I{IV#6V4ZA6A*Mq0!&ZNZ^lFO`A9 zCuYQz%0Sf;!;#7e!7-ByX9hTYxp30Kp%F(K&K7W}y-LG52o8-qQkk=yFR4rwI08AD zkKoX_C6#H6IUALwG#paX!Q->JWZT#vaMa{DlfcoF<4gl*sT^koI1W77xPAx62OKso ziS|!$=yvckWzWaqiwq<4msLcQf^#xdi)=2Qa~$I0zy}#+mY8fIc4`~)=C3G?{*F+k z>UEgDF3~qAudPqc4Lb5zJEvccwUBbNA5>|{FgOKKav?!cGbv0S7%cP;b&tjQA7gx@ zV_4o#lqh?94|W&$M$q{Uj4z(IcZ|?KE;=MO!P}pLK?Wj2L!iBu)A!26C)NhbS!A6g z8Rk^M%B4>dihOBsqV<>!g^HqTC|qL8iE||>CoAU32~sJ`NihsgM5eS^O=jYR*4J<* zj$FnAS3N)aXt3VQpq_PvZ@3U|Bghq)x5UA^0SDBslQ71=0T*ZJGZH${$p_-3$p7TFX{57 zNyhm9m@Z$an!y8Tf*B{Pu6>IZcKQu+r0UjZND>RK6_Qrx^%5{$oD7F&WK< z#|8|S(cN&Wm(hH%SapZ887%_$hm4*jQCzYaH9!HBf)~s1!|?uV7-nJm`YR+nsGwuY zj*8-|1LHduD$J$&BPmg0LwO`a4_TWTig^qa(HxbJvT*>m0S*JU2U6L000sihfg)fh z-~wQ0;4)wr;98(1un34pIngzsHLwQQ4fqC#I7DB8-GQW+&K5|EZgxQE?4%>4M9{@a z=d&?&6v_A*tPhYF#LZ0RkQUyFAM1$K_WzId1XGjJgZKI+-Jt$pijRzJn;MSv(S#E1 zNkr*z{ae9dn1i(1=)JbcAmh)bIO3fuKIvR5yvRQ{8ySV8oVHKS%9_lHu}!S_&%W@7K}=K@jm+`t5=X&-1w`#D&co!WF? z)Z}?_lm>6NgtuS9bHeIApN`M|E61eM8abrO4y(>{Y$efXkeJ=NhtLJY)%jo@i}NhVy(To$NFL*Y`w`4Tj^{y*zv zHo_2Z-N?L&%WU4Dru2?iYoXTkl<070;PDzA<`oza&C{IJw7pLZMF7-_lzGZ%S?w4K znxh%*j5y;Klp4bu4~k|!%A~WDqYi^=#qf@S(qSkC3q@Y@QHD_pHdusHXu>l@p(`{} z;5A|jpM4O8AY;TMGg-u=4$(CHvCDrfMJb@AE}X20Uv?=?PeL^T#V!sSfohD4UH)S! zKJ0B69y<(yg0kFGyyZjzaU99WU@=De_=1};eEHxPMa`Sp zw_`qlGjlj(WEgrieyMFsIk~X8$#G7>Ms>!f5Co&ymui}gojBFFsEu>2{M)a>s$OXE6QUl_SZ*g7{HKyo@5Y zOJbF*VPJ8CbL>Vu$?}CPvw@Whv9n~+Ldp=YSydqhV&#q@=R_0J!HOfa+IZ? ztvslsJoIsqk;pZ$@?gx#u##MU>#aNp;5e_I+`qH(kdE-&|5Gau++n!?{+a{(6tDwn zv#9qp{s}`rqw+T&4|KGYc(t^30!}k@VM2?#V(v z+9AYjU{Bx%E?=3Td)Dg{^wdqVBzN?u`NB@Y|8UM;BYr9xv7vMs;Znk7#xb{X`P$Cq zD~HS1Ww_TrWrgMylrP$JEc|J{*fTivxbW)%Iz3ewAM770jC#EcldUjHKRrEhXK(z_ z)2*2SLk$vWsgQ~mhBLzfnlcxdWH?|>CJ})zHk2PK4{cm%?~Iwpl}8$oTF_#k6L1O8 z4Y(BO55zbvLffZPSVSl@-g4j(;0oXsAjSkyH4yDy^c{#5Wf7Gd+6&VkD7F8_Q5XNt z!4`k>df!kwPNk0)D{BQJUi4WDdbfjs~Fr%C(=PPP!= z3;(Y_+d_WDtqA?>EQ*j?xF)mqMijf^#`1hn!Yof29b27|Q{yNN9-Uy#^5#o;cR|sd zUXxeJQ3wwmhUNKi6jty+(YzijcpRm{3u`3i(QA<8ic=x5u*ELQu`l2zKdb-JG1hUI z@12iV>$Uri?yvx#Fkyv`r9sf!&PFwbb!SJqk(_LDe|ownWMs%z1GdOpG;M!J#DR z=_b!X3J{_dLRKSWznX@l8ZXwGUV%okc(SQtcrxEv%cSM$fuAJV<|A~Rci5q zA5xfwr$KnNqIY3*XSYEmQBo|(iga0Fp->s8NiplHKQAtLkx7fVXccG)^oOEtSXS|G z$SVB}S>?YW+vsn|s{9RE)xRN&58wWBnW_H`S&hFTtNAx%wf=^z_TP}z`5Usje?gY* zI>|-&SONVCZBUu%ZOZ6v$~@gUEun=1Jq68J+Erlrq4U&S`NDqC%F|65i@w74v>X(0xjaP;#Hr`d98#f2EtH z;u9t5T~zkdpL*ZlBtPT-d-_`b$HQxAdcqWemF!5PMnjLxbVW^fm$DhkTbU76mK9Zo zs5v8wnMhiS!b|BKM?B@BQRjG#9zJ=7TUv@5-Tgb$B*Vo_nVGvF;8_h!UK-?KfPC;> zft?8{TM$XVf&1sp@^oOlDI#`n?Z_2!62_<>YUi|*OEE=$H z+0zn=*wEvo*vQi2e4W=+%xf z>yFq4cFK0G%Br;8Rq$T-t$2${jQ@LERkXNEWh^y6ZdK93F7BwjjnjwY8JLWCjgM&Q z789NnnCB5GhicUgF-SSIV3^HuaKnb7r4rVNH>L)O89d@()2W*^#~~lmH@4~7N1nsR z)$pbhp9`aQu-g=l1h{h~r5)QWQPSNRJmX+n!wSFDk_^809RT2rKZlGALt_z*c@$&A zA=W}%QhS%mT<17andjh`Nn~UKMGhfD>FGfagBZy-8XB$EEu&JaVVB(eip~XzD#Yk56>e;a(R*zHfJy7=jVfWy; z*nr6R2+0ej;)cj=`$(+ZmQ1}c#d|kDup1Vq7kZfnVOGxrIW+9W`zJo?&Uo0vF(HX19hX8PXV zQ~kYtV{xRcUtBEC&~5@=urMr27%j`ifUNHu8%6`OeoSlt^70B7eGbyS-s*TP#yJ{L zBY^K{Ok)kjN$;t;Gbv}5#-qe;@`yELBdj5dz@>NXTot0Gy2iy0hzkrvikrh_K3rm1 z7k@vgQ!_X%mGLwrg7ZTTSeNBq-t_mAIJAVrI5?Q%a#a`+7w#vFb`2a68R02J!7*{! z!HLhtC5_4oGZA)?`v)i51aARHa~Xf)_{45hI%1D5zA>>}gqRw!uilE?#QvB7ec(wx zoophhs2pShWIegXMl*#-_o(*s!a3GL&@7#gjK!2bQPzVeJ zk}_A6kw^rb44eZD2d)7|0Cxc~HxU&AF`*Eh1I7Sv0^@b@z3RF?XncqM|AnI7u0=N^{6Sy1b0^AE63Csif0uKU1fd#w!rH^J75`b zIPezG6?hxy0jvPhxO5*#CJx! ziHmE5kU3tRBC!IueppOEG!BXb8WVnGq58wdcL!b-r5fJ^5_XIcz_!KAvJ_CjUYk_lsFM*jr)Td|<@HOxx@C}g0 znmQn4cyEE~i1Qtg#+;A9_P|d-+Qs?`v;*=Kcp?E%3Fr${0Y(7TfYX5pLzD%??!G7w zs0lm=)B=_Ob%EtTJ>XZMK2Q(&HUydhn*zH7n*nh_+c^A7%)wbSY#Se{LJH9)_jFaI1c*Z@(1@M2|@w?0L501XKHuOTk zzW3u6bZC-3p(Vy?CSMKj1kR?&|IWMU>>S36o67h{Mg0%$BmR5G)BlegbRQX=fMf1a zSpQzy#M`Ff!f^kn1n(GxDZjh;svQ`p7Y%?W^ENe68oX?@Hm$&acV%RpThy4a7!U1Mlfa(V`$G3bHTJi(sXf$#H*z(sGcC%ovu^Spin6u%^Wq z__Hsalhaa?k~l#j5!B5P3vyOuVZ6e^yniotagcRkUcVQ+xY7QD8>7*v50>wu8`bQ> zEd}AwXmR`lbR|Lu(R}Oy&};kOizpfji*>~k;y-X@c8u!#WdhPYu!sp^K15`~B@5I( zS1SqdS%8~vGHu`z&yC9*M>$A85@0+)*dfM)1Rby~Ij1NN+b;NufJ?2`T~G~AOisrMEEpG*@;EL)u^qKWiD@LZ zyFH!F#7_39fvj+Hk)k;68Z=pkc^U&XlQc=(NH?4si2M6lDrhcZPMnREwV;_Gy9&{X zY=9`2aRPjdpdgMjj*D}g03qofu4Z;j>Nf!T4h2y(5IwaeY0GBv3qcoTTGHIzD9b)` zD9ghnx#CLuJ@UoyPV;6;+^D&d#YbQG!isu2Z(_6EavvC$;Vv_Es%)(s{~tbWyE?#pJs zepCL-)%n!nX)j489AX;PIN{?OVlcxBQ`(A8Z5c-W3VhnArWq$}$BZ~!dNCT(n7Kd! z%lT3AAJhD7{6&7h9BKkjl8=~N&>)~}Z5jm}C2eVZN{J8EtvOLqMA173G*_eooYv?U zRhy!kt6Ys*u@%5nhLw1Lfj@`il|~4-FKs#?guWEkKai#OGybZq+FzEfFBqK4!}!*B zDrEo@FQ#IHNeG`YA$@!r{j7A8Y3~0I)7wr22`J2)NEuD8oXKdgvxB8C0U;eJzr)b4o3uVZe$C-kcc$iAy#sX*F0q9Rw}~j=shDln-4X37yhP)g%tx z=IW0@n@fW>r|2lxow>TH`Tp(ucXo$7`J|ioiLMyV)R04E9x2CQsZJQuS?VKhlPqP8 zyFN=T0;SIQP_V++R9Epe6@68;jJ~D9a|vb)Vk4g8lbziZLU0^KVHx0JznaozC_VhL z6gA$a3=cmNqXmjOxzuQb{P`Bo7r6e_X{cXFgqM44WOTSoh@aOq+wNXYLch46(e4r^ z_6q!XuV0_7%PAxC@zrQi=)bzMBr$u+_mM@QSOkZr?ePRL6RJ^q# z##vwaR@AO zYDC=0h6;p?2-7(#U8(tTi-%TlRUpv(S&t2@96NCo`=N~(aAJh?n8_INW)0OK8R-^J zJJ>|1bty-{NYIbi7d^ePhB)+HQ7_JpriPS=)%3985a-9Qh^Tdtsj2FP2R^Y0;0Q`r zLmN6q;8RW?RX(RXDreF-q{d1qVAdzN_ATaAf=exqm60srgG1r{Y)ggS^d`f|{N;@p zKIaS7Lb;Gxr>2_xS2tp85vslXYO908c*k*WgP2QTC2;WM+1FprAQ6F_h}>r^KiQf2 zr}1!GEB{=M+iCd==@JL|H*+AV%Af4Ubnn)SFJmOTF;+56kmB7K>mJtK?HDK8jnQGg z!+BuCd{;mX0ks(|^pBk?WGwix!X-O0GW-U7>h35-H`Q3{+Qi~df(v)FjzKe zhSl26tXx|Fvl~-S&IDoY?t-tnvBXM-njBxx%|~_wA$}MZ%RvvCOr}XU zONnoe>k=nJb}|j^?$Bi79puEjx-`Nwa`nQamVVY6KQhKa&&ok|la`#QPnJUNE+_d{yGnJC`BGm_rngd< zVYpOK|FVXuw|cuuQ4ol(Cr6LsXiERmu2MR}`;UE36cQd478xMjR^s{mYuidl(<@v( zQK3 zFzk3}loB$05~uQx!m#YB5FZ&G%CPCHBw8%vmS%mSz=-*zKm=YKBO03!CB!_1-D&#& zxO*4)x~eLV|K!mmy-Aw{3KRsn&;SKWO<&MLft%*hgywNc(g#lUCT&w1Xq%V^6hyhu z3e*4=MP&xWiZ~)V+5zREjFSQ?Adb9L93Rse9i`UsfvC)g^8fzUKIhzXZ*E%ZVNld8t-iJs&2utQ`f8X|7RKp&Zxd`VI9+-wWT)^hhcFOLD8leKJ3dwREj4bTg-` zz%#h-0h_^IkT)0J8t`I}Hx%jjfa|~;LEcoPHR@Rp{yo?aJ_l|De+F&>nH}}s1v0zo z4S{b3F9GA=W#B2`d%$I28q}1*)u3hpw}Q8T+rYa(-hia<2Co72ruqHg6X5mWKJW%` zN+EkOz)J7~U^Vzb@Gann!85^+g2e6pEvSAgZ&cDRg13UNfVY7K$mwHX3Ahui0Y3pQ z0q+1?!B2wHzdJ$cDQ_ou1JzUwgx56E^;Yhtf?u2wlAAV;4sYPK;z1NudeXx~Q9Y41 z9tSPXkE3OJFX`jhv$>{u(hR2qre)$3mwqAV9CT_?^?8tVN!3F=kunFD(k(ray_8MT zh0#kZFYf?P1ohS`3HE}Uz%}4C;98J3K(_bnKJY^BcZ1Ze^bf#(Q2KEZNaxk|o=JXp z^Q+B~UoYu63A)y?e<>qBUJwlOF1LT=VCNM{f(f3FN>DWEw_jb>C=|&`c|jh?3X-Zg zCy)9fbgToTkj0&OEAasQ!KJiHX4Ck6&L?grk4pa#sHT&OYi}nAFx|%eCEzOXa!|d| zcZ0WsSAh3`SAzcpUIl&|yc+yZa2xm+@O_{LsK`C71$Em&y^VN3I0qa9>%k9z=Yu;y z$?_&pGA}HY9nIF+sdOYIYR%Q&myvl>|K@d_eS@a5J$UE2u&omAAYM^{2d|ytB@%A` zW{NIl-2r(dV0Pji>KjaL?Av_d$Ocbu)FsN}_+cP7^bT)G4Xj^3oFWZr zr~uaUTkO+sL1&~6p9Ixi{0z7Oq~4~{C-1Z1r@_yIUj@GaN@xEO+ymYV{ulT~@K4~E zz(0f72z#UU6);}FoN4YgVgi%SHZd96W~1XNsyHg=|6*vOMuGk7ETP4ENYx4@ggzknYEi>NO*gR+?)24!3S2VI++V_O&EUxS~vlHET8hr3p) zvsu4sut5i4YP)Yb@X1CD>@;suwNI=`)z;3hojZ4d4zr6;Q`Wuc%vho7EZ@d0*fiPc z9fT9L)7h($A|^-nNG3!#-0y{3_I6wQLh;Lx!U69%F z^{ul|^I1Skdm;=~wz!X$x+oBfcR9*HWz;1DyAB-T*HJJsFoONvIMBO};N>Or<-BB+ zhXXI=wHq&&Fy}@4q6e{;CDw&nMd|9&AVOWLqbN~bVVBBQE$pIx2baoTHnoc%eMYzw}LX!9|M&FRtTh5gLi;w@RQ)3;GH1$)cZ8}Ly-P)dLMWJO?**xU-hE&{_yBk*_#j9<@xBaFAH1)C*MJX!*Ma{Gl2&gVBrfk^kg&Z+ z!S8@y17&N!4*n8+7Az%?-vw*H?}4+y=fQJ9RyL$tz<&jofjBoEj2GW1` z{sSBbSzVQW3j785Gm!p%S|7pw4XBr(zXhj&zXvq~{W5qC_}^e7NL@^y2mTrC1^)uB z2VVtcTj>X-uL6s}Ye3qE^o?LSs1;AN6X^#)#ue#@K@OfyKM&Gw*vh3Nz>|tupbgFf z`M^keKFF#sv$3=%=`rqSfFA@;0DlOc1pWn_2^OKYr-HJ5r-65XbHMw+x!?mJtH;v+ z1fBuD3N8dIutAJ#($(N%a5~6Jkn~ItS*JB_tphazZ31P>mV&Zj&ES86ltns@eo_`@ zyIw+v4)dl|f8cl=b~RAht;0Q$Y{SjN;r`{cfV*)E=Xx6Zv@H65sbLr&JSGUEeuDz2 z>kU2c3UdcO57$H8;y+6}!!sSyT6Wz`=e2i=&~u92b9wHi^ERgb{JIh&gY zV98kmqkQ-9LxuCMXjx|Ti7Qt=ZuDzbf9}|8|1k5p`CobKi${Or%y(EHBkzit-@!jy zk-Xu>8~-Z{OM+z}uk{6p&V(Gim~(4a2XjAf!v6VSS<0nh7PD8Se0hf3^InM<-JW;3 zV%`hL)zM^$9Bq)gs`jDW8}VH+?~ftvPa&;}y6E_(`7TbG#C3>0`$gZy>J{pqqc!`k zm{&tRI@I`7^W=(oRb>Hfn(yLt%W^kHEcdqgu9$ZpuA}VPFZ-^T_av?(jrNr9ig~}l z^%kS)+-bRD-uEkl@P6dGV&0ik0@^vgE9RXS(%M7Xx{$UZq}5cpWA@9vnZ7ILorOzp zUCO<4eOJuu#C4|8R`{-%cM-0$jJDZ#kzZWu9gtt&74trV>ujU_o$rcypT~8M(eCkG zF|Tz$tAz5urRII5y@rnKMJNCC=6d^e4@`D%X^pS}!gz+@-j9z>-rhXjf9Cp{G-(iJ zS{TX}9@-T=^o>LXYT%jYHxgCSFRk~vPETox!9o^bEc9R*=`k1OJ~GE#Ap{sVY2G&okv=Ut`@h;N3G?fmi+2;h9@E8JwNoGZ{G8XqBfESIz9CE`OI47eUIUl zcyy!4U`3hDN?LgGFa=n7Uqwu7dcx#o(jN`{)o~Z<{AZPs=)?M)?W?ao{qN= zZ|x(8sXiHg|1WQaG8vY+7-Y#c$^kKw!IE6EibW1>mDd1Jgrv9Pf7lVweEvVI7C8%xL?_ua)vHm+4)&;G~Q6P5Qp zuDX$^{OYzsiLZRO(w-P=K`f9_Iae4ilp+fe|Lt|QJ|#i6%Pv_F1ndkAp2ZI+ZKo2a z)6L|wFDP9BpG8r5A4v$sTHw* zY_R!;ZFSGl$~A87H zh+12Dzsy4r=nq>ID4VnuYFXv|UgiC*HS^Ef{hl*(3CGxj>s{C;Nqrx<&>r50dKVJ~ z#$x?;LdhFLBsr~$s+hdGtQA;ZNQE_ITeQHCn<}NCO3Rg|4{0&eo%B{jqD8}M%cX;A z6vp(*`zD{YyYhX^l1XP1uRf;LN0~D)60bf!W;zLDMNFLk0H;Ej?yu&uh-dmYGbttp zBX&T|;$j@bwz4ZfuZ7~LgY=LN+DV;Pu-Gi&;(cGvq*-YrJBx?xm>uG5B{R166xU*{ zwq(s5BH3P`=gFliXCih<;l7~*2>-Rp)feUQ3bSxX>$eg_k+hYANpfq|eeXH6{(C>p zS}EF9%lxRBpusVZQpqH4@8R$rq@b;Q^At480jq}8I4AZ#Mbj9j|3R((k^T>^-+q0e zj^PZv3g%hyh4gu*;H_4Tq|^(Ql7)nu7=E`oO|+_4(n)$Pex0IlPLMwo#9Vp*wmQY4 z5L%6Vwo*X(?Xo*x*Uf98f8%2EAMdVdRi{E>?7f_}E=aB^WuA-^&va#5k5A96Rg3#Y zVGHQ8QpN)flmm+?nb6S+&jyu~61Tq^99BtV%BrnYZVSAb(;KoXoUa(JM6?fs^fW}% zXzMq3DwSJbD0EfJj1~=JbLD;fBR`3)dkeEF+30Ecf*CO@%TZbw@*qEZHRJxjnkh{e zWhEa&fNtE!8r`#YkKUSPj?F7D$EJ?t)me=JzdtiQkg{b#mO^!$hDpa}A-Pc7Mo*9o z%n(>P%9yZH-IlP&eQOin_pp+NU1+Gh`YV1|QQIJMD0MZfphi7`N+cB2s4KEDUwoy?Dnb**ZE%E>@U!$LBpOrnYFsPwzXy*6}3#o97G=J zy0RexrErhGxHjOwA9Hwj#HA#d11gO?A9^lBHHvTN({+#GA$FO3KE9k(RyJS+4O%_gmcx zVH$EL+7~1pJ!jP=5#;WwEz>2w5o@oU*S=A!ZmK{2v+DOy>sadkbo1B~%~$PKLM#IA z^9H}qnqaGgdBe!_u#1#>IxT~z@JjslsuQG`%ZAO&Sf|De_@uoL zISH$0!Pv(yU>oNz8opS}wUru2;w9zBGmnT9_uhOHjq2C*~xrW>rI8 z%NISOW_^AePWA=aV40=iW7)+L#!hrI_kNkqhhkFPVJcf$Y+eR+@g!bJdQzS2$Pm`z zt9F|oU4?^1=t|~YVd&m&*RJ_t-q%pDI*4Fw@^06#1!1U0vJ^MgN)6Jk{1VY7r{tU_0 z<-7T+hh0C0_SSNRR@q(;H`3mF$^Qghvi|W&rjVh|6i7i`Bj5kH^9y9Te1$^qG%nv+D*t&)f}^%f5`ok{8f*pQJK^uPh&MS-&pLu zh)c7K#oluCOY@h-T6yNX^v+51m&M*ap-X0HvC*cJVacgdZw_@)iT$)KL_P&Zsv&hBX_h{ub?_BJ?zzEenQOndK zn?$ws(M0NzCer7$7!~(^%ddvi=C1BL8u`q`Ppfb4oq@w$T?0eGIW1ZXkqGG7m~e~D zl2D_I81!0y6*RY&ORM-efo4tLh5egtK|xQhSFqMflf}pLWA&fbXASoD52dv3%obv) zf*+UTX=}=~*i1RdicKrDg0&QRm#FEZb+uuTZdC&3kF&PGeFyOt{DMm|60d62^*#|h zl2)v51NqrGC+C4!sq_GdrL)xlOTlB1J7tqT3xp@lsvU0`*bR1oY4CjT^I#|VIM@yT z3S16q1?>t@Wwa8M4O3dm!&Jq*h44DsV&4_>f_+^DyaJDXuw<}+SKWtpRt^^M3cT{3 z^1*_dLT}28C4&UzX;pG?Y2|5fv0^B^v?49Iw2~sYrsHr&2Rc_7_ir^?1^+RA_$qDA zh4Hd=<3%i!bN0@CQA?Ju$cyt|@+|Ud_%EC4jt+D#<$R9OYWc5_iX?g8wGh|oMl0ZD z{I(!1<2%{+9EWADJy8G|?)4fCet)Hp-@`LZ$yy#uuf&N-wN59_v zct8I8=Po?-M_(QM`Ez$ae!<%Nr=9rw2bMp3?1fjX@7`E<<~JTZbkZyTbI+~+vaa@> z4IlXG+_L94jKBM1$HhMR5A(lX__3?6KJKocRqy-NDHkV>EeQ7O1^9n=G~+l5EUnC3 z6Zh?Dug~!?>@K}mvmIPf9?6}rZK1C!r|n<+O|NrBclgjrf#)e00_`le9d3E||7{w$ zqz`^w+P61xM_{m7LmaAmuBv20jzbL=%J*O)#N!M_B~PSbbd+FW@^469hDUGHt7yM7 zl#>*ZT|r#x>A5SQU@0RM9Ve+etxGYNm92{{`CYOxic+;UMT`s4h%!HzFGCXSMWREgDZ9XN#^A0FA zSv;&Y^?IOW(z6xHU>1e7dETxp%9o(Tp=3gS0!l3u7kjv73W}~mPZV3~GUGqzsNq1tR=Fx`LcdP-`b12Mtav? z%y-#_-PY3Jduh2FO;fpRVr%AcE@!xYwr1V}?owJATf?{Xf&)7P3+3+>4R8HjrjdmD z91%)jxgy_^i;{v*$wg@sza$s<1}BAP?)@Z01mq_nO7WQj1L<=Fw^4~kQkhE*QkqMj znA#{ukm4*_W>sKjZC_?JU)E0HaHHk^_Sv4kFdn%My3cmr+%x7GzxLTy+CJMyW*vB+ z?Z!aW0~O7)&o+TMz74(~s(Z<$`GkZ{JUI{Nb9&Lf;cMX;2Ud-2` z6CLLaAm4u6uS5UnNscG@pKm|zIx6lvX42-L?6_o`^X|Yy2KnXPkNXvP9`X5P zw-Qwe$Jd>`Z}(g9d?%ML&wkv0^LYr$E-T-NEfaAIzh&rC)wgHEF2xw`e^l=xxRf6yIL@!ar)zDx@~E}x>fHPUYy^J_ zc7gv1_JThHH-TESemh7zZQuUd3*O7U)~-JdvN|>WYw*9oDa65u+fEexHFyH|wB|Ny z{~g%Kz1FsG2LA|N2L3m=4bEt076Tz z11Etyz!LBiAnW$ip8_X?Do?G2SMRKtuySW`Zo*%q?J@APnQ~v+x0&_X-Mwqv{>%g% zd9KI|PPBlkC^YpdM)~P;kL$29)zwwp9cL7`bxvIBnfP35*V^UQ@yM<*Upb%hGrGA2rkJ$x`LVYT7CL03{WJOzXdhQ z_!y{Yd4Z9>4%`Xe4Bi1sNA3h41nHHh9|b=HejmIW+zWmV{2llY;LG6W!9$5_7gz({ z1I`7%2%ZCe2|N$HAM67k0EfY^fY*T!fwzEP1=(BT{WEwc_%OH&d<1+5{2IvK4LeB{ z{kD@-(KkCu6}_-Mc+PKn%x1=$CZ zWmlGcxWy+5lopk_wDNipxPDIBl|ITVEx&zW6ZlK8AN((H5F~%;kAg3Pl(X$4q`Yh& z;qSpeKz|kdBUny6e*#;;SHLacpTV2Jzkrejye6{~ap%hHd&u;yg!MG|4;h*1(35q2 zt?UDP{W8;eur&nfWac*PvYnL^2i}TLJoM??GBVWbZv=DOrX_7v689vVPe-%&ZAmy1 z1ea!UXMv728kAMTXpNRB{u{E+r36Uw?y1qu!BM+?9Pq%TZdilew>+EOL-wTPq$kzw z(j2C)O6;g)cNjPaoDMdCM}qC((cotASnva29HhQ`GeBhn8*V4Zo&?Iyp9~ff_9>v+ zlvyA=wtsUTxPbd6Q2RBL;37~NV?>+Y2%ZgI2~xk)+re|e4}$gJr@=<>8{ks#J0Lof z{wcT&q|K0RO4Am2?ci~s_H{BDYx_7)2fMgWfXl&mg4nop4@er)dSkvCyc~Qd$e9VY zpHq6ZhI`f7r}*Wz59qMfS^0lHSN}8^K1kOMaN`BjXVn6vm9`^va1RMlcg6{%V z?}xxaQ2SIb1*yZPFPDLLaDO@Y_u#w1yTCN~G-&qCJ#Mn@3B5v-(Fjj?l%+Y|q5T>ud;JD$0!gjTEHk)Dq94qezc zV%)1Cy2P*#e{?vdBC{x^5srI!V04I0sli6gZz3jL>PE`8tGNm8!@l1hN3;KuVJ)sB z`O$vaMVpzHTyFs7huyU@z7#6?YmUp?qTR30UrVX1!SHn%^pLK%%vBC-vZADp90SZdEcGh z4n6~FKjpKabOswlS-e^M`o41xLE5D`D{aI5-`wqYH0kbL6U11L!VUFbxM3uD@uj^( zeH3k3wG@6xFH_jqr~Bi$5B35c!u<=&c=yq;_O)&Xl89PU|UG?Cy z+uu2Q&c8O^y^leHIu`j(&{p4Wwj%le+kU`c?D>DNAMhTE|1m_Udh7NB$`#Z30zU0x z-^HG^khU$PjZ;tFV$VM6yJB8nQ9$eWT`^BzK5%@yLfWiJ_H_%r74=;)@7jpbF7{4_v|om_uJV9yrSFP)YeU+FA?=EgmJVqfE8HA@xi{#$V%}C< zBm!Ao>$_s!-{B%cXt(>Wn0F5@0^)a{?}~Yk;o=Y4lfEnF{TSC2qy2~Pig_>LnrgI{ zeOJt@fJyCkxxE*Xi#?mrs*E<%cg4KI;^IkMCD~W$ey_5et7yukBPUlEob%S%Q%^tq z#F8_QIwdyukmHvWUa@%f(Hm#AR*cN=p0=*0p?J%}Rns@jY%crF;I7)Ik~^yQ^z4j} zC(@+GT?K_j#gj@(DZ>I9Grc*U#0a#McOo(Jb~t_2Cf*p86ciN}6%~hRE-jr@R8SHt zte93jy{xt>p76>m{Hv_AqJqE7HN~98v9gL-MXao}v}|%I@$uu*ZCOQm>E!Z?lG2ir zN!*o`PnNT^9LbbUE}J~LysUh3MOlSJWxw*$NhJs_Ch?W=K&)JGPkEhJCVj8XHAOK5 zKj+AbbVu=?$~~of%J&rQnX+fnp2>R(9`M$9d#3IwIo{h7+f%rwVo&j&vOQi;Wlw2O zc~4Q#l%7e6LwY9n6!c8(Dd~w-ddb3toQjt8dMb7lJ?|}{G*;1)U%@GAi@jU;(#>RQ z@<#e%t-N{S!p0YWtsHmo2b_DI?UCa{{cvVHU1?PC{7_rRu zYP_mRQ&~H3xYt0x<1yOsr)VRZy{eLAK@Z<#*;!diS(h-k{1)~IpF-)Q!G*>2dgh`P z$1ppxqhJcH`XsDe88eZ;;l0(4!m8pbZ)fSw@|{JA!o<;uio~=;abkL+jM-2xeQdfi zeMGu6{g!lj`p|Sy`k3^T^kL~q=_AvV)79yM^jp(Y(}$-^(nqCZ=|j?m>7&yX>1pZW z^z?LDx+*PmP)TM=Nl>|W=*}rSC+(cPvtZ}coh3VCI}3MK>@40{w$qDO#!KVn@uK*Y z_@wycctLz>yd)lr7se~%#qqMZH(ohjI$l0rG(Kf~()i@@g7K;2CF8O2!tsjn;_`6v!|igQ@+Q18%X@$~~k@s<6X=gplG3p*9@Ig1u9I&IFP zMGNBo<1L%l&W^|HHg1e}s@E|b@9Z1y8@i-#-IQ3eccgFgNW6Vuc6`CC+68lFoiTp_ z)PqFZ*>~aW`109Zv*SEJJ5K*R-o0sdykq_P*;8UG`sl}y#yPX+%$c(PZO|;Lo46U# zt@P3|HM#i5#**gk9M~G%HFLKxykp^Avn{lXe z$l=*KA#tR5-uS*r4-_lXt$B8JX0{n8@+}Z`t0DWxHRoD!v7krj!Y{8vjdf`F~xmA+lo|(mM(HPHI zOMFrD(W7gO60y_zE{)k~zWWi{>14!CC$ZCr%8b8KT)VwFZu@3Neam<=g%O4txW^JM z(7)%zv_o^lzJY_vBj%-}*lg9|5SP`oC`t>Z2hL}_Og zWXkC^mCdxRdkWq+Ub#(ktZr?$5@oiN8Wnp$mTK=-jDw%ZX;v+@GXgftDW(@$)sP3< zj%h^MZZ&xmgVMZ97OPA%&r7~>Z)6a^cwklLJ1yog2)7Y2i6m#ZuPV$^%bFGbF+4eo z2y0|j&Yntkg4BP_84f>ntZ$dKXZQcCAlZ|o>3eTKkOY`kbP~`33ZrLa2}7C^o?nnF zI?b1pvf8~&JZH;LQhzX`I}-(qeIw|ZSjU+%g_ZBy9^rNt@7yn2^N~l+Pephq6d6WM zA@4iu%Z!~#)x=`DDe^d9$%vLW*1{e>b7G!LOuAi$G?E3Z!->S6A3I zxKNt6uS~2wVjtgdtK>r~lx2UYtNA;192gN5ZNhYxCYnIw1a3-XM77}%YtSrHl|)bp zbOgXv$O8>+E*zbshj#C=UKU47OxybJMdkVi%S?ag75&EGK{fEp_SH)oq@u!UbNtyo z%6dY5!^Bu;m2~s99~L@1Gw5tvN_44^T71NH{wK?p1K~2w!~+*D50H z@h*uG;X0ynA0S$XLj|Z-)A z>n61sKN)M6Z#yl-J#!U@cf=*AyNR6S%-6ulb;J9|4dG`Zo9jlw!d_!;uj0@@2 z^W`?UWs<-5 zcebrA+aJNs|7(+uOl!to&e=sa_6^jP&nHP8rjqhvP46@QmFtVRG#OazJ&B9CCS1>j zzJJ0s#b^vm?SL;vrMNWJRqVxaxlq)UXsWB&ON6vlxXO&y6Vk55rKz)G9eVDE_Yqvj z8tuPuRhnyts(`r`GcBn4RP0?Fx_%zI&LINlduizUb?BN+RL=L}&~_j$XKx%RXV2KHD%YaYwLS^x44Z@@zf(~#D2@~_x$GNyqx)eA6PCHn;l3YdyD^>U!{eXg7kFgFC>_fFA_arT7r|6_9RfdK~;PI1AMBezyfl zE+%&=8b_=0UH%rNPChZEEl5LbK{~$Bn>rNBzVGCox8bp8N(KqY)55Rdx+&uRTS5&k zEfxr_KL!p^FAjrCVse{(oJ-1jqS2@XW-;8hB-xH4W~-cp+_oguDz`1kx#HZkUM|`t{e} z-+lGrFFp6w2WKZdsjdD>R(E}|M8cTTha~p+<)ySKeqCy!w-4i7jInLH}l2a zf4KkAPqsh1XxkaT`MYnQxM9ZGm%Q`)hjyL+=V@n-omm1uNQ4v|rXT5$61+5~&ihY^BEz&R zO0lgE;~@oywZczjQKT)r{Px2UkF?<_664YnU1+W37Zqr!^$c9oMtgn$a7B40abHvr z)Px;JRA7{(q0#M7CB~zkTcG!vpXR`F`;IOSyW&U#O3rquU}daW=n251OSN3rBq&O^ zXLWTPPw_a)GN?U7lc6jZBW-$yl7g^@mfBJL)gQd<2q=2sBK@-~i2c0*AxzKpSroQI zEeZ(AarTGSNB|O(4bt^Otm@0orT>5DJB=r6vytpc5idL3Qu5oryP?Tv1@88p#*?+N ziLCLI=(=J{o0d4q>rSnPF5}6Hi|q51?5`xbtNrnZGEaRQiZ0_Z*H8Jc7+jh~lC9U% zEL!tmKTST;aLMkvUK4@H(II66&3XGUplk$ z6DM8=_!moz>@ps6y$?zit_GI9Hm^9wc(`FF2pQ&8+}3u@1ZN3MhI z3gXKN3+5TWb_G?~uAmgFbT0E%DfjDp?}RSJ%DVFG3VJEQs!D1_Q@!I{2PCvBDCets zw_?U;FJ)DAtK(B=FtghyqttQe-)nO`!GGh+*>&?pJpTyaXWJc@8lyy>T|Cc2{}DW2 z>TrDOAR1p}Kc{?p_&rVUd`_qCoWV(G*Uez|_9j*MMtIKm`D9*Qcp1Z?=VeX?;JMW2 zlPGx~op*Q6Rq$-j<;$}>=R-b^!q;VT&e@&Q1O3$;K3RH-K5KW*=xG1C*_>j2{A(h& zwk)Y{>u$(l?r3djuWM`UIzFx@QbWO;_`PZ0*6ZG&@6`>@9$0e`{j|l^Dx;@Z3UIXd z{Sh5m;IOTK?a;vR!1|H+%+8bJ9fKo$$LR9@%@^AH@BWQ_LnO)4CQV=9Ev?plaIL_h z!GkptGXkpD%p2;BeaVrbRQ<*QmilQiX*~4JaxhR0zFc=AK{HV0eo^%tpXo}53X!3r z;t4Lry%4ofQ`F!Sr+NN5Z17}ghl3gpFm+<p zsmoFiDZmInJ}lUO;pX0rd{9T~kt<)NBUip?mdW=D{F-ypT?er>w3z)$z(q^&6@-BB4= z93noq`O_-XwNX+1qBt!fWW;+N!iNG7daeVcj*Hw^IIyT3|-HH#_*cJ{4* zb3bP?=yQBh>_kZ4)Vn443hSb31Zr1ZVBII$L8Ud<4$@B9_aCVT>3aN`Y_m4%96!(R z)iXJHj_TF>^5wacnOYXxx4%wQs|wK>@h_!E>DSbeY@;p)0BNO>j=S}5=#<;{ z70(B;@%mm^TIufwe+zz?UtP|tg*db-e$)9yu6+5dS>L~Lq^8!gt0sElRdw|tWG|ZC zGji@1WM#jd{#~SR5RZf?cW!wpU&_Y_zufQTE`fF!Kgs4jfjALS-$>)o(7=!-S~eul zMHxxM<9Nv`>%-2&By&-5{abV`P)oRQVK8X`1S%eLe2E zIl5L4P35Qw_4j7d?)uH$11o714w8O#niD)7bSs@ubK6wKlPgoo-ekHCzuKI1Da51s zN%yYIq-#k>N9*fKmCCE5;F7%Ud;-7RG*$a)`ZRvIvKoLUyWY<)ok`P#PRahuI*?V+ zwbffL)ijsNO_`34S@mS-6Lwdm8jOMMI^9=|34L3oGgmk0wEZ}kyAgHK~sJk`EASOH`9*!Hr*5?4pW{hPftwS^Q6j$@RPz@yWkovy%9{v3sZxA z;=8o{1Ea&41}&%o4MEl|?{S_8E~PoQOzZqSjv|CZz0&GGYs$jwUe?mykZNpS-iELp zvA`#GHr97^HiYCtpWN2bu)MVqbLF^;d~!>BcVlN$U40{iJLgmE`!uw4CF{EDn;HE% zk4e5qeMfz3T~`+)Dn~Ez>2<9wbs1`@PhH;L($Vf!!#m{!jl}BfQ}qpv^{tjbkqSj> z>#9%Ib=B9kB3Q?1WS^!iinYjC>jGAZL*!zSySf{Aywy@G;v^B9l1+78-9`_XON{vf z#nozA5Ob*ooLrfmvNE3r*RQI=h#X;3G+e$OWE}lgm3B11||%UWLx9 zy`w$wk?iEdd20%*tGlkdrQQl>(2VDby3SOxv9qNepLPmIsh3ZICm)|(q7t#ti1i&X zV-8EJr!!7xQ*meO+dJADQ>`6jHPu#E-`vvPXsMNdLFkVLbk?;uc3bT7Dh$24JC}EL zH#US16@@;gHhSnS#MgFYB)-nZrKyI-rn=>=E<|~Tk;$`pS!)}k)Y9s=nkLtGw6wQ$ zFRANlOttY$OLuc;V_gH0O6^`fR3SGscGa7{Bfv%`8yvkLLzfK2WC_(XybTMUL0;w+ zJXVzP>b@XJU1>{taX-l7j9*JzvbCkYrMoVf>{xOhudPa}>ljKGcuS~w&2{Y!t&MuT zi@YWq+Z!6&>o4FvacT8iEXB!|hPJL2E2rgMsrHV}HWWoEkavNXxEmZ%cc!vtwyzBXw29B$i1zER78<-C^V01G-W!|im7R^O8(rbD%-9L zx>74!+UJ}e(h36Fyt#BQN~^_JXf$-#()wqsBK4HQ(niyZx`u|f#C4JC3tVbhIsPU6N{CRo|FY%&CTs z_Kxlp&!K;*rn+w8I~DFiTK)p>ypAO)l(n(GJ4Mw@brM^O(&+B&Xr-yBTY~wY>oXS~ zkh!gHRcZ-wtZZrMZf2C>A}BuKGYweqRCnD{Izx`V^nmOpj#N`?-O?_m9!jfAa&yqq zkv9VieBP`KS*dt)z>A>EPZRCtbKCe(!QbPY-4Kc-O|5_0ig^_rx^tq78!O7MiWkI z3^li7IY}~=5>ugBAD@YmZKtT=V`+&Cq$uj&N!_L|U<@bt48>7~C5=mor(hlU}tW~T)!c(GLZ7prqN@Uoi>I!UXl+6;_;w3B?Sjaj20 zfmKmH@{r9H$fG*SWuYxkh6D2i4lDPLK&p=3fC%k8;u< zb5wMH>I`qES!jiFRFqGq7JXK~xudH^vDI~Vqidmlza`2|dDHXmY)p1^ zb_W?^z~WMObdN`4?wKS%v zZQa&}DTo=_3~k9e+OlK^J+TW?*s{i!6*P}Q-fOa%U1-abbeX!kU<-8OgnVq+Sy_4$ zS19!p_si*W6EdE(U&hWxHNPR_%>6PV!?t8M3lyE~PTntLYhztkvo(U}Q&$T^ zhj!XOSIi-Q&@#L&%AXy$wYwcFDZ@auYNO0%F8zKD(^*b{bFw%l)WpEL@;c1%&yDh% zx;L)sru*8`-qzC9X5-$VZ01E-lgpR1wsbXPdqdM7DBAoepR53#;cSZ@Sn35)&aST3 z<*QOu+9epNWq$WhWqo=US7RsUFBMeGOzi3`iu;T#?)H|ZrpAWUgk~zJ&kLj6r_WzP zmj{h>V+D;`6=D_-BYroyl+U8*(^NO5tszw#D%P2K{pW=KXXW*u8~QKK>pw5_KRd7g z{LufLy#5P9|8w*DpC0-r^7@|<`q$<4Ul{r?$?Lx;^smqBUl;l}zmP^eJo%4zV`MBCNPOKlfBV?z9FT17F?n{nL|IQ`x* zH5@xj4@h=WiDH<@BaN%nQnohH3NDplbzQ$yH+_YepQV&FQdc`0nT+nX{_htUt1??O)GrHw;qJbG$GR9csfFxpu@Vu_)NG#R z)OyQh$WWQh(A?40ozfhM$zCBGlFgvmDH|Gf*-U^^V9x~2vS$6{#q3ew)zIE$B`h-2 zQ~|jqxnh1uXOb#HKi%dTZ`X9K*WS_4$Si~nJwtMVBQr&y@x9H0io4K}>A`ijEI|}D zJt2=G=h01bVedAxL-^isQnTXv9_KN8Hh7iPw~w$des8n6wDf8Ox@-($U~i50&S5Hg(o5 zwNTY%{`KJ!;HtJ($w`Hp3IwLKQex0?dU1nLt5sadZgJSNi zqaL(c9g}x3hBoh3I=IX0mNtgI!O+=!RYzn9Lf>G_Y`#n@cdgV^y(FQKgTbECLJX%^Btp6;JU`T5o znk-6b*doj3=DEUL1fyCPeRrqhvk@8fR8>*I1;bk7TGi0W+++)LAfavqV_NeM<}-K+ z(rh+PAp}EO<6!=?8+|qH2*eo-XN^HK+bvAKhrLgAzZ6U`tTis`_^Jz1p{@ix!B{rJ z6KaeG;R+`h#TpN#+Sr-wY+)uH5o(T7EWuFLSfZ(o+l*Uxk{PPj)+KfI%dr0~2m~YL zPgrZ9B`)3-<>Lx0sRpedW-h-tt;)e@wZ3~5Eo^to3JtPWEj%5QsLrdk1NHNcwc1q+B56? z%XGhlDsN_0PfQjie21m?Pol;|W!O!{(JK{^Dn#NfK}#LAA|Or?F=&W_L{y2`GAB&L zG`nADO@l(J(LDnl)oGbx(F)UE+NdT2_gXH+`Ws&1UC_nr2fFBt?yV+>%u75+mddD! zkr|W+ukoBmFaijDD4onBW^EL=p5aZN^HJB{R|(O1k>}GXby)+MDCx_c^s9I~QP+tI zG2zhBPWPm>sZ7Y?=p+AAJT?NER~)lJ^qk>DL#VNVgm- zNZv@8XK479ZKfg7Y*BAkC0(x$kS1El6vHPxKW%AWsR%OgOgHnQ|$J zsR6l#enr4r=@T0|+8Bg};;Hh<;RKd!nF6T}0tqDUKNy5}i0|)bT`wH}P-n&4wLE-5 zr@($k&#b^>uCwz3x|zuqziWy4ZZzvI|3cqi{moQIQ%a-3lzV4kQWsB=&*M*n@y5ZQ zRFfKrp*V-Z`i9a~c~0^@=^rtmY&Pu{y(Fa5Z@~CFMU_u!5L{imM$auvmEa(*GT#%c z%KNv*Zra&pVVIMBPjtu41zQ84Fk=}XfBw0VF+z8zn<*AYd4|J1OB=$=)nt-!gt|iF zsfb2yTw&BxGLKtTX*5Hjho(k+=)If1i(VNGteL)lN9P4iHUKfn|B#o+EI4fBy+J2M zC)?`UF+tWN)Cfv^B_ZDuW?Wa$D0PJ~ zm4<%UcFnw}+SG8lx#cjXvXIN(e)})K^(uUsnsw`ODW=IGUtqZO+RLU6^PPe4$R7ZP8qkLaYe+!VqQYgT989y7;Dqe7u@r)-56>^$)}{HDn30 zpUL0be4fgXr@5OpJm_Pjf{uh5NPB$|1X>k7U_(gtwz@m~zLuu-6>)XQV@nt6nEO#4 zuyOUvSYqy&4hfl-@+wlM6#HZyAv3zzY?%jticg^)8a~inw`2)J)FquAD{Uk!6CsXi zA%{(w*_^28hlTV&C46(B=}O+9@g~GZ)8ajR0&i>M(mH0BH2|kbG?@?<>JcHcdoxH; z(0iu;>E6IurBvOGOPXyz7p@!78WD?$%U2?XKGEZ~%IQ?>WJv8jmj!Cli@;hRnQi454-PQu%s% zXk%HmR>;-cYBADWR;|9;NbiL~N3Hv^!9MyyWwss%y84tf1S^cDB}>p`@AbOgQa!33 zkS+CKeufn=oe0Gmgxpi5s|Zxfw;D85O7Tho;g;D8?*qN=b}yEv!Kp?sMeND0Ry#PoPSywm~|o4U$yN#WhVk*=kSczMVtxoLq6d?>U{UxYHwS@((QEwkyH6obo# z)>MnORJUyAn23!V`373;94tXuwZ5m5q#0GOwan&R!zAcEunAA=XHbR?NiN$3eIS-zBZzO4EhmesQNZ=xdkJSV}UxAYOQPk0M% zuk+suquzF#xp4+lJwjD4Dt)8nTx;Zb?MM@%^v5ZUB^S_qOVOsVvNBn}Qhj;(Q7%?e zm>pjU!zFws3)4%tLx+)aS+&09)tU^TFR|OB7vnaW#!sR;|^|d5g*fphu~q{_LdHq&Q`gx7Nxy zOqKTRPZ%1XFz~Tegh92lbRis-gzD(>mdzt9#F2NLTPyp80%Q#6)>^_dI^WDxW&Y- z&PphOQNv|7YQjG0wzVF{a>nF=d+5*!`GvT6;0c_1?OHQOmENb|{=ss4%FA3GO4 zIq;$?QyH}Yd223BW0}qE5h2ZQJ2uE7r4#Y;n1n^jY6qX}Q)wnQj{TFRsh zhHI6qq_rpuDyz4wqyt+y+P`^(Z*fzK5|zHh-ReS;&9%BmMKhZ#f9XK0Qvw+-t%oE` zH3t@Gz~WxI(?XWn61MEcb9A?sH)h*vGb<`~%{d39=@@ zZ0@eDtTw~KKL%E<(IUZ1TRWDp*eFR`+RQ`(>FF{#QZGGMuT{8*N~(Gk#Zls9N}>&* zHGYz#rcxwun@6$QA(ac{CNC3CXErT-P2gsZ}}u;Esx~k zV0~mLI;;4WH3>!bxz!nH0)2^JvOwbqrsN8?-~6M8-h0|Te|Yk=6?dNf)m44u!|177 z&b$8ypIg4{=^1_R-}Ua#-tBp}8~yR&({?{``k_BL{pc&VTy?@#Eb9NQ(N{mRckQ`f z8$9jq|4gntVZ(2Kz#a=Cs495o-OoP$>hC}B(q&`E9&zvWe?v+>VDv=~{i6QPXI{B? z(fF)GPrvowSMqHuqd&6iyg3~=p83SmYrlB=eW#wcnxl3K70z*MR1W;yUO2tZryi2b@J3bUt9h2!+yoS5u^X&kh{)*<~!a=>l#LOe9ODx0nfX|=-+?% zgpx&n+FH2y7Zs1+`{2Uo_#Tzf=N|FnufF{+lm79t^>-C~sBMU-i>T+e1oBln&{TBS?o;-X!FP$4aTIU{>d8*$QP4xHZr{K z%?S)8qtzc6dV`^jDvxiL;&X7&z|duHwwl`cM5$qyQLX)QC{6Ju$KNIN5HLK z+CS1fx@L9P$iUDh&dFarJhXQ8#>+SLuC8D0dbh)~*J3Hmc9wx9UTgJdX1MRKVCret zp5(t=F|QiC=xB%eu9&`k=F@6J+MT#)BYBpuD48qf{W_%mE~J%VA01zX?_!P=7wr(w zcKfcFwn z_^xuVIiy{WOZyVay&b+Q=DiZqn2R!Bp2bC%8@^`W74z;2X`c&ezrjVz4Btz>E9Ujk zHaVKUBO@2j;yT*+KIgkQDz7x4Rr#)%*Ny8K<6GssV&1nx+S4KJg^>2kkk*U>Xy048 z*Xp}s-mZ}L#gO(gF72f&_g?W`eAr-eKuh|rn0GU-xbf+$HFCwgXK>NM=h^T2u9){? z$oGekuR^DK7+;m|ig{PyI?-rp-xc$A<6302ulcT+_cX4BM*EKMqKt64XNlTelo77u zjIY^u#k}i6+VvrAXGps9bdm*IFVq;>B z@zwgSnD@z$_UVxJP)HjOX-Bh}@dSG|?z>{%?IG=skoG`GdnlxZ2lnPaos*L@Yn!(& z^hP+cU(T_zS5;%Z_l=L1z97fGsm|jYy7BC^Zw}84&qL09Fd%REU*@n4bLx^hV=vkbWFI5smX6ms}E@7QJxZq3%ae2hQKYi|N46N2<=g(gzCA`hA7jbuh8AdFwC9UDiS5F8@f*KjA)x zXyV+~>?@=8)F>P%e4!)jY;V(>Fg>|pDk+I(j=N59$UULN3B=ns*@UW?6h)o@`M^S1 zz9cHN*BuxsoTv|Z6H3rYKbi87GoX)q`l!S7-L&&sEWP!9 zu>CkT@Z2fCw2NJkrhJQfh;1N#FqMBkn}Rt*!XMwJdOelA=4I*tyEMPZ&+wGs|36 zp-UZr2BWF7eww+|L3XY2Z4D zTqE3HU^MB)0&`svy3)A*#%SC4f4aG@3tiXadWX?=@ZV|I&7tcSTq*OtjsL2jMc&TP zbtkSqqus^-v&{9m(6tNKg+}`#|0S;?eWKoXJ%p>@Xyg3XaT-P5qoM0DTo)VdN&cT; zuBSrRbGSAc%}w!eY?*(}2aAK7zXCCIS=V&#n)$i&sawn?hPeLumxc~bH=V1D`(C5@ z3!;xqA0XD>Ye zjN*oWJ>r$wGk)=zlArg_DE`|kKlP)w!L7G_^ZQ?1(7E&HcTB(LiQuH_0N|98ym4DXQVldCmk%>jcW%vnZS#B@=9y;wjNtQZndX55H{6&IuG(I?<o5k}%C~BQD;oJj7?R6%u zr~RigJg-1$&f+ zP-I&(X`YVfsw|#)P_||9v_a{~;<*UQjx3&Qprk{d=&{JskIY%~E7n}{-w^!kZl2O* zJm&fqlsk3FXO<$Ifw1(>vscUTI=+9?pgYdkEv)b-z&3P$nojK;iiG1F5Z%E?DLNvc0TT4OAB*lkWf4F zHw^#)gh5%jNQwc;FL^vyqb>EbuLS#m%F?m;NA~CdL(G}QkvkwywvDpVHScX zGKBDK%L$}8UXJA5sf{kr{y}z;Gwoas{o_F=1eQ0f;ABKQbN+Rl=$}f}r-ldn*7mRO zUz^%s$7BzAHU5eDE`6C}v;AZ9Cy=w)qbE^kJrMQCD%;4Z`xEHF;rkOjCZ55c#S$FF zpF{Lhno%Y{g%Ls)i_@|!CZFW9?MKmq==bY=;K!p1=SRMukg_=aK=bNwkfQx~9_Z1m zIPCcRn!KT8@%aH}wAWW>KRXlY6CMbw(}YJdKKpxUPLSP9JpM!Y_z&f+l73wI{SNS8 zQ2!3_e8}Pl6AS`^q-O4YhAi{o2b@jw86&2{XNyvNrYxi4vt`qK#t9+|5;)Q0b$;Pu z{^{|^b+9j7%&DziIB$U-&=)RZ_Jxa=Ru_2l{I)vZ7cTT3KI_W!g^QZI8THZ1pQv5} z*LQg)p)XwId_iIdJ&~)w%2e&6j!)gxguWn=^CgVWr3vqAp7;4i7x@q1i+jnQXxCmL zj1cGI_5yEL(($RMknn0Je37D-Ueqt)Ia;GpE_GduZ)oBdDW)NhqxtF5|HOX2NO2-O zvvc|Ke34?I&tm~9Jjo^Jixldh-kHOvd3g%z|7%~QXk}SQwRc9&3AP`F zrjq`!{ATdaU4G2Tp@G5S%n{CkZw@BhHz}$h&+WA%Q9V0e_eBWJ5njbrh8ie74Rmxd z{hQW36TNA@MyUlgMaML5dOOI3ZCYt#ByT6cY9O&VClA$Vt|tG>!G-(DLp!T&tdGf> zjYF!4CEw*|B!OR$k>Fd5BhWeuHuhc8x6v}EyxqbtxReIvO+vWdCoqT!>coS*W}^Im(YO!mL3z zN?2W&;iZ0iJ>->3r%i7G9WNgcXzm@}u;j84Hj?P6%xUFSj^7@VOe9;a{3`b8*A+OK zVjt2i(BBXCfJ_UgF9L4_KLmaN)O`I8@N?izpwj&z@DcE4@Coq4;4|Pyz#oDi1%C?i z!aDss@bADv;=UEE25$r7;K#u8!P`OQaVNL|`~)}veiFO{q(_uagP#Jg1^*r-ZCa<8 z=2?#q=%xPwCd8d3P)q6QBR~maoMAL=HZX%x21%OGQP6MqIK4ojRJSU)cO}0r zu)BdB*(F~8Qhrq4hjK4_ple5&t4lY5bGZKysJ7*1kaocPFsM5C5wHjRD5&!PTk!MX zt)R;JW1!0QcJOE5PEh4~2Y592N${=Ur@$HDr$MzzcY(d&XF$pMZcybh6?d*pz682# z?~QoaELYQR+vgw#KKt!s*@3#tX{MR&&S)h{znjBEw`?mQz?QS-8hm; z<xRuc6!9(ZWyKJId+xj*|M4N^& z&*h7D2VS9QrOmfMa2mdj=7fdCu90^NE)w6BrPEVgeHV=HIzqB$L9^M?T~L%7qlisL z?g0o+M3<`iHEv$l);n~u$$A{GJjL=Dr>e@6^rzs8S*cYT2v2|wp!>eQcA^Y zpo$@=fni^DC&b{AOjR~A>^J+w&r=4HGb?b@36S--Y0cB#2d)S22ZzB2z^x#kR!@(C zUjb!n{|Qu``zrWL@Snlof#cw0;(8c7348>c4L%Ak0KWz<0>2KbZt108?w2Tzf+oG0 z23|fv2ZDOl14o{V!dF=j;+0d@TOds=>onBtvc67y{KB$UH)02b`Mn}i&#;av|BOBv z%_-(OE4`fxBV$ah`>98yS^H6$U3leD87Wz=%8X~zq%u;CRgkk)BMBu-HSFsR5=3xG z*3u1`?TtS1o0N^@|0F2;`!C>9@Y~?|;M3rR;4|P5_#7ztd-FrqlJEaFPM*YV?0*D2GoU1axV&|OP+amFyd2yug+@Gs>{@{NJ3eHwDM zvD7B;1ZbPVGr$2*{hW7!ikJGAz8WNwv=j#$YyFx_LCJ}7GHjFr%fXYu72qO}MTY5jfER#Qfo}&t3NkTbW6gJhd%0%`qP6Ee z;7r1%El<~jYe0SAm^M9qH@FV`HrNNg1g-~p-^*VtD{ndpLe#IqyjrMOICvA%V3Gh(xn_wJd9>danJ?{BAX}$uQ zlB)jFxp~rDXCw0ici)3L7^FAfFjwPQjmdOH$MR|;f=g*pp31;hpZE-ESF)Z3naA?J z1Ga$Q1($>011|ud2eDJ$zkT_M?I1G6%zldbj z50>TA{l|kLyw!ndIVvr=<@jULu4MfiDBa%!Dy{$S=Sgi{Zk|vT)4dc}mnTnQOND>F zYd>md>FtR;pm>zt$zZon|0(H`-u(=e-u)a@+xY@`D!3P%5AFk%55}13F7Q{N()(*r zWu-Rz%$&0N3^axHNq$T6;4<*jM0_`Z!cLk-Recb7~ zo&jD^?|O{l{wY1V`G1l0D~;F@vsu3fmG3`*jo=?a+Enjl@N)3K!JEMU0hO;mfy)2a z`Q?6rOSVj59|P9s$$!^|{`DiR1D76TXs6642`0#VbfEQ*(ChedskMxQ`gIhH^lci< z>VT|=+|G|n(v#7TQ}7)HYev`mU5@B{%5}!+{wW`l+f;5<&vpHUd@FCSf=WO^p_{8> z9?HH@HVM2IdI|VpuoV0h$WF@i7r@D&+G^%y)BgstuQILv4vXN@rNmVUN^Vu4Ou=YE8rrX~Viiq?I_Ety1Z_@Sg# z>0wR1)&0XkrR@km4;t&7n^Q+V3+*I+l1*ctJh*{CLqEIQIgMlFV6!p%Gv{>s$jT+X z8%O(WteW87Wsk~Z;abnieVH?A*OflyGiuk5B0oy=F`)XI%(t1{=F|Zj-yH|u44wT7 z>D$2*K;`d5P-Ut9W^P&TgC?E)Pkv4Nl>;e#on@(7(M*^+io?cRYitaz`s8FXeA%Wo z0~@UiUlS5H_g%V#&$F(xsuB;$BO@cG3=pKNJNN~c(l0qxg4=xJ$>djgVi~8|&{M&s z+|L446=#EL|K0|^3#q@8&vk%yGb7qzlWl^>vt%38AC*IJDLs-G#bWcm>d2{Jf55M429weJ+JH3oND_<=4wRdH0U>*1D zLbvxJ=YuzJ-wCR3-39(5xEz!$R)CV(ANb|Y2mb_`?ADL?wM1m*-m=z2I z*?7?T;9$OQ)G8d)$ZPCbH@!pzzH0PmHBPreKUV{sPpT5z#r2o1C8@q)i?(aGz!O}`x8%$t;k(HTkdtKbH=t7V4zLk?C#e2j z3hV}Z!6A@wM*2!{9jH3n2Yv{=5d0Xp0sJ)B532uh5h$B_G59>V5tQ6Ffhr%hjSF(x zh?}9w-rmUXyh!=Dy31Qhld!3?vXbYb_DX%@cwKJ-Vv=c%tF5YVS+#Y)1*i}dw&Na@ zMmPnQ{zlsjrB`xQF-m6t4|Q(?URP1=aqqM#4X1^qP@q7C0|Y5jF|-BChnUlxv?nD^ zLXx&YD@kdKt&}z0u<`|hWw|JiHS%&b|nX3fW*y`$?2>Zdxq2Rs?P57c-A6##-i!Q-#|`-s`JLu7`4=gx# z52O6B>R#-JKaQ@Xk57Q7f}aGH_sw7v_-XJ0@H3$7`4;f~;AcVU@LxdbI-*UB$1eE` z<*jlTjnZ{1+UV)kW<1{{4E`G^ojeFicSm8X z#lH6*=*s&Je$AtF=WX@>3o4YO&_LwcVvRW;ZVN^+@stOeo{{DcBP@o#L>KN4J>#CH)lp?XROx>FgVz+T$Tme*0UXir5J*2Oj}10v`p{C%z4S5qu2%63E`G ztp~mfs(mESDMe%BzeCeJ<`I4^`S#&)qvrczN2!YF5|^Ltr-`}@iQIvn%6T1lR6~1!FD{yVv)+MZ-RuGH1b+iQ3+@H~6Z|bWjxv4+ zN*8|sr8AvTIIYMwehN)?$Ubb;I!b4DWQe()+iIwVuf*lm)O;ML%Z;BDYvz`Mb}g6ao< z12w<;U+`z(K2Yt!`&M>lqzsg8@Rh~>Gr@AO7MuX`>>}C^)N_xC;K#uVP;It9sJ6YC z-37c1=$r462T4GO09V)&g zqjX#jO0T;3M2D>p4gfFY{ye>ZOb$tuJ_P<+KXU{T-5|_8AyLqOHUW@TA_~gi%%Ql$3xizXZ zw;F0mQ&C@3nenB1Nk2G(shxIR}Z@fy%Do z)9dSAxmS;?m!^8w!sex^UYt?O@-;oZJc_n0zceK~1*~1QPDFKtysuT~5qrVJ>XW4T z3_mV$O9?@TnM;FZRG?Lwme%#TYeZ#7LwKg+N7_Omw9 zR7BUOy0q(b`ji!Rhuin}cl!IAxwjrH`@Gc?1=6|N@F2pU@bpt?BdLEDcoN8q(zYg_ z1HOa%vq4E;3u=EO14;{Z-~(V5`~g@G{tBEA{tjFKs#*=;0hGBA%z#ZGXBi?sY}CIJ zYyo8h=Yp~o`Gn$i&jrvb`E~K@kg)Dzw$7K^nIWE%-%pC;iqQ9iD#)>+XsI%dd)G7= zTi+^cu5_RkxI^huEg4^uNxB>l%5Zd@M;#<5FOv6nfp7D5dXR8&oj7Y?V+rRgqVo#s z)Uu&x74^#3Nm7@%e4Wxn#dVTh&fwnFsb^Jp!@8BLHrf&*Z-x1)%GMlfsOp#tIMsh6 zzxa~;s{dpNYdx`x`f7Z<0MvS6CD;M30zU*^2+BvU0UrY20e&0gHT(V-!FAy4$a6i& zd6cLJlzw_a*~WeRiq{QSK~tHR^LtBy9t(7sY&tmO%j>X~`=k!#)QfZ|x7iZNcn#C4 zYUdd9TI~w7pw+~9niNE`7u(P!)K&Gl6jYrq^L2lT@X1Bv!qMa0Gm^u>x900UkMGo8 zy1d6dFQ_72iK~S1=t!s;k9p1u$V84&^_I-8mMb>&*yFhJKoK7YQ_ZWY9LGn^MNF;kU`IRg}Z z0DM2V75p6dA@D))!{Ec~ix3w|6t5V=1As?BZ$W!KwSXw?+8Z3hFY>hNZ8 zS-x%YdClE@Yc6Kk)(Hf>a;eL|A)zn)Xe-{^=P&xHS?I!kt`i%8 zd`jK`7#ZDI_ZrBWF1b9`*;`pQa67-H8C83T#uF`CzR@`&8Pw_!BZJZo^&Ti`e$8e1 z9cnFOyP&xu=yDt~wz}kd-5S0G>=$5`*a~9y;Dk_x^27AS%h#-9u&`=At!&NCtvKvl zWA84gZtP{jvD{|OYsJXV%jNPF?-0b5IYm%ruVuO$QrdW_mEQR<>b4{!<-55?7OGcW zey%ZP%CbNXzC-$28OU-x$zF90G0XXJNnJ01L0xh8eIDWsFmal?+wC7Gb9iG}6g|t2 zOZt+Z2|2XusJIOYFyuAkrX|TtRGl+19WIHXju|qM7{zbQ^uzG^a^qL_Iw+fb&Qr|( zIXK5pGh(RE1h{r7PL_u6@d`^OskD@JQqg3x1QjhFN9?u-M9Es+LDFOQ zxAaHCS{+zv-^{v|WZ}wH6U`v#bBW8#q>fx0xJ%AO_0Z+RlY)qifm=s}3+zr^&~uu137pz! z(*uh9FIltWr;`qE$0c!O22S}5pFQ>pf}FueA*W$UIs?`9y1-u8&(*l{&n_#@La1@2 zz+Lp|tz%K3~-IOXzF1y$n z7@b`tZDBQBkK|eP0<2SW-h`6udV%7>gDhvY%H!O=oXfZt&UuFzyG-Zlko(KKjFU<6 zj7ug1((alQ%Fd@1cj=GOQAZB7LZsSf1GoAjzH^ovRsz{Fk@UMEf>>6AWulR{03$ozy~&fx(t5&MsO4aZJ0Y z#V)2FZRN-=Izoz2jw?gHp^M18PE_jZz+S>GVjD@e_-w}PKcuZVO*7Yq^rNPk=H@~) z(#&HqVJ`IYK#k2ryc+{mb=9DzUfvz3qlRLQb32YPQRL711LtUe_G{*orypyqQqo{x zEmD%)(NKt#bcLh#b;RWrnAFQDY`*>OI4eQ@=B9#7%-zVKZVlwp26Y4R#U0|7kY==z zeFh`@ezlbO#VPtm%;+RHOhmoCnLeL)%dB=7>+lkEUNJh3TuooFw zQh{pCoinTm8=XR${E!pdqfnb{w2J^8T<)&JNRqxPEaoSE>M%#yTLi&z2JOs8`uHf z4{D#}0q~vRzk$4K52oml;9_P9TYy$U!%fRQr3&G!k`fD=3 z2er!h6Iesv`ET$22y{q>js1^0qH;OW;gV;ndO91pgE6TlvDKky6S{@|~` zNud75%K_kl_^boLX&}$$`{#fMfz9B-;1%E@;ML$^An#X4)4)5yBS5WFrh~r#j{=_q zj|P7Wra`SkjswpJtHDhmI_TG5f;j>FEI0$a8{{vP^?w6=9jLzw!{6QMe;zy;{BMv? zhxX6LHfMpCg0n%bOil%_15X2Q1>XqX56%U(9yt?y7JL(U1j~f8!G++P!KGj=s6{~* z{4H1yX4&Xj0Imdc;HBU~a0omH{0P_x-UcoL?+2T~C&6>UXTetR_h1|NM{qIt0@wj+ zHL(s%f$PDkU^h4$>;ap>UhqP21Nd(667V|kQt)>0GVnq0UEt5bcZ0tNF9*jT$UYKy zFnA?+47drL4_*bfg9G3?@M`cH@EULk90ETN4ud;DKGxa)4G`Pxe-_*V{tT1eb%ifkWVzz+1pCgAaqZgPN(|1^yDe8%#~%ukeAVfZM=2@T=fz z@P2R$_yG77@N3`?!3V+J;CAqj;12K*{OQ-h6TokPZQwV-UhrX1Q~pQ5`8?o$6#NtT zI5=%8{s%k>d7;P1gz;2%LP6J7xS6?_qV z4EziDQ}D0gZ@|BSbDPlVf+vHoWkUQ0@N|&*O#eb~7I+@W2WI;(0_TA5 z0^bPU0L}&f1v~@113VMd#QM$P<6tfLJU9%S3f z03QMuf^RtrzXSGweCE3Uqu{xqroHEZZvx)}E(G5Sz7t#qehGXV_&9hz_)D-0{1dnw zJTT4k5b!nN3UDU45l;5x7yybOFNcsJMseh2IYe+F&maxhyc+y6_+IdSa0vV} zcrB?DgV2LJzZ$pRv%0CCN zH}~}{;JP@j5Nq8#zBfUQA8~0VbSw962RymapB9y$y`$(h`nA$Pc2CwOx}K=pzEd`k z!@^xt@m!MJ$X1-@+Kqv@#@1&vVHJHzKmhEA6L334Q2^ML(pUmL%#QtSG|LL>g$tMi#F2*McMkRU%?q|v^ zkxK0+lq^-WjnI6lw#lOvb6=k3CDFp;J5Y7q+~pP?_qvS3!h@(k@SBUx#FuPEYY(-H z_KU*8e*&%qe+pg#{u~?vcYz-Up8<82^B3Ufz+ZxQg3p5YfxiNu z27e9i26uzf_+Id2@Hvq8-lP8lbvBGobNBB6e+Tkjb@Y4im*5{j?M(d4CV{^KCxg#}2Y?f3_yfVi!AkH*5Z(53t|giR&H<-_8^FWC0q_X$2JlGmX7DJG zbzF2bcprES_$%;OP=-|vPNPXr06z+{F6sXaI1^+(6ulmlE!BXG@6jnB<4H6NWW0!G zgNzT+9Pm!?R1kj^od$j#d?Se8iROZ|d2~8R8$@S-=sY?T{5@*Bo?r3#tZ&mE$3oZI z@ciQlxXZq?hx`s=t=FywB+(D)u?*wCaY=_~T80qQ}dwC+Zb5vu*Lmmt>M{ zv-}9(5;>bXNX}ZY3(SD;2j_vegLUA&U>2M~+Impi-}AwbfeS#@F$YQ)tN0b4FSr^S z-6|U3*O}Laefqjye+t)~zaqBO1(tI zJO*q6-vBm)XM-)E{Oh^kTftUv4cG?C;k1L2e=(?f%Hf<;^t^d1H0knv{JQe>v{#a? zsnbN1xO@$3h>Dw9W58VQT~n`He`yPc)Z)F8jzk_RQ+2KYCBLo?WRx6l0Z#$>YvQ(d zvJ5<*`?rDb1kVQt!A{U*235Dq_!XbE8HUDm&f0K!qHb%}uFdE#NZaP+D?M%**HVL8 znoM0SwSg4uwia@HschAeE*H+ttw2`E!=Dha^W_(UYLmBvYNyqp>Y_6Qrx&%;N5<=X zw4H5;E-0)^JT7r?A{>X-W@3rU9}ws#Ha;M56X9gt=5Qa^OC{Yy^w!!k5h@3c(Ze`-hB1}TW$GhQ zZwE!Y16&N=32F@e3aI+r1*+a3;#XYn0cdKiEBIYFy53nHXN0d8rQs=Yl^A+T)mt-< zT9PMpp^wHT{B^RvlB>AB_fQYXx(z%V{3^HvydPA39{^R4uYszs`gZZVl3ncc%_43o zxO#Mb>v%`9dEKgce46+o8*U?XUgC-;6vW2eK_@1rajy}C!|T1+3y+U`ZQYWFu9nc^ zX=4k|#_VH!a_2LWF^kuA$8pk@+__8T2JhLk?EJx;K(^BwjOs)rJL54hX#T||FE0ah zLKS^QGnr;Ka_mwH=e*m&G{5FDJ|_OMzoI ziX?Fq%`%m%+(FA;xAnad%i`Q^}i`Zgn_xZwhJiZJ~>$pb$;7{uxXLg z{k`PmoV0t~w$wOr4F@|1^(TM-sV;YaAKB@;vCG}-F_o@3o>!Rcy1C26zlLpmU5d9J zuW?xCBI8T_QvH1eglbR!7X4U#bthN{J_?=(ejB_9{4RJo`0t?X{c-RP@O$9b!6(5- z!S92+z#oBs1%C`qp{$>P8h?HYUIhLJcs=+ta69;Oa4)zE+@A_P18Ob&EGQe_1J;4R z0pAKf2W|lW0KOmmBPh##5!?g*1=L#huiy;uC6H&2(ci$Yf&UBgtc^u7YwB{=(BQ@3 zIFM&3(FE{5a6j-NumWUnI@%vhVab!gdEjJ_y|?H9P!?VVJ_1ew%jr4?fvmTqgF)6@ z(V-x7kLWNET}9JCbP^p7l1Fp|cs4j4To1kmd>?o;_#rS2ZU>J88|fd_U=R3OQ2pg~ z;O*c^Am8VVW`fJ<8m|Y}f+vH&0^a~Gq#tlDrCXdI7OVw-0A|36*#10lE?5V)gITZ#TmWtbbKost1E{{z2tEonfj*E+Gu;`dqKirvg4ZZWv#I0Ej9=X?22`gO%oh3E&gZm98q zrqdI7-+a-kRozS1tXsMMQX9KsSDYBl&6y98L4u|cK3U<)evt3&MT6ipDtZlg3iw`7tF3E6DPS}B zC2$M)AV^>B=iTY({ooJ54}wQipRM3)LHcn28Q_P(Ht+^ecJxtD_NFz&tfFt_zJd6o zh&vH{$8iMQ728{QQM@INDMW8>T~K3lD_+Pa4dFicG(dBStr~QO@QzVdu!^`Q1m@BN zWCrM1*`OZ9+(_(q9kUF&hTG)aLS^NR&XtvzuhzJfB*J&02ib>IQSIrUK!4KFC&AZ) zp8|8>P2l<9r@?oEp9NLBTfr}aUjV-Yei8f~cpIp8_!6kS-7kas#@+3p=52R?4d9)i zs(v^4F7RK$8^C+OyTGr4s_g@y#1UVg&9WqC*(F@FRFH7P z=9;B~1Wm5_<@(%-u;0j!OYT&CuB1D49YS^O=NDhPmyQ|MESc!PLRZqqufYZ2Ztxx8 z9&jD_8}Lf-Iq-epe}R(Vx1jvz@4&~w=fNL?zXyK<{sEMZ{|Krrp5j-$_c#bmeegZ} zE*{+$yyMipyvKb3cI;+|zeqHm$q_T>ZktN09o8)uq419-s0l9Z56OL?v5w{A?G@i#%`_5a?B;-hq@rJp1#(veJCl^oNwUxfn6R(7dU<4eUzhqP$e zR~c8~bT}TA4$DEMnE*v z8t?#6vU8r!>Ztxz?6WsQlYR8?>mFT4-aPy#yOruFg%{Sb1xi63Wh%0UF-@h5$b`qU zzP7rMmh^(Lieud+?L>7gwv&UT4~dX^XDk zL6bVH-RC-*{V%zsk8)7sv932!56OBqs5X2vD7kBW{WcRWe#Wo}n$l=2?<-lqIyMiz zhpU09#PxFKTdGoj@RgD+C+j3xitAM8>y-6%ss|55|^*pbwq{vf>ylhIkG6dv1(Jlcn2?SvkLp$3EEz~6`tb)sgcc6J?4@v zJAVfwUw2*^c9S(p+oo7cvmw8gto=T9q~}mwa*`r1t5%7Hai3aELy7%{hG-ds^uSRh zdxCu0oY2R1LXI!#P5M6+!ULYT5Iswm=YX=g7Eu22T(ARd1y_S@U^loJyb@djs;?~t zHUB#g{2cfe@J{fp;Qin-@G#8RJaXb*+&R}|S=zoY@#;=(5uMU#2+d^YtaPC1$$GcL+Dw6!#5&Z}!~n%}UX zv#l=E)Y#Be-`U)nt#55;TF}|h)L!4(n5nDJas;Em&-IQs6VHnDchOJW*5~jnpfW%rAeUZvSf6&zOlZ&-gBrn z;ux3YXsd5;$}FmHi>iI>_@dZsbKT-a^-Z*ALvxd9Q+bppxfawn)wj~jNBJx!BqJM| zmSh?mvYGb!AmV<>cvqSEnTAHRGm{+Nc8pb`dC`K#d7bqgb@eSOxij0`)ZE@l&9ja5 zo%1v8ly?%`zWs}&_GS?ZOp$Nb48N5 zp$TO);z1T9I8XGP`zJXQWhYqUx}=h%DRNuIjKOj{fMc?mt%I##UV1Cm^e8Wz>JpVv~KXOpQbvjdZCCeVDkzI;%g z_qCq4GRbQ?Y&)+B@$ok1jpVbGXH}AqIuvrn`k0dBvfLK81Ow1WqO1-|GP(G;`D2!Y zlPr{$$R#dnYLbP~qP@AUxzTIRMimuxNRp|ZdP(=@a};}MGIj~$$oz)->}a*d7IavW z-Ie6bsIj@uDNF8O8Ba@cX6t>ivC0om#!5TLq*9&ZZ8ZTLp}v#e)^1~%vN*1gVNpwlv8<)Jv7zp~PJCH?!xDzaxbD@3%r3XZ zElio(+F*-q;`mZ*4CM0krmmp%*N(~QY7-bw7?ZKJUc+x-oG~UNI$YG!9>oTC;+Tw$ z^_jMu4UtmN>&E1h`(4nQ$<_yLpOobFO3by^&kw`N%mRklEuFb~(zk}zczrUy4XtVh z;+rkB#>u|*Pfjx9o7x)M)Eh?e$0NfVlKh34+qm1jls1e_t0u{8?$Xa|_^z2VzEcV~ zM)kzlyYfDaG=XlMG`(6p$bZBeG3ZX37F>?CW;;(3h?Z8>~zaQ(5N%}Mh4 z$#9`Zk3IFNNzS&m#>E|-blQ11sdN1FPi=i#0atx1?yocMnEBE*Srqph3%Hva=FhLs zc8(gR;{H50$$i?Kc}#h*NVis)=5s9IVZ3V(hI4u{HQi0JWjkv^{23+VPYLm7mW-bj z;?F7>KRd*~sbu_|5Px>b_)|mtn@h%@7UFA5#=kMdXG+G;4e|3z#-ASI>q^FFLVUJl z{JaofUoyTf#Lq7opAGQ~O2+5snYohj^Mhw;C>eiBO<-79n&Fhda87B4S%IOkG{bCL z08XB2>$m3CPWps-rA3*Ax|_v>Vd9kjw5<;tS~}^4=XB0r%q(7uZ_!y8Lif}AY<&~c z30prajwK;+P4!FZXmQ5%9r&@fz{0u^mgYv>WHC!z0*gZB!c{v@9nmlUfi=r9stMPejdr% zST<>dY;CX>5zm290ncK3z11=>R2DMinyI8_zovWTa8Mz`TbTaa(x}aL0+hR@iHGGw z5L;1Ymdv8EO>Ne~B9F_H8(Nmk3H0#=^wXGNPMq?|gCee`=4?H?5VrITqo_N+CLVkQ*Cv@}>X|3XdTwY2Rzxj9W+q^X1=<2AHJx_OUPD`SBNN=knFaMBHeNbgton!?L5Pjl%of|i5^^cKW1--9 zvFy@jI$Ih#>Kofa;&^!+N3)n}ZZ)%)Sn-nBVw>B{{6vq}zb=(JE#hM6nu{ntUiw&%0QAzt_98LTsCzG4j~o_NvgL_wwMY>J3ixE9gSkhS@< zBH|^jMQF3AQ_B{4Hn-0eY7wt$UGeR$j?Y$P^iy?3Wfw1NjjJQu%HCuHdmzC!;x(7;Ttg$4eP1}xJdkZ^Mjg9j%b?4y! z8&C*N%5PX}p(U>IQAw`YlWNiWp(E)S{puX7R_oe37-8ERmS~aHG50iFq9(644%E%T zk3?;&diVoRneOhjYgR0`56H@+z3+I%HLP5_s%`a#K2B}w_3w#Oo+0mX(USJghFRf$ zyxq^S4PwPt=zbm!(%h;j`-`GkxXtCK_EAGit4!=P4)O8W>=d9{kzE)q; zv$qI(aRvnp_I18Q^pS!pV!t>U&ji8%?0a-BA3Nv zS*%7ld0|D2izDI%NQl8WTu#BrRduB)k7Km5@D?fhgh0pW3Qrgc0V$+Tj@ z>~}ObF*|B(c#Cr&isb2tMb2++V8^NPypW2GRf}NkWy*pD%VEb^@>s+oeRs8ee5^`j($U(ml6szXFwK#V5KBdzrFNB!#WQF; z6vO_WL7t^^J{tjHd{J!5$5I6sX%0w+sn|(A)*Ndr>ts*#{VXOQ5R=*OT$C}}Ru%`w zj?OW}6qW1`g_}^5n38CReIVro@@V8utm~{0{Q*zUrFn{7=T3w{3A}wtjwQ zaijCge`I1<7O~aZdLFafmIgnwW%Q`G!A0@oe7vT+oz3$*wHWPmk4#MK;u-IG{4N|1 zJp7)X%s>p~MGQ7Im8~jrf{$c+Mpw<5b&I}Vpfhb@>~V&wn2B+AnIUOn5fs+Df{FpJ=r1=(YWhuwWfiL7Jw;fM)tkuPLK;Yxa5SxApEopipmIDJz zT>X6g-r#vE15d75S(w8lUayNt|g_NMI{iP4?QG{Zvm+6;$w)z_YliuCpz} z)|2XhkE=T;ic3ByFfHIos9Y)j$>w3^bn)484}OPHxgH!6v}fkcV}(4gwRx#6#N{Hy zF*R`5j-74Eihf9-$0p(3fp$xIfX9OvTg;31&{4dN^$Rj=ZfpHdlV~p^H0oi2**%z~ zDVV%7{dG?Xty3%0X@QURnG_ui=s7J$blUesy9!CVu`D_p5?fu9=x7|q= zp)HFoIh)sQHlqBEi4U_0dk$aUw0Mz?C?YbKFruFjXbxaOw6h=T4W}{7-l=qY}j~` zv?8+gQ`b4aWj;ff(PL)zcVIqGWi^_xVrCzQj9Zo#O2+<;Q4>Iq94TH6;R zu!aGV@wy_n;F#kmDO*waTSYO$ieofBD+W(%y-Eii>a20}kvonzWm-Gg8*-1JXdFqe zm@Za(03I9FySb;L*y!<5 zwsGc1I>oTnlTXA_n?xFc7ag7`j}5ah-%$M(846Qm?wrO&=J<}nb~skjtX12*40F&$ z%uyQJd1S&<5jUgX$3{EnUYXRG<)J{gyCr&Ao-Q4V$!e!K4#&i4P>n@tv{BUfe3WJ+ zas)OXP+WOFu3=FNJBbbL4E6X!ds3g_Z3nm2;T}sWc^h?YVQ!3j)9kon%3&vPX05%k zvyN%8rqf}2>M$QUDq;!|w_^%C=3uF0vyVxT`lxuD{vN}0ZnP@wEVU?PzECmcyXUZq zYkQY_fA0VYI!jnrf61zKeRRBvDJ{#nZCifHD)-{_!H_=RMG{-rZ7M@ww#bPpR^U*!i;>%0YbzZuKq9af#97 zBA`iIYDCNR$CT7rmneTx9|K&)l;fy$PcLV7JKg>L@YOBqYrAaS3YMNOKC3;PPM&o# zx;lzp6l}){SJ=6nmphf?&c8^0O^!PetEFwRmd>~+X%ZWVIL5NTvKN~c{cveu)C`9? zP%Oscz$X=}cfjYnhgrgn$nLah-$~ce-Ol+Ns7SDcx*qFd^C%oqQA`Id=47%0j0 zj4DX3V{z6P>Wvzn53zPR@8s95@5!y~;fVMuz9W=fb>W(IcntN6V-enZ z3PVT5l*iC-1EMsnbCOsWe&0ez4DwkQ_^_nrk4LPzc==jOyTn(^Uah0)tp{|A*t&e( z+x0iYEnTCrIqNW~r%26htmWHHff5K0=AZLeMLyLP_mEL%++9ymE65MdTfcs-^(pzm zl5S9H)%FkG-X=v-+Xhl%udS;tH2byY^5&aczK&flBY)osv1rZ4PV-0TPu)ijva`TL zhAf>IjT_RGOhd-eiyPMUagtKeX$0W04<`zmOljJTp_$$OjVVQ=Hx#4}uF=HIZ0K8$ z?_bsDoVXfP^p+*f?CU6NX=PPU&${(=PQ|{H`=#a;be9(IJlV0Ta#yu?08Y6MAp=R67zF|VAIxb80RadXlE0i#HOYVPOl~E=vf&5%b$+5 zVO4{5Nw;H`p@%dSz(S@8M{JqPi*W@u2Fa;vo=6f+azYwegPVm|$ub9LcSn#wXQB&F zM6*g=TwgeJnFG|AsqYE3s8h*K7q@gSXl>?y_5qj|N>t0;(iQi6-{YJCiuZn^uvItWzXpQNF1eb(w#d!u^{o=DUhh=6LM<7Y#0r=Et_9Zhk&EnK z&%Ve-592t~>>lDB5B=s)jh6Lm*0HbLzMgkkdYExZ+VBp=-;?w z;VI4UJLAy>@4fqz_nfql7nD9=^kXhq()8BP+n22-+T9ykL>&J_y6g# zk)sd0Yx7%Cx&Dq`RoTV^hHgIn{hxexzoX~<>E?eQxrSYhaiag`pj*%V-uI&uR%ZLI z`%biF8;>=O-g(2qdw+7<;&YxjZq>DSy!(s1DD`Qh|LE(-?|1rN2gaTCo5_#db>G~l z>~CX}&+yj&c;G#+|H}V7_WC8ayy@RMR?%kTmH+n->^t@YcU|8<;pCAo*Z!(*Bi}qQ z`Xjxs-|^^a2mkW4=~r&tbo{2Xc=wn3{)o7!?u=zNS6Y5?dj6WVt9sKjHqJfm#AWW& z6}{xxWASf0G+} zXY^d(^D1+rk{7SKczw@h%e&XS`m7LY&H5F6YhP_nW)DnK!A`_m(S2EG@Bd|Wo>=@smaDQ7cAoq+&Je(%{v`m-C@i^mw2>6=>Tqg5!-HgZ5NMAD+O9x*Hqg3gDrU0iWu*_LqWc5w!9aT|(4G#oIW+DJ zOFP$x&|jbp1=?g9_eA5X@*!jnwC+F~478y@n@p3w&ZYICRJ0<{-X3UM0`2-hdmzxZ z2bw0tOrxo9w-2HFKzl0C^mj348s8irN=4fO?SVj>%j)>`#&?zvrJ`Md_H3Z(?_2QN zA?1F;hf-11^q4l)hf;hXhj0BD-=GhrqM5IWX*E8SitZ*6bqm!%!;WFJaJ zTLbNeKx;o*-@leD9X^zbo(r_+18r^Ey{n9_e2Bh(OiVk=htMCP*_Pi^K9q`v=rE49 z*@uuh(6$BIS#*v$mbTW1Qqf-nZC{{O(_tLn3?E8G`r8qwTG~5&C>3?lIUH@J52d2r zgibTQ=X@v?eUlF3Xpi_%DtbQ9{uF3KbdEP#+RZ*heu4H}pmoy`<{Dq058<-|P3Esy zd?KOKjqg?;N=3I~;Er~i4`Bxw=^4g1=tJ~<4ARl6e29KT=uG45_94av4ARl2`A{nA zBXpMWZS*1hE(YmnbA1T;2))V4=R>LJ&w=*WK&!$?9p6+RN<|w9oo#6^_n}mD6b9*N z$NEqz+7M`$1=`00?NfpF#X!3~(C!bk2LtV?KzlmSZo$Cc?CRk|sVF@wrd9h8G83wG zGW!sG7_OsL`%o&{PAFr15BX3kT8TkA+G-z4MGp{~XMEdzC>6a8gLJgzKExOwXtxB~ z4H#sdrTv5trJ}nq8%Mj>hf>jh2il8)b_NFI_|EpBRP>HOTNh{_4YV5r?eRc+D$uGh zG?(90A4)~%2igUJHWX-^1Fa0>b7?2|P%1hp(B2Se7X;dcfmV)DxwI8Nl#1#CZ9$-| z3$&gN;t`DW6 zN1J2XcYP=oO=^j0l|Gb;Y6C4BXv2ZFCD1+^Xg3Dh-GR0((5ANW_ah>WjnjOHxnrPh z4YYJSk8+K#+J~4w2U=gCRV;SjFPRig_96U6psfzHX9?vjzui8RigHV0TB8r8qB{sR z7~kDKl#1T6G^U;JL#gQAK)XNC4(*8fj_@JI%RpNhXuND2EwnP)eF#4kX!i!%u0VS> z(DY%Vb1dzk52d1?1==qH?YDvUhd`@%Yn*nn58j%fi@6m?+>&O2HK|r?K6RPd!XGFXb%S3Hv;Y71MSH`+Z|}n1zPP2-or4R zW_>6X?Y}an9pFQ$=#7DPW}tNj+KND1A85USHWX-^1MQAge5%CCz1xRU(Loo+v_pL; z6}>6YGJ*DvKwB4Rw+7m6fflW1yVuGn_n}nO9%vnb_7tIWjqhn6N=4VKiD}pR5Nm@# zdmzxd-oe8*OS{sC*gv=^rloy|IXWR63qI!tAEIBbjcF@=hj*?~G}0_965fXdQueHzAyeWcDG}M?EoZst={28G$x4(1r-%L`b{Y zhnQ3M#7n%$G3fq?-M?RkJu2?vObiGIs$E3pv`=r+Z&n`)%Z{zw!La`Ay)rUm`q_@K`_PR{X1gHrCI{63gUJ z^%(0{ik~es&TZtc83b$cxBqZR^-o@L{>5~@qiMy?h56N#m;aWgD>VnCUGSg!zgSMb z2HdiIO^?YM*F}G#0Qq^$-y0?4RiM5TrFM_6Z3L>~8*r%TKFfWQKf(I{%V2R`iuE(+ zRo1t-eG-4b$n<5lqz?E`Ud8$UU-yS%eXK;zq|UNM_y1%yUU9NwRsFx+pOW7nlaRIg zPtNk6yo%fFY4W*>Us*Jbr~wPr5ZY`ZeO+wCLN^fFYN4kIeaJ%kR{Aar%^>u13(Y0; zGYjd<>HlG&X~_GGizW0c3+dBr|7oEc2>roAPZRp1g?1DAvxR2R*e_TpN2rXld5Kd7 zV4Mv2}Hy(>GFW<^1X%Vu9YCQBmBYb>VdPW`Hua=<<->8WUU>UTs>T23

qYdZ6G2zOiN6M?WaQx*y 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�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

o6&xKRuJXuGq3U6KXK){)#*fx3F> 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

;6QotN)B3a=q?IYnz9}|3_08OPDj|wPnJ&LRhY| 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¬ZQQqM?@0% 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

gPOLqy1AxUm z8dnTP9eAubPE_gz3uNMBtdI|!l4PZg9@^25PE4{!jZW*ZLAXgtRz_!fM*zEI#&l*V|4#T5$Hy=wXPw76 zlFcl-QvQ3=;GZnue)%TqH%7Stp)_0=i-0u;y1YX z8ZJ(0XEqe`@_hq>y3=De>(Se6mLhL9z>s&xTY_s<`-)?_xoIj{9v7c0Tqgc14mM|f zR4{e~=LyF_NpV4N4fx@VT>L#>xE!0Koz535gufRES739ry=K7}?n2?hHdhYrO2H!d zdy#NeHWvlAKrq^ESh%@1$K0~fBum<+3CEZe$8ep3EyCY2;W})t8ytVhvI&)`NVZns zuj1n1mI$^Qe=CGrV{_}kEfZ`5{-UEq*jsJxc5v4Ub_f2>5N@N*-35;EBwKgmZ$!9n z+uSB_*9rE0{H+vjv&}sOE-qLf{$4EHqc*o4-1UMzfxnjsx5MV10mr-~ThHQem2l77 z+)i*e2=)s8&J=E!&AkC`jbMB6w_3P&Y;GU8PYJdke`|!}NTN8-TGt7d3N9+#2%AH9 zVcjU$Sa6pLH_qm`MQ?*(rhmbOHJ5+1D+N_HuDDcOw+W^NgcRa0RJmM{ASw8p=)DH#nzY0G5k44|ed8X*ilP|dU3lpxL zlzPgv+tdH}@Z*bSmb`j??8%28yK&9=TdsM}oMdk3%HQ5!Jo@9a-ZO;|Zo*kwQ(Bv! z>mCv~aDb&4z7ogLObLZH1Ojn|xQ{qy`6UNJCb&)A#|I~g3=cSF+i~0!*U`qwfRh6} z+!+6@U&MdD+>v8_(20z2Vi8P+JY8*vJVe^#-60QV4`~;UIHx)#pK$;%Xxj=g8a+B#r`fkj+4LdXV2S z6cX;p>;pnK#4;(&fYuHajU#gokR2Wb$Cy}sC{jlThizCpJjfS-gixf8%pZX8iL--D zLh3p^$kjliFjz{2c*QXSLD;;k2K>B;s&}`Hs&_Y{ z>fNnb)w@R63F~^-NHLL(h{%r1P7jmrq({}e8&UPH5ecR0-HoVv*NDWW>RltMG^Ca_ zB6(N!u92xsp{jR{;IMjA?;7FcO4qwPl&W`)NL;GkHIm1kRMopiav8mppksC@0iL9ZF<8aivSB zKK!LybL+L7LTdMj4ka?4xFnW95G^|b*-fiAecpt@VKX|ENeOxyv|3b-yyVEVSymAc z`a3co0g?$s#YLGLfQ<9Vd`BaW%x{2Xdu09zBnZTjISoyOHRQxq4J5}SvjoWb9+@xd zP>!B$K$u%c&t4!jMn~p&WV7Cuan~uj4p*J7fAXQ@)aU@%I*)||Co-OLM)!hHCdRH^ zkKEvdx?G168414(NEn=xo{c~nfEW#Us01Y9k=X-ekw<0}j4SGq2?1H=k+~GeT#w96 zKvsKXo&eI|kr@XA+~ARE0F~%@B8zu>WNrh(6gqi-0qplZG80h@ zagR(jkUo#hav*CwGJQav@W>2BMKKpnTopi`^~kIOa=S<786dBCWU^6p8$B}3K=yiM zz6yjnb>eyz$bOH^X&7@hd1Mv<;T#=Fm)-!!>Hyj7k@+1E&eR>5v`pj+b;dTDtUj1s zslHeOQEj~lpdE)=x`_xyCo-PTY|~?)@0=9tP$FaIKWsYKf6h>g$alPyU2GeKscNqEv+c^{3kSf92EdDL{GwPSd|Bz-XhrGV z*d@8q!cuaf@a5slt&1)Sxp(%5!FEbKz|tbw7}RITL;$e{%+U z0{^*{I(_a#2KpsXpN}2(97Uj{=2nUZIVC!wKXZWm+Y6~$Ibr7n=CI#?t_kKkD_4h% zRZEg{J;xikw7L(}h2DM&SVgnk@u8Bei=3lq4=c=^0{1Bi;jrjPcm!)Ab^a9aIxj2* z={c(OaKctr`qRSfBs!5Zk+w>IQX~=fnUslw#HvLm@i~Ku0`x0zr@Rv$ZI?&~B9&M@ zC$A+EWMs2_cIwX~Qpd zb(conA?1w1Lv*i3-=V~exDNy(J_Fp34DkF$7nf}m{G^r`VB8(8J~=*gNfK`1{%t2B?Af=6-PDZ8TCgO z*hD=D1E)#IV5l<58icXfBx^8KnPd&l@NQBzNZL%|KG3AWr0IhxF-bX$8HkDSa72yT z4>oBrF@8WTPGSZ;-8az;K~I64L>yIU6Zv3Gq)c)KO`l2NQBKfIdX6@@iTGuXrU&S+tN z&~fHFqs0XdM$UX^G^;e8*)|dN)YpTktOJ`QpO$??WR=!d7 zY5Znc0j>vq@JF~f-n_Y+Ulp)FNy(+jqxmGIq%G%6o)|wet0u)5 z^%ZmL@s5zfQWREJURqxotE(uhudJ!Y`+CZAh>oDTzOw$ZSZ&4hirR|mvI@Knru>Jx z{jq$m&|wOV*4C6&)YVm1&p^WK>T72y-6l_|I^vp{lKA6w;Nc1`uPK`)xJhT47mw9n z7OlX^cq+zppXc=2(iswZJOtjv6EUnX&#YoOF<8tL*ooRV;PI8>F#(f2US&G5C+mR8 z9$!1n7YQ&U@RM?B2!JF7Gnt(;p?Rc8lI^?8@oRMphN>{YUcyM1fw#Qd1wG&jx! z#gJSWIt`8f>27~r90E3AoH&B%TN(im8>Qejjw z$}PhpWn-g9hTEeOjq`Nvk?HoBUR63H#+r@Q*Tib3U5s{S=OW837_F~Wa%DBuVu);t zjAyi4YHoRLtfsbdMrE~a8)Mx5S3>99i}*sa|={f zSJqdSR>h`QR#k`{n9@4lErm8d_p+F6D@Nvo{xY`3Owbt`=axaOR@6poE9=n7mD`Qs zM7M}Z?S~M)Oa_*^md+(DouwTei&~o+yZQAu_ANJ_%I03#yr{+gs5o24h_P%xWi_?2 z*=SPe?Ua)?6nvwMSJSvR$UrRhn_>Ur`>Nb`Scj7JxZ&~B4{QoF~Y+%EGCYEs*BC4 zuBa=+;=R-{MN*B*3bXj({^b)sOU2B>MIfy*KlGfQz?uZn(@fh#dA85J2CEU%ea3X3+yld0jVnzB-RRHE)I zqr{ZB4rug^*8V!{9IXCcD%D#zD^^}Hy>wPpz4S4E#Z&Zvb?K~%+RI`UbEB2D5>E`R zUv&=jPtyMN=nY~u(_>Yo>_8&uJ5{MuCRxi!o2{;onLbF&fC4E#0U5m5`_XfV_Qdd7 zTTvImlWK(zwQ&qP=sPNGb;FFh(&|`s>FmlGOfXH3>Qc2Q8f9Iqx}qN4^d+{=;o1|n zQ&x(qDVP3(!O|Qbj@G4BRTbrEm9>{iH%WjY11YQp${QM=nx!)FYkX z(o`y>`)8n0E}zor6=LtiGu+A|m38$swU;Wz~wd7GV;%MjENeOYyp~e3>8~mMFs44>7VTNudA+{KAryTH0hsW`_Do5UNZ-? zB#z!P*Qvvn3MDnfk*b)6ZZ}#JofVx~T8;5c<|*vdsBNe%H?1Oqnyta;Z(rb+c2hMIwG7jV;o=gG3Nm0brs1}n>A0pL>v)+#B_z%E zHu;H_B2Tj`=4$J(BTTm?WpWBrv~5!Q7E=TxY&lya#}+eGNv$(sBW=0T@^a~>?NZ|K zLXlCnh{?W_zjL%qhAk7RuaDY8RLqP+F9lDT<*{kC zHFG#`mKH*Zv9?5AUDd3)*gvGAI?l$8N$Bo?<6B+LEX*Xa=SRsN-%qxxVn%7%Wta`k zjG{_7Cfb#Hf-O9~rnamihN{5i3)2_$4E3|>q*4EW?7a(MRMoZrfARpr0470HR9d4( z#TNz$2#T6XX2L`!nK3irq395j0FjWykSHqZAlMRvuU^~QTd!4XTdTI()>^%_7SvnN zYOA)rwXODIpHggVt!=%%w){WeeI9cr2_!ylfA>!_aPnPe?X{n4@3kN2oV}H>$(|hJ zYZbItfe!Ut+@vMLQOr@M#>)OFjKe(1>Ts9@yY>BWk6)?U%OoP+V7%AHlL^zK{OxdA zfaC&=tHN~+wWdcAGsj`p(+x66RmUK9uEVa4g&Lw^lL@i&9CnQcA=N?VH|m1qlJB^X z1$0*xF$$5xD952HRz-)9FcTv2M>~AR4#5m}jKgiHQyCW%_yh(iIaXCwswxz&ikbw9 z#Q>!$Rhy`ylG1j~yv<`fJmp2aJR=%(Mb*KIoiBDG8Nz$iq*lyPVphki>ADQx6&`Jb zmng2N$%2H(n1JJpvQt*zaDAz0LwDF;wS}ZGLBV`Mk|BV0fvZ-dl_Wa#p-K`@EH6`3Kb3}2AX^@`g+EzDpRq>i$#Ig1evqB%n4#P)Geq}XXGZLNX(k) z-u)zVKgTFSA(iUhY0NSk;^n3}0YqF=4t66?nO7>4OA_%gO)HvUE}^C@HucD6%V28( zL`5S9jDqc;{@)DDTo)=;#*3K)DQ@|}F4!*gKl7ali};uYhfihITvZcj4c|XVf?0Zs zX;xJkWR6kG7_=rCsn-lYWE!fyr)7vitFdP^kT9lkOtJVmmd95c(T%Baa?8!QQP#%E z^_G`$QpRNH&3I4V@-uEVwee_8RZWti9Q_@isEsKO9VKoCHQ!WW=Rh+pG-PaN` zj5wTNc)hPCRGX-AItI60Dg|<8N|o&#UgUXYMwR78ClsxzHA@Ea%DgJeIaD94PMX4$ zD-)|MS2_n&p>E6!geAiCDoZ3Bs!4j0GsVhsl%XPRnkLCFQ>`p#0*_Uj>iGQ=mFdKi zM2hj=^w}OS$K}nOVcL%5at#j)VWQP1r_=#6bucQXQ>_ixRx+H`0*{>O5;D#qmZ_2q z4~>KpCJB0oj6@=wR1LGcOu5o2WVyOCOMA#GOCc%xh>R4KG+d7*)p%Eq^c5LL$9`&h z;UC{r>a?LjPixVnBpU5 znCeUC8VxSN%vRUTPth6GF#u;kPhB>vV8$dy>6SxgER$hyLE|VI2dKB%O+u zX;T^l1Rbvh{`?H>)eJVPnHC4*#(LD#g4~5n4Hp^w)@e8^nGkJ~3Iv#dbfMNuQ# zplO0V8?TDR?YX*y+?7!ylpr&R)rVQ>U?ijQwPf6NQ6po9u{ELKLfW!vJ#GoRi=#%$ z?IJT`nu#bdcYV|jOiK&y!eK^MGeOC^OQuHFC@rysDG|dm+fKO&bXQP~9C^r=a?8VA zKFx&I5ZBtLQJeZ+Md_}d8X?==Rlh6ZE}*)x`9g7{a#v7|h&%OkO3rj0ippI@b;7Y% zqm5yatGjw?Tv;%ysjdl!1{SMZgWQEwBW}lJFV1N2X%@xQF(_bnIn_uqsW6M+W2J0CB#EQ^682LChUJWQ zU2}1Cwm@y1MHCi)7;fotT2+_@m5`VB(rjTpqevwh;%0J=m|G`~8BC0cOV}G$Ywn=r z9lKXaJ2#$sj@zqXeb_v!a6_EBS3$~{U+YcYZy?W3RMN z^vgPh$OyXH>rPI}5||lx9-w*JIN9&c@~C+X;Hb^h#x$q!rul`jO$intQLXdvD5E`B z)u;I7vjaDsYitoZbgNdGU)b1hXYj&CCARLSXGsibiLP~Js}@^+hF{)PcP2TEt7__M zYZA3)@xrygGyS6RhRSG7B7*JpOut*v%KdV(0*ul$-pok4mU@<7(kxMF4bUvxkZISr z%+8WBvsd%@Qgf3`n6C7xS<+f|Wo2wYH|4hHIezKc<&}(UsFC)BK=U~@hb$Sb<9iin zuHUyiqfC`~?xzjvKHYOaeNguqp8LE(-Di64XAJ6I?zx{isQWC>{j5RVXM64ygSwyU zxd#VzpX0e#4(dMFbFUiIJ?OcI26eCW+{1&qS9$K$gSv-2_xXdmXU3V4LEWo8%ThC_ z`}8tT;OxN#rh5Vl1{av&2}B1Mm}%zm&(1OP-HuCIx^y^XZR5JuH9c$0vOv1T%o=Or zT5?&Cs%~JIuGzKtOc&uh<9Fue3?vM8cV>#XnWZdwXCz|}Nz8(>841(6&HEq504qi&k9Y|$ zre6z3tFfW;WmKKVZhFENYe<@bl!RG`M7W{OEXVWMJXp!d!Ytd!l?6$qj1^;ospM(4 zS;)Vi87vE7U9D>U7;RPxgOv&9Md}^vYm7D|b3nF?dAGnU)~IKfKw-8(M6V5)#UYi9 z1SVz+XhqPdGGW#Slmg?&UFp)Yt(;hhbDctU38P`LSsHZNHSvYz9-oClAAdGucKi6$ zn)Yti8K!Wj)z8#mi=Tv1U>=5dH?DM_gqzd6C&Jf4FMO@5qSuAwrob$C!&5G`JV6;{ zAN*S6+=ukyM~W8}7?Bj18TP*B*Y>nm$GqwpY>Eiti3UANVkNu~E_T^s_B!7LC^5b4 zfRu)F_G>UKr`QQ;@Z@wptkzADb5>i?Y=NoNDJoqknyRVlXl~&h?e505HV*VHn{JA( zlTUi%ELvzWv%vHTUQ8PCnqts$sh-+Mqf}5+3`dg4OPW?ScCnMwIDG2fy#8_=H=3gR zN?^cr+06Sth@e`zc@Sl<<7ydOV>{NU2Df#LY$RL7%D3P zl#wYlPf4b1c;8O(=%I=V+FeU_9+A?`CwaPNmt}%?8&XLo$OY!ji29b!w#KHGwN)Km zk!HPn*3#A56lz(~+TOC(r0pmoG>SJN6f30(-c3mIG^3zcj#NR%%&-7wSIa?brD~Oy zZ&|A}k8IppW&$Szx-TI-nlvNDI-`6ot&$&mZPmo6)pGa!>$9&Fi+d1!%ocaR`>{#ZwIFy1G_Hp*ndlLvdDM6Icfv_?}*Dwsv~YCjgi zF6GREpDBB-Y!WC-pr-7VyNmD^wf(70A5CF5Q2R`qmTA%B9lU7m+VdlQ+0#$@vjVf~ zn!V=AvROkoyYZXGA=StNyCv?ZX1Z6mog@$99R^-05@`{-|~?t0bj=Ge!lq4lg4&V*?HBhx7a~Wr_&eZtedd;j=4A7_KVR+RK9t~cl$nMSyvhU zZzkS-&I>=Vj%yBe-}tO`-NTmkwBf&S`S+gM^QRl$ytMC#L%y=*JPL1euEM$R@b5ly zK>hCOuH$Ndwr1O<3oWbB@GqPA@y8#(=&*+8?zr%woyVUy+p@l5_&2__b!&6=lvhss z{ki{Mc*vGkmb3VdyeKDi%h_N1$$bqAoyxFYcOF1%n8%C4ML7dc|NbN8c7t9bX5XiHSI5e(#x*6?t!*u9OQx=y zGyC|Zi)iT`m#i&W(AvFr>GZOtd~DIy)7%0%t!&!#IWuR^m{zv5XU)>it`3ar+U`|d zEsf1<8#`Oy>zUVUmhypQd-wYi%<{&yE$=a)wRDXw%}W(h_uA(7ConRI0q^K~kD*ce z_MzbKz0{ptvKwS$TkFd9_nNS#uI{C4yPI1(-j9HqI=Wg2Fm=iM9-;{_#V(jDTHo_g z?WWqcb~JUjy&rl0UpYSBJ?#BGwRowvsr%B-_u8&{Oh6gccD1%k2U#c4H8*NcjW>p`xAxnAdL!p{rH+yH$yGCRSU+_%Gj z9{NP^^W3+9pT@n3OQ)^K-*oT-@P6=rkUgC1XIvYQKMsBjzS7mf^)YzA<2s$|a%Ap< zw+5MuK!v{%Yz65ytQ2$s*Il^(5PS*wuY#Wkzli&Xp_Q-8xRl?C-2XeM{^o1Y{|)~e z+~+}G2k%Jmn_M4<)}~Z!W^+H4 z>pSom7FhQ~AI_D=O=E{=xo+nAGhxk#e+k#Op{tO+5L9}#LC(kEw{nf;QdyL7eGU3{ z+$y18;EF+)!dnJ@0)J1zyN~-V;Ag?7xxNYiOs+;Q)!o~1(@?A!`Wk4}^`p5iz`YOt z`CKZaCa@g-7A}od^1*+FHxaiG_sW~%?}EOV>sMUYaUF*HUqRJJ)%A0b(O5)s2Z2{` z|4C%Va(@r^Cqd5w>)>nKy!*j4*I&6*PeO?8>)+Ma2<>LTi|cu{|ncrxUS{8AKs%}U&j45@J6oX zTtDO5jJy1(ovH3gXD@(3_!ZEtT+-E_xxW(r=b$wP)aHcJX9v8;xt|A}=91l1I_JPs zy;ZzVaD5#5Dg12X`T*`vaDNCm4Yx0W3io*2WUCm4TXWz&C4XGE!j~;t2wnh6U)sXx zbm%sCmw?~rUUq6DbQ!!FF4dn#@xkB2*I8Vras806F9y{%Z|B;AjM}H{o7(vI;q6q| z;7_@ie~tfD|8m8Leh@qZ_j-7Xz(=_5g7;_cFT!1IP3`}8@MM=y=aM}>7%YMRNl$-eC3+J>CP{jt!?xMcT~h7WQn9pB@AGS@aPZBYCGGKWHM0)GsuUR?;k9aOmD zcSD~Fz5sriOLj#4+cnUN=i|tInEUbID6Y%l$xZd58NTY*WAHx%tqm=2fqnpb8<*;U z+VfcW-{yV>*RAlRf5r1t+~og1xc@scEnI5%_3+Q-lCHD`<(0_fBQw}Gwv*w%-`m*c zmR|UmAAIGjZyfw`)r{*G{PEboc3jc$u|F5oO}#iZ_SU<`zebeim)Tx6{~c^Et8ZJg zfBvsp$*Pr?qwiWpWq$rIS}77_%)kgLzVhDNGIA;>{UnoX`M+oTtp4Syo<>`3?2;?~Jmt+0%`g^KU~amr}0WYU(|geo8`x zRaP<0Y|dj?=8xpckV!gnV_mtf?9Yy6@4tx5ZS##cQ->?8c!l?Mwaqq){1!6bapX+A zMHRMO(%xuJq8bUmh|JFZa)W%u{2NEciNY?IeqS-iaa@QVvVN2ms`>|f#e5UdCam}A zE9O=9W-#yl8)kbp@)y!}sx`mZUoslaoXquku4D;+?4O#&s^!78Ynel9m3}SHF(wuj zxz5>GQOufSad8RU?$H{IH{pYqiHnQX=CqC*%V}$AU)jCNFv}#z70X%E+8%9bH%#>w z4zqEcm?`jgC!aaXUB*yaUt-@=kCK_-POs>n`wf;AcRU+h@T)=ss7Yh3xVj zJ;vV9{kN1tLkU9m&o1BE#?>tC=6L)yc6p0gf}kzjuC?g3rf@UrYBl%ep3sFXlNT4W zq-n`xET_ApBihlvl1E0i=AEFX8wICPN(Z0M$8s)dX$F3OaPiN@Keg3oaBag*=432 zcX*8MHJ#L!(OJGV%-0m!@%@Y^jBf?^oX5EIQWMkKqKj z(_;)4obpzq{>={V7oM<_w^u!e>)W&jd(~i_T`0!4>Z#g;G@=oTepS@#1t4u8-3FqZ zGz-rf0j8e@li&})2JmH&QF8isAnh!jOBhSQgTeE_(?J%w(+j}!LCtCzGo+;$^qt-X zE(3oDE(g^EHiHwu7Eq(_6<`z9XeGD?Tm@bSwt`1d2#f;LGr-m0JdiY}RXDWWw6>k5 z>rDRu>;!j#UEuG)wO}Fbvl~1F>;aDeF9y#BF9DZ>>p(THOTml5%fSuc_28Z04d7S7 z8^I^Ro4_A}9|3;^{tNh1@MciJWf z#*4xv}SWi|_nYZmPc%xxdxneTi~bSw0As zgI@)yyP6@VJHfAkw}X#>-vR#}JcckH1=oO&fm#Wm&Zo6vwhi0{J`QR|`vgdGtS7+$ z_#dEVLf-;U0=I+G;|@^zKJf&-d1~*5F|u0-{h8S?#r^(aWVaCeh0l@QLfoxYobqtL z)F0U`WMsFHRXyE2%xyQ{YK`m`GO}9;@2Pp;(dxScy(ToWTZml_BfEv@75kChLTDCx z+i+yJ5Z+cD*)4=`dq;K)31#+1&~^bMyM@@>o9GqLk=;T@b_=mL?--+7O|HG*xzV zw2f>QGO}3+wbR{0V;Gx-XqytfBx-Mg^geAJVm5_QGpS-HgMWgJM65T-Y?}8>`OnT5 zBRh#S@D6xU&i~#{BHBfyD5vS?uWq=z;dd|QzF2zolDGEUXn$S$ZN0Vpp7t9U*9-BV`@Cn#$POd#d{3eOG7;Qz1Qzhmb1r80-?j+CfS5(04K4J6jqYJWmQ~92Ok13JU7Y?EVX7>b}_h~G& z&3oCQ##yg;ypyn@wp^J*1+2?G-c=s&VUPEy$6L&IGviFWOC2g;t>c>|o44Mf0#>Lu zT3Qn74V6xg^d?J-BHR`%ifnwXDAM=#BZOu>{0zT8-W%ydZhNRyEUPb6TGpFiy1Sq+ zzjV)5C>V3*=9gY|E)pswYj*%v0dD+-s+bF2Q5IWe^o%> zQ+WLjnvGjtIenBD8JTJ_Vybau^;2+3c4)lG(ViX3DC*M(iYh8aDcZ@KzDjhI!)HxW zjvT3sn@aTsqY7oNO~9raxBJRB~#=HJ7Fs&ihf_7a(AC7 zF+0pHnS|S=DK>#A#k)?W*u1=LF#)SM`xn(o!ze0!eCZaIXs4+3#btI;$Qw5e3ltEl$o$tfz^c}uC6aJ#6)CNOcmqB0^|Ou$Y9 zC^7A#L}hf63}NpU(`s}-b-?{5Q{#`>V=7e?4|Yq~@QOI6Z@cm^+nY~}1iVcGc2Bk= z80eDaLyeWv@dYeS-Zq+`LfNxz941DIw2h4Xmh7{cm-w3bF9<=^Md;{P-^7X~Bo4Xk zvzZ$Krj}Eq`2C@ccurI8Z_5o6*7c{0%0?mj;t2Wr{ohin*Q#6SuJ-#5$Fp z7n;H(uw*H2;{&GC)!o$I{A+iAMZtR2$jPvsh?7m2gp$99ZtN-Jr7!<#gL(PadZC(d z9v>`u{WDYI&x}6R-FI;>AbX@p{f3i)sZm%{gMH&SlaLd)k+$)9JNmYvu<pL zC1g%4Gh`aS`wr*|Q^N+=Y#HwPc8#abP-@qOtXwa!sVDZ&?xXe)>?dTQh%4WEo4+R+ z>Ma=URtOJgD=~1$ov{Id|qB)CpTZ z>a**Hjo@=;dlwsfA2A8&r?2nbpT1;vfBKp^kI?P!n)6Ib4lz8%&+~Cym3Es__(vI@ z-s9F?9@}=fR0))tN1kQ2R)BIgVz8V&6L1;)rvX)wX*0HangsdpHIyqdtzdBf|F5|v zBtTb=*^}xBLq+)eK|?L(?*|OUAMZB-N=+*BI{-4r=;9x}V^jXhoz>TFf4(4a%u{#X z*YWqG^KTiy@WF;(d}h_x|LyH-Z@TIFGj6FoKL4r8+4nbe{^^bl<1TaYAGfoU_AF9; z%l!Pi6{%k3)rhdGXU=*;G*O>X7Na4NZbj=(Y;_Ly*f zuCET4;e~U>08U>PCzaAxLfvd1p`RO$2E+DGoYH6=M^4y3^Y9Z+da%L~1+;g8en!Tc=G(6c zX~j+=|_rqUXFmnhYmyd0$r5$9*u3~H1^7#Z@8FK2Hl$?whA z2OM8U#)LT24UoI+9mZ7NL+vo8RgJuyxCzPsCrqf?x?}lesT7+jwRCkyQmGYAwUf9^R)-t@B_SWu7?doCf+*2jkiG6;;-tfN5 z_=2&vrKzW@wfj=4J;AVjaL4M_7OS+UokiE?Qafh<7Eq;T$FM;h22FY?x~OYh)50Re zzTG)R$?P`OZ#N{*Kc^<`&7E9_TGlr0U7(uXz*|C%-HrXS)h{k9D{BKBvr1%;O<1yg z58|Gs7jK`mEd6*j*RK{^Apv%#E1${sW$tgNo#|%HE}N0rnQpS#nXV8c(d$&r!FHz8 z4wG5GL3XBlF3N6)G}zp8Y{@5qia~a!n}Y?tXED2ZK4Ht90hpcX`t4w+wY$)_*h+>= zKeg_XB6hH|cYaG4CVzHtEkWkU?KVfYr=n=!j(F@hWSx)9Lynx9^kCt=3IAzi9#g>l zWP=6^Zyo$!A#=e~lA?uk4HjMj315%Qrl*ZqCcJgoJLk#T+~>&Hl8SfWPJFVI4TvtN!8yWU3uG)t8Dvb~03N6h~&2BWLQ1 z=Ey*rUxih%)oY;+PkQ?%a@!qQ6YpMjGJGDHAN7|TWGBO)J2FlbF1i_vm-pK_>y``IQ42R=qy)nL zsqe_dZniP3P(>X0bGF#iPGj0)Z-O;mQ#lZT)M_6>voTO*@Y%= zn#Vk8YqOigsN`08GVSxFi?tlSRb1Sb;Zg`KP2C+#LbMg^t)9bW?jC-dJr=tbDt~E@ zVHYchyrcEZww=oV%6$IlB*5b09bgYvEazedCfR#*O7v~b8*Nc_t@{$aX^bcO+&)C< zN33JVdZORoho}-Tdb}t4;t->q|q3o}~ptTXZM5uWWt4NRpe* z(N~8M{kzr{ZPC|;5Pkh1PxSR6L~qtArXA{=Lx|2f)DwMc2+^19wIfxRxA!5s61Vge zFI0>1+`h`SNb7`lTD8i)FVQb*anTmlq+nm7(IY+4@%s>6hE)7$Pqb(V(T^VEiRzq= zy(OR#sVk53L?`bM>TY9*~_41k}vt6Z}*b%aGk$c9tVkKi3m&-iN3{ zJzjHhJ5;UP?JLwn&hkXHA@JTr$6-Uu#4M`vlD@^0yUY}G|C+M_$!#^B_>G9~ zEvG8#`xkhkH}6CAB-}o9juBOsZ{gNXy}JvuKgH@iDztWC>qTda>@5ir{lU4O=emh7f&4#cP+qgF}d3qhhc{A09&V_!XY$ zqy0n=u;v!$jx)|ye5!(*TYN^p`!D$JweRp7h%a+^@~OF|+EFW4(&4YBbJ0AM=MU*> zun*J_^EyyNitEAk;0++O*)95Z@FwoR41NTB68snNKf#+pb|Z=vxm}JH~&2Mr-1i>LGWHM0p16;fL{Q0{>>M`UhsbKli&m37r-xpI){tArgb*Y zS3sQu^C0+l@T=f~dG;>NI;ZMu-0NJMhe4g8@(8#R#N?*egI@=40v`oG3w{Iq2KX4L zRn2dLyTNVXAHgTUv-0iTn!kbZ`j+HC2AJu3Muty;t>Cx8Ul*7&gVKKozr+320n7R> zcpJ#jF?}!iJoqH|J@7^F`{1N;v{Nt!z6hqlAAwhcKL)=E{sjCf_)~Bx1Hzr)YVZ~C zYVcrY_Oq2?T+^!10C^XSqKf^Wf}F~yuA zm0k?~5BER%fMxv+d=>mVxZ()j-vK`aS~*ra|40BV1=%4!edkenZepb$2SS~2e)`T*%bEb*2Oa=E0TzNUf<@rVAVZAw#A6t|fYZT)z&el} z>C1`h{=;1qBncm(+TR7+HoM2Cli;b`w}ErO&EQ<{I`9nee(+52cKbXMfSD`s%c7kD>V4SoTf5B>;@fIkImz@LLraMVoB$O9*Ub>KlDXY!?4akAoI zA9xP3orpbUe1|F;E%!c4;Vh3w;{kdcqy0yF9$CIuK?GBSArh~ z)8Oa94d4#&YVbvHBNzypbEMKG;D@;{12=)_qskHOD_xmDP8Py?uY!Q;XEz@^|9z?;D@g3p5YgQG*(b?^}IOW+jn%iyu# zSHLU52f;M>Rq$5uA@C0HVenz_5%78N-@!kFUk4|KvFG3nkTV?9J>X;DCEz!~&w*RP zuY%jaUxH77^XPD&1f$@8faieU0yl!&!3V${;CI2Nz#oH8gQMn~v+L3)fzNQ?4L%EQ z0>1-(2>dSiS@1dVUhqG`--AB{_kb^g(<9h$2KZ;N z8GH*|2mTMZ4g5R!D{v2(8^=E9(hq|<;DP6G3r+?{fyaTPL5*oSlQaD)I2Qa=J#X}b zp92{qq`wSuVn=#ASO~rh7J!GpjG@L!f=cfm)%O7PTX>@Ijd7y^INg53pkR$zC*t5#xn!Ows-;Dg}V z;A3DE{4N*+cY=(;(re$UyW>psh-tQKu4|08k>)aCl*uOQLqg312xi-~op6@U?8thk5 zY-ZCXxVdZ9nq5m&am8|4Eq9DhweWt5b5)N0W=z!KGTcck9bD#w5r#ME`P`R)R1xb) za26vwD9_D_$gy6Sq?tYtDgazcnx1S2Pe$ST`AAl0+Y zTx#Tm5I*=CSRNxMgitp^Y^xR>IU!`^gpfokoTv)M!}Nt?MotJBIU!`MbxuRLeo3k( zk*W$-MZzJ5DI+I@uyI;_*qpUBazY5zVdR96>TpUUi;)vTMotJ>Ks^{aA%t&1s;W}8 z@kQ|<X8#dMotI`TgPG+wNrbcvutbjE3XXCuc=EcsT(;VWaNYp>c$8Bb)%-CZo$Y2 zA#ojZz)GEaYRt$9A<2eBDjtj0R4qwG>ciDMdbJJ9$O$1%f2+feli|f9Cxncg5Mp}V z3cpnyIUytwu3s1qrK+uw6GGytSTq!_PmP=qlBx^VhE0vQ{~(P~8@gIk@%mUiT%V+y zi6xS$g*H=Ow1NImlZ+lP}~wH>Lng|Hh!EDjCqqsPB|H;P+fu-e{3JQ8Fo#4 zVY$c8%i_=GF)l|j@S0L88Rr3BG+G&~T0kmmV)Zr2CHN{RzWx|qVQO6I?)8$qw6le@ z78Fmg`SMg1t6OMzI_nx)!H|rSoeP~gvK9q_l>luR-6z3BE z*|Ex0tn%z|RWelS%7M zY3G~dwzgDR86TAEkbut7ymed^3EDAf_CW}COqza}VyNYf_LLK9eR#ep2Hx7TE@|R$ z0g6HAU+7+?U>(QJ=&1TWT&#mY(|601-0)o(#DZ@XF4QOB&99GL73d4z}}E99-c6rWc&wy74XR=z?_T^Otn z*EQ671z>9B>~a%(579N)Crn7(L=}rg!@)XJm$Wu(DtaOwt}^NCqzS_zOjGk!Rq~XB zg|QmD9q2W{maeY$4pJc3i@0B8Dv~*SLb66TYIA=iFx7MOY&{k?HT@9yYVdCDltrLc z&M?WBG8wrh8lp+w4=gAS9-k4M-_l*V|DG|Twlod(R@X$sMiE*krRWk%5=IddaKDJc zjm8%xFb}d9yfFC>J8(qy?O?Flp^m1WH7)JkYnRS% z?T+*;Uz%W#nKjYYkPea#?iv1y3g{bAo=k{0 z$)N)J-qVU3-VqKJuug{J6Dj2Q8q-h#eMf2W`4v3Am^4&C-!@u&x&^Pnp#oMDl)e`k zXRUOofW9@f78o9185$~}?*y&04UaDa4Hd9H0aaso|K?BueUE2F4397G3>DC~aaOhA z@fDn*0{TwP;&V9S{hmVwtXH5yhR4@th6?C=F^kXmko${61@x_#RcUy9-DRkNbqG|@ z@D6vVfWDcsDh%&rhYDDyL!D)KeDP$cfK>~1rs19APyu~MWSwDnO%4^XE`pk8cs&jk zur@-SZg?MdsDSlRsM8GZ6Al%yJ_j||@a}b}fb|Fz(=hV(4TlO?--cpJ0PnjF6|i20 znr(QmI8?y;J=842`=dhzteiaUHz&WN94cVx8}*rncZfp;tYe^N7~b&?6|hc)nr?Wf zJ5<1`fhse+T89c)=RuufcqxYpSZkoB8Qw(>6|k;?I@$0xI#j^Y_wRffO!_|RPytJ4 z@i5MY_c@0OSYL(W(<69~I8?ye4#jW)-nShpVEqV+$satO<0C3y=^Ogv4Da_26|nvW zrSG1`Svia(LxEkM~WF_bZS08;@5!){XZdhYDEpJYI#zTj}vud%TZ$ypMUjZ+N_I9`99;_nOB$ zFyO{}h(iUeGd*6V$7}U?Ydqe=9`8|)_j8Z;YmaxpI5&=o4i&KGdOYpEp%TX?db~c5 z_hpawkjH!3hYfNc-uYR8y@e^9`6Ga-0+TcsDKsmcu|kn zGXc-k&|*Up?ND2e|Pb<4^%B>ha)yw^S6+a8aps-utb4mHjy@_3~lZ>q<;k9{H7`T=|JfI|hW0#s`A#yeEN>V(qw zk>jjxhoVgFqq;V{R)JB`Ay>~K;5+0>dkkhDa;2R*BOGU9yAS{;X}I?r*A)Z`ui+bX zPhxwz^sj`-&z0Gpo;rYY(g04`08aS;&YS_9c>_2V12~}poX7x9bO0wlfRh}+Sv-KV zbO2}B08aA&&Z+^NwgH^Z0i5oBoXGa{x`8aSnT<~yNNw&X)n`oY2Yvoynz z%HS-^aHKLg%^8kV24_`WfzrOb z^`)gXn47YgQXI_9Sxo5;=9Vm`)Ccp%ET%LF^X4q3lnC>dET;4b^VTe;R0;F;ET*&x z^R6tW6bkchA2ZTtbgHxF9>``(uVO!(&6aM(-U^#@WkXe| zq|d?*=~z7{!@K^n+#gPfPDyf8&^I>HH@5Jhv7C10uzG_f{y4XKvc%~+5QYA8!j3PT z-W;DZh0CEh8Q0z*;dn-~uVQ?b-`?POpXPy|!Cn233j#hM|;a*%~1e&VJWYR{50jGoGrsSw$%_ZO-|F>}}+^ z81r?ZE0!wa$ ze}M09?v)v{Hj6D^T&KQ@sT*H4C#Y%&+8dneIut%sandzg3pd^4EBDrlskeV9$KoWk z=XVAlMnhKLa}ka#W5^nb7-CO+j%TNPH!P-cy5Tu~_iTOst>JiG=JOia_^?8o_?aX{ssT^F32$vHY= zM)z)X#2!;_Z!I!QM=uSfBMA&cM-Q?`Q%2YOosNP&r98DblU0;b^zM|x7Ba3v z=TJ(Kz%Z0@gfFH0OPAnlI7@s=DPNSO6g`@Edh2&$&DcfFRf@3-N!5bT9%p3_XZis+Uo)v*Olk4 zKSmGHw5zb>?NyRcA2Rm&&5^zxj+5fR1{3&_FZVaB%^VWSsH)c7sH?< zJqZj$*Xx0Rb*5o(x_wU{=+biZ!{$7F6X7~o<-L#oVMj;}z z+Dv}7N_>xaoRuI645Q7|)nrmi1pCDrrzW(S>N;nT!9kD(NN@CZ*t^qCJfj_vS=uQW zN;?u5hISs9|4*+S-kW$gZD(;tJ0i2RGkz%TNMIP+nOObLt(}eQ=2%ylCkAF|HIKJ3 z-Dc%1t#8~KaOYHWgLCYs3r6;bJQwF-@nV!~?GEsCVDX-;dNj2X$bo{ zB~u5M`CLqYw#3w#MB{QY7G{1IC(Z8^UF zx#^6-`&@e8wz;&?!s|G~$1|vosWe|>WQ=G@MvL#jh^8}26zMafCD|&>Oh}!cSnk6x zqMPSsYSjLsLa!&jW@}IG?qkuC)4f5hLSIYQPoVP)8MCEM2y@)znwoHn8+%54yi(zc{C$TL?C!@NhHXVwZ^dnk z3DQY$zr@^ZyWO1g41L6|(|8|%{4B$(JqBH7h7Ze}@?BPVUHPa?wZeoQiQwSN{GMl!#>QHL79;D4;!Xw{9fu?vu&?# z;B6#FAqhy{p;b}ktPeQUBwu&b!lH~@Lg@0Sj4t1SA-gf7N|8Q87R^@W07EACVHmP+ z^5vGB%Kg!hjoQVrdtMIF!_n_b54U9WAkwFYxG(s@M&)uJh8|AkYq|Yd4-@Iq)mE^0 zHnF?NF^iAYn$X7?>f-fh0GppRyu(+f;-U?^6Z&s%|&iujpU5CGgTKoD&HTxfhUoI?|Ms+zXP6I-{|g z>uxT(?lpR#K6wnfqM?KGWGU$nG2 z#3xB*qN1Xvii(ITiT3S?_VJ#+E$clCH^eXr5GQ$jH^J=8 z^r)RK&sh~B>NH74=iQW*Z2UTI2dx8IJJ^HURoQC?+d~^d^1|A|rqZPp=pJ6=gG@r| zl|ECOb+bpcSp+?Tz$)CbiNA<0_KWJqh>Ac|V6C6C+V)$NXNyOgwwTCVO>N#3*uqPm zWY{D@QHj|7MVGTxJ`}C%qj%G_TQu~zK-spxk|83Csna^E@ESelqSAMpLhE*hRo%W} z-W}6TDXr6|x2j@%uw$#3A(0u=kb=96oBL&p?acQh(hsh8`(5p7;)W4%s)?y3ZvDi| z1N-)(s@mVn)_r?Xt?lpSVZ4yzb!dUV6rfT{?6)W=ZuR0Z-9;(4PLHpz$XyqTL4tE5 zrG;BI_zJ6hRELC}Dt4gcut*V9yEU3G3Tm8vg)!(6+_t{S!LZv3HU z`7?b|KfNCV--%&4lCIv(3h;9GE~~$nnjgrhS)^~6(CiB&%bTrEIit?oiFF8d9-xdl z^>cq2u>A|_BulEy&+i;(7lT{550Z)ZDe_^2P$Vrw;wSFt+jh;?^~da6;tY)@d}i(G zld>zvz%cEV!>x8)7>M;wU0BKskXVgQrUUDF=ew3$Z0UNddz>Jr@S2Hy=8mD=j8D_m z*xwrxy)D;sIQiV7V7C~VJkn22CBFLz6GYEsBy^921h31FI0BB(=XY{17sQ8U#9un` zpWTQbOKH6iM*QJS>lV2$Bfbiad#%*&E3*0oyVXm|t>FydP?Y8L4;;%$Dd`rl@;)hTDxc{{NVVZ>{u?tkk1M;q}` zXm{Uce}EA;rn+!b7c)lNTyI(l>DXH{3XtJ7(;Kbrc>~p^O*tAxyZ0LWY8;+*Kf#{n zn=gP|hdyQv4CNK5d0W&Qm4~hkxozG4qOE&1V;IRp<+79X_Lc zxw+v*`aYsh(N^^4pN(g^n9PW9GpD(N!r%Sz-K)H)F4${ScQgLkTU7cAtvCPLA!E8_ z*Y>xVpO^B1@?PVqARhYD^=2-#nf9Z!0Y!xye+3LsMW3w+GP53MWlpfg+^H|^+v=9R zt0b+xIDzIBerWulz6frM?I6%fu;x*s-4b@^z(Inwr2EWNOkx{f&5him4qM)ziZnen zY=3#4zm2D=`zMpjPASQnp5S(+kcT!Q0up@KbqTQx}G zhIIltv-Dp)G_7VUsPCl;;J7wWk1UvEeV#z)#g2YU= zMeP3MULxVU0P2>Vd^<>Ij*cqCwFySKs5t=kiC8;HB%=B2ycAU$g*JZ5+%dv zdYy7=FTiv{dJ8bRF&Yp-c?wv7`K;}$+b^mcBPs$>fwlfz6}x;5tXdMV%Tcipqufj) zWp+jE-hzS*$Ee?qB1`?d=25a)y@#=2bSqw3=uP%)&FV;a`V`n=M4Ye&b}Tan4|DH5 z$nH~y>tin+!Eom#A)e4{Dej+lacL@b?tPe-?8ppQMeb`}a-*rc_Uaa9LW>@Q%u6Ii z#g!czVj!F5B`0?z^UpIcxpoS<#!}d8M(=!aiD`|i_jfQac`l=7k-mA!&3>&8oR`QM zb>2R-I={rrult)i|Izc3HN4*KuN=czT-tTpZy6|mfrL17liWL6s>bqjBXfMS zflnLh)H|ySi^iUUeda?#1@_hG%L6db7SzI>fLFZx&~bd;2zBEzfSid3IRl0iMfq!@o!2E5ZKPa=nCBneg2%aO0yJO!n4)AdAgl z!<5g>#?|)>{*}oD`+2t*w^wL<=~eJ=RgCxO?deWtHCnOD2p7=EJOT6N=AphXHwXV( z)7_t>X0)vU#W!faPP8+iCz@`7ctgv+O=;zl0*V&63g{mY!wHjR%C7Lb8EXI1gIi9K zzFtiT3m?i4YP_4(p))L0u*dA-F;|vC{If{H;>~4V1X`$y^88!&RNCGTuy>gqbj~ra zld7!oNZ%Hd~7dcs2g_{?j_7^ujKDD*uk>dZ@}b~ z>8`J6Rhcq0~Zm+-~_;2aRGq>*cJdTp)2IqAJ9>%w| z>k2*;b;F2^vMn2X3_0~DGVfJ87+bl$!3xi*f&>mwxy$OSnfLsz%#7M;ACBU8qGVTx zef9JF`j?Ym|897_L9aOaOmXZ)Wzy3B? zQUh(SxVz5s^{&*pIsGHg->@ySZ=|m-@4abX`#v=7J9&iXR+PT1=BgZe`c#9+w62PI zrd$gj+UjN^yU`Dxk^g@*%GdmjQaAc}CA6hftO1Sk(>|HKH_F-U>Eng;|DvpENg-ut z*ABCM?^>+_p02qQGXH~mp7!r^W7F3u3TI`>n%}leBMoc!*T zQjk%K$SkGYJ(N-;Fbt)n#_rcjiTjk&&8*tjQl`B-r4(h9A~H)U_YI{K2@FFiPxF$J zo6`NRrJQji1@BYK%PhsXncbdl!*c8AaViRUKl0u5Gm|rl5}Bo_2ZmCV1csrgBYkP# zpA_YmexK3DAp2!(ke*yAEL_>U(@{xAMLm7I^tdNchioh zW^^PnOGjFL$&_vBz(KSGhM}V$F%Zmzv;Tap=H+R)?MTmBohOd(WTI1+(UHh39X&df zjwCP)9nH!L=butGijr?Ypn4tDWzx_dY4U>6@}UGHWc z?Be6B@7=6}T|CZ~(lpua-5kwkZZb@r?c$T%Y?wOR#mC%Ym^$0V$J7v@ceBoR@iA{U zOr7oGW8PwzI@`s^)PwKd%{tq~$GqJz+p?K=8K%y5@k!oom^$0VWonh^0l1Og&FlKH zAGX=%a2ID8Rnl8+whnh;ftQ;^Glx_0MVL15FX5acXWX_uzf>99%_3zfFFEFyZkT6wfxBWs zq$!`nTkxUxX0+MIHCwyOjqga4@$NWID%HDZW~qUY-LJ-sWA6qztVD zV=>fv!&?Sr`)FpT+`|m-xTJlCSH5*{gUfrAy|LFB*Ke=1EN$c&KlA*>!X?B@s6+vlA zlV?qWI>k_vp)@kfv!+0)|If2Zpw!FcS*1`q$1%^E3PmwModh+@P-Rej^9rvVim#BN z=0MFc)I2D@Fo#zGb(*0S_V~V zsAi}tL#=`e8LAB`Y^YACYD0BHMGUnLs>V?3q0Tl`8ft-|HbF%VwHd0`P+Oqt40R(E z$|j{ZL&XhMu_$ugC@7k&;1aHU{@F*ZZUQT<`7D`ceyqjliHkLs>jl*+^Q%bNr-P@= z!N93b4t(uik?QE|ZtZAaOXZtb*r}N9Nr%BUu52N$Sn(UUO3Cg| zX?T$fOJkKf%!QVfR=O60O4|}p6=)LIIOAJXz`B^f%H=rgGKUISw?Nr)w>lKZ@tJQy zc@#J~(wi(T@+<@!DZl*)P1J88DjajDC+YSlq|wrN6sy76AG}l;=_{}WHa=OFdO|f= zk>wj*@Kg`VE$}aLH@#nhlMz$@X`I#@UV&Swi&r?M+-AzxUp`1WKb7w!tGKv=`;*W? zEGL!d?rLdVW4NkP7uwuvj^1tTHrzN|=?mFtM^j^43r426m~yo`nG3=VcCC!IuI)Ce zAx$`xak)RG_iiq~a<0y`(rUw;`Cw7(%FG-@kgZ%qnAaI zjjzR}2oCOuC`{JGe5PG?2MEcjw;3q>!5=+f9>x7`AS!7^z%jk{>T;Wb1#xA zs!m%vtkcAox3*`F7GF2Jd}*jB)yrJaAR%Gu@}G`B&?xHQ(uda>8%#zWTQh9({AuN%wx}o;NRB z_=hD=BzwLT9COIutxM1T#Di0IoOAW8qVGO>XU>y1{Vtt<-=g1M@|o|yb;YGi?l^3B zPw%#mzJAl+);Het#QM8_`p5elI{$RXhH;mqPY(%3z%tn9{|oV3lE*36mg-50mWgUUNE=K|x`|7TjW%BNIz+Vu2!InPBc zW12Hk)4E&Mb(gMb7e^H*FK5nbdl>YkjZ+@C<@_?zV_uFLzG8hlay4TU_16BlH2%oT z*}-48Ipka7`NNS*UXILxe7_c2^~}I<#u%A5`Kws<8$BQ#Ro}cEHCUzolyFW z*&LO;;grv!Z_&iS)F1hpK8JDnSp*`Ek(oZX%(A{uCGc^OX+^~zXGR$^e<#=sXF5gy zQ!1N}LtIx+@N;I&VE9p(#X;siY*@zEOk{!+vpC57=Yf7sIl13)P!cs4~{*9EKZ9Tn;s=yo}hhIZE>v z&h^VE&6P|2oEgac@cb+eGHr}`yx7ZUB6Cn<7KdCuvfR%przFmA&f<`-oE0udX`V!y zcdm3fO7kq@($9`-+Pdb(ZsO4|z=cIJv}HZD{HAu>LW*$;;pk^%EV?w$m#l7Hj=E`u zxNypa=VyE+9bZPq^2cT5y|_-;a#O&zq6A^Bb9~uh`s1RB`QrNRtF32eeCf+X{fvw? ztt*ql1K{T6EaR`Ny7j3?%QKetQ;shqBUkH7aA>AhhVvwxxX1D5f(Gs@u?r77^OKp7 zf8>O0WU@+3p=V0$m}|d!RmRsY$Cr`G%0;p9wT!>Y#ggB4-T^qjw;W$a#_);}QWzP| ziExw)o8!*~CW!QC?x$c*p7uJEUH3QN6d5x%7Zv)Qn0>_t; zF}!X#8n)Tti1lGO(r`xR6L8$xX9u9KK-^z0y}4KEOjvn2hdYk{8GlY=bbh6Y`E%z^ zm-V&dW06Lj8K;&hc3tG6tGlVRrj}M}FIU-h-YG(OZlphU2+XhRD{1@Ew0dv8^q!P{ zM#fO1)i9i&?Km-uZuD zrmpT(Ysd1`ik|i+gzfbdMs{mD+Px`%*5tqP+!?9mm!(p{wQF0tx+AI7ipJJ9OWfA> z=9YCe?cE*K=C-*-1H`VDwQJ4os^wKI1a!BAU^llU8<)4WthLrOu5PJq>|C2_wo>)U zs#MjgmZsH-?#8Co3md!E+Ps?f*6zy2wJr8tVpUIfbH^p^q;-BG(%9bI*3xBsDe)~$ zJzcHcm!_H&Osc7)V|8nbRoc?tysEh?HKVkgPOo%rLLN%@S!AWg(hVWw2IN~aasByN&Va0x+E>@OrlqvZ@^Q$2sAX-FpHQ$S%3Y3))62?c&z@aUGQE7poKp>JS)lntqpbBuwl}`Oa7NvXe*P(s?ls|gNre9w zD9W0O$m#VmR(-KKCm2&@8=VTPsM2rbOb`rM&vazmASOqhG;TcQ+e7^Jw2_>)7n~>A2lpCUaD%7p?<=#Xs9k&8%`Wm zqM`dAxIV&_v~tu3z4r-rQ&&^B?8>x`a zO_WnzEEG=F)GZ7~YeF77$7YA4;o5Lr5=(AN=i2OGGFe|!*^ms=1=g@VaoDiN+q*2L;q60{vhIT6$)Ym!S+_2KGpeYmbFOs{6UkM_H>a&2?R*xY!1 ztSX#H)YQ!<;fZ8@gB`Y;rvfM9SglF?!H(y#HairnYA}2^oq=qAD!C*cwvKQ-jqB%F zT_2opd{05(_v#m|#kEnDlf0$e0z1@kWo60dYKq78n49HPo(#S1-+z9q0UP z=VZvJNa-1si8>~&aoOz#3iY*cjhQjp;tAz06nCo{8R#k=L$y99()t&V! zTO!Xdftu@ssfPL})zWs(_d7>}b@Lm7^TVF&D8Fk%B3!SgSM7a_0`l4w>S^-3)IxrBx{1vRCP@>Z0dnqS_k{3 zXyc2Qq`bP~${aFK#;Y+$IvJYmmqDxH`gna!0wWjl8pEM}5jVAm;lIiZOA{?!7q@f; zJ3HH2n;P|C&KSn)Ss7qSpJAKZQJYFSev;ZxRjfX>kS2wZOVtL?*4+#f-Ca26Sn*&z zDX0q8#p-IRFtz8}6+n);j$?IwO}H);UE=xTF{$x|?QE!*nN;nN)snA#$I&Tn+oY-L z$Z?e8=-CaKMmdaj9D;RK5t@lgOzbfZ+f;E1Dv@fa3n!|Ajv9z22toRL$TT*HQFtnB8MG~RRz6XNnsbefw(2^cyz;?=(sysS7-I-piyt4 zA?1uXjE(st^Q;`}oQ81yl2mwcyr$m7lcM$8#zF46j(ZYokcw5OqCpvu2)5Jiek7CU z$e1=;mrS`f$W#Lf@S=i=#1$}|m#m*0M>&pkul3wW`CxWJ5iwF-Fzo3hVC)ZG_? zpkBe)Ld7)JlXDGMC0S>%ZYLz*IlK8u1 zA*ye2yDFn~C2WEx7Yv1rnf6La-HSvH@I>6~XYzN7BU9+fM3Tw4*F~k=ekkP>qN&~r zw8-<2pc0x+I2m)g>Z6@Ni#?f!x~fznxG)@29%x8a3wVFWPTfRLXnr`UB1mDMOh0Oj zE;d_36sPGa<^w$s$zWw=IFzcak1f);*|ZQzO!6cWiD<)O>jWpNgFL=lB^-00{w)z} zU?j=wM|QFf9v~YH&kt5DVKh`5Mdll$V&&5qzG91MmWooSKpTaoIldKMhNw8br5BK<$s=Z7i;tj@oZ9JJUJ<8wA zYFu)G##Q0EhFa63h?!&A%zC;(2C3>8#LjitwXsk`G;A^rfJ&)6ZD;f`^*4RtExVgjG=|FQQT;8j$4-2a3G zhyhKas3@Qp2+|=`DJlsBNFMiVeZCf)%Xj z+S_7T1<_r*?ppYNzGuq4cM>pQ-uL;xJj}z*=gjZ?=JYn_oH;N^iLxdzAC)$7LZ%6z zL<~?Sn)fzO?8p=s$)b&Fs;jCFR^k|mbMw-8Jkx|$!nP7l%AQ2mW#q1M zJEJ^Xer1{{NV&anID2Mf$YLF7SSTvVJKA5>gc%t*dD987x&eu4btTTGVRo(5tI3M? zR#uF#TpRVzvZ19lwTcp!F~O9A0B`MNWj3vPX6E=*$^b(|#=Q)(re)qp(_#nvV1)O{Qk% zPRN^OH^FLQXN?-k%eonHso$S^7~yi=$eB3V8|5hCvh+eF%k(LkQ)xrnC%%vS#4#^F zW2ko@ZSIHD9NPA=x*t!MW(tU&*iRC#MyNDP8Yk(*oE*lhN>hnCN<@NZr1H+@3ip?A z`m`z2)ET*fNRTjNhbIDA(xVL?^I?r80np#{G*i)d9!n~CsMUC zb9t9gRhF1?WQ)~cYXU?`BMTY@+d}=n8JM{?6spi8<{e0W>lxYw+lKyUvh%_sIn9D2 zr?Bc>RWHyQz8^t=nSaXCTh;hf-Z7>!>y?q0o})MXG*eM`Xj#HaW6)~aGb+eLn#T5t zl1GK)sv}Y|1x|KtLUyFJv2q`a4p}K;YUs^)Pmjff>@uciXJ$;u$YUr+f5*P1_KB%| z<*8m+&49?HOD?4J3BX@@!pV;o-E3hvBs{tBfU08MhjuQ{n<1?_N#-* zVmj5S6Q_=6II9UBS<@w$Hw$B(#xzwP!$YH?fJuWMBBYT!F;6AT?lNUdrx0Q5zFFEs zUbPg`qK^n^QAj7|(2{DrD@*!{kfqap>h;16B7H{4-ZoB3)i}-?fD0#gH<8GiIyrMZ zuT+|$(olqPTvnbvww{6} zRX>)NnyHtY8CjW3FtEqlek>vm{>SWL9Rrd)Iu%XR=4%X)>O2}79-m)-)C@K!@midk zZCZ~UYLGjTso^4n-)WkYqk3jdXEy_^=;o9UkuTMD>v$JyY+z6RbtlaGy zu4x8lH1qZ#oLOeN7q_@|3s=l=#)+XKq+Uwy9TBc(Hwzl9m}wu`9~o|+lRDE2kfso% z5C~TwD`(A4qqDUe7j<>g=^n0QFE22lpG<$N=_hIQ2-mPz6&RK?+I5?Yo{JXu$d3>+nu=9h~ z!=BsH1g^rCmY?j|k7?F^h-W{xS^J@${V~nj5A*DgZPtFcXMbF?_9Hy|an0I~^z2ib zwLjXkPi@wIlxIJ_S^LqR{e))iQ$72%X6?s&_7j`6pWxZE->aGYN%QO{H)|gnXQnr6 zKgnxZGMcp?lI$rQ-@L*QPhm>)3PU}G%;pt_nfLhTN16BC>N84f^##b(!UYxc8|Is7 zfnY%In-em!HRUoTf6{b@>3X}CoYzI<&iI}8a)uJ-1zC2yC}KBl;!IY}-4#zJ?{gWR zYQ!TI-WE|Y3o3pU*9Tq|}MRbUe%EspA=0m}wi? zG9jsuF=LD~<5|r%6Zv=X2FpZPZG~z-jW#odspE5bFH-NAlVNg0ItN7Rn7svNvPM0- z6yhTl(zR{COb#h!q;O!Qf@TCwR_2=d0foRkr70o=+O%nq<%fsn%(fhZISZ4BZLj8O7y=wIo9a zp47eB@Y0(by_AQgK$90_^QM0UimKOU>B*kC)x@<%bIhPkG@(0Cp;H`6s2R&V?E8z#9VeW>9fp~ z74yciroy_VOZAXaWrt6h!N@b0NnBdfSTkMfDo!q~AI~OVd*`rS5EVnW)DvNqL`?|e zV`xU$OLLR2G$pZSmkT;!8(d6nJ_;+%oH-*hwad-ToADwVYc>z!1PhSUv?p4PL1)A! zZ<+CAWiKsvswtdQPLoVZn3?u;f2^4hR4Ba}Ka=*F+C<76s7ZUp?ld0Dw4YNI?@9Vh zr!bl-uGUBEJ3OMvYwsE5m;L@phZbw5T_Y!5nKzq0F|sW%bwydDCfH4JCu@dyMcrw> z!W$d&U^gDr3?(6%oS8MASu-}!O-yHv0*`V{{HfWNUCdR84pM69QF2X64N+v6yyI8;6{hQK_VPc^-Dx0KBN1nqp$W z2WB`_9;J?iCF`h7bptm%GxDGhM|M4D!IEA}j?rFM$sb>R{E)1R#ym6mg8TlorvLGC zEbCe$AN}yB6K;I@r+Y`QA8^pfYu}$~Ssxksq-n*6e>m%#0sGZ--Ez)|A0FkaeLP5r zTCo4}8%AIJr;pklIsTg)UTi#{|HRqIKRxi46JCDR>Rpmnf64RKs5);~7w z`1ay&7B(Jv=)EgXBKbP={Xs(19bH~rcR(`e|>iYhe|D5<>{GluPsICK_8YD#JUv>NgZ{IO}%1b>< zFI;`r?YB|Pj65c{!`b6fU%jdC0b8D&^U1+{(RZDZzxi0NcB6k>+UA%~J8rsn-KbYA z>uV$LUNmFcNq@Ov^@TrNn>4oO0P4drY#2_6T5Dg_RX^tA1<1_%>#a`5>k>94fBn zQ)oW6IiuBGbidiDDyx|LTSGd34!K%UU0h%JTV1jfkAqo$bC~3kn|hR#;+lo|b*&M) z;(9vVR&gklwN8A^_XGNLt(}#bI6Gijt1;`ogLR){(ub3LCf994Ox4(P_j~iG3H!fu zddxxd<~@1nJyXv=ylwX6Bi4Q%dsO@vn|i$V+J%D)pPkabsBfjWcpKjy&wtbNatgb@Tq$ z7AGd0IJZ+uw}pQ>`JKgQo^@T#^JS;hZ&}mxs+qTc@P~_5-EisXOA3B}%=+GqjqiSZ zan6r7o%^qkOU|ElQvbjIXVRw+jx4zKfhCK}?_D-<@SVew|9$JHhunGN$sH=MzhwT< zS9;fcz4@0JtKZF-a@w1jT}D3rW4rGk?-97~h2J0B@JyfJn6Iw;dT8yBU*5cM z$2Z>{_x^n8l?zs{nX#zi zl7mlsZ`CUeZ@+ulyvp@C)%Sm#Sk&gn&1H{Hy6%+NlTJDDrN!N5mKD5{Tbz9D)K>^ z=VRxs{(9x?WV(&vwi zdFRCIe|+QLTRK+E{`vX&!M86eIQprqlA%|`o_Sv5rnBeVd12l5)l<%xv42d~`w34@ z88!0!Nf-B@JpRJ7tU1S)ZJ6~@%DK~XPo8kXpT>6U)%U1(x_@C^H(+wNQ~Hdbdf3Qs zv)>px;Ph+9T|4i@u}8gjaP+0mzS2JZ^DEVfVAI*Fj(cR&B|Fw7taa#F(;haWO@`JElUURghI^^(VvPdo4GOD;Tl z(5fl3zrQ^;FJ;Z9?1>*=H0`S&vySioZpX=gSpWQl?u*Yo>xzO2=diS2`@=~aPXD>X z`Q^tSGP&}ya5vo7z% zpK$YKM}PcK&aiQROgwIRaPyc|o3Bh7^Zbm!huaSxnD^Z)eHR{e>ys~xE#GixxBkyv zZ+*J)rtCXkJ8){{%g@dm{Le+F|NHF?&))Fi>8}-ha@Q9fzd$sZ5Yl^N|{HKRjA9q>DJ9k`pcf#ts z+UjQ^yc!BU;lZ2*?kYcbymaL=#xj@e_zV?cWc=4fBUeJt!K@)p1*fRFDv)U z?$1B--*5l#9qOU)+Za5CUEyE0G3?_LRu+uS)zIUluutY3AroS9A^bZx+5Fnav2Bfx zzH*Da^lISyo{Mh*hYxM`Tfm`#h|B#JaKy+FBW!(r3wW4yCf@>1c!5I`9Iu-D7VsxU zBm8RSTflcFS=Na}ZsZhOaTG|=w}4^CpvdOnYD&;l4n=s_*1HS@tn326UI*l(ALE^r zpDtbotUv;KVMnh>zLDQFbPjo3cj~?HH=(J&oOxj7pmV#U*M|G%+|%38qv+iG1O_hU zS99(yK>jv5xlc+LKYWh!DEaA9IZa7O!CyYmcRsb3T5bM`SoBfRaV~{Jb217`S4VylCj#nz4jckGpdy$7 z^P%P<3*hCj5dIAoLp8D`P_0loJP^)4zGp_ zpbi*W2sgnq;rnng{0=UMv4sCZ7=VqiA6yBC!%JZ*ybR8UmqYxteh*i`E8w5tmGBOD z6?_SDv_??*axMIlcrk^;DW#J&zvf*>VQR-OiC<=bKlY{kE2`6}3^O@wq15D_Yv-er zdkKi$+%q|3pW>)q&AsH8@<=_z07r-{DF1sy<`Y@nu!0IpU#Kw8Bu>m$b^@o9PET_2xMlQosM?d8U~BF z9}drgBcQ^`w3>;J%zb_Fc^jDyjCqsav;cqXtEf(!VRv@Qsntxns}^9jo&Op%;e^T`IX%P|pFbk& z!S70bSpojoS5aMdL%p-Ypm+sbi%2^0Qd{AcC&fzz$&N=ucs$fdxR?A@JXAK0afEq< zQ(>77Qy|lxL7mpXv}iH^!%c=ISf6&LmLst>yI38TVM02P+PU4(fh_DAqj-klKOk9~RPbJ$fn z!IekS33C8xcos;>E?N~{n8WLf{PfqCd4y5nm=F8GDwqbVA!%;az*=}3Tm~_l@>T~` zzMdrwj`ropFfy3>WE~E30vPOTZYfih9QiUeZ_WJTHij%3Fmvyu2^c_1+{&67>c8gE=0?nx@l{V4DL zRP#hS_YKD7n)+HR5jSQb(E?6Z6sK99PHT{usM7GeZW1kAXap&qD`(WQvJ{=@Moa(8 zk@_7jxmAEMfH^CQRoIFM&8b-RQ<2i*d19h6%Z_2~!iD*#8d;6^bgg+@E*6Gl_48{Y zT%3ecmxWwBEkbiB#iU)>&*`_nK*_z7mkP#M1Rpu_h2*{R_X)}7)g>VbJ7`_j$fgi!| z;K#57`TGe}UG9zB{=WS8MRr|Y1aku@*;gHvE3zJMCZn3UoO-+-Telu>!R*#!^&DwD zX4lzzyRL=qtLuwR)tcjpit71HD$%SJ+Rx0dsLCw0yHfQvw$QHDncn@W#$ocu+D_+^ z6;;OhQ^w%}Po=2XIIQO#hYJ_TVbw1cT3_wY^Yl2cTskG5fbm!@`%DrOD?L$RWlecu zE;~kyD)q!Frn8`Lsb(L8(jdiCJ)LEBYQA@0m0McL@vYUhbu5Y}CaO=g!&f!Awz{FF z&O{^Ilg_O((OBRK>Pjmo(1R?8&6hSI)9RBU&4Jltq+qv?a|R^y@`pjc-ny3PL1IsObgr* zVRs{}C_de&SrKY%UD2~K5kih|RC^Zg*J9jwYcPLUxkNu9!dbs^XKa(wjk2PlULwGq z(@sk?!V}TX>LaGa#F615BS}JX>%n?X$3FW#(F?^3YBlxAGA~iwe%49K6;kVk_a$wbDxc+#;c-y*s*g zzeaD=jfYGZ<2+PZS{43`0_VNoX)}&{shyBxv~^aABd5HWeu6ng(@(U8Ct=T#oxwlB zIJg>ifO?Kh4{n3|L%r9LTfu=a5$b&oS+D{g1TTP{;7#ygsG{2iu7$i`2A_xB;H&Tm z_#r$J{uc&dG{wC;JOK89>PLD)z0Z+>!4qLG$h)c47wQHD+@FjQ#d>LK_{{gRsufV(D ztMGC78hjqU4&Q-qz%SsNFeZbB6SjkI!z183@My@`EO-ojAD#j~fMt+67Oa9F!As!3 z;79OdIEp6k6L>7#3a3GiRSo9DPvIu`8C28wCENzTf}N+ZzXT40-@ronEi8lI!v*jM zcp3aJd=>r(zkxr&whRJ(h5`5stb#jW1B_zc<$Tx%J^|ao*C1of;OCGzpI{6x)ce66 zFb>Xx9bgbL77d;Y_lK83+LGW)FcE$T4}xmBJHZj~V8|Xa>kxPvJQQw%?EeXN&*BRt zI1)0p4UUCfU<&L8^}qNW0WXH#;SI0{ycPC@cf%z3Fzf|ig-5|Hus4j&X6^ytr{F<(v{Ueb>9kYuq?xo+aK|i;e20JGpw{EyWQJzr;P#U( zD+ON6xF!`2E98H)furDLcp^-PpTQ~cOPB?JgxRod5$zX@gE{aBmL>2N-r0X0tD z(odg|*$3(EJNA$FWOMSN`yunbWB=?gxAqW@_KDf9&p#HUBTlzGMG( ze(awPJj>~0S^QtzoOe`OINzMF_8i|BOyob%=DSQC{I=_J0liZUtE($_eMq1@i%;M) zGrqDdtkmI?I)827v4IS4&9RUFj~^STf-s2e)v?ulCK7A@dlZhkYsE7Jb$X$`9k5T4 z+`SV8b*$+jiEP%?0hT&-a(Z_D44iOe^dsv2wx zx15s*b=zH*1dgvD{{M0?p@OAc$*-s`YA7?ujMfm!-9D#Kr_y$oJNY_)%&EaO)fH8I zEL6v5BVnh=no|tF!4vkwTm0iYh<#@m{+~X>Q0EsWM2&iK)|AixnRwOdRei=i_2Zm} z?XwM^!|t~pM7Zy4!`(Ow(m6tK-`R#OJv%e}biRFO8}9DOqv5Id|H#>foV2P_@ayIr zUsybEPFi&_hf`N^y6WVL`t*jPIk|i|3M=^Iy$B}>t7vR**3=%XJzg0%5oi3ob`|=d(@L{^<qp)I$ZXCHv(@R^7ym5tYHf%ex z!v;rB_eRgL*K>_QNryF2S-O^^cdV$hJDLZcPSIG`et7BHOR#CPD03aKw%T$6+L%#E zMEZpJ&27NkrZujx!-!g1;}W@?zKYL!<>JPW3yz8SrWdDFnkUm6GXm++8`B%@0H&`< z%{BpYg4d8?w9JF|j1M!P7-lXHnVnSP)F5l=`sDaEb_$04wbS`p0(Q@k&{OxMhM8xF znU4xH=Z2ZXbZj3l@uF}1nmBCzgER%io&*W`p4OO>{9tFFJfz{8;@6}lrJuJxei?^D zSoa(na^#-cF!RJP^QbU0>E}9h&m|$V6HdE`xC%~E+xgwgm)~Th(cWoBE`1_7|8bS% zu*)gyl<9=0gUeKaxa1ADLFYF7p)mcWYmNTd6-K?$sBhTXSy4zxFV3h>Z&Y1s%*kFJ z6KAWW)bChttXHIBiyzKITVieL68Y#@$nB+DT?^f9UlAS>5`nb{#g_H78+(KeEw0;Ut5cXeO?T za#&QCeil&s6pOE6?Nc&djv^a+?LeN^xc))e%iUyCu5H_dUE0R(!geQC=}VsoG#lcG z_O#jXs`iX(8ql4%=(Ww1te@7=WroKc_et-kQx+k%o{mxPXKjydj7i$Denm{ul4Fwe z%DH%adT~sWQX~++W?57ao%7b$_xFST7G$y-cpU5jVX)lq8nI|x@h~I1TLZ3 z=sxF!Z^>tTu+5`Ctt-KOFMC!dU2nv6;n)s)B7McOB-@W=j!nua$#hBqx-{@oQqD+}N7}f^7M+qyn&( zpOrpuJvwPI^j0g4bnJ$PgNdb*!z8N=+vbsI1i++G{6z_fTonaR;$iET{ty+v>{Fa{ ztd?$xq9mTI04bUIL|&n~+~jiEijLz^liYYB!&()8g5w3ZaaoiyYsY$1G1BL4!sc?5 z{418l$!7a3*YRPSTH>-vlNMFn8u4o+kwr+d(r7G?-F~AR0Q|HaSGo0scBm*r#;g7t86n}> zDBQwv0pE*PnhXr3e9ZA!M&xNo`6{;%HriEi$9kvi?%0rCY;w;|{tK0{+n)Vt$BupF zZCB;ZE%{2;S>#9j1DBhouWUu9RDUi=SIuIREKnBO7H+*V$*om>}>p!*_ad`i+-bj`u*)}PrUyuh1 zlVtYmLG+>t;lst1#;P%6k^M?w-||*qhughPt!(mEV7p0czI1&XhF+CVrzNG~nYBHR zt~ZUQiN8x1C8f1nJQ=GL&nm@OrJz(f8u{Yh>BVTKSFCSif^YknzG_)i=4AxEm;vuo zF|qO6pWJ>+C>{!&bxz#6b-Yb_y`7@CWUZ_=V!JpFUl&Pldy)H~Z95C0ZA-UdZBL7| zT}@MJ+p107&U=I%QTy3~{ajlm{PtM+!JD*2Y!*?;zrg4|&=^!u5NeVey=Rd#fFk}N(>$+u%837EHdDCRtqsCi1t zJQY=?h0|Jar$?NAPR8x`$O}Dtb}=S(#|l*a3@3C^^_h4l5ksRz{pldDrb8O`SpUc9 zry7!X;fZvKg*-8VGO=(I#3_F9E6>CF>-c`Q-q-ObuKy}Nf!BDBLW!TfF}}|R_W^WF z^+9FRSMjH8_$oeeS<+R+EL47Z(iUNtmXz$oRWG{)Jx@hC4MTRC6CYn8-etKw%}Jz` zMMokzG+k-Ri<8PKI@@ml znXWV~sYJ#c2_@9Ll9>2acT6y4uSvzk=|#jSZSjGo_C399nd*$L?Qh}S&h?Mq zWt#PK>vAlW$1R7d%ggU}>hjYu%Z)FOZT~YtT+}Z9JaxOfax{JwCqP+iP3z!{a7+Ui z-a;@^i`}p#VV$kC39m1=TftQ;@ir%0L8knO5SjkF65b7PeI<>Ylb?U2~9 zuFdwgTNS)v>yn#5A9=Jfe%Z$cP6q zfIERZOLxSF>Wl~SEB=9)R6I%2*?jR2*koi)aS8QIDlYE8niq{&tmKf>#LC!`C!_2q z6%yx38C&vX8~aJc$azvm#e<>cUJ?^V6?;!qqW7Mt#Oys$X}kACrQO~WmG*m2RATp@ zsO-1*L?v$TiAsmPCn_EHo~Z1<_eAA@y(cR1drwpn_MWID?mbaCaPNuAL3>YBI_*7C zIe71h${~ACR1V#HqSATqiOOMnPgD-yd!o{1?}LO48mFm0o*KRF2wvqSAZsiAtZnCn|mSo~ZQOd!o{R?}^HQy(cOI z_nxQ>+Iylhc<+fy^4=4bA$vts?2UT8cJL*e+55}>O>ZY4oB6ckZo^i#f3km1-@3S) z1f6|;5zn>pS%y6q9cHBsbrH|S_$G2nz zt01yVn{QDf_ZueQ;VyUHPO`U2vVE1!@|*0<@}V89+IOn&803sLy0VQhP5UIH&4$-B zLYQf`P2Rk%OdsE*B^B)0bj?^ehg;q6e9P}3%a_cgIV+Z}+~}l3xx242eobD|96q$Wh3)h>QEn2h+}Y&$ zzfN|#`Zjrf=!hfBxbcD{viBf|l1O`y^;OtlBu&YBi_mAEHf`F6gv&?`PY+WlDhcBZt@tAqB$E8otM z7JAibPrUN&>}a7^2k(hjzMU5>^olR_cR#OuJ0n`?)uDUhm2c-l3%%;RCtmq>7PQbS zM$EgPfWDRg7J7B~o_OV3nQx(2UG~H)-^zIlz3RFrUintGTj&)>U+jKf`Bt7==+zN> z;+1b@xP@LFxhG!vR&HD9RbWrN@~y14(5voy;+1dZvxQ#u*b}dOE0Znss^^|~Zm>O%C|DsLa#W#VE0=K-^x`Bz3Q_kUins*TIf~Z zJ@Lx7^3y`E_-K6h6VSIZ(?YK}+iCZ`@~xb-(5nG^;+1b@qlI1#+!L>SD-SL7in+ku zPe9+wKnuMZyeD4yX6{?)6-Qd^eyn^m>n-$Z$nJTyP4mT?ecaiM@;N1%UyYbe{?(93 zfhR6^zIXrC+0X6E34wjWNcOh39^J9S{lwop(c=+2l(Vj0`a%2X$2R;B%?I??Glj}b zYsrocD^@1m$W7?f4yL|ko7T7qldRG>3NP}o!d=ctk22HGIxgUr2zND?ED6Vb*b~f= zZf?IX6olRJuGIFfVtsR`T6pIGq&rjXJDHrfPnG0&iS+1aQr9JtU}>Z(M`>=>TfMdY zf^Fj-=HMpI#E4xKx9&mrV4Ee2lFF^14xN!HXOd-|9k=cw*OpXDH&5%#ozPl?j`m1j z%u6qbUqfauUm24`x@>=QCl8dH#feo<;+9vOGzG3x&om*=Sy(zaj;Ax_opds>Gmc_6 z(pEJ(Iuc9woVPWBKxLYFd?_0#$|JCB&H+cZ(kQqAzI83y<`^*7UB|{3%)F#b)(-wh z=(hFzmGzAHRW-OtRB8e^4eNo}TuSPQqV)JxccLL5cXdn=DIF8b>PY?B^qnnGrAF7c zND(({7Pr{Vnr&lA0LoE)A|>Tvx1=DbiCP@D?h#k8E3e%n*C?y@@=-IZDYLE)J2Hhb z%~^?+97!3_c{}wg+BI&`-nPI#aHL845~lQo#fudZb5_+QDjA&pAtrcdf2gsMA)+5W_`^mUbvK*uz1is97>3$(Af(@ZV3+Z6vyc?4T-(uOw{%b+iFQDw<&8(si!%S zW^*OM4k^b)sx(mU6%brJJk=CW=fGI|d=R@f9~?SIHe7t?P92Y5wFJNY9?V1E)VQXR z&E9oncROg;Z96qAIozYdj`PxoBg+UN$<$vbJgp`HLX9cSt^`e6aqnp_byYGJJ*b1X z+=V}rU=o)<$l1%0;^vY|nx=g#XfAQ=!bE`F%vYO$dgkJtr^trpGi#+A`d>?o`}~O^ zK}!;Y2<&v(HGb7tTv2p(*64V(R1FV#Qeu3y`Jj#`i%8*}B&E~9JtOs9_+^F+@`tm+ z-MscW^`{-9ZMcaq!WB(+rvH2b!JW7~Ga-Lr95g=6RLZuH!3HrKWtK`GvLCoN7( zb5B(`q9{wy!rWUxP}N|BpPe-AK&5;$XD5xog2KDIXD2E77PwjIcF6Pzix?*S-EGZj zpmdfN|D%ra!naPoEy2#+CeG~S3^T7}sr@ItYe7|t>UI{g}hbV^eu(AikrSQ?^bcsx47LZZu(ZSTg6S^a&@b? z>06g>6*qkg(5>R8Z>70a-1IFew~Cv-wc}QC)3-?6DsK8#gImQ--?DG3xanKpZ520t z3%RZ0rf6>t>UI{1+i7!^eq*( zikrSQ!B%n8xA@m8Zu(aFTE$J@a$c*r>07sJ6*qkgbgkm1ZzZl(-1IHEwThd*wY64p z)3=EB8{OQtj_DXpH0*4(EdJsv(b%1-jAqx$7Py}Xq{gqgJV6U2d^(^nGF-Vn9ncpU znatg!XEHse8H>p}T6%o^noez)%~&2Wm$B^xW~~Ugv&e>Nfmt_MuQRx0?J973)z<5B(1no4L(@{4wHj2)`Ih=g~J9Qw%nT z8Pfrnx){@BO!`k0W2{_EJ&h^fGtKi%=X<6bJky+RuW$}NmlcqB;^){w5 zO#O}Nub6_y^gbp#R0s0EDpVTT;h5}D-HPdOBdcb*{TySu0h9g2>zL*n**`JaPb}xZ z9_K?F{GFNW>eXVZGO{x<*?M<*wohTIHnuN#wr_d1?_;Vlw%a`0Q}ZnANFzHJlO4Y6 zJ<~HYT-n>6Y2r-FI>J1$43izcQM24M&GJnD@Jye2rrxvNc#OhynsFrslO2x=Om@x$ zJ=4ED(@&mh_=&D76EW2qSEgb*%$T0VjOtvex zVmjQ&{&2GE%6~l51d4<0$CaLGyJs4g@7iAGnLhDMV+&l{i#^kap6Td9*S66!{nIlI zD{^fw@Jw%eroqLo?NZP5x@YQN;@Y0$nf~FKdY8JkXL+UnR8AGMZLh&(mxIli?DFzHrg}^DavLVQynKy`1VQ!#CcBM@r7GHO zM9R$cRWvbb$OYnuVhn%3%7f_J8f3UsqpJQJr5? z%m43QmS0^{Ur}9E$N!>xAj=KSU4fKDY&#~Z;kB>)Ec+q-Prik7OYti!@hhy7T?MEx zyumM;UlKoEv;skeiy9qN*r=1i0Z{*OX$SMPOmU`3RxCSMXYyC3IO{6@+IoL*OmSAG z{->BsMh%_QBmP^(nkt8t^Cu=oK&tf=^LItXgZhDx098an8N)4@*pcJ zKexWNv~a$WrXxMomQLdTO)jiA(rl#4FLX1jiwi4DNt?t(($%VIXQZjMb2BUI>P^-V zCM=TqxtGFw3%~HpIk$}!R2-H<#e@ID(qv9&%y#C;6lXobUt6}(F~wP-CDeEFgb4H7gPpk_$1h5ajFnz0GSOCwXHrVhZ6HhMZ;~-(dM5d)6pS`5^fD&h z+om~~R0pE10{$vJqpcFpRE|llMzpnXAqcw^cPlDPu$xBzqs7%U#9U>Crnd6NQ11%?b9 z8Yr$Vsi>MOtNud+bqnX$Nxh-2G|qXxqN<|4qOdYBx3;>W2CV^slW=9wAdDvu2$UDr z$x-uMpI*ZU4Jqr@t8X0MbJ_ma6xK;)OrWmf%+f%G%mZ+&Mt;-<3TsOP(!~whWc#w8 zD_U4zS~n&zzp$o;@R_F^`?}J~(qaZ)wo{fx3`zr)rB!q5%UzMtlw5*vcTGAV8xtt5 zEe;$TNM6t@dDMadq{957imK9*z=WI$VPX^JV;wgXuCj_M(xO@IIINuz+UNtwjIgV3 zm}GW}a=pwt_~7La-16hSwH2ASCOo)qanj?+dloVNCec2}I)bC%t_x`UA zeCy9Qj_O+W#WRg1Z*J;z?925drtDZBKkd$gdcSvf-xF>>)hM&?ml+- zC;xeR)1ZU?{(iT`$DOq0)I|#ib~*5%@}%eL2hYF8>M{R?6;JH{`7P&ueqYbaiwE3( z{%zl!IpfROkLNYqo!b7;U#x}4UwvQKjVGKtBH_h{{~Yzij1RK!{l_mi22VNpj;&*s z-L|mrn_mz8=E_Su^^4D5a`@aw4!LW3&9^r!>2Rh?tKs<3-@lif(c|pmnI}%&`k9-E zDI|T(po)?=>tmvHstPS-S!rSYpycFBqN0MfWKc;h<-=}il>X6CyjuFMK_yD3Bn|Tz zAxh_+NtQJ#LTgZc>4N&C`Bf4sPokp^=8fbsOgB&Z^ess(D_lqU86Bl@gM9rd{oJXx z+u?q-H98yl>$Yz(mSo}X$R;{UqX~uVv$XQ(n!3~8=zPOp`Kqg36L(^fMn^5sUw(rx zy7=a%?&u{XIx3a`yY9pqcMy9LYO)E5J=0;^xDxeP_T@^{H$_THocngh9e02!VXWtJ zjiVFt>-;8?%NFyei6py;Ig|v<}?jR z&83`dXN5}$l24+tVRVL=zMeakk1mLr>k|JY{qu{4)BUU;S2I8fTYq`K38sUACLye(jGm z^51qxqHB>TA3{2sT~_Eq zIvbI6j?j76k%V-%AxVnR`36ZK!kt(OX>x>47bJZmbOs?&s}u@Pit|*+uUsVQo=$j4 zI0$KU)FtG(TG&o6UyuWwtCXj7869I?DgA?<{e_cDcWbn=J11{;<{`YevlD4t( z%PQ*`N|)$Pm-5SuZB)cet+Q*l?n2j~;_`WQBZnKoVf>Ab+8DBQOvm6)etvCfO?7R3 zer;jZ+|uIm(&Bk#g%y(le|<&$NkdV9$w80Jnxz}nKfy77|Q_H`M&rOd3Ys4q45 zb(WDSXyXg( zNHA&SmN(RwRG(2ricHQ;FRUu5EUh(9DTzvp8;HZge3Q=k#nsjGDoU-ShN?3vs!Eb} znchjJzx@>**P*aUS@*dxkuyL`qEt^SoL`!hY=udPR$6IYakywwEm~>n?cI>NLp;ZE z@7D2OIU1RVj$$(wVUHArWpda95n@L@GH)GapU_jCX?Y45J#nZ!c-CQ}2sKkwBD8FY zqZC$%9HlTxlVTN??#%(76WiteqKS1XoXBJkkU;!(;z^|tP{l)KF);0WeDH?$U^uk`e zC0Dm|BRZ8I=uR&jgfD^cg}r=BuGisP(24p`cXn6UoO|D3cQ88pePq-u^|{Ttr-9QD zbZ&L@l$6c6r&r^r(RuM-KKH_2i)5qW()W&ztto$#Q^H?PB-c=R2YMYowzcH1(QC%N zzK)KqxpVi1pm(g_y|C9CJzv1@By=8f^fZ)6NyttKe_26f;_;%RqkCODi^uEeedy@! zEFN=6zo<_v>tv11xKs{OtfuMm85VQV$^F!*S!cO=zId!A;NAaYSucHQ>**yd#UdU> zb#=DH{;T-;ub`E%-mBq`rSk3Mub49Br^|#dAtlAD^S0QeOEo%Y`1QgDTT-p$x5UwL z9wmH~=db~nhuGX9Ndhf6~ zwW7GTx~{scKF}wpZ$PW(^DEBOyzT@Ba}|t%>~N{HjPfm1o<-3bKsXy<=Ku!#vPX-0 zTw_5EvUah;Y^5af!eg&6KS9%(6;)SXJD;5iiHYerM?evox#3)9scDnvu~#86G262{ zy|lKdx{k3K<8XVK*?#7X>e_je3N;(ebU^rmW|g_`g9DG-{&7D#aWnV2va!&8hKgI* zy*@Y$zyG7}{u}515OPk>AMO-$_ddmUe@fWByGOzGL;fgj%W+fbTj{uc4V{7R{{*$9 z_GefI{{m~^O^}Ylx*1*z{|X;~w?e&=-3C>OZ-?K*JE6AP{S79LiiAz2mcPwgpb1W;d=NxxB=b(AA@Q= z9*2*^C*aHQN%$Uo8fw~$ni*_Ex@>~+@EO=0J_iTG=iylR0%XzIdJ$?ufxHdo!Pike?XPpSKybV$0PiP`^tDF{`Np#29F3}u&>B6ZpwFxYZpn%cPFbYrNUfEsuO2a z)EAeVQmiK+1we83=BGw?TERw?jG-i*1&{ zf5X4QU*KIZ4nJ2zR;R7Ip~~64urs_5_JQ}q;cyKc4IhB|RGrP5!HMu;I0HTcwbAqM zumL^_m%{ZBx2+BEA@~@48a@tHPM?AwKxC%8ZiK&ZzX^6EeV&1uD0~(k51)f4z~|w~ z@C8@`H$#;J+%)Bda%~;$D=&)g5y(}qjtpS1ugLN;v8rVEn?$!23vabnI?lVT3^mqV z?!9WgF85xgLznLD0wak=T<)dttGskXQ0WL?Bfg5$8!#EZ36FzsL6zXQVFi2_s{eWq z-Vgr?H5lCjzlG#MunlfA-D}#Ne?hn2jq#-;d1yA9k@xhxJZxWfI;NGnZ>f9MyQl{V z^)8_vr3L> zn|u0-;28KF%!IU|!4mibTm=6IuYy0q`{2*;RY;jN^=t?HhI{-r=@|vJz|jUC4x`~w zkgdx>osH8Lrowh`Dr^sD!&q1fnKlpB!Z>&?>;QiUsT;vR!~G$3+ByL0WRe7^d`X1L zzrXVv>C3;nsV6Ekx5K0W2K(~o->c@s9#c3dvD@OnG8Js1k*!!Wo44u{Im5%4C+P8?G|j)sqOKMKAEN5g3R8UwpP`ZAM`$H1A~9|zBZ zhEG8?Xx5L1wAe3A*f!>MopoCek2Wy1z| z0$c=h;JGjlUIu5ttKcknD?AY@pHG4+59<{dUwPRXt5NKmAZgi7huLZ*XQ5};A-j>(z@-3Lv~jVa%1nF9n{rRF zYPu~=K&txdRKe1E)@kekjW$FnIAv7RQxdxqd73VZ@tIRa&DbWvh-GD2N(<%5k(k~5 zn;c_rK1_!rkxzjIkOdeshRK2Na-Rpc!|70YI}`SYv*0i|8vgIvX~^Ak=%!639D& zwG_S%mqFF%^Pu8-KHOP5q**)p(GLy^V6d-HnoKUOcS@?#g}Tt(<)ljhyQb-)((R^; zDu&Ybs6>_Ru!=Ftdo;XaAT;{|?P}0mJEZXY+o5NPuj2F^RGEJs9t&T9r@|NE8E`Ya z5xxZPgD=DP;482l?!F2Sg|9)S&+Aa>_%gp_U)j2YdMQ6|76TaUE0m6{R;;pd*-6fZ zGE>k(tq*(4j3f!2P=n%*lx>Nvp-c%iFm~b8*tZYybT7q8Y1;#V+5}w}lLm_CrSNEY z87zdqhYR2p@K$&gQPjCpl4vvR6K#j%z0#AWA!i(X}koO+z zukd|%D^xpj8|+Daza0*RcffRbCsd!k8rH*mp!({2;k|GT{1iR_yAZ#1um^k)(*Iiz z!9w^jq~Ea~f!D!D;f-(uR31MD6(5VR_}dxzt29!()jJ?1bJ=CVtm3s=r=)oy6$m?P zo6ZY`ibiNuuX&*Y@0qZ9A-CfRl^nNo3Y8RfMS3R+?}}7zwo2q&ioeRu;oQID$gYjH z%grC5>Lh6zEP#K38VlS6pMrmdufSViTjevYVh4DRoOdgomYHAcT1 z^1g1}19=a(?u8G*`ylVL*8T8p_yGJAau!-Jp73&DUhok35S#|t3}MRA-(dy!k3!|= zdZ>K=h@bz{k~gqdzH6?gPXL2`h2{IN4DU5UFuB=eAfkM9+fZdnLFnFT1j>=v8Rs?v zs^X!nY_1VdOB~ADc-##&992WjFhhC!gVdZ$aa7)R<^D5A_6%vFcs~c#CcFR(;fqjh z!e;na_!4{oz6?Kx|A61aSD@a{UV{T6+fIUW;G1wBdif|>9WsIkRXsPX%Dcmwf_SSq4MzGPZD%cU84flt4!UN#nVLbdCCPMX9 z2f~BkK~QzB6C4K*f%5B6I2U$?r^CZwBRm{xoZkg9KWTM^AHgG_#`8x))wKW|346d3 zU{4r?N5K`aH@pb;gBs8Ghw7IHz$f59_%%$1Kf)n!f6`+pJQxmxz2R^;7>cW_<6cT%mFvz3o^ym-$q%LZ7w|IpCHy1&8r}oHfvlTY z-@+&0ckp@mJ^U8_7k0qSAED;Ze}cW>&rt6Mzrf=lZ_dFy7zGPp8>n@pw(xw|4qgJ= z!^>eD{1fZ|Z-NIv=I^a|sQ26isB$zBbBeDVseULW!K!NNOc_r@VaOB$l9bRCx)XGwwpVD{Xr~%?0J1U0TrhMH>}0(--uQ1c%npx#eL zLd`uM4Nrn&U=bV(Ri4<27_5WG!UlL8JO_@0DrXa*%2^t`5>A8)$BF#>V+_p+&;*)q z!-oVg*q2?7SjnEjXE$0A+xhq4T1^hU+o_him)us`(j!8BK@ysS&7h?90(=`{+o!`;?h6ng#Uv}6_S`c`Rl$Drv1t=>qv1vBwO+M$A z-~O;~Agl_{V^Cq@=l~P;)tLS1z6u!)t))r)5dr?#mmPNYeAx?WDXu({q`O`NvXO?r zOw0=1J1-LjNbJbzWkU6RxF@MHzDSnj$;_Oo$t{g9<(_*fyozru)Y^`&jl@rJcm^u3 zo`o~vbFdUX59h%b;C%QZtc5Q@)fM#*{yeQgCO0*|Gcv#*`?AyJ471;M*8|W!O_=5q z0l$?FN@w>{_>>OqVVWa+jrb_cZ^Bgg7EFh4!)fpxC^z1P)8Rj%;;%IF$3G4kF9If= zj}Bn4FFXEal?`>}ztT)7{s}zf7L2eyJlS;(${&CE{fKbM?~h?D{KN_8g_!-}d<)qT z{9fTVD!?E6vcp;I&A%$z&0J0aF2KqSr|O~-&6%dJ@s-w4$+YuiL71xwi{jD|Ryy*} z2)n}f1?&&MgsRzJL3#5vEQ8-bmCbKqBm5q!tp5Q20RIOyZut>D34eylyOsR>X`(q@ zwOzCMjSld~zU(xy7bA8(_v*geyJ@1~VILf^=VEc8s$ssF7nH+xy+-KOSH;V{6c(k4 z^79x+cvw5TZ9N2fIN%djwS2kA#Y&2B2eoW1@4Ab>*k_xI=(H_GQP>zms0E z4KH-AHlzgTbvOm17ZH6v>vR>S-i60U{`%uXz6KSR0WcGehBF{-QLq|P*MbTsG83PB zG5gn@&PLXqpUP8@0DtUD@nH*m=>j(BS5GokPL-;ei-@QX3}9tPgvS<`!W+uD;$;}z;T_DhMfX7^{Ti4G zAAo9aIN>a)e0>lq&JRK5wbE^bje8$1LSzyK_S3P%xCc<<*o!WZ7-k;!ef%LfJcV_zku zWrdvd!IvKFd#ElpLEd?(RGmxVLAwrC*A$-CP-?PMF>rFYzI1+_$@Oecrth{*ryTH} zJ>9JLjo?0fl9e0fr`jU-Qn-~KDhrflbCnZM#ias{gQr5pi~iKaKZtp_FaBeZsr`|c zodW!^uTcEUYD?{9v4CqANy@UKuf&Onz6!VkYzqrZNA% zsBoR;g#RqeNBhFB_Vx&VSMWPHz#sc!Ygr9n?dMmOo{?|fdVi%lx~=HrlqKGuO|Hl# zC-a)GQ}Wwir_La(3J+~aupc}Vj)a6gI36y7C&0zV0-A z%z>Z6v*C7l8~hBu20w>dFZmDr7UGuKBSSg{rxH%W9@G(zU&EW=H}FY_UqPki4^U}d z#BY$VoJ>NdG*97ocz{3lWk#!RDG9jJNYdh{P$wgeEYwQNQDM6B!(XOK;yKnAR_0AjSea+Fx&%?9u#cQaluh2J!)itIzrnoARbON4@ z)D3uNA`;+Uzt9F&P34F0+UiT7D$(Flvzi1O_+>?%SzKNop?Nvt>-cf0`1OGSex~@@ z8@$>@=*#6o8! z8McQRQ03!zsB+ZE?-*Y>N+f)Wv*s+j1~Ax{DM!w9u&*E`xH^$^3Q_>6TaXSTPoyMS zSV4+d`?*94&ZV#@PvW^>=E$-MyTW$@>;ZG(KsW=Yz}Zmm>dbwa!^>DRFnjEoPY+&- z{1kXA%!g0F0!W)>6~Z?7RRr6^5~wsNg-WZt`T56X?_jU6s2%DSz+hkYOuF}B=C9N? z73pjqY-Y=3c)E2*CBV;@Zac4=VdXrQ@VS@5tTa`)e{zKLh@Y|1+^{`F_n3S5EXL7Z`Rf{A=KYZ@Hjz*Wy zo%M7+(^dJUr{z~yX*ndc(84-JLv2-lRdv1n^-B#7y1OIY*Q)@stf+ZIBHG5~ROfr! z8}C(+I$^3edd2zkl1+1|PTF3aDbBC2H{;-dM2=Q{HYbRwVkU=#b@_#-^TD_ROdoHz z(Dsr~aUG-81*`~Rb0jt?-b3}(^?bo@qR6UdesyJuS=o$5A;6C&I4l(yXK2wU0Sh;@ zRb~X7Z#E)!!)~}|SL=*yyzhy+V@DQPp|L6AN&m;`6TVemva4xS7r zL%!t-&Vq%o7?!{)SPC0p8C(L{gAu$CmcuJx1$+pe3ZI1Y;LETQz60mO_h1eD7d#Dq z1?%81kbOtNp8HWMVKO`&j)7;wGX7I2^8oQy}Zx!CZJTyc%8tZ-JM>N8x3#Z3o&*m;iqdPlQ*%e0Vji zg4e*`!E51P;2)s=W8&-JGw^!&I=lgX2>%Sff`5U(z#Cya_2wqn1+v~A9030c$HLp7 z+T+`y`rz~UrTE(I?FZQH_P=1y01EciY`dL1H8sQE&WXE8`iHD zP*>bb;ZWVnKtTC4*As+W{p!i<8W>i;WH_5W3<`u_%07~Y1e|L;K6f4<2x_5Ytx^?wT_jdet5a2xyp#!|mO zgni+^Am2V%A4B#nSf9WJa4WnL@=S0o+zy|BpTQ@o=byv&)a!r4qu_twWcVdar=ETV zFN9yiYv4EVI_kx@@Kg95{15yAegpppcfg-u9Oe0EcqIG<4u(76B*?@}a2bq(S3tfw zH1#AJZsI-$z7N~N_LT2-up`_L4ul=yWXL{_;4~NyPlO3@9!!J*%Ikq}96SgXK=ykC zE8!uqJLUAy|BtBo^8d-BZJHL6mI4KeTp&PzwxkbA3svrIlJ*AD} z-ID`uW693NfvC95Z%LD;{z`tLTXd)2cfXnPNf~Z|&W7F!JqP+8sOa|&sFd%$P^rf~ z#LwT?;GR2uRV?>82J>SGnPcrWa+yO}uwbQulbMCZmLK_PT)a%K@ zhc4ZU548;_Lp+|9Fc(C3cp1HxD|ZOo?qxK4#brDHP#GV+XJSi&!=^RT8Rn47HG>Vq?8+YpzA}RI+SLW~TiVy^3)?46 z`{;Cu($H8_iRK*IH`Ok$ZK`dku0;<`_{4B{P+`$Y z22C|JR@XK+*EOu5;LR;fttM?(_!66O<4P_3Q8w~q1J^WGw<_++SsKODEtjNfS*nc9Ljm*I>ukP+lS&3f1Ou5ep+h)wZz5+lWPxP+#Vm zHn=z%+)|@mB;}b92}#vycl?2#E(n&@HPp~r(rn4vL``i|a}Xmv2`mf;CaSAzQ!VM0 zb-cEM5Aqm^qOb(r+>}VS>bAEDE)ECRCmL3?CRWrkshH3S;n3FR+9r7=h7X+>4oxMR zn=fu`s__|53Wv5P(y6-Dwe`(Da!Forbz^;F6Jx?;JUJZN*sSU&^(_tKQlK=&MbSmk zBz#IZ+_ne$*;qs4HLG%n)YPz4s>BeOjFwT4}riBGlElozQy0JkOQHG-AGd(P| zx~3`J*i^TouEFcZ5#jKf#)}*38xu9DL`%}Q!;G**Q)6Qb`l{ODn)Ar8fUKzN67}ij zb@jEX2d=e_3QIA@S6`C$y5eMx9xLND=0sbenPC}vwYDkMRM(7=tMP;3n6QW|?XkqK zUMNGlxoeOqH!(2K+tbmmuV@h4a_cD)R>xc8{EOsdbWCO1EDWj}o6@ToQW&}P%ESe7 zCUh7?}{Cfa~RLv@m2A}uEHBnzvG(@@Rn)`r^V>V!3fB2wa# ztYs9ah!v1AE&`LSfM`Z~c~j#`ZyzMI)P_<86Q~MwgpE7JhU&m@Wu0n4MkfucQ(`~q| zx=dETO=$Nvx2ElzgVe^nc%+~gwbnLWlCE8ys%z4G(u{s%93;HZhPPl1(v8d0_3RO* ztCQGHGyRB6k(JRg+t8ABHb~V#1d8(nbn+7GCxH`eAk%A8ZF7>HIfGC1IMWWcqt+)k z$t9O)NH-)_)vb^Mi^@rIB{q;j*_>{uZNW@m=+m5R1JRx81YJ|3_CunT=0aq)WDY!M9ri~Ovy=@xR@XYQ7T0$GLwqT)Ntl1<+DC47hQ)+t(t#{ba*HvvAkCGUGTDS zV#&JZmd2(_mh+}2)J!J+AIc7Bu)H?W(%MAVs8Q8gVg0>8ffu;6u|a44RXJsn6bik7 zsCAl-t*Ms;#O_LXQ8c`{p>Fwd2^XU&;l)1uV$6Hv#dt|Fd#kV0%m*cm)P$T=?J~@6 zsxj4?TA65IK2twMjGCl2(aSBXP13WC%>FK?Nj|Kmt~s%c?dz2nrZK=Rjm)M#rxGtE z?DeX>n-nwM#9;6^qqRN7hc}jR9%~9?93HeZv{#^Ge26PrOKm;oD5tSv|0IoLz2x%RS_}h?6Q4gTRFrUfEdFT3@S`5STB+XcBee zge*_6zL6}04!5SZx?T$?5DrRpdS!DpO3K*Pb(@DRCUp_4NJSG)R3=z~iv@0OsUdp3mR7(C z0xnO<WqY4eHt5z+DP1CMSVb$yFmnF~vTtxg{oUDe%CN_P8 zQ-~{4bm4eXZow>>4=|%}Ng>gcPSvuyLXl-9D@`FG1sWpSP2RFz7O+r3W_2zL%6u^M zXi0(*t#gUmS0+F;uv&EqFYw{0Q&R$sS3Q%ULLbCpxVgnnn-WswLsSPPk}M-WAS#&E zPOWdQZdq+iuvpmDix;t2SC32P{gua1E|*4A?F#SZNW~@4mr4SY7uK)DU6?wp!S6fR zcaQMOKlZ@n4zx+renjRpKufxAzCSP0^M%+-6J8?c%b4#}dnCqWLHuwLRTs2W(AuUZ zoLOmbfu;&XZ`37N&^hoh0b3g`Y>=7C6{1|gx_SP5hMq6hUXqk5s=9 ztWYt`hi3anwN7STpXx0x9~LtrQcNH@DU`If2{S9kPXd`pa)H*k%G$#fkqIRiZrJ4saq_s# zF=^U6PSi>?u3S;SjP;gmUx}ZBlh@c{9Pirna<(Dsd5Ce+v=ip5`ZDv@CoaJTFRxpX zW~OSuJIC8cmvxIw?PWc4c8xkZg*szg(74R42gKuGS;wND{gkH0di(@&ow;><(lik+ z3=Sr|GO;=>Zt=x+HEg8Jv2ltI8mEToJKd64!QH7Qi%AC+SEo5G`$Ns@)=kW>L0#jx z6*!yJMK)4_d|8>~Y7+Ib@>$hb&+Y?{9GGa4I^;()J|Esn3p0-F;iknwNZ6<);rjgf zsOpI>XU&{Qsr6`L1i4*K@g?z$8)UzQ0dWdM!0mRbz_MC)%iLl^_V;{Y+_tBRISDd~2)W%)6~fLrITaEYTQYQ;pkp%> z>q;*);JC^PON8B)s0!Of6}g5aPq&h8do(}qkf@ktN!0C_s%WdMALBpZfjLT*-fikURPT) zwppD9xm{KjH#wP|8}Uqa$4n*$N!abRsw688-67Y-o`kw>Rt=Tbq4tt1ro5(}2}o?W z$Q^69V@-atKi$wGu3lp^Tg8nHTyLUly?!4TmZra1TQ$|D8k<^Nh1A8BbZ3Pn)iJ}& z8xNf=Xr>pZZpViO>#U!cQz4n9B)zwU#f(`HXGQmfB>aSMcvIqHUm)3E5P?`&fUaD9 zNez>&F)lLIiOh*%8FTFcZ+`{zt?W&S#7SWZbIAdp9dFl}i<6@QD^u*Surq|aCD+=j zYuRn7@pZ3=3d;qIbaQJ;SMG>8oj7GYF;+FT-mR8}g%t1914^3O`0hFFfPzi6dLhH5 zSb0D}+K@%NSGdy;C|F;cUo&fckBBe31(dt~TNsuTD}a|K{$@_nS?aUHlDdB-8-%*2L#3T@Srn1drLA7ul(k7NO(%U$L|XP_ z*)|(9O}X*BI4r$r;WGRhG}0^xWIZRtAtEE2{9bXEgk!rEWxC3TpF3{&JRg4ExZ(4C z_|kF17x?hEjvKzvhreyy@UwmR`QwH!^5OAu!_V>IiE+ah`|xGshA;8q)#HXIe0a^c z;mdq@?YQC9K79GO;Wa*d#kk=)KQlRQ_;PPq>c$P9SLFpR7++wX7r1bIf%#sbetdxi zx{m+)VqNd{Z|EA758ke9-`KOB$Esz!AsdtRW_4Xkwp=buFK@+7m({i4EEmD8|IWG` zS3(!a62?N2u!h=;xuotchqANZjC(2`kBG2ZL`1K)5zEoa_p;SqBa zos}YCy3Zxi@nnokqPxxN2{XF&<`6Z&k|T>pqSUTtUaPHNjtyNQM%7-Elgn?7t#XgI zNuOOxgj*YQubyk_iDh^ex@{v#v0Eu6V>_8-mT{?DclqyQ19I$*{p$Te90hV1V6C7KP zC3eF@d)w{Yro(SmeP4m^Nc`ScQ zrpc2LDK;@=bF)O}2%nR9z}hOZwps9+5R_4`SFOyZuk3k?ugCsct(I=OluqiXc}iKYYESp}44FJ*(oC1&I!gh# zdqf-2_nEd0Z^n~+BHhA*xkPWHXzCj1ZSUwBs_q|5 zcFJ9BU4uOxHC=r8n@|2p%bi3V)dTGfc|RAA;Ip^f)xKWS-1|2?L(nYG&gkjSIjzZ^ zPLrB7bK^q`mr6`xD6})}FYE8`WjD`g{J07)8d=7pDCQ%KqNAd-vOCOHs9r8| zI;>@-Jw(BVN!xzqP=Yn9#zy?o2Ca;2t%Flm8T2Tr?8=+I#m#MI z#~9OHqI<7)YIqg2-oFlsMaE?d!LpWBP}{i!;G5i8M~ zZ;%PyccXUXRDxvB&iaBfBaF9W#}c?i?`b3nu8TG>@-+HPVAUJ;TDjm@)4Wm@A3LCJ zCarX_xzJFeTai*qzt^Z*F_*qp!ysBCJFJMX6|21>RlSll>P;eIT12s1(Rwv4V)f)2 z6j5Xk-N%uhG|ONuhIFO*0_L$qkiFpOPB5E!t+i1Tq(f9pp}gQeC5kG#)S61KXlmq_ zm2P!yy}!Vvoh>tn>qFbw#v;X}$iC~O0@nCS^~B7G;+H(@-}PLC|zI%ov76j(%upky^wJvSE8iF^)i$yo+yrMJ<(jbs}Tvgk&<0$ zGaX8?q*vr4r@Y|FE1%d@i6b}jsLhw#uB_FUo{&orq~$Jm=)^Wt(n-q~Q+XDwy|*hp z(BIRS;YDP=xpfq4bzh=v*#enQxvXFC)X<#AzP9Ly|5!BZhK-v~*~}ASEsB42=LPc` zZ$0;GE8g|MM;|)#f;HR+toV{ge^!0>w_p9jlHIe9SoGl^U98Wrlg{#nj${90^-HrS z56s$k!`UzY6VGFjL3zQ(!?xYEBk$DbAi;k&{ho`y{oUZS&YH}Q zuLrm6((l`VfBV|+JoVad-t*GcBPSgFg`3|_OV8vUe3;yw6KGS;Pw@&VQ_s(nY{WNN!cyaTT>(5Vo_mig|zVDyc{Pf8G(sv;v|NXC= zGI7Z(TMC!{Z0b{AczE$MJjbE(C$3%9@b*vKwe#ICf4Jhjfx{V`yu%Xt?YI5wqu0;* z{BQTpS#|eYzr4DO`>hpU_3nkwteV@r@!Lb^eeBeK+ROlak@kFwF!_L5O1_WOzCI>S z#!#$sC&Re`-(fqkpYlhda;oC|~ zH$$0jc>~x``#{g!?l+nw-;3?byeY}7<-@gaFrgu=aaZRWNhveb`Q{`>1@#S1Z!k4l ze|^{b{=uu?c&po5;s><%^5x+-S};t(8vSDOn~@NotLYNkvf)in(S6ie-aqt4OS*my zz1q{?k?DP-DVfHTi~Vm#O0M+FX5QAw9I_0=`1Mrl!9G z54H~rw4x`I9A3MonNJn2ukTsAW@xZu&Dv{v2IliC-*4=|k_Erwk4M*7t=3PwFvjEk z@aOS2MZZ@mT&d1I2HVOEVXz&Rn<7uETkKAc-R-fR9(%xJyFK=}$Da1sGalRLvFAMY zOOL(eu@dGFQ@*K|E0y=&>+@ezoIxKSW+$xVmxd3HqE!fa;3p% zJ$Apxp7hvWkL{xq&)2xmS*|ol^DLpkIxJTjZ1dR79{Xi!5X3d^OO~TurZ}v{a-~6= z$2vVW;IWLyvL4&&vD-a%hsPH4%waeUG8th2Rl?JmtR^_oyo;zHoal0)? z|9b2>k8R|o9Mvkf$#S$azL&u&ELR%rhO1Gz$1PVHY{H2&Sk`i-!CqFMwJP_tF4wqETCOzMfpcuI+bmZa?8Nt6p>hvcj<#pTZ?I0wl?J=u zk}CJ8@cIq*vgJyHt;d?@eWwK5ELR#l0hiUdU$b0k@UL(;DE1@EQQzZS+@~!E zHp@HV-5!gb z$-8tky$Z{r2Ob;n*j_l6M%eqOEms=M9q>D_I)(%?uQwl~-@mMaa;_gJ;Z`aL$}u@8FeBOZIwV|zXJd{q#% zX}&L54qcn)ur|vvj@asGSGk#%Lti}hfXDVNFz+B^4z*lqaPmUdOd9tz%P}{??NICj z%asNraBCHNkL5~(64rkPn`*hz;Pxea=S=19upDydI&7-t7+Xutx4!T}ELR#l@39v= zw)(BSD?`&;V>#rQXbtv)<*>1F?r10w-RQJjX|NIQD8)8et~B^1gSHrG+r3! z(JVKfum@sq50yuE5-aV=`RAV>$Yz4MbCkK6bGdWF0nu}A#a+S8yBvbEv+APhIk(-f z<}OF>x=q(|w_d=-gk`PEmz!%Q#IgHTkvO8y?kFu)SMV$xL1oU3>Gnfkdv8qFSutL9 zyS8gEc1q{m(w6R?p&0+$V{3;mLoODLIy-jC(A?5gZx`#m81IVgAI!vhGO}x*@*TPM{aqOF)q>%3AvXx`O(H9}<8 z(J?&8_OG^&5gdwjT}7FO*@C}1M$>dk8r?mYb$1PxUJ1&F#i`%A3=Pvowk^Dj>xvrln|_rgbgX|c)=zs5(u;$gz9L;3gT7%+B2O`vUOqgOu^mlL{W1A2{Lq|^ z?yin2v^)6BG_Qvpk_@|tFYB_JC+DR$Bi$!COW!^|G+SGo&gC=KY`hHjiQe+2;LhHw zPgjMA$*vL^tVJ(7HtZ*0Ezt#-oW#zjww~cCDAt#f!+Wa>IrV zb4kenbIJ8|q!Ww?+C@fyw6J~GgbaH0L|$?mt6Y()?>v1jDfrZ4lE#oL*7{*aGg?F{ zjK%)p%V<)DqS}DL*s{9D<{_;w=3ovgDRE8DOFg+X(-~VwI}g(Y63vuHV#PZ9yN3Es z%Z%IJwz0d~GpO;^GNgUG>$nctI5Jl&XELpeZBVPi^SLyv6uq|x10h4Yt9{T7ybMia z><6)XyE4=@c12(R22Epjtf#X}tikMOR=dSX&>PGe@;a zhPJVR6sD)QSL!m{r^AtA^z>at3-w$kMyN+BFIHj$f3a(;Hl9+oc;oDtq1S;8@<#?S zQKGf%t98bB7unFc3>^BSGxk<1I$M=&nD>==h&^JqGS3#fGzYshM@*8Lze)1H_n2h% zF$#hbxXF~IASj2EhA0ST!c9?5*4R^(tAsmDxhlBBm0Ju~rd%AZTse6o&@|;zaMP7r z4ac&Ml-uBDDAx_g5)Nztj)fcCMmUyca5dZOD`GXcCxa#nJ2a?1-<$&ptd zmh$Y{%kkp9$&vbs`170xH|-uS-SxZIUVCkHQ4veJEt@LhLFNQVvS8CpA(L;I23Z|! zD%}kE15vIo-SsDl!25#&4H_=lQ&X{;bykoZsi}x3w`^P-43``J7O8uX+@4(Q!s27Y z;)z}OIl&{(e%~cAl1!@nYpKOaYEvl%s|+aWA0_9JLL*nH^+;|n5!uS*o;Yh!7qTZF z3!kuZ;EiQ970El_SrCw7EZHGHkL@cod5=78$`{U(~z{;G_uF-K$+QrcG^mh?lT zFeRFu63x~z#XAZ$^Hg#qUKQ1R4WI5>MDkB1my~2|MER(jR(&L1f_hhxYE?nzBq4>F zQ-labs_SjU*TsL1M0QWN8kuq9Skqjl(mlA(EGB7__=9!rj#Kraf1Ca z*cVD+XuE}@o5A+~jYKUNKH2w1YNW1Yd(tTLp18bBjrVsFW&c8vEIhDeu}CfyNn5WI zZNUntDDZ2e3i@s+B#on@Uah1+E;a%PdK5 zysmT?4IGT#tEn)iD7*k_o<=_ar{#B_1W?Q7Y*QdFdQ)ol^yjkFS6Sp8<@yce?kCtxeqNUQEJcUN;}G;W4RJJfwRc_5oYO zo~Z>w=m2(#R5v<1B~tv2W6ea$*(s44Yl&>Mlo`bN)-cX&P(`_d=Li#E-Bm;%bD0|cZfH6z=N zfbyHWMfeu+DG7ekikY~Dn~n*^9Y;pf8`&;NEZHWBG7z*Hhr5D~s2Y81pOqAydTjKB zDUaEb%DI-*hD#bI%7QT>Xs!6q`zI~fJ^DE8WdGHvtw8w;!|>Oy;H) zdZi!-uAu}k*(MP(leC8W&!T;+_MdJuC@IWLRAA=lw-|=1E}7DYuf#3a7CnHG_WH}X z9P6P+ZO%_@mE#An&rjI!m^5YBK7ZB+Y}u8f20`X{DK&CCKn|Hp?o@=vS z-(ZsO&?F_7m@H4)${w1&t)-wu14lH>*vr`V&62m^ZAl>7qYb|MwI|`a_p|<$2AXg? zGBvQPNh{@S9}<;hiu18J(h_1hnM}hysL(di9W9a_==+zNc1d3rXYym3y5+?baP*xLlg6wH zGO8MEe4KHp+3v5;lO!z?%gaVVD#prnYQ@NQQ6%HiVe+O{BuBQZ7Kvg$UOsjWp!RZ{ z_8Z?`l8tJTnz(T^i7}xDvodNh6{ZpJhSg#Q*X0`>XZ!LJu(ppES?f5!VRG7)pMdEB z9hKn{2#nQwlmy71)oXq{)1+hK2~51LE@KAd>h0Th(Y8j1I8U)du@k^Le!NWIg_Zm{ z6P;H}Yod>KDQwv#orw4LD8Dv8lcugp%Wk^cX zhrCGbG`e-%lD1-IxxP{x%QoNe`SwhDEx0PbJqA@E&Z5{%md9I@o|^iqSWGv=r~|D(3v-t^DCGo)p}P&=MRNd=XCz)4z4>( zx+;`_n?Ldr5P0-VYgeoM>@l1l9WgZqdC>(PeZiVQW<+m9^W!_;J1@S#qn{x@g=Hm> zA4|1`puAWDk6z_+rK`Jh?jePs>zR3OM``TLbDi8sqcWkB_5 z7koQpk1HucWkDudIetyKFEtDw*oOYr-Krk>{q!-AU~!w zuIP@hRZi3PPZ<3)3WKc;?Uky3shfgP|8ji&W~}O-qLhC?6rJ%+g(TB@s^2YRwoU5K zl?prvt@#_tkK}UWsp|D<*tv2!j|Be0VeyI^Re#~I_@czuabc`Lcg_k7*p42^K^rZ! z(Ls+^WTjQbQ{Sqr2_V5X9H$yLB#grj!nXw7csb1l9{PBZuNTl*-mB6fQ}h$5T_bk3Nfl- z!*~0bAxlF32eJpIUTQC0*K11SjM|(}HvW9L`Gp>pJcWLlG3 z9<8_sD9BtO>`rCRhuaNTu<2~eO}^nwxF;oa(}|WVzTs%NrxiPFv*E-ya~BwnkSv?Gjg+v)zFZV+sJKNkmN1&(eom(eQSkSebN;YWTql0 zoV`A_Rcl}-d_wLdL{6k%cEQ84Xx*wc9+9(@8D|Gbz6iBkXtOHL6z*T*<6=rjf-@gW zQrvqa-GW>R7wq1DQtoWm%go68r{w@!-sH&3$&tNwcUNnc9NClH{J8X5bj|#R`uAsj`s#ow=XF!_A$HSJ%s?u*>WEyryJRu8zardUZ@2^F7bkC-Kt=Pq)eqq4EFTju zwghQEWYPTE1y9v8Z!Ug>(!Cb32(hTHNTQmayUQj&Ik9z#hv`qe0}>R!Xu(s@OX+Y5 z#z~Cy4%rnU!Ia&u8ZKrOEY?MX=JG-xuUq@ zHSS-scVmqdKZXX5vt78?sWP*F}j+BTtFv8_&CZ#`Zz{7kHt= z2fl{*u-w#O(%ll?_VyYV8DHg6sA6K+K9;;~O);3o-2NupD#cW|h`pI_y-ZO{5!jhl{+!U*!A%&9gUt@dCMVL`K{(o-6a* z1iewjb)Fl~k)7-OmK8OKQ<7xaeGF;($X$Y^WHC|G7-jLd7afBA5~W|vWFrYLc5OSp zwGsPe?-0yyTZwJ5-xKe3y2SkfnGml|gcfm6c3UCWsyS?b(70&aZkl;B3Q5OYcSN#- zW|dT**jkX4RQCT+93gh>ng~r zw2kYYEzcLrD9b6LX_iB*)9cChuPTcwNKJH@cGS_=Eizu4;@gTD`B;sSc&M8XIH0_~ z6L+jDBnefyaia#stP3Pp%Wa7|GCsYyq*qR}hvwtd6O>E)A;s-8+$r-z^uz9Q?X{|s zlC-&fa9~NYchiK?2Xk;h9GS~M4kQU_w;@h~LD@sHzQDX-LPz3ju=5pVTR&+#oy^(_ z%5M5wcWMW4rI8K~(NtuJR*oH_DKkV}K3Z05&TMh)u%ldN*j3tLN3m>wq_!vMEh#7- z+V@n@Qg^ zlw1s#22PGlPO^@YLZJ)mNN21uqx( z|Fek;$b791CeI|LdoF&P8c<=mqRr%?hwU&(V|g;lA=G8!k2Th zQ<)1sJzi;JwzM=WrIkq|Q)gN1!`pJja^c0plW3o+g8dVOFfXv?&Xb~;)H5)5>9`iq z>E>9uZjxUml|@^%wTzvT?bGc}%Xxt22vPSF{-Xt$kC1~MzBf$&^-`{OA z9%d3DG+z!#t^-V0Gj7^lwsq?yZ%{Ki*4+?_tQjYh=Ib->&mik~Xu2eGE9V~yiL?jF+tvHwp>!woR}BiR_mr)YlMNHP6T zlK?x^3~tAh!F4o~P}#&5VfLIzPO^WZe;;<(KL%AvGvOoMjtzdt#OfZ{9eISDgmK zrjUE$v&hC)H$Kz%i-}Dh+_a36$^{goq%|Tg=4b(^FJ4yeHg*~5t;eR=p<9w&3r`rm zj7#il(4;!&CE}TB{%m_9KAI$0W7E3MK8)L#b9kK2Wb?nPF_XSAlcB~;{$-7MEO$@) z<{R6Xue_3LOxZip_8Lz!_hBObH#TOyZ_N5oW7hv=jrnyhhaIFbKS%HZ8}MTj|93WE z$~Ryt)PSjjG@!K5mfgh>3qGDo-NMHD>rp8@4x47&Mf-0xdM&8^E3y+wH27s0%D02mEt4= zS4xo-uG+uDWONu4j=Ef<>&ftS=c5tErcORfSumID4E}2pcEGUaCp|p+M|xZwuo==f zJ+zlh;IavKJ5dCC(-QkU0N&rqH_?fjls?GFNv z$xCk6d);|i14Ls^9h2b9gC&TCA<_)Va7;&y{+^jsbO)adms7eb?oZji!na*~=C?+^ zR+Ow5c}(q;dZXU!L@DA+k`+T{Y-$=&$5RuNA+lW`e9}`heyqbt*i`!v>;QcE_HE)- zxo9)&)5{bO^-FHw<{rfn+1U1^@e0XT!nxx%nJWmT-=2)k-_5e3EpLJSI@S~aT;kUg z59Zi$*ApW=cBSS1|LY0X6W8%d1JjFR-C?yxYn;IAUQe9lVkRdfRac%i86}tM8Xhwi zGeFKmmZ!4H{;@crDm+rR^jo7`SCEBUa^!vT6js?oQ%kwXgI>!@qG{=4KQ7$z+y?+#viFm`k-{GZVsi+y)24tK}mzpy(d>ze2wqvLsQ%hAy_-Wp&t zGld4e>0N-`8QTR*|7UbT+;>4d+y(K2b%Cnqs!q(`If2*h z#Jt1B9ABYxgXVQBbNzVATz^1iHjD2=-Nt{@Ne%FYKj*2u&v`22O^xfAB>pW^)!}0;p=H}DZaUl zk=+1&nC`XV;++Ni%cWd#S$FF)OIOzZmOGcU(%k*wxtscS4RGJ7MogZ$PqLlGOye)( z-CU6+I5`3aS@3vr`__tX5N^?bi6<816@suY!^%u| z@+^Z;P3@5&%dVMu`e^_0$y;tSosWnV!Iap>+s}nT6HMr~{7~sv)eY^}7b(6kWILR+ zXu);zaENjySe5X42a1kSR8b!pBJzZYXq7x6V*2AYQ~X=ptXFYw%UiL z;f~eN%Y0}dn-;57?j*P~luN)Jr*d_0CY2AsHEZZs4-5F1y5v#FM&D`5ozMG8-=^I4 zaHlHw5cl)Nm6Oj{7;GInW#T>p*QueSaJ8#dB#jc{`{?i!DsdxH67N^wvFXUcLx%$4sS;FfBP7vSEi+#ftQ_04En; ziUaQ32`*Faw{WI)QzyB0c|TlSL+|n27d7^) z&`)@-tipU?q&PSa?uQyGFMTs{KLWR0u`k2@NV%{2(56$&2SJL14W8Quw@l^U17|es zPS4#BcczAZ5l%*1aj+ZCSfM3-2i%1k+6!k=$->Dk%*DYrIHRX`_|Q+l$@PHZ z;9ej4AY7%U^2BLQho%7lBX|Gl=C%68!P?p8Lkq=0FPs_EEp)xSbiX+GPq=qzjQCj& z`xczRjzXE+H1r*CW}FYf8GG8-+92%QX($ zSnIHBmpkkgI3xFs6%K1kI&84c<@T`)TZ`|+!e}w8177MgRjD!pxo!VicNzcCm%tGDK_DvAdvSt6bC24(MWKo!=0qqB9E>%xuo&)F{B7lLS+HUn#2-`O3i)H62);eb z!SS^DxFg?+?d<7K5Ad@1%(`^{fV>rdD3}#Y$5@Yd#NyKkovNSoG~ww+6G^`1)qYtQ zc{NV^H9^ui?vOG(%U=zf#L7!8MlS zD;zd-N^pne_*x7XEXI55)3{E(SQz{Y-pC>szjzpldyM5dxTHGu?(ucj40!Zn;iV|W z0SXo{_~2ZFe~zjyh|*Y~t(v}+*WDh5pqURE!kE0(UIOaxT% z=ME|FJ^Y0`=f=Vyi+KySK&2kM^hi5r5xnUf;Y#(BYzBLhbA#m`H_~@VX}`$(#My@! z=V?26$j}BykAk8M?)!uUCo3JeE7Mhki<>zlvee5)|v0xr;OG zHos;BxgPs8$eg?$+o+g%`TT3l+V-&hrM)F>Joa$C)ke_R-s%R8_LlUER3xuoq-$fq z8UE<5CjIC{sJD{f?vS$H!yi4Xo`m4lMW(lwLuLM30mYmINvOB!G23??^C zF!81n&!y+;A##$g#G6h$myV+j7dqe8*VS9(1$XD4x95&FO&mA|^*gcP*1{Q9t7K^< zw^v=Rt;|nwt(YKt^vc{|4|#LEJH8U)?+?j{C+m*qL--#Y2-S;}_FO)_=#ETC{@D=U z?F68o3&}qd%Im=pA08+1P+alz-EoU!ptd0tDGlL22=Ov*-Eo6spx1|ZoLGN|6?DgW zj)BTV>5iCVpfa<$<6lE{$DQ-XbTOXx5YNON@+g)&s;4@Rb^YNver1jgz7=Xisk<3( zhLiCowz(*fga(x>_Z+Gc$Xr_#$e12dPNr7F#o%@-R>7}W(IWNl4JQ`w^NLmRJFMJ7 z&xy@>K(VF#UZq^zb2V@eDVF4SgL3trOTq0@tc72(CPiv#47Y~!M-*%0_iE)jJtw;L zsA9eRifdD(`d~OI`Ii-ww60ZdljpKm=NyBY2)itXU{I^}Nj-0g6W zD|QFJqD4i)ou0cJ?g_>2;dirgpYfcu@z)iT7Tc=aF3&v*_ie>?^LvwWl9S<{gnLG@ zz5KpYxu-oRA^%sgXZd}XazFIkJ~+XPg6H^^nilCA(Qq$t{;!JtlHcvhz2v!<;eM>x ztNgxOIVJ?l6~jrIML`MNh;nkMvGqspsNw;?5TZa?ky0<>b1j;pA@T7Zppv$xK_McGPgI z!G5FI8n{c9Yx7(u-0u|Yh7;eQDCqUv0Nn2t%fPKsZlmWm!M&nb7EV^V=%44d!TnLO zo8e>~TNLc@+--2LDRw)Y*tDYH4$s{QSHNFUa5ukg8hVfCJ|iI-x|82_4Sm3KyWl49 zR}?(T?^+Gr?YYO{CTZxC{B~&QUe7%ZH(5iU;kQ#mpY_}i;ihQlK7Q9}=yRTX9&WmZ z@=dSx1p1>2F6GZ&KSQFC!=;~(uf2w^;UW1(^Q$0@;z*9K@8m$`IuQOw^IP~=D(`Tg zd}1sJ*7tXI%_oo0WEE+Uk{RaHO%7~>k+<8q_9?d*?%$Q$2=^1^WGwzvITi?nqk%zDATXLoJPxZNLS`X#>;(SUh z_p$Mfix#e_>Efe{t<4^sJJ7i{`1P*}D=z=tcfau9uiF-U^|W}=kuTk}=0Bc&@Y2qW zr&j-M_t&2JWGZv^g|F={YxwLDr~TXgr(bmMhPUlM?OXNtK7ZM#Tke1B!k_+P&r@@c z`0|gAzwT{s-*@?@tLGdy{fO?0y_vJte<(O<{WrEhe%R0Nx$)-@oP1ly?0et&>6flq z^{Y$1+A@59V$#un3a-B3gAdGl@}e8hF8}7EA1`=(->;6H@i%|!`EBa`6PCX6;oHi8 z(RFFz$4_|hao0HawGRB|uFX@farC6?J1)L-JgW3@XhV%{C=jm;57_yQ4n9p zr{(5WRqZG!$QopB=U`Vy=Bh4iBwcjg~{>RsPNoQzFB9Z zNuLxIWG9&ql-GP$xPt9s9*}e(sQpSZ(M2mC){5XRpv>4g_C0f z|Dx&8QKTcD14A-+p{9H9*mO!%<|Tez4^A4B&SaI@D8Kxjb?bX5x}+E`PpQg?Eph2g z)^y~fj0D*uM!fZWi?F{VjC5`6$++_%5E(h{w$KERJZ2Fiv#z7Jf5@jTvC`{0`}wG= zl@f&SR}S_|r|O}|y58X->G&LSSy#pvNApU{cQ^ZFr$7#k6-w74@@Y^b;AHeOp$?K* z!+qhT1(D-hPQ=$syihqNnY_$Kq9T(O=^5(mxy(0_q=VPc!Tz8<9I{@9fF3R{@fGDL z_IXJU?VuZTh+JJMM~QOC=^!zbCx^TZ*Q4rv70iHhcs4v>9Q!^j}W(`8}gMnTHM z$lrpLPY)w^iOi8<BhBni@15l*KCWM2en1NmhHkzJ6dPYK7`2ogUvjNA%h4%er5O00;? zePd+44AOR*NvBAo%Pk!{BFMjh?28~j1F5QXv3mH-Y`UpF*yj;RNS+@nKi$a)GKmc0 z9?{`Nv?>g_^q0x~7>I06=8&^M?yL$U>~99U=Y^3~AUhX?kpYk(?vV9Yuj}ex2h!+} z^iWquJUlQC*J2~YYV$G@@)1c#4<~c~804SEAYYFl>2yc;6+@XTqUrowM5dy?f%2PU z0%T$kMi^pwh*(;cnJ2TJ9L4-GI5~bx%75g~Ad(KvXUDRQwM691Sa#{qpmr=gil>|~@oW-L1dz>Z~y$oy}{ zvLJF4Q|XstuI_@&1eu^?*~ZekoAK^qorcVZPYTCc2J(bQXv29@9%B<+?vlE(31P(8 zgfL=kf<gF)+Sg)I>*|CFk);%IF_*hg2-_Z^}2OwxTd`z zW#>C&?#7%OCw@gy0mfX9r`Eo=&v*`Ux`|kFs7!#{?43UhJF)Z^Zq=;I-;s-TmyKmY z!+D8wlgsOjo8Mb%ybIvqpKUCaiR2}oV=k|sKi_jfF4p&LER_l74(3Y8L_@4Lehc{v zKKAHBzB$ElW4nMf_B z5t^&TDer#phFq*gHkQf+;k=j%iM6J{_ zY>=vmObrN=Oen855Y#!8*R?iQF0c22BqK8SfXI-_$?OJciO75pBp#7@5u`05b2x@s zQqHAwB1msUW&wzFO-|-Qkc|JpBK684Yd{7-ay7jUa60muU&xs+Q$wnb$6Kz2uD-U%WtmP_Y@AbTS+awpyG z5t)Aic{U>RZ4l|fT-|>PvO9wO5hP%o2oJwF84~1=Rk6`I2S~AOmeYOAXO1W z?$?_cL9!tCL{h#D0@KLxTgBJ)L%S0ggt0I7_m{2a(Y1bIc$i6AqW1a?JIt^|?w zL#|%uf$WaRG=j{C$gBl##PiBVWPT4)9+4?!+Ppa;b1aDHPcEIsAh$$$T0_ zbR$>y$3UtgGXDW0d-OS(VhoVQ<*A5L4K@Z$) zEWas{g*>_1mQZCB-2!r(Pe-6zKt2;e{to2T2yzz)&BHB7rrberFG#?=VrnsWFw;>{ zw^A-l1xJaD`k4~L9IkYaNGuMO!HXkSi-~nK=z(I%`a=$tQSK)ek&{BVAJrmfGx;kj z=oL0{%#}skqJ@eb!*5Z6*rw?5GO5yM^Qx*A%%AVM1)f{zxwAdD$aCj-Zn5WPN!(rjHG*AIL-z2qcc-^{|e))B^9uqL87QH=d zS9J{zaUZ3X)r~=up4ogfyzUMf)@%zJ-fTV^-fUkQ-fUAEKAlbsan&P}OsChi_w;H$ zu7Q`ab9#j$J$;>B8|(Tq{mb>V)AvEJ_L_7@f8V;E%hLT<1f5;$+J}2H^sL!+&7JGU zEWI|+KG>D+>)McBt7-QPb*&%BTrC?v?VX+Jf%cxkbf(`1cJvQio$l!y7|x`J`!YSf zs8##2-1aJqkx z8kqJ?H?>r!tGl~8u4vA*cU-ZmeQ+pHOjLGRJ3GR9*4#au>FnRohwiUvPHIsGHI@v9 zu8v`J=V~@^NQM&jU(wSQREP?1=*e_+SIF431?<17Yj9m}|AvZrj9j|O)M~JTje~p< zDJA<+74sO+VMzw{5G~c7>5^Kf*;-C_U77Ch>#8^hTQS&`86NCQ_w{E6E6%}U4EJrI zZz~QuzAJQL{%2%dLZLfTUAz!vZ-cDB1UIy=@8UI3A%w=Q=^E+?L(2z|s*!C0S5kK) zrA^$Q+Wd`DyAh^##Y&DBGHxWgMwa;%(Fnc(QCO_YxbhkhNk2Eb#}+F;>;Ms?S>+<- z6)qPrrg(Wlk$k*;j8rIxjuAE%Z;Z5s$B5^Q>zF8^pfS;+m6qbsx?$pz%} z=OE>c3LU7#QK>&)=A8V2N*$Jn^krxsjdV;Hk3`UUHX>?}h>)2fB2xL2@|Z@FnR;wD zI`lw|AmPzUD`I+egE%H*GV*A&`8|A~tW+SHmxUsAH?Bpb?qj@-F=gryZ)hH8pW(&&Ob8#l9e3;j}cdQ zYK*i&t?*c9%gT=vV59WdYj9T3pSs|jv*sj1h!q;^##z~M0&Em_5zqB-?%WED?+Ds- z4-goRI@VhZ#~mlsM$Y#sZLBe{6+f`cX(Jv);9yA@-}GQUR-cpbkASt7R2)xx`p%nv)#gZ{@HHfJpb%-sIVFo?uY28 z3j)8{5MBqE6+r1(OU|yEAIlx{7A;t~sOp@Bi^Cwn>}y1XeNvSHV1W#n9rczIPkd_hw%c2$FSAlGAMrE64fob=vxi0Qot zxew>37rIO-`L^-*Ffzy7BWI@l;^nD$_(GuIQja-SM$Y9pP(98@E@5STJ@WG1NrR=4 zDf_HRYlfs3jLlar%6t!*=Fb^9ZRcQY`^om&waEO`%5nb<=^>Z9Dys=RM8Ey!K9iRF zjR*1FeuP@E1bXlNLGT6sXGV`XqWIV7epA^XVug$Pqfyz)YmOL_oU(Bp3b?rs3#o~OqA-CEj4+yf5qSX`D+adrb+H^_?B1Q#Tn`!%*^dydpS=yFP$dZ_B1=%vx4tuWM|vZl|3DU z{X_lhGO^00(_`|K@A{r=u%R(osdM|=pefrtx?n-x1C>XiUKNz}Flb2(#vJPV${tcP zx$9$SMTKt=u7P*3J1_0OaDF93{m;R@!kg z^lWG;bUAbi^kV2#=sM_OP_dAQL*E6R0evs@Na$|pQP6*e&VqgidOTG0>Mc-t0D{|K zvT|Xl5-Oj!9aBZ-y>~ zehKxkDxzKMy&w@(3QlBhOamvdHvhqmFLa4kn0iDX82j#Y`Y(12Fl(O%H zQr+yQpxiN){UY>SsI>oiP)RR=t}e{$r&*JXcTof_h#_PS*H0Ho7cJ01|4U+zbJR}b zQRH){?IX0Ypg{X8pjq?!iy>hl+h5YJ<$$ignll3yvWZ-lAs>M%JT%+~ zBx)yJ>#Ct8Yy$|Du)beoq6JPYW1*ObhWmh|whKM9o{Mos(>T?mk>A6qIfvNPyJ>Ed z=QYJ=EA$GejQRD@TcG{Wk3z46imk^k zWdAR82>Kf+-H`nq^m=GHY2N@n8Jgw)h0x8=>!GBX{Rng`^s~^LpmHh({3cV95U3fS2d(gj! z{u~|o6m-JGAovI9anMgg&xU>mdJ*)q(2YCFldt zU(vquK=}MT+jv5$v5ga^zkpa`{=@lHaWW!w#)XBnULkhP4WfKPjH zZMXO%G7~)uW(KA8dPMQ}c~G4cu^@ap)5;C%P|W)Cj*fY1V>&&O)bnnCZft3uKH5UIq{Ve10-=Q)N{}Y;q{sbyM*iWJ8 zg4{rql@}t7LglugpFwv*Ux5BA^yko*q5lOvjI@6NjX{42Jr{~DWtT!nT?pmD|Lplt9(v7Q06hZQ3gyL8*)Av#iDVyy z;zwrx6UqzdveOwCylO7n0-XizgdPvQ8u}LKQ&3*nl>I$420e9>zN9JJ4aGKPH$p3* zw?Oervv)x&q5ll!5tQuDpxgqM{S9;u^mMv(F0=u97F5Pl6;!@eF(3K}bRqO{=-JT! zgq{Qa4RkSd+GKnl=uyx(GzLvTmq3?6YoOK8E1@;e4?yvgvkyX-L;nT30=f^Hg#Hd% z2NkPv446t2#?r2S#apnrc5r)w(o2^Ax~JI$*xe zfp-GruaE8l%Ud6bUBI&0xS`e1F2D@k!}`jshQv{!dxIE%jRhU^HCx&*I8lKiV;SJB z?YKe(rsf1p3^dIpF;9ozuK{+W-|mpMk+COZ>;a3n)0Q%l!LtnJpa;r45nK*^2-*vM z4!RyH?cE1m3LStV6I==XIF!eZvR{F6n_c#o&|zpLd0YjR2X!_=WzM=9`Z?$|&~HFD zLFMt5>!1r6bIg}I=VYNba=sb*2=qqi51?D2;;`NXjYILRbM>=x1sNY{u+84R66$q(A7{LmC`xucIZu<-vRvs^dr#y z(2qioW2}4(+6=uDIs~OnbZmVB`hCvthEAqWKM74h{~p>7y$AXp=s!UBKtB!r9rRx4 zS?Ky_ppDSaL9c_}2bHn06Z)Uf`=Q5UQ$G)VEA#>A70?HvpMbIpl>H9$AE8s&lH3J7 z6Z#1B5-4kt?0cb)LLY;E3Hp2Jm!Zd?V!NR$ppQXsfYQg=`=DQi{uKH+bkbow-~l}w zx(B)*`Xuxt(5Il^g?ThPO=Lsvk*2~9zthRRKc--ZrApMlC4{w`F;dMi4W zzdrgR`Y?yE2cg9=7<0&2&s)Q$Tv(Jced^bq`5FY>=XNb!L6`A^F zG-o|%SG(IhU{||4JkY5Vv{;#lQ4n`wu@~yr`Bet0$;&tc3;p@!Y7*l9yn8_B=-l#W zZO>&5nnn#W!~8WCT%|?=R_p}h(;w2V*aKMu>#Hmz;OF#%wDqr`wa{NfFM_@Vm7VF| zK(B%R7P=MsG8BI@_&xM<&{v?3L0^ULg}w&;Hz;MuGEehzEaOWTLN6lk3D9BaL?~lD zz#q;s_JR`VUC_x;bUrABqPqd}efAqr{N?PwL(8B)g|Z^eCa^C@K)awbpuR{S5Rts65a&3;Ipy@zC!sbPu zWq-MYq7=0j?TLZPUt>YLo>%(wwO*S{c!!=7Y~}5H?L;q9g4#pMBYJ^33q+0Nz_w?l zj2A#xLNA2Mnz0_*30(=j7TO5SLh%K)zAeQvPeqe&Jcsr=+9tYy z2(=!)*lh9WWn9ZU;iBVORv-D}Itw<=xZVaF8Q0>{@9Us%a@1{17?yA#C8|^*3WGa@ zalWi<0jbZ6jdF+B6tP)n1K=C!f&JGxY%^4B){W2|(5+CJv)&2)40IdxCs6iQvaAh* z5onS$*niJn3cUrIhVFp=7xV+rKSBQ%$~+X@4m}3SUQCvGA@~q<0rbOA+0S9^nH9zT z2=oikk3#oC?}UCAdKdKHq0CF!=b)c}{sMY8RQC8k39Upm{~jtD{VC}6(0ibN2mLhk zPUyYRPeYm4viCth3l){d56^PFBDfEFGL$l8xgH^FgKQ7W=rVre}dLPcSGL^{R;Ha5`0DIuj%8*q4GG>QxXpS8uU5n|A8)}pQyX~ znqP;?oET8Xxp{NM_wfm93EB;v6cZsm)aP@Tz^Vuv=dd$G?EkU%E#Prg)&6Iav<+!# zlD0sBB11``&{EPTDHNDVX3_~vGDBw42h=-Ble7sLu7iF5dy}GLb{)Zalo3~lXCsttK|{d^Cwzvz3Zh*gvV!B??XXUHfmrPu=i?UnCbxV zIED#c0H?D+#OHu?^-rUE)KU;P5^=vQsZy?f9o`zjbQVUCqQX{iJac5~+hHUhK0|cW zx>nYlP6f6T{1tUqZ+kl)b4I$F@Q9Nodk)!qC3`G;xt;TMXg++$6c+_}$riXp(jBn( z8#sDRcO~O{M**>hp1dEh4DhRfivjlmUJUpgtp((3)G@$20kL+UdYu4jeuM%-UP^ocLU(p0pADs93bXH$%BBK0bd71-;}I`qrv z2jpv}UjyWt$Ik%Y0Q?_7`i!3go(1>|z$(B4fN?QZ;fWHC! z8{k2}F=*FAfENJ%7H}TmFkl_v?*Xp{d=;<>@HN1%0{#Jz{p26c=gWcPia#?6H%?6? z5KL6nEc1t}0v7F2=wLWl9ju9?Gf~tz3hj@_YpcrZ;z11YR79?dhzD21ozpcgPvI&8 z{(;ZN3yPf+MUq@qsnM$UqCd?LOw8g$OoiNrd3-{WF$^(RuFZu)k($oquW2#*T5v*2RLg++Ag3$GT&q{#a~zq&8qP9_Nm&^CzNJ zD}v#eO`M+*T@eXKYBBmyVx8cQjl{(KC~kopPk|B;7luwlWBhn`yw(ToGZKLEVqzSm zn&762Mq=?qMI>@%RnVEP*_=3nKpF!zD-}j26WugaDH|Ij3f&P^Xq@Njh$44HW!S$o z!J19PBZ)})6=-L+6vb}BXuMX@RYYpU5ZM%&&m=e1ia>25Qd_mOs>a&JWOsZZvb-i7 z@du**c*yEuikqS~5{biJ#X5{SPjVAf)l|i+{NY4pRX8YiV6=6zn+k1w#ma=W6+?5% zNE&M~XXye>bM{wsJlPb9bp(HY=+>qOK+wtMF^zNRoWRGKhvDB$|LufdnUL z0vb!AvNlp}T?S(dbS#RXBE_aA>$Kx_th5y)>jaHNgN0(HQpo8>ye>NXuRr;vdSi77y)RYV z&L2)9_NuyI?aD-OMYO6`@=3rUD1X8D933BrgGfXw6Jfl0o2UrEovI#*G`X5ansH4$ zVce3K0SWRl2&6xwLuBL_9f=;dHW&-x6?}ysYw_rb;7)>;-8jR}Uz4cuFRNNgfoXDN zm#-tyPGgChU>u(NO3U*E9SPg1@S|!1;!>EbAQi(794`?E18AtVE5&n?Vtk51rG-~Q zBZ@}Bg`F#DCb%;fDx39*spQgBg3==}(L`5_zcMKHPJE%8S*R)&kJPTL#6Dn{8OH)I zOl1qN4Ep1BwWu2Lvr;N_2$sNO39gRR$Y5Yu%9zL@#}d%26R6lgm<;HO8K0XTAFHXV ztYkd>DC6^N{Bn5w$Z`yv*rChtCx*3uMKvZx6)cA*jz*$&(Q1DUx;PoS(9e$t> z99KDtj`O6HAO$wslqcawnU)1tXzQ>Uj<=LDUWF-In-t$-R4~EPS&r;(Oz$PNPQgyJ zbpAj<+_cpadmNHXv?QkZsq$T@X$mb(C?1d6UMpd`ri50am^Yag*#t2dq4dk~i0-}5 z)=Y~nO(_$TRF#p%LlbJU`n9&?^-6U6=H z<-tIryf(6&LuqLtq?lqUVzF@D3T$;%S)F9@#w4^mVE-12)M0RmM^cLR>h(qU{&MOyr(1kEtrzo(Xq_alj>cosqx}7JdVu(q9BKt?>Z+wjA=0Cf zwde*hZe_M*?->pcH~=d?`R!RB>EV>Bp3ZT@YjPbPS4sx~m9Dg)m}_j;M%K zphJks9Etd`8jrDqKZPBqv2``naWR;mh;fU@slbU0fnY^g1SARrl!`=ktO7=gwkuOP zi`F=ng}7WH^&3)lutekQmN3kC0LjB5Es!|2*DfTu|m9(d4;72BpxS>qs!AJ z%hyvnvcTts5c=d3&+z%VTs1ZY946wK(X)nSr#VLKSACGIMBV-iaOs3n>2DL^OyA z7Yvz`TdIOF9*LoKBX3TjiOdlsdUYJO!Tw`Bs zFLuVL92_ZsG{K})YB*LAU!hzuJ?x6IMVPQJx^{J4{ z@Td(gwWAysoRL;4Mux5oSHp*nEB+<;qm1!H)jWHjEB6cF4pn?U@5|ApiGeW13B=eI zL2D+qfY@MdEyknos5%myX8H)zdw8Ak=FW8ich8-z19X8iQs2WDVDX0kc|1vN$ zF)*rB5}6h;Z>E7?P%-F#mg+eS@o)GD!j$w2CuA0|~-4jw>eKlftu&kVp)UaXG0t=vtyoGJGnl^z{jZj)k0l@^CiC|p%7s|ZYrc~x3;pw?d*7iBUQ6RWgXbPlKrc4IOS zCJCljX(YiwRorHdDOOq}9TjBbG>K_3)k=#7^GKzb<8!lEO|g}+1jc(fZkWD;IFG^2 zpC@gHxE#U3LrAuN7YC%K4pPPFRI7v4>ToBIRbt&p`!dZkV@Y6{R*3#!!HxW9&B{ zS4`p@=V-*${uK$1e3w@RuzYfXPLp@kGy(L`iMW3$w!f$>#vPSh#>EM)3dLmPHa4>a zRgtU(SP1TLb!+<1?PK7JC3625$I%&SU zJjYHdgUw1zi~UjY9<^veW^I$hMGSsxxJ-xU8L7i?QjCp6W{p#bP<=IAlGd{~#+wyR ziLXTiMjs#q?Dt7v);NWrJcu@Qd`%j&R4OzwjI9dzm!U07>oFQO>!m_vy2un6XCh=~mP{2h zE-jd~#1t)Of}}O8s6s217F&ra5r$>TPZoL4Cz!xA7({0#jP&NfRr65`)Z$neYZg=`77J!ol~uvO zNVOUZGHa_su5wa~GaP)%q8K{{GBzu$LWxO*tc%NhjLjxn8D4f zK{ytk(Y+XRJHt&_rN@aW6Jjq#e(!OUDYwAEiY)su{!Dj#t$(={h)W10@VW_5l`B>T z(Ag^I!mf@qXSr$A69)|Fm!iMr@)IehyD8Lz1`NwF+BNRt>~wBw$_=DjVpRiQ~ zv7i#LWiLr5=3|RQtS%~(bC4OEn30VP6PKVJR&(w^@y;2QQkBM5&$*)#)&}MAh2c1J zR6^(w^Kxr&=Z#7j4*IdkY5d0dqtem+F0IAz*lK&0n^r3kBj`%ooy<-nm><>8)NE~B z;Eu=gs5}PH)n;pBj#l0rH!*xu3=5E`TKzmJRePqYFLcwVGndXavK)12OsmvQEdE;$ zUa(tA)!p1QiV-c*cvpO?RMF3K(~G%dl7n$oRZVpjPSxS!h4H`h-K5dF@^Dow1mA02 zzcDl%_=z^9R(xc_hfx~Gn<+};sTaB_Wr>PwfU<0ZLL29@D2+;Huku8bbCVQLLw!*i zHJ4qnGB%={GVQs{O}%JAImR`xNHrnge2&c_jfU&^)^KpPPO7A4MwuwJ@fT-}pKIeU z$r?Y;#xKblKi|e*nl*lbjlV2w{6ZUldDi$vHr|&t{vsRi&l+E5ydS zK9DuO+{Op9##h+*%B=AL8^1Jbd}^E-${Js3Jxf*AcpP179Q_s93FcaYE3*^KvjpMn z1oLGc|AR7_?{-|@+{G{VRX1#GUEjN2mIabt&NnNnqHKXzCMxSNOy}&HcuW_8*W-80 z%Q2LY2{Pj_QAAu#a5)~NnG&g5gT|(4};$`mr0Iutn

#>WeSi{38ne>H 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 z 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 literal 0 HcmV?d00001 diff --git a/libultraship/TestApp/TestApp.vcxproj b/libultraship/TestApp/TestApp.vcxproj new file mode 100644 index 000000000..077c0a27c --- /dev/null +++ b/libultraship/TestApp/TestApp.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {3c4a8151-48d1-4518-be1a-24016a5b800f} + TestApp + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + $(ProjectDir)..\otrlib;$(ProjectDir)..\..\ZAPD\ZAPDUtils;$(IncludePath) + $(SolutionDir)x64\Debug;$(LibraryPath) + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreadedDebug + + + Console + true + otrlib.lib;ZAPDUtils.lib;StormLibDUS.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/libultraship/TestApp/TestApp.vcxproj.filters b/libultraship/TestApp/TestApp.vcxproj.filters new file mode 100644 index 000000000..26604cfae --- /dev/null +++ b/libultraship/TestApp/TestApp.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/libultraship/libultraship.sln b/libultraship/libultraship.sln new file mode 100644 index 000000000..b0adce9b9 --- /dev/null +++ b/libultraship/libultraship.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "libultraship\libultraship.vcxproj", "{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp\TestApp.vcxproj", "{3C4A8151-48D1-4518-BE1A-24016A5B800F}" + ProjectSection(ProjectDependencies) = postProject + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.ActiveCfg = Debug|x64 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.Build.0 = Debug|x64 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.ActiveCfg = Debug|Win32 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.Build.0 = Debug|Win32 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.ActiveCfg = Release|x64 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.Build.0 = Release|x64 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.ActiveCfg = Release|Win32 + {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.Build.0 = Release|Win32 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x64.ActiveCfg = Debug|x64 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x64.Build.0 = Debug|x64 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x86.ActiveCfg = Debug|Win32 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x86.Build.0 = Debug|Win32 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x64.ActiveCfg = Release|x64 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x64.Build.0 = Release|x64 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x86.ActiveCfg = Release|Win32 + {3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x86.Build.0 = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.ActiveCfg = Debug|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.Build.0 = Debug|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.ActiveCfg = Debug|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.Build.0 = Debug|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.ActiveCfg = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.Build.0 = Release|x64 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.ActiveCfg = Release|Win32 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.Build.0 = Release|Win32 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.ActiveCfg = Debug|x64 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.Build.0 = Debug|x64 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.ActiveCfg = Debug|Win32 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.Build.0 = Debug|Win32 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.ActiveCfg = Release|x64 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32 + {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCE19FF1-37C0-49CD-915A-DD695E15F00B} + EndGlobalSection +EndGlobal diff --git a/libultraship/libultraship/Animation.cpp b/libultraship/libultraship/Animation.cpp new file mode 100644 index 000000000..be2decad3 --- /dev/null +++ b/libultraship/libultraship/Animation.cpp @@ -0,0 +1,72 @@ +#include "Animation.h" + +void Ship::AnimationV0::ParseFileBinary(BinaryReader* reader, Resource* res) +{ + Animation* anim = (Animation*)res; + + ResourceFile::ParseFileBinary(reader, res); + + AnimationType animType = (AnimationType)reader->ReadUInt32(); + anim->type = animType; + + if (animType == AnimationType::Normal) + { + anim->frameCount = reader->ReadInt16(); + + uint32_t rotValuesCnt = reader->ReadUInt32(); + anim->rotationValues.reserve(rotValuesCnt); + for (uint32_t i = 0; i < rotValuesCnt; i++) + anim->rotationValues.push_back(reader->ReadUInt16()); + + + uint32_t rotIndCnt = reader->ReadUInt32(); + anim->rotationIndices.reserve(rotIndCnt); + for (int i = 0; i < rotIndCnt; i++) + { + uint16_t x = reader->ReadUInt16(); + uint16_t y = reader->ReadUInt16(); + uint16_t z = reader->ReadUInt16(); + anim->rotationIndices.push_back(RotationIndex(x, y, z)); + } + anim->limit = reader->ReadInt16(); + } + else if (animType == AnimationType::Curve) + { + anim->frameCount = reader->ReadInt16(); + + uint32_t refArrCnt = reader->ReadUInt32(); + anim->refIndexArr.reserve(refArrCnt); + for (uint32_t i = 0; i < refArrCnt; i++) + anim->refIndexArr.push_back(reader->ReadUByte()); + + uint32_t transformDataCnt = reader->ReadUInt32(); + anim->transformDataArr.reserve(transformDataCnt); + for (uint32_t i = 0; i < transformDataCnt; i++) + { + TransformData data; + data.unk_00 = reader->ReadUInt16(); + data.unk_02 = reader->ReadInt16(); + data.unk_04 = reader->ReadInt16(); + data.unk_06 = reader->ReadInt16(); + data.unk_08 = reader->ReadSingle(); + + anim->transformDataArr.push_back(data); + } + + uint32_t copyValuesCnt = reader->ReadUInt32(); + anim->copyValuesArr.reserve(copyValuesCnt); + for (uint32_t i = 0; i < copyValuesCnt; i++) + { + anim->copyValuesArr.push_back(reader->ReadInt16()); + } + } + else if (animType == AnimationType::Link) + { + anim->frameCount = reader->ReadInt16(); + anim->segPtr = reader->ReadUInt32(); + } + else if (animType == AnimationType::Legacy) + { + SPDLOG_DEBUG("BEYTAH ANIMATION?!"); + } +} diff --git a/libultraship/libultraship/Animation.h b/libultraship/libultraship/Animation.h new file mode 100644 index 000000000..20ae4e0da --- /dev/null +++ b/libultraship/libultraship/Animation.h @@ -0,0 +1,63 @@ +#pragma once + +#include "Resource.h" + +namespace Ship +{ + enum class AnimationType + { + Normal = 0, + Link = 1, + Curve = 2, + Legacy = 3, + }; + + struct RotationIndex + { + uint16_t x, y, z; + + RotationIndex(uint16_t nX, uint16_t nY, uint16_t nZ) : x(nX), y(nY), z(nZ) {} + }; + + class TransformData + { + public: + ///* 0x0000 */ u16 unk_00; // appears to be flags + uint16_t unk_00; + ///* 0x0002 */ s16 unk_02; + int16_t unk_02; + ///* 0x0004 */ s16 unk_04; + int16_t unk_04; + ///* 0x0006 */ s16 unk_06; + int16_t unk_06; + ///* 0x0008 */ f32 unk_08; + float unk_08; + }; + + class AnimationV0 : public ResourceFile + { + public: + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class Animation : public Resource + { + public: + AnimationType type; + int16_t frameCount; + + // NORMAL + std::vector rotationValues; + std::vector rotationIndices; + int16_t limit = 0; + + // CURVE + std::vector refIndexArr; + std::vector transformDataArr; + std::vector copyValuesArr; + + // LINK + uint32_t segPtr; // This is temp + + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Archive.cpp b/libultraship/libultraship/Archive.cpp new file mode 100644 index 000000000..41c6649f8 --- /dev/null +++ b/libultraship/libultraship/Archive.cpp @@ -0,0 +1,357 @@ +#include "Archive.h" +#include "Resource.h" +#include "File.h" +#include "spdlog/spdlog.h" +#include "Utils/StringHelper.h" +#include "Lib/StrHash64.h" +#include + +namespace Ship { + Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting) + { + mainMPQ = nullptr; + } + + Archive::Archive(const std::string& MainPath, const std::string& PatchesPath, bool enableWriting, bool genCRCMap) : MainPath(MainPath), PatchesPath(PatchesPath) { + mainMPQ = nullptr; + Load(enableWriting, genCRCMap); + } + + Archive::~Archive() { + Unload(); + } + + bool Archive::IsMainMPQValid() + { + return mainMPQ != nullptr; + } + + std::shared_ptr Archive::CreateArchive(const std::string& archivePath, int fileCapacity) + { + Archive* archive = new Archive(archivePath, true); + + TCHAR* t_filename = new TCHAR[archivePath.size() + 1]; + t_filename[archivePath.size()] = 0; + std::copy(archivePath.begin(), archivePath.end(), t_filename); + + bool success = SFileCreateArchive(t_filename, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_ARCHIVE_V2, fileCapacity, &archive->mainMPQ); + int error = GetLastError(); + + if (success) { + archive->mpqHandles[archivePath] = archive->mainMPQ; + return std::make_shared(*archive); + } else { + SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up."); + return nullptr; + } + } + + std::shared_ptr Archive::LoadFile(const std::string& filePath, bool includeParent, std::shared_ptr FileToLoad) { + HANDLE fileHandle = NULL; + + if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) { + SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->bHasLoadError = true; + return nullptr; + } + + DWORD dwFileSize = SFileGetFileSize(fileHandle, 0); + std::shared_ptr fileData(new char[dwFileSize]); + DWORD dwBytes; + + if (!SFileReadFile(fileHandle, fileData.get(), dwFileSize, &dwBytes, NULL)) { + SPDLOG_ERROR("({}) Failed to read file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + if (!SFileCloseFile(fileHandle)) { + SPDLOG_ERROR("({}) Failed to close file {} from mpq after read failure in archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + } + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->bHasLoadError = true; + return nullptr; + } + + if (!SFileCloseFile(fileHandle)) { + SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + } + + if (FileToLoad == nullptr) { + FileToLoad = std::make_shared(); + FileToLoad->path = filePath; + } + + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->parent = includeParent ? shared_from_this() : nullptr; + FileToLoad->buffer = fileData; + FileToLoad->dwBufferSize = dwFileSize; + FileToLoad->bIsLoaded = true; + + return FileToLoad; + } + + std::shared_ptr Archive::LoadPatchFile(const std::string& filePath, bool includeParent, std::shared_ptr FileToLoad) { + HANDLE fileHandle = NULL; + HANDLE mpqHandle = NULL; + + for(auto [path, handle] : mpqHandles) { + if (SFileOpenFileEx(mpqHandle, filePath.c_str(), 0, &fileHandle)) { + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->bHasLoadError = false; + mpqHandle = handle; + } + } + + if(!mpqHandle) { + FileToLoad->bHasLoadError = true; + return FileToLoad; + } + + DWORD dwFileSize = SFileGetFileSize(fileHandle, 0); + std::shared_ptr fileData(new char[dwFileSize]); + DWORD dwBytes; + + if (!SFileReadFile(fileHandle, fileData.get(), dwFileSize, &dwBytes, NULL)) { + SPDLOG_ERROR("({}) Failed to read file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + if (!SFileCloseFile(fileHandle)) { + SPDLOG_ERROR("({}) Failed to close file {} from mpq after read failure in archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + } + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->bHasLoadError = true; + return nullptr; + } + + if (!SFileCloseFile(fileHandle)) { + SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + } + + if (FileToLoad == nullptr) { + FileToLoad = std::make_shared(); + FileToLoad->path = filePath; + } + + std::unique_lock Lock(FileToLoad->FileLoadMutex); + FileToLoad->parent = includeParent ? shared_from_this() : nullptr; + FileToLoad->buffer = fileData; + FileToLoad->dwBufferSize = dwFileSize; + FileToLoad->bIsLoaded = true; + + return FileToLoad; + } + + bool Archive::AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize) { + HANDLE hFile; + + SYSTEMTIME sysTime; + GetSystemTime(&sysTime); + FILETIME t; + SystemTimeToFileTime(&sysTime, &t); + ULONGLONG stupidHack = static_cast(t.dwHighDateTime) << (sizeof(t.dwHighDateTime) * 8) | t.dwLowDateTime; + + if (!SFileCreateFile(mainMPQ, path.c_str(), stupidHack, dwFileSize, 0, MPQ_FILE_COMPRESS, &hFile)) { + SPDLOG_ERROR("({}) Failed to create file of {} bytes {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str()); + return false; + } + + if (!SFileWriteFile(hFile, (void*)fileData, dwFileSize, MPQ_COMPRESSION_ZLIB)) { + SPDLOG_ERROR("({}) Failed to write {} bytes to {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str()); + if (!SFileCloseFile(hFile)) { + SPDLOG_ERROR("({}) Failed to close file {} after write failure in archive {}", GetLastError(), path.c_str(), MainPath.c_str()); + } + return false; + } + + if (!SFileFinishFile(hFile)) { + SPDLOG_ERROR("({}) Failed to finish file {} in archive {}", GetLastError(), path.c_str(), MainPath.c_str()); + if (!SFileCloseFile(hFile)) { + SPDLOG_ERROR("({}) Failed to close file {} after finish failure in archive {}", GetLastError(), path.c_str(), MainPath.c_str()); + } + return false; + } + // SFileFinishFile already frees the handle, so no need to close it again. + + addedFiles.push_back(path); + hashes[CRC64(path.c_str())] = path; + + return true; + } + + bool Archive::RemoveFile(const std::string& path) { + // TODO: Notify the resource manager and child Files + + if (!SFileRemoveFile(mainMPQ, path.c_str(), 0)) { + SPDLOG_ERROR("({}) Failed to remove file {} in archive {}", GetLastError(), path.c_str(), MainPath.c_str()); + return false; + } + + return true; + } + + bool Archive::RenameFile(const std::string& oldPath, const std::string& newPath) { + // TODO: Notify the resource manager and child Files + + if (!SFileRenameFile(mainMPQ, oldPath.c_str(), newPath.c_str())) { + SPDLOG_ERROR("({}) Failed to rename file {} to {} in archive {}", GetLastError(), oldPath.c_str(), newPath.c_str(), MainPath.c_str()); + return false; + } + + return true; + } + + std::vector Archive::ListFiles(const std::string& searchMask) { + auto fileList = std::vector(); + SFILE_FIND_DATA findContext; + HANDLE hFind; + + + hFind = SFileFindFirstFile(mainMPQ, searchMask.c_str(), &findContext, nullptr); + //if (hFind && GetLastError() != ERROR_NO_MORE_FILES) { + if (hFind != nullptr) { + fileList.push_back(findContext); + + bool fileFound; + do { + fileFound = SFileFindNextFile(hFind, &findContext); + + if (fileFound) { + fileList.push_back(findContext); + } + else if (!fileFound && GetLastError() != ERROR_NO_MORE_FILES) + //else if (!fileFound) + { + SPDLOG_ERROR("({}), Failed to search with mask {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str()); + if (!SListFileFindClose(hFind)) { + SPDLOG_ERROR("({}) Failed to close file search {} after failure in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str()); + } + return fileList; + } + } while (fileFound); + } + else if (GetLastError() != ERROR_NO_MORE_FILES) { + SPDLOG_ERROR("({}), Failed to search with mask {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str()); + return fileList; + } + + if (hFind != nullptr) + { + if (!SFileFindClose(hFind)) { + SPDLOG_ERROR("({}) Failed to close file search {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str()); + } + } + + return fileList; + } + + bool Archive::HasFile(const std::string& filename) { + bool result = false; + auto start = std::chrono::steady_clock::now(); + + auto lst = ListFiles(filename); + + for (const auto& item : lst) { + if (item.cFileName == filename) { + result = true; + break; + } + } + + auto end = std::chrono::steady_clock::now(); + auto diff = std::chrono::duration_cast(end - start).count(); + + return result; + } + + std::string Archive::HashToString(uint64_t hash) { + return hashes[hash]; + } + + bool Archive::Load(bool enableWriting, bool genCRCMap) { + return LoadMainMPQ(enableWriting, genCRCMap) && LoadPatchMPQs(); + } + + bool Archive::Unload() + { + bool success = true; + for (const auto& mpqHandle : mpqHandles) { + if (!SFileCloseArchive(mpqHandle.second)) { + SPDLOG_ERROR("({}) Failed to close mpq {}", GetLastError(), mpqHandle.first.c_str()); + success = false; + } + } + + mainMPQ = nullptr; + + return success; + } + + bool Archive::LoadPatchMPQs() { + // OTRTODO: We also want to periodically scan the patch directories for new MPQs. When new MPQs are found we will load the contents to fileCache and then copy over to gameResourceAddresses + if (PatchesPath.length() > 0) { + if (std::filesystem::is_directory(PatchesPath)) { + for (const auto& p : std::filesystem::recursive_directory_iterator(PatchesPath)) { + if (StringHelper::IEquals(p.path().extension().string(), ".otr") || StringHelper::IEquals(p.path().extension().string(), ".mpq")) { + SPDLOG_ERROR("Reading {} mpq patch", p.path().string().c_str()); + if (!LoadPatchMPQ(p.path().string())) { + return false; + } + } + } + } + } + + return true; + } + + bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) { + HANDLE mpqHandle = NULL; + std::string fullPath = std::filesystem::absolute(MainPath).string(); + + std::wstring wFileName = std::filesystem::absolute(MainPath).wstring(); + + if (!SFileOpenArchive(wFileName.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) { + SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str()); + return false; + } + + mpqHandles[fullPath] = mpqHandle; + mainMPQ = mpqHandle; + + if (genCRCMap) { + auto listFile = LoadFile("(listfile)", false); + + std::vector lines = StringHelper::Split(std::string(listFile->buffer.get(), listFile->dwBufferSize), "\n"); + + for (size_t i = 0; i < lines.size(); i++) { + std::string line = StringHelper::Strip(lines[i], "\r"); + //uint64_t hash = StringHelper::StrToL(lines[i], 16); + + uint64_t hash = CRC64(line.c_str()); + hashes[hash] = line; + } + } + + return true; + } + + bool Archive::LoadPatchMPQ(const std::string& path) { + HANDLE patchHandle = NULL; + std::string fullPath = std::filesystem::absolute(path).string(); + if (mpqHandles.contains(fullPath)) { + return true; + } + + std::wstring wPath = std::filesystem::absolute(path).wstring(); + + if (!SFileOpenArchive(wPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) { + SPDLOG_ERROR("({}) Failed to open patch mpq file {} while applying to {}.", GetLastError(), path.c_str(), MainPath.c_str()); + return false; + } + + if (!SFileOpenPatchArchive(mainMPQ, wPath.c_str(), "", 0)) { + SPDLOG_ERROR("({}) Failed to apply patch mpq file {} to main mpq {}.", GetLastError(), path.c_str(), MainPath.c_str()); + return false; + } + + mpqHandles[fullPath] = patchHandle; + + return true; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Archive.h b/libultraship/libultraship/Archive.h new file mode 100644 index 000000000..f8fe3e0fd --- /dev/null +++ b/libultraship/libultraship/Archive.h @@ -0,0 +1,55 @@ +#pragma once + +#undef _DLL + +#include + +#include +#include +#include +#include +#include "Resource.h" +//#include "Lib/StrHash64.h" +#include "Lib/StormLib/StormLib.h" + + +namespace Ship +{ + class File; + + class Archive : public std::enable_shared_from_this + { + public: + Archive(const std::string& MainPath, bool enableWriting); + Archive(const std::string& MainPath, const std::string& PatchesPath, bool enableWriting, bool genCRCMap = true); + ~Archive(); + + bool IsMainMPQValid(); + + static std::shared_ptr CreateArchive(const std::string& archivePath, int fileCapacity); + + std::shared_ptr LoadFile(const std::string& filePath, bool includeParent = true, std::shared_ptr FileToLoad = nullptr); + std::shared_ptr LoadPatchFile(const std::string& filePath, bool includeParent = true, std::shared_ptr FileToLoad = nullptr); + + bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize); + bool RemoveFile(const std::string& path); + bool RenameFile(const std::string& oldPath, const std::string& newPath); + std::vector ListFiles(const std::string& searchMask); + bool HasFile(const std::string& searchMask); + std::string HashToString(uint64_t hash); + protected: + bool Load(bool enableWriting, bool genCRCMap); + bool Unload(); + private: + std::string MainPath; + std::string PatchesPath; + std::map mpqHandles; + std::vector addedFiles; + std::map hashes; + HANDLE mainMPQ; + + bool LoadMainMPQ(bool enableWriting, bool genCRCMap); + bool LoadPatchMPQs(); + bool LoadPatchMPQ(const std::string& path); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Array.cpp b/libultraship/libultraship/Array.cpp new file mode 100644 index 000000000..f256903bf --- /dev/null +++ b/libultraship/libultraship/Array.cpp @@ -0,0 +1,61 @@ +#include "Array.h" +#include "Vertex.h" + +namespace Ship +{ + void ArrayV0::ParseFileBinary(BinaryReader* reader, Resource* res) + { + Array* arr = (Array*)res; + + ResourceFile::ParseFileBinary(reader, res); + + ZResourceType resType = (ZResourceType)reader->ReadUInt32(); + uint32_t arrayCnt = reader->ReadUInt32(); + + for (uint32_t i = 0; i < arrayCnt; i++) + { + if (resType == ZResourceType::Vertex) + { + Vtx data; + data.x = reader->ReadInt16(); + data.y = reader->ReadInt16(); + data.z = reader->ReadInt16(); + data.flag = reader->ReadUInt16(); + data.s = reader->ReadInt16(); + data.t = reader->ReadInt16(); + data.r = reader->ReadUByte(); + data.g = reader->ReadUByte(); + data.b = reader->ReadUByte(); + data.a = reader->ReadUByte(); + arr->vertices.push_back(data); + } + else + { + ScalarType scalType = (ScalarType)reader->ReadUInt32(); + + int iter = 1; + + if (resType == ZResourceType::Vector) + iter = reader->ReadUInt32(); + + for (int k = 0; k < iter; k++) + { + ScalarData data; + + switch (scalType) + { + case ScalarType::ZSCALAR_S16: + data.s16 = reader->ReadInt16(); + break; + case ScalarType::ZSCALAR_U16: + data.u16 = reader->ReadUInt16(); + break; + // OTRTODO: IMPLEMENT OTHER TYPES! + } + + arr->scalars.push_back(data); + } + } + } + } +} diff --git a/libultraship/libultraship/Array.h b/libultraship/libultraship/Array.h new file mode 100644 index 000000000..6bccb2d7d --- /dev/null +++ b/libultraship/libultraship/Array.h @@ -0,0 +1,85 @@ +#pragma once + +#include "Resource.h" +#include "Vertex.h" + +namespace Ship +{ + typedef union ScalarData + { + uint8_t u8; + int8_t s8; + uint16_t u16; + int16_t s16; + uint32_t u32; + int32_t s32; + uint64_t u64; + int64_t s64; + float f32; + double f64; + } ScalarData; + + enum class ScalarType + { + ZSCALAR_NONE, + ZSCALAR_S8, + ZSCALAR_U8, + ZSCALAR_X8, + ZSCALAR_S16, + ZSCALAR_U16, + ZSCALAR_X16, + ZSCALAR_S32, + ZSCALAR_U32, + ZSCALAR_X32, + ZSCALAR_S64, + ZSCALAR_U64, + ZSCALAR_X64, + ZSCALAR_F32, + ZSCALAR_F64 + }; + + // OTRTODO: Replace this with something that can be shared between the exporter and importer... + enum class ZResourceType + { + Error, + Animation, + Array, + AltHeader, + Background, + Blob, + CollisionHeader, + Cutscene, + DisplayList, + Limb, + LimbTable, + Mtx, + Path, + PlayerAnimationData, + Room, + RoomCommand, + Scalar, + Scene, + Skeleton, + String, + Symbol, + Texture, + TextureAnimation, + TextureAnimationParams, + Vector, + Vertex, + }; + + class ArrayV0 : public ResourceFile + { + public: + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class Array : public Resource + { + public: + std::vector scalars; + std::vector vertices; + + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/AudioPlayer.h b/libultraship/libultraship/AudioPlayer.h new file mode 100644 index 000000000..175cc5100 --- /dev/null +++ b/libultraship/libultraship/AudioPlayer.h @@ -0,0 +1,15 @@ +#pragma once +#include "stdint.h" + +namespace Ship { + class AudioPlayer { + + public: + AudioPlayer() { }; + + virtual bool Init(void) = 0; + virtual int Buffered(void) = 0; + virtual int GetDesiredBuffered(void) = 0; + virtual void Play(const uint8_t* buf, uint32_t len) = 0; + }; +} diff --git a/libultraship/libultraship/Blob.cpp b/libultraship/libultraship/Blob.cpp new file mode 100644 index 000000000..ce8f577a8 --- /dev/null +++ b/libultraship/libultraship/Blob.cpp @@ -0,0 +1,18 @@ +#include "Blob.h" + +namespace Ship +{ + void BlobV0::ParseFileBinary(BinaryReader* reader, Resource* res) + { + Blob* blob = (Blob*)res; + + ResourceFile::ParseFileBinary(reader, blob); + + uint32_t dataSize = reader->ReadUInt32(); + + blob->data.reserve(dataSize); + + for (uint32_t i = 0; i < dataSize; i++) + blob->data.push_back(reader->ReadUByte()); + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Blob.h b/libultraship/libultraship/Blob.h new file mode 100644 index 000000000..14bece8a4 --- /dev/null +++ b/libultraship/libultraship/Blob.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Resource.h" + +namespace Ship +{ + class BlobV0 : public ResourceFile + { + public: + + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class Blob : public Resource + { + public: + std::vector data; + }; +}; \ No newline at end of file diff --git a/libultraship/libultraship/CollisionHeader.cpp b/libultraship/libultraship/CollisionHeader.cpp new file mode 100644 index 000000000..2cfda6f83 --- /dev/null +++ b/libultraship/libultraship/CollisionHeader.cpp @@ -0,0 +1,99 @@ +#include "CollisionHeader.h" + +void Ship::CollisionHeaderV0::ParseFileBinary(BinaryReader* reader, Resource* res) +{ + CollisionHeader* col = (CollisionHeader*)res; + + ResourceFile::ParseFileBinary(reader, res); + + col->absMinX = reader->ReadInt16(); + col->absMinY = reader->ReadInt16(); + col->absMinZ = reader->ReadInt16(); + + col->absMaxX = reader->ReadInt16(); + col->absMaxY = reader->ReadInt16(); + col->absMaxZ = reader->ReadInt16(); + + uint32_t vtxCnt = reader->ReadInt32(); + col->vertices.reserve(vtxCnt); + + for (uint32_t i = 0; i < vtxCnt; i++) + { + float x = reader->ReadInt16(); + float y = reader->ReadInt16(); + float z = reader->ReadInt16(); + col->vertices.push_back(Vec3f(x, y, z)); + } + + uint32_t polyCnt = reader->ReadUInt32(); + col->polygons.reserve(polyCnt); + + for (uint32_t i = 0; i < polyCnt; i++) + col->polygons.push_back(Ship::PolygonEntry(reader)); + + uint32_t polyTypesCnt = reader->ReadUInt32(); + col->polygonTypes.reserve(polyTypesCnt); + + for (uint32_t i = 0; i < polyTypesCnt; i++) + col->polygonTypes.push_back(reader->ReadUInt64()); + + col->camData = new CameraDataList(); + + uint32_t camEntriesCnt = reader->ReadUInt32(); + col->camData->entries.reserve(camEntriesCnt); + + for (uint32_t i = 0; i < camEntriesCnt; i++) + { + Ship::CameraDataEntry* entry = new Ship::CameraDataEntry(); + entry->cameraSType = reader->ReadUInt16(); + entry->numData = reader->ReadInt16(); + entry->cameraPosDataIdx = reader->ReadInt32(); + col->camData->entries.push_back(entry); + } + + uint32_t camPosCnt = reader->ReadInt32(); + col->camData->cameraPositionData.reserve(camPosCnt); + + for (uint32_t i = 0; i < camPosCnt; i++) + { + Ship::CameraPositionData* entry = new Ship::CameraPositionData(); + entry->x = reader->ReadInt16(); + entry->y = reader->ReadInt16(); + entry->z = reader->ReadInt16(); + col->camData->cameraPositionData.push_back(entry); + } + + uint32_t waterBoxCnt = reader->ReadInt32(); + col->waterBoxes.reserve(waterBoxCnt); + + for (uint32_t i = 0; i < waterBoxCnt; i++) + { + Ship::WaterBoxHeader waterBox; + waterBox.xMin = reader->ReadInt16(); + waterBox.ySurface = reader->ReadInt16(); + waterBox.zMin = reader->ReadInt16(); + waterBox.xLength = reader->ReadInt16(); + waterBox.zLength = reader->ReadInt16(); + waterBox.properties = reader->ReadInt32(); + + col->waterBoxes.push_back(waterBox); + } +} + +Ship::PolygonEntry::PolygonEntry(BinaryReader* reader) +{ + type = reader->ReadUInt16(); + + vtxA = reader->ReadUInt16(); + vtxB = reader->ReadUInt16(); + vtxC = reader->ReadUInt16(); + + a = reader->ReadUInt16(); + b = reader->ReadUInt16(); + c = reader->ReadUInt16(); + d = reader->ReadUInt16(); +} + +Ship::WaterBoxHeader::WaterBoxHeader() +{ +} \ No newline at end of file diff --git a/libultraship/libultraship/CollisionHeader.h b/libultraship/libultraship/CollisionHeader.h new file mode 100644 index 000000000..543f0e2df --- /dev/null +++ b/libultraship/libultraship/CollisionHeader.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include +#include "Resource.h" +#include "Vec2f.h" +#include "Vec3f.h" +#include "Color3b.h" + +namespace Ship +{ + class PolygonEntry + { + public: + uint16_t type; + uint16_t vtxA, vtxB, vtxC; + uint16_t a, b, c, d; + + PolygonEntry(BinaryReader* reader); + }; + + class WaterBoxHeader + { + public: + int16_t xMin; + int16_t ySurface; + int16_t zMin; + int16_t xLength; + int16_t zLength; + int16_t pad; + int32_t properties; + + WaterBoxHeader(); + }; + + + class CameraDataEntry + { + public: + uint16_t cameraSType; + int16_t numData; + int32_t cameraPosDataIdx; + }; + + class CameraPositionData + { + public: + int16_t x, y, z; + }; + + class CameraDataList + { + public: + std::vector entries; + std::vector cameraPositionData; + }; + + class CollisionHeaderV0 : public ResourceFile + { + public: + int16_t absMinX, absMinY, absMinZ; + int16_t absMaxX, absMaxY, absMaxZ; + + std::vector vertices; + std::vector polygons; + std::vector polygonTypes; + std::vector waterBoxes; + CameraDataList* camData = nullptr; + + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class CollisionHeader : public Resource + { + public: + int16_t absMinX, absMinY, absMinZ; + int16_t absMaxX, absMaxY, absMaxZ; + + std::vector vertices; + std::vector polygons; + std::vector polygonTypes; + std::vector waterBoxes; + CameraDataList* camData = nullptr; + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/ConfigFile.cpp b/libultraship/libultraship/ConfigFile.cpp new file mode 100644 index 000000000..dd4e5bec5 --- /dev/null +++ b/libultraship/libultraship/ConfigFile.cpp @@ -0,0 +1,159 @@ +#include "ConfigFile.h" +#include "spdlog/spdlog.h" +#include "GlobalCtx2.h" +#include "Window.h" + +namespace Ship { + ConfigFile::ConfigFile(std::shared_ptr Context, const std::string& Path) : Context(Context), Path(Path), File(Path.c_str()) { + if (Path.empty()) { + SPDLOG_ERROR("ConfigFile received an empty file name"); + exit(EXIT_FAILURE); + } + + if (!File.read(Val)) { + if (!CreateDefaultConfig()) { + SPDLOG_ERROR("Failed to create default configs"); + exit(EXIT_FAILURE); + } + } + } + + ConfigFile::~ConfigFile() { + if (!Save()) { + SPDLOG_ERROR("Failed to save configs!!!"); + } + + SPDLOG_INFO("destruct configfile"); + } + + mINI::INIMap& ConfigFile::operator[](const std::string& Section) { + return Val[Section]; + } + + mINI::INIMap ConfigFile::get(const std::string& Section) { + return Val.get(Section); + } + + bool ConfigFile::has(const std::string& Section) { + return Val.has(Section); + } + + bool ConfigFile::remove(const std::string& Section) { + return Val.remove(Section); + } + + void ConfigFile::clear() { + Val.clear(); + } + + std::size_t ConfigFile::size() const { + return Val.size(); + } + + bool ConfigFile::Save() { + return File.write(Val); + } + + bool ConfigFile::CreateDefaultConfig() { + (*this)["ARCHIVE"]["Main Archive"] = "oot.otr"; + (*this)["ARCHIVE"]["Patches Directory"] = ""; + + (*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto"; + (*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged"; + (*this)["CONTROLLERS"]["CONTROLLER 3"] = "Unplugged"; + (*this)["CONTROLLERS"]["CONTROLLER 4"] = "Unplugged"; + + (*this)["KEYBOARD SHORTCUTS"]["KEY_FULLSCREEN"] = std::to_string(0x044); + (*this)["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"] = std::to_string(0x029); + + (*this)["WINDOW"]["WINDOW WIDTH"] = std::to_string(320); + (*this)["WINDOW"]["WINDOW HEIGHT"] = std::to_string(240); + (*this)["WINDOW"]["FULLSCREEN WIDTH"] = std::to_string(1920); + (*this)["WINDOW"]["FULLSCREEN HEIGHT"] = std::to_string(1080); + (*this)["WINDOW"]["FULLSCREEN"] = std::to_string(false); + (*this)["WINDOW"]["GFX BACKEND"] = ""; + + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CRIGHT)] = std::to_string(0x14D); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CLEFT)] = std::to_string(0x14B); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CDOWN)] = std::to_string(0x150); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CUP)] = std::to_string(0x148); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_R)] = std::to_string(0x013); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_L)] = std::to_string(0x012); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DRIGHT)] = std::to_string(0x023); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DLEFT)] = std::to_string(0x021); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DDOWN)] = std::to_string(0x022); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DUP)] = std::to_string(0x014); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_START)] = std::to_string(0x039); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_Z)] = std::to_string(0x02C); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_B)] = std::to_string(0x02E); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_A)] = std::to_string(0x02D); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); + (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKUP)] = std::to_string(0x011); + + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CRIGHT)] = std::to_string(0x14D); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CLEFT)] = std::to_string(0x14B); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CDOWN)] = std::to_string(0x150); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CUP)] = std::to_string(0x148); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_R)] = std::to_string(0x013); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_L)] = std::to_string(0x012); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DRIGHT)] = std::to_string(0x023); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DLEFT)] = std::to_string(0x021); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DDOWN)] = std::to_string(0x022); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DUP)] = std::to_string(0x014); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_START)] = std::to_string(0x039); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_Z)] = std::to_string(0x02C); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_B)] = std::to_string(0x02E); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_A)] = std::to_string(0x02D); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); + (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKUP)] = std::to_string(0x011); + + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CRIGHT)] = std::to_string(0x14D); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CLEFT)] = std::to_string(0x14B); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CDOWN)] = std::to_string(0x150); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CUP)] = std::to_string(0x148); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_R)] = std::to_string(0x013); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_L)] = std::to_string(0x012); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DRIGHT)] = std::to_string(0x023); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DLEFT)] = std::to_string(0x021); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DDOWN)] = std::to_string(0x022); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DUP)] = std::to_string(0x014); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_START)] = std::to_string(0x039); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_Z)] = std::to_string(0x02C); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_B)] = std::to_string(0x02E); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_A)] = std::to_string(0x02D); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); + (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKUP)] = std::to_string(0x011); + + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CRIGHT)] = std::to_string(0x14D); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CLEFT)] = std::to_string(0x14B); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CDOWN)] = std::to_string(0x150); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CUP)] = std::to_string(0x148); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_R)] = std::to_string(0x013); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_L)] = std::to_string(0x012); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DRIGHT)] = std::to_string(0x023); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DLEFT)] = std::to_string(0x021); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DDOWN)] = std::to_string(0x022); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DUP)] = std::to_string(0x014); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_START)] = std::to_string(0x039); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_Z)] = std::to_string(0x02C); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_B)] = std::to_string(0x02E); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_A)] = std::to_string(0x02D); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); + (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKUP)] = std::to_string(0x011); + + (*this)["SDL CONTROLLER 1"]["GUID"] = ""; + (*this)["SDL CONTROLLER 2"]["GUID"] = ""; + (*this)["SDL CONTROLLER 3"]["GUID"] = ""; + (*this)["SDL CONTROLLER 4"]["GUID"] = ""; + + return File.generate(Val); + } +} \ No newline at end of file diff --git a/libultraship/libultraship/ConfigFile.h b/libultraship/libultraship/ConfigFile.h new file mode 100644 index 000000000..dcf2a0e4a --- /dev/null +++ b/libultraship/libultraship/ConfigFile.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include "Lib/mINI/src/mini/ini.h" +#include "UltraController.h" +#include "LUSMacros.h" + +namespace Ship { + class GlobalCtx2; + + class ConfigFile { + public: + ConfigFile(std::shared_ptr Context, const std::string& Path); + ~ConfigFile(); + + bool Save(); + + // Expose the ini values. + mINI::INIMap& operator[](const std::string& Section); + mINI::INIMap get(const std::string& Section); + bool has(const std::string& Section); + bool remove(const std::string& Section); + void clear(); + std::size_t size() const; + std::shared_ptr GetContext() { return Context.lock(); } + + protected: + bool CreateDefaultConfig(); + + private: + mINI::INIFile File; + mINI::INIStructure Val; + std::weak_ptr Context; + std::string Path; + }; +} diff --git a/libultraship/libultraship/Controller.cpp b/libultraship/libultraship/Controller.cpp new file mode 100644 index 000000000..e400f6e18 --- /dev/null +++ b/libultraship/libultraship/Controller.cpp @@ -0,0 +1,96 @@ +#include "Controller.h" +#include "GlobalCtx2.h" +#include "stox.h" +#include + +namespace Ship { + Controller::Controller(int32_t dwControllerNumber) : dwControllerNumber(dwControllerNumber) { + dwPressedButtons = 0; + wStickX = 0; + wStickY = 0; + wGyroX = 0; + wGyroY = 0; + Attachment = nullptr; + } + + void Controller::Read(OSContPad* pad) { + ReadFromSource(); + + pad->button |= dwPressedButtons & 0xFFFF; + + if (pad->stick_x == 0) { + if (dwPressedButtons & BTN_STICKLEFT) { + pad->stick_x = -128; + } + else if (dwPressedButtons & BTN_STICKRIGHT) { + pad->stick_x = 127; + } + else { + pad->stick_x = wStickX; + } + } + + if (pad->stick_y == 0) { + if (dwPressedButtons & BTN_STICKDOWN) { + pad->stick_y = -128; + } + else if (dwPressedButtons & BTN_STICKUP) { + pad->stick_y = 127; + } + else { + pad->stick_y = wStickY; + } + } + + pad->gyro_x = wGyroX; + pad->gyro_y = wGyroY; + } + + void Controller::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) { + // Update the config value. + std::string ConfSection = GetBindingConfSection(); + std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ConfigFile& Conf = *pConf.get(); + Conf[ConfSection][szButtonName] = dwScancode; + + // Reload the button mapping from Config + LoadBinding(); + } + + void Controller::LoadBinding() { + std::string ConfSection = GetBindingConfSection(); + std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ConfigFile& Conf = *pConf.get(); + + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT)])] = BTN_CRIGHT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT)])] = BTN_CLEFT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN)])] = BTN_CDOWN; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP)])] = BTN_CUP; + //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT + "_2")])] = BTN_CRIGHT; + //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT + "_2")])] = BTN_CLEFT; + //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN + "_2")])] = BTN_CDOWN; + //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP + "_2")])] = BTN_CUP; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_R)])] = BTN_R; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_L)])] = BTN_L; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DRIGHT)])] = BTN_DRIGHT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DLEFT)])] = BTN_DLEFT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DDOWN)])] = BTN_DDOWN; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DUP)])] = BTN_DUP; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_START)])] = BTN_START; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_Z)])] = BTN_Z; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_B)])] = BTN_B; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_A)])] = BTN_A; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKRIGHT)])] = BTN_STICKRIGHT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKLEFT)])] = BTN_STICKLEFT; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKDOWN)])] = BTN_STICKDOWN; + ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKUP)])] = BTN_STICKUP; + } + + std::string Controller::GetConfSection() { + return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1); + } + + std::string Controller::GetBindingConfSection() { + return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1); + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Controller.h b/libultraship/libultraship/Controller.h new file mode 100644 index 000000000..c78142af4 --- /dev/null +++ b/libultraship/libultraship/Controller.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include "stdint.h" +#include "UltraController.h" +#include "ControllerAttachment.h" + +#define EXTENDED_SCANCODE_BIT (1 << 8) +#define AXIS_SCANCODE_BIT (1 << 9) + +namespace Ship { + class Controller { + + public: + Controller(int32_t dwControllerNumber); + + void Read(OSContPad* pad); + virtual void ReadFromSource() = 0; + virtual void WriteToSource(ControllerCallback* controller) = 0; + bool isRumbling; + + void SetButtonMapping(const std::string& szButtonName, int32_t dwScancode); + std::shared_ptr GetAttachment() { return Attachment; } + int32_t GetControllerNumber() { return dwControllerNumber; } + + protected: + int32_t dwPressedButtons; + std::map ButtonMapping; + int8_t wStickX; + int8_t wStickY; + float wGyroX; + float wGyroY; + + virtual std::string GetControllerType() = 0; + virtual std::string GetConfSection() = 0; + virtual std::string GetBindingConfSection() = 0; + void LoadBinding(); + + private: + std::shared_ptr Attachment; + int32_t dwControllerNumber; + }; +} diff --git a/libultraship/libultraship/ControllerAttachment.cpp b/libultraship/libultraship/ControllerAttachment.cpp new file mode 100644 index 000000000..3e0b5e825 --- /dev/null +++ b/libultraship/libultraship/ControllerAttachment.cpp @@ -0,0 +1,5 @@ +#include "ControllerAttachment.h" + +namespace Ship { + +} \ No newline at end of file diff --git a/libultraship/libultraship/ControllerAttachment.h b/libultraship/libultraship/ControllerAttachment.h new file mode 100644 index 000000000..00a35a509 --- /dev/null +++ b/libultraship/libultraship/ControllerAttachment.h @@ -0,0 +1,8 @@ +#pragma once + +namespace Ship { + class ControllerAttachment { + }; +} + + diff --git a/libultraship/libultraship/Cutscene.cpp b/libultraship/libultraship/Cutscene.cpp new file mode 100644 index 000000000..4d804167b --- /dev/null +++ b/libultraship/libultraship/Cutscene.cpp @@ -0,0 +1,21 @@ +#include "Cutscene.h" + +void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res) +{ + Cutscene* cs = (Cutscene*)res; + + ResourceFile::ParseFileBinary(reader, res); + + uint32_t numEntries = reader->ReadUInt32(); + cs->commands.reserve(numEntries); + + for (uint32_t i = 0; i < numEntries; i++) + { + uint32_t data = reader->ReadUInt32(); + uint16_t opcode = data >> 16; + + cs->commands.push_back(data); + } + + //int bp = 0; +} diff --git a/libultraship/libultraship/Cutscene.h b/libultraship/libultraship/Cutscene.h new file mode 100644 index 000000000..09ce31021 --- /dev/null +++ b/libultraship/libultraship/Cutscene.h @@ -0,0 +1,28 @@ +#pragma once + +#include "Resource.h" + +namespace Ship +{ + class CutsceneV0 : public ResourceFile + { + public: + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class CutsceneCommand + { + public: + uint32_t commandID; + uint32_t commandIndex; + + CutsceneCommand() {}; + }; + + class Cutscene : public Resource + { + public: + //int32_t endFrame; + std::vector commands; + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Cvar.cpp b/libultraship/libultraship/Cvar.cpp new file mode 100644 index 000000000..306a18e83 --- /dev/null +++ b/libultraship/libultraship/Cvar.cpp @@ -0,0 +1,100 @@ +#include "cvar.h" +#include +#include +#include + +std::map cvars; + +CVar* CVar_GetVar(char* name) { + std::string key(name); + return cvars.contains(key) ? cvars[key] : nullptr; +} + +extern "C" CVar* CVar_Get(char* name) { + return CVar_GetVar(name); +} + +extern "C" s32 CVar_GetS32(char* name, s32 defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar != nullptr) { + if (cvar->type == CVAR_TYPE_S32) + return cvar->value.valueS32; + } + + return defaultValue; +} + +extern "C" float CVar_GetFloat(char* name, float defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar != nullptr) { + if (cvar->type == CVAR_TYPE_FLOAT) + return cvar->value.valueFloat; + } + + return defaultValue; +} + +extern "C" char* CVar_GetString(char* name, char* defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar != nullptr) { + if (cvar->type == CVAR_TYPE_STRING) + return cvar->value.valueStr; + } + + return defaultValue; +} + +extern "C" void CVar_SetS32(char* name, s32 value) { + CVar* cvar = CVar_Get(name); + if (!cvar) { + cvar = new CVar; + cvars[std::string(name)] = cvar; + } + cvar->type = CVAR_TYPE_S32; + cvar->value.valueS32 = value; +} + +void CVar_SetFloat(char* name, float value) { + CVar* cvar = CVar_Get(name); + if (!cvar) { + cvar = new CVar; + cvars[std::string(name)] = cvar; + } + cvar->type = CVAR_TYPE_FLOAT; + cvar->value.valueFloat = value; +} + +void CVar_SetString(char* name, char* value) { + CVar* cvar = CVar_Get(name); + if (!cvar) { + cvar = new CVar; + cvars[std::string(name)] = cvar; + } + cvar->type = CVAR_TYPE_STRING; + cvar->value.valueStr = value; +} + + +extern "C" void CVar_RegisterS32(char* name, s32 defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar == nullptr) + CVar_SetS32(name, defaultValue); +} + +extern "C" void CVar_RegisterFloat(char* name, float defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar == nullptr) + CVar_SetFloat(name, defaultValue); +} + +extern "C" void CVar_RegisterString(char* name, char* defaultValue) { + CVar* cvar = CVar_Get(name); + + if (cvar == nullptr) + CVar_SetString(name, defaultValue); +} \ No newline at end of file diff --git a/libultraship/libultraship/Cvar.h b/libultraship/libultraship/Cvar.h new file mode 100644 index 000000000..7bac8f20b --- /dev/null +++ b/libultraship/libultraship/Cvar.h @@ -0,0 +1,49 @@ +#ifndef _CVAR_H +#define _CVAR_H + +#include + +typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType; + +typedef struct CVar { + char* name; + CVarType type; + + union { + s32 valueS32; + float valueFloat; + char* valueStr; + } value; +} CVar; + +#ifdef __cplusplus +extern "C" +{ +#endif +//#include + + +CVar* CVar_Get(char* name); +s32 CVar_GetS32(char* name, s32 defaultValue); +float CVar_GetFloat(char* name, float defaultValue); +char* CVar_GetString(char* name, char* defaultValue); +void CVar_SetS32(char* name, s32 value); + +void CVar_RegisterS32(char* name, s32 defaultValue); +void CVar_RegisterFloat(char* name, float defaultValue); +void CVar_RegisterString(char* name, char* defaultValue); + +#ifdef __cplusplus +}; +#endif + +#ifdef __cplusplus +#include +#include + +extern std::map cvars; +CVar* CVar_GetVar(char* name); +void CVar_SetFloat(char* name, float value); +void CVar_SetString(char* name, char* value); +#endif +#endif \ No newline at end of file diff --git a/libultraship/libultraship/DisplayList.cpp b/libultraship/libultraship/DisplayList.cpp new file mode 100644 index 000000000..93d53a24b --- /dev/null +++ b/libultraship/libultraship/DisplayList.cpp @@ -0,0 +1,31 @@ +#include "DisplayList.h" +#include "PR/ultra64/gbi.h" + +namespace Ship +{ + void DisplayListV0::ParseFileBinary(BinaryReader* reader, Resource* res) + { + DisplayList* dl = (DisplayList*)res; + + ResourceFile::ParseFileBinary(reader, res); + + while (reader->GetBaseAddress() % 8 != 0) + reader->ReadByte(); + + while (true) + { + uint64_t data = reader->ReadUInt64(); + + dl->instructions.push_back(data); + + uint8_t opcode = data >> 24; + + // These are 128-bit commands, so read an extra 64 bits... + if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR) + dl->instructions.push_back(reader->ReadUInt64()); + + if (opcode == G_ENDDL) + break; + } + } +} \ No newline at end of file diff --git a/libultraship/libultraship/DisplayList.h b/libultraship/libultraship/DisplayList.h new file mode 100644 index 000000000..906e66197 --- /dev/null +++ b/libultraship/libultraship/DisplayList.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include "Resource.h" +#include "Vec2f.h" +#include "Vec3f.h" +#include "Color3b.h" + +namespace Ship +{ + class DisplayListV0 : public ResourceFile + { + public: + void ParseFileBinary(BinaryReader* reader, Resource* res) override; + }; + + class DisplayList : public Resource + { + public: + std::vector instructions; + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Environment.cpp b/libultraship/libultraship/Environment.cpp new file mode 100644 index 000000000..7f10c8c44 --- /dev/null +++ b/libultraship/libultraship/Environment.cpp @@ -0,0 +1,15 @@ +#include "Environment.h" + +#include +#include + +std::map environmentVars; + +namespace SohUtils { + void saveEnvironmentVar(const std::string& key, const std::string& value) { + environmentVars[key] = value; + } + std::string getEnvironmentVar(const std::string& key) { + return environmentVars[key]; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Environment.h b/libultraship/libultraship/Environment.h new file mode 100644 index 000000000..4d6ab3346 --- /dev/null +++ b/libultraship/libultraship/Environment.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace SohUtils { + void saveEnvironmentVar(const std::string& key, const std::string& value); + std::string getEnvironmentVar(const std::string& key); +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/AnimationFactory.cpp b/libultraship/libultraship/Factories/AnimationFactory.cpp new file mode 100644 index 000000000..a9370610f --- /dev/null +++ b/libultraship/libultraship/Factories/AnimationFactory.cpp @@ -0,0 +1,25 @@ +#include "AnimationFactory.h" + +namespace Ship +{ + Animation* AnimationFactory::ReadAnimation(BinaryReader* reader) + { + Animation* anim = new Animation(); + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + AnimationV0 Anim = AnimationV0(); + Anim.ParseFileBinary(reader, anim); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return anim; + } +}; \ No newline at end of file diff --git a/libultraship/libultraship/Factories/AnimationFactory.h b/libultraship/libultraship/Factories/AnimationFactory.h new file mode 100644 index 000000000..b46c57435 --- /dev/null +++ b/libultraship/libultraship/Factories/AnimationFactory.h @@ -0,0 +1,11 @@ +#include "../Animation.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class AnimationFactory + { + public: + static Animation* ReadAnimation(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/ArrayFactory.cpp b/libultraship/libultraship/Factories/ArrayFactory.cpp new file mode 100644 index 000000000..94e4e6770 --- /dev/null +++ b/libultraship/libultraship/Factories/ArrayFactory.cpp @@ -0,0 +1,25 @@ +#include "ArrayFactory.h" + +namespace Ship +{ + Array* ArrayFactory::ReadArray(BinaryReader* reader) + { + Array* arr = new Array(); + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + ArrayV0 arrayObj = ArrayV0(); + arrayObj.ParseFileBinary(reader, arr); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return arr; + } +}; \ No newline at end of file diff --git a/libultraship/libultraship/Factories/ArrayFactory.h b/libultraship/libultraship/Factories/ArrayFactory.h new file mode 100644 index 000000000..d17ff3f1e --- /dev/null +++ b/libultraship/libultraship/Factories/ArrayFactory.h @@ -0,0 +1,11 @@ +#include "../Array.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class ArrayFactory + { + public: + static Array* ReadArray(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/BlobFactory.cpp b/libultraship/libultraship/Factories/BlobFactory.cpp new file mode 100644 index 000000000..5bc88e098 --- /dev/null +++ b/libultraship/libultraship/Factories/BlobFactory.cpp @@ -0,0 +1,26 @@ +#include "BlobFactory.h" + +namespace Ship +{ + Blob* BlobFactory::ReadBlob(BinaryReader* reader) + { + Blob* blob = new Blob(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + BlobV0 blobFac = BlobV0(); + blobFac.ParseFileBinary(reader, blob); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return blob; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/BlobFactory.h b/libultraship/libultraship/Factories/BlobFactory.h new file mode 100644 index 000000000..5311450d6 --- /dev/null +++ b/libultraship/libultraship/Factories/BlobFactory.h @@ -0,0 +1,11 @@ +#include "../Blob.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class BlobFactory + { + public: + static Blob* ReadBlob(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/CollisionHeaderFactory.cpp b/libultraship/libultraship/Factories/CollisionHeaderFactory.cpp new file mode 100644 index 000000000..075e19ceb --- /dev/null +++ b/libultraship/libultraship/Factories/CollisionHeaderFactory.cpp @@ -0,0 +1,26 @@ +#include "CollisionHeaderFactory.h" + +namespace Ship +{ + CollisionHeader* CollisionHeaderFactory::ReadCollisionHeader(BinaryReader* reader) + { + CollisionHeader* colHeader = new CollisionHeader(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + CollisionHeaderV0 col = CollisionHeaderV0(); + col.ParseFileBinary(reader, colHeader); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return colHeader; + } +}; \ No newline at end of file diff --git a/libultraship/libultraship/Factories/CollisionHeaderFactory.h b/libultraship/libultraship/Factories/CollisionHeaderFactory.h new file mode 100644 index 000000000..7dd7fa01d --- /dev/null +++ b/libultraship/libultraship/Factories/CollisionHeaderFactory.h @@ -0,0 +1,11 @@ +#include "../CollisionHeader.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class CollisionHeaderFactory + { + public: + static CollisionHeader* ReadCollisionHeader(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/CutsceneFactory.cpp b/libultraship/libultraship/Factories/CutsceneFactory.cpp new file mode 100644 index 000000000..ba9ddaece --- /dev/null +++ b/libultraship/libultraship/Factories/CutsceneFactory.cpp @@ -0,0 +1,25 @@ +#include "CutsceneFactory.h" + +namespace Ship +{ + Cutscene* CutsceneFactory::ReadCutscene(BinaryReader* reader) + { + Cutscene* cs = new Cutscene(); + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + CutsceneV0 cutscene = CutsceneV0(); + cutscene.ParseFileBinary(reader, cs); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return cs; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/CutsceneFactory.h b/libultraship/libultraship/Factories/CutsceneFactory.h new file mode 100644 index 000000000..62b89f012 --- /dev/null +++ b/libultraship/libultraship/Factories/CutsceneFactory.h @@ -0,0 +1,11 @@ +#include "../Cutscene.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class CutsceneFactory + { + public: + static Cutscene* ReadCutscene(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/DisplayListFactory.cpp b/libultraship/libultraship/Factories/DisplayListFactory.cpp new file mode 100644 index 000000000..021d393a9 --- /dev/null +++ b/libultraship/libultraship/Factories/DisplayListFactory.cpp @@ -0,0 +1,27 @@ +#include "DisplayListFactory.h" + +namespace Ship +{ + DisplayList* DisplayListFactory::ReadDisplayList(BinaryReader* reader) + { + DisplayList* dl = new DisplayList(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + DisplayListV0 DL = DisplayListV0(); + DL.ParseFileBinary(reader, dl); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return dl; + + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/DisplayListFactory.h b/libultraship/libultraship/Factories/DisplayListFactory.h new file mode 100644 index 000000000..4446525b4 --- /dev/null +++ b/libultraship/libultraship/Factories/DisplayListFactory.h @@ -0,0 +1,11 @@ +#include "../DisplayList.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class DisplayListFactory + { + public: + static DisplayList* ReadDisplayList(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/MaterialFactory.cpp b/libultraship/libultraship/Factories/MaterialFactory.cpp new file mode 100644 index 000000000..c2a8d29c3 --- /dev/null +++ b/libultraship/libultraship/Factories/MaterialFactory.cpp @@ -0,0 +1,26 @@ +#include "MaterialFactory.h" + +namespace Ship +{ + Material* MaterialFactory::ReadMaterial(BinaryReader* reader) + { + Material* mat = new Material(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + MaterialV0 Material = MaterialV0(); + Material.ParseFileBinary(reader, mat); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return mat; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/MaterialFactory.h b/libultraship/libultraship/Factories/MaterialFactory.h new file mode 100644 index 000000000..d19ccd5ba --- /dev/null +++ b/libultraship/libultraship/Factories/MaterialFactory.h @@ -0,0 +1,11 @@ +#include "../Material.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class MaterialFactory + { + public: + static Material* ReadMaterial(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/MtxFactory.cpp b/libultraship/libultraship/Factories/MtxFactory.cpp new file mode 100644 index 000000000..a678f8ee3 --- /dev/null +++ b/libultraship/libultraship/Factories/MtxFactory.cpp @@ -0,0 +1,22 @@ +#include "MtxFactory.h" + +namespace Ship +{ + Matrix* MtxFactory::ReadMtx(BinaryReader* reader) { + Matrix* mtx = new Matrix(); + uint32_t version = reader->ReadUInt32(); + switch (version) + { + case 0: + { + MatrixV0 Mtx = MatrixV0(); + Mtx.ParseFileBinary(reader, mtx); + } + break; + default: + //VERSION NOT SUPPORTED + break; + } + return mtx; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/MtxFactory.h b/libultraship/libultraship/Factories/MtxFactory.h new file mode 100644 index 000000000..971f08f11 --- /dev/null +++ b/libultraship/libultraship/Factories/MtxFactory.h @@ -0,0 +1,12 @@ +#pragma once +#include "../Matrix.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class MtxFactory + { + public: + static Matrix* ReadMtx(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/OTRResourceLoader.cpp b/libultraship/libultraship/Factories/OTRResourceLoader.cpp new file mode 100644 index 000000000..125e0d9ec --- /dev/null +++ b/libultraship/libultraship/Factories/OTRResourceLoader.cpp @@ -0,0 +1,71 @@ +#include "OTRResourceLoader.h" +#include "OTRMaterialFactory.h" +#include "OTRSceneFactory.h" +#include "OTRCollisionHeaderFactory.h" +#include "OTRDisplayListFactory.h" +#include "OTRPlayerAnimationFactory.h" +#include "OTRSkeletonFactory.h" +#include "OTRSkeletonLimbFactory.h" +#include "OTRAnimationFactory.h" +#include "OTRVtxFactory.h" +#include "OTRCutsceneFactory.h" +#include "OTRArrayFactory.h" +#include "OTRPathFactory.h" + +namespace OtrLib +{ + OTRResource* OTRResourceLoader::LoadResource(BinaryReader* reader) + { + Endianess endianess = (Endianess)reader->ReadByte(); + + // TODO: Setup the binaryreader to use the resource's endianess + + ResourceType resourceType = (ResourceType)reader->ReadUInt32(); + OTRResource* result = nullptr; + + switch (resourceType) + { + case ResourceType::OTRMaterial: + result = OTRMaterialFactory::ReadMaterial(reader); + break; + case ResourceType::OTRRoom: + result = OTRSceneFactory::ReadScene(reader); + break; + case ResourceType::OTRCollisionHeader: + result = OTRCollisionHeaderFactory::ReadCollisionHeader(reader); + break; + case ResourceType::OTRDisplayList: + result = OTRDisplayListFactory::ReadDisplayList(reader); + break; + case ResourceType::OTRPlayerAnimation: + result = OTRPlayerAnimationFactory::ReadPlayerAnimation(reader); + break; + case ResourceType::OTRSkeleton: + result = OTRSkeletonFactory::ReadSkeleton(reader); + break; + case ResourceType::OTRSkeletonLimb: + result = OTRSkeletonLimbFactory::ReadSkeletonLimb(reader); + break; + case ResourceType::OTRVtx: + result = OTRVtxFactory::ReadVtx(reader); + break; + case ResourceType::OTRAnimation: + result = OTRAnimationFactory::ReadAnimation(reader); + break; + case ResourceType::OTRCutscene: + result = OTRCutsceneFactory::ReadCutscene(reader); + break; + case ResourceType::OTRArray: + result = OTRArrayFactory::ReadArray(reader); + break; + case ResourceType::OTRPath: + result = OTRPathFactory::ReadPath(reader); + break; + default: + // RESOURCE TYPE NOT SUPPORTED + break; + } + + return result; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/PathFactory.cpp b/libultraship/libultraship/Factories/PathFactory.cpp new file mode 100644 index 000000000..3cb8d836d --- /dev/null +++ b/libultraship/libultraship/Factories/PathFactory.cpp @@ -0,0 +1,25 @@ +#include "PathFactory.h" + +namespace Ship +{ + Path* PathFactory::ReadPath(BinaryReader* reader) + { + Path* path = new Path(); + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + PathV0 Path; + Path.ParseFileBinary(reader, path); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return path; + } +}; \ No newline at end of file diff --git a/libultraship/libultraship/Factories/PathFactory.h b/libultraship/libultraship/Factories/PathFactory.h new file mode 100644 index 000000000..453969689 --- /dev/null +++ b/libultraship/libultraship/Factories/PathFactory.h @@ -0,0 +1,11 @@ +#include "../Path.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class PathFactory + { + public: + static Path* ReadPath(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/PlayerAnimationFactory.cpp b/libultraship/libultraship/Factories/PlayerAnimationFactory.cpp new file mode 100644 index 000000000..9d1b5509e --- /dev/null +++ b/libultraship/libultraship/Factories/PlayerAnimationFactory.cpp @@ -0,0 +1,27 @@ +#include "PlayerAnimationFactory.h" + +namespace Ship +{ + PlayerAnimation* PlayerAnimationFactory::ReadPlayerAnimation(BinaryReader* reader) + { + PlayerAnimation* anim = new PlayerAnimation(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + PlayerAnimationV0 Anim = PlayerAnimationV0(); + Anim.ParseFileBinary(reader, anim); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return anim; + + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/PlayerAnimationFactory.h b/libultraship/libultraship/Factories/PlayerAnimationFactory.h new file mode 100644 index 000000000..7c2e5ba21 --- /dev/null +++ b/libultraship/libultraship/Factories/PlayerAnimationFactory.h @@ -0,0 +1,11 @@ +#include "../PlayerAnimation.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class PlayerAnimationFactory + { + public: + static PlayerAnimation* ReadPlayerAnimation(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/ResourceLoader.cpp b/libultraship/libultraship/Factories/ResourceLoader.cpp new file mode 100644 index 000000000..7faec20f7 --- /dev/null +++ b/libultraship/libultraship/Factories/ResourceLoader.cpp @@ -0,0 +1,105 @@ +#include "ResourceLoader.h" +#include "MaterialFactory.h" +#include "SceneFactory.h" +#include "CollisionHeaderFactory.h" +#include "DisplayListFactory.h" +#include "PlayerAnimationFactory.h" +#include "SkeletonFactory.h" +#include "SkeletonLimbFactory.h" +#include "AnimationFactory.h" +#include "VtxFactory.h" +#include "CutsceneFactory.h" +#include "ArrayFactory.h" +#include "PathFactory.h" +#include "TextFactory.h" +#include "TextureFactory.h" +#include "BlobFactory.h" +#include "MtxFactory.h" +#include + +namespace Ship +{ + Resource* ResourceLoader::LoadResource(std::shared_ptr FileToLoad) + { + auto memStream = std::make_shared(FileToLoad->buffer.get(), FileToLoad->dwBufferSize); + auto reader = std::make_shared(memStream); + + Endianess endianess = (Endianess)reader->ReadByte(); + + for (int i = 0; i < 3; i++) + reader->ReadByte(); + + // OTRTODO: Setup the binaryreader to use the resource's endianess + + ResourceType resourceType = (ResourceType)reader->ReadUInt32(); + Resource* result = nullptr; + + switch (resourceType) + { + case ResourceType::Material: + result = MaterialFactory::ReadMaterial(reader.get()); + break; + case ResourceType::Texture: + result = TextureFactory::ReadTexture(reader.get()); + break; + case ResourceType::Room: + result = SceneFactory::ReadScene(reader.get()); + break; + case ResourceType::CollisionHeader: + result = CollisionHeaderFactory::ReadCollisionHeader(reader.get()); + break; + case ResourceType::DisplayList: + result = DisplayListFactory::ReadDisplayList(reader.get()); + break; + case ResourceType::PlayerAnimation: + result = PlayerAnimationFactory::ReadPlayerAnimation(reader.get()); + break; + case ResourceType::Skeleton: + result = SkeletonFactory::ReadSkeleton(reader.get()); + break; + case ResourceType::SkeletonLimb: + result = SkeletonLimbFactory::ReadSkeletonLimb(reader.get()); + break; + case ResourceType::Vertex: + result = VertexFactory::ReadVtx(reader.get()); + break; + case ResourceType::Animation: + result = AnimationFactory::ReadAnimation(reader.get()); + break; + case ResourceType::Cutscene: + result = CutsceneFactory::ReadCutscene(reader.get()); + break; + case ResourceType::Array: + result = ArrayFactory::ReadArray(reader.get()); + break; + case ResourceType::Path: + result = PathFactory::ReadPath(reader.get()); + break; + case ResourceType::Text: + result = TextFactory::ReadText(reader.get()); + break; + case ResourceType::Blob: + result = BlobFactory::ReadBlob(reader.get()); + break; + case ResourceType::Matrix: + result = MtxFactory::ReadMtx(reader.get()); + break; + default: + // RESOURCE TYPE NOT SUPPORTED + break; + } + + if (result != nullptr) { + result->file = FileToLoad; + result->resType = resourceType; + } else { + if (FileToLoad != nullptr) { + SPDLOG_ERROR("Failed to load resource of type {} \"{}\"", resourceType, FileToLoad->path); + } else { + SPDLOG_ERROR("Failed to load resource because the file did not load."); + } + } + + return result; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/ResourceLoader.h b/libultraship/libultraship/Factories/ResourceLoader.h new file mode 100644 index 000000000..2bbc90ea8 --- /dev/null +++ b/libultraship/libultraship/Factories/ResourceLoader.h @@ -0,0 +1,11 @@ +#include "../Resource.h" +#include "../File.h" + +namespace Ship +{ + class ResourceLoader + { + public: + static Resource* LoadResource(std::shared_ptr FileToLoad); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SceneFactory.cpp b/libultraship/libultraship/Factories/SceneFactory.cpp new file mode 100644 index 000000000..2130833d1 --- /dev/null +++ b/libultraship/libultraship/Factories/SceneFactory.cpp @@ -0,0 +1,26 @@ +#include "SceneFactory.h" + +namespace Ship +{ + Scene* SceneFactory::ReadScene(BinaryReader* reader) + { + Scene* scene = new Scene(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + SceneV0 Scene = SceneV0(); + Scene.ParseFileBinary(reader, scene); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return scene; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SceneFactory.h b/libultraship/libultraship/Factories/SceneFactory.h new file mode 100644 index 000000000..e4842656c --- /dev/null +++ b/libultraship/libultraship/Factories/SceneFactory.h @@ -0,0 +1,11 @@ +#include "../Scene.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class SceneFactory + { + public: + static Scene* ReadScene(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SkeletonFactory.cpp b/libultraship/libultraship/Factories/SkeletonFactory.cpp new file mode 100644 index 000000000..2e1b33295 --- /dev/null +++ b/libultraship/libultraship/Factories/SkeletonFactory.cpp @@ -0,0 +1,26 @@ +#include "SkeletonFactory.h" + +namespace Ship +{ + Skeleton* SkeletonFactory::ReadSkeleton(BinaryReader* reader) + { + Skeleton* skel = new Skeleton(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + SkeletonV0 Skel = SkeletonV0(); + Skel.ParseFileBinary(reader, skel); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return skel; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SkeletonFactory.h b/libultraship/libultraship/Factories/SkeletonFactory.h new file mode 100644 index 000000000..a0c90cb34 --- /dev/null +++ b/libultraship/libultraship/Factories/SkeletonFactory.h @@ -0,0 +1,11 @@ +#include "../Skeleton.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class SkeletonFactory + { + public: + static Skeleton* ReadSkeleton(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SkeletonLimbFactory.cpp b/libultraship/libultraship/Factories/SkeletonLimbFactory.cpp new file mode 100644 index 000000000..c696ae96b --- /dev/null +++ b/libultraship/libultraship/Factories/SkeletonLimbFactory.cpp @@ -0,0 +1,26 @@ +#include "SkeletonLimbFactory.h" + +namespace Ship +{ + SkeletonLimb* SkeletonLimbFactory::ReadSkeletonLimb(BinaryReader* reader) + { + SkeletonLimb* limb = new SkeletonLimb(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + SkeletonLimbV0 Limb = SkeletonLimbV0(); + Limb.ParseFileBinary(reader, limb); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return limb; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/SkeletonLimbFactory.h b/libultraship/libultraship/Factories/SkeletonLimbFactory.h new file mode 100644 index 000000000..5a651e89a --- /dev/null +++ b/libultraship/libultraship/Factories/SkeletonLimbFactory.h @@ -0,0 +1,11 @@ +#include "../SkeletonLimb.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class SkeletonLimbFactory + { + public: + static SkeletonLimb* ReadSkeletonLimb(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/TextFactory.cpp b/libultraship/libultraship/Factories/TextFactory.cpp new file mode 100644 index 000000000..d0df6136e --- /dev/null +++ b/libultraship/libultraship/Factories/TextFactory.cpp @@ -0,0 +1,26 @@ +#include "TextFactory.h" + +namespace Ship +{ + Text* TextFactory::ReadText(BinaryReader* reader) + { + Text* txt = new Text(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + TextV0 txtFac = TextV0(); + txtFac.ParseFileBinary(reader, txt); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return txt; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/TextFactory.h b/libultraship/libultraship/Factories/TextFactory.h new file mode 100644 index 000000000..e2fbbf7b0 --- /dev/null +++ b/libultraship/libultraship/Factories/TextFactory.h @@ -0,0 +1,11 @@ +#include "../Text.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class TextFactory + { + public: + static Text* ReadText(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/TextureFactory.cpp b/libultraship/libultraship/Factories/TextureFactory.cpp new file mode 100644 index 000000000..626190047 --- /dev/null +++ b/libultraship/libultraship/Factories/TextureFactory.cpp @@ -0,0 +1,26 @@ +#include "TextureFactory.h" + +namespace Ship +{ + Texture* TextureFactory::ReadTexture(BinaryReader* reader) + { + Texture* tex = new Texture(); + + Version version = (Version)reader->ReadUInt32(); + + switch (version) + { + case Version::Deckard: + { + TextureV0 texFac = TextureV0(); + texFac.ParseFileBinary(reader, tex); + } + break; + default: + // VERSION NOT SUPPORTED + break; + } + + return tex; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/TextureFactory.h b/libultraship/libultraship/Factories/TextureFactory.h new file mode 100644 index 000000000..ddc6c95a2 --- /dev/null +++ b/libultraship/libultraship/Factories/TextureFactory.h @@ -0,0 +1,11 @@ +#include "../Texture.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class TextureFactory + { + public: + static Texture* ReadTexture(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/VtxFactory.cpp b/libultraship/libultraship/Factories/VtxFactory.cpp new file mode 100644 index 000000000..64f619626 --- /dev/null +++ b/libultraship/libultraship/Factories/VtxFactory.cpp @@ -0,0 +1,22 @@ +#include "VtxFactory.h" + +namespace Ship +{ + Vertex* VertexFactory::ReadVtx(BinaryReader* reader) { + Vertex* vtx = new Vertex(); + uint32_t version = reader->ReadUInt32(); + switch (version) + { + case 0: + { + VertexV0 Vtx = VertexV0(); + Vtx.ParseFileBinary(reader, vtx); + } + break; + default: + //VERSION NOT SUPPORTED + break; + } + return vtx; + } +} \ No newline at end of file diff --git a/libultraship/libultraship/Factories/VtxFactory.h b/libultraship/libultraship/Factories/VtxFactory.h new file mode 100644 index 000000000..ff8e696c7 --- /dev/null +++ b/libultraship/libultraship/Factories/VtxFactory.h @@ -0,0 +1,12 @@ +#pragma once +#include "../Vertex.h" +#include "Utils/BinaryReader.h" + +namespace Ship +{ + class VertexFactory + { + public: + static Vertex* ReadVtx(BinaryReader* reader); + }; +} \ No newline at end of file diff --git a/libultraship/libultraship/File.cpp b/libultraship/libultraship/File.cpp new file mode 100644 index 000000000..d2307d055 --- /dev/null +++ b/libultraship/libultraship/File.cpp @@ -0,0 +1 @@ +#include "File.h" diff --git a/libultraship/libultraship/File.h b/libultraship/libultraship/File.h new file mode 100644 index 000000000..b5d484d2d --- /dev/null +++ b/libultraship/libultraship/File.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include "GlobalCtx2.h" + +namespace Ship { + class Archive; + + class File + { + public: + std::shared_ptr parent; + std::string path; + std::shared_ptr buffer; + uint32_t dwBufferSize; + bool bIsLoaded = false; + bool bHasLoadError = false; + std::condition_variable FileLoadNotifier; + std::mutex FileLoadMutex; + }; +} diff --git a/libultraship/libultraship/GameSettings.cpp b/libultraship/libultraship/GameSettings.cpp new file mode 100644 index 000000000..8599367a7 --- /dev/null +++ b/libultraship/libultraship/GameSettings.cpp @@ -0,0 +1,133 @@ +#include "GameSettings.h" + +// Audio +#include +#include +#include +#include + +#include "ConfigFile.h" +#include "Cvar.h" +#include "GlobalCtx2.h" +#include "SohImGuiImpl.h" +#include "stox.h" +#include "../../soh/include/z64audio.h" +#include +#include "SohHooks.h" + +#define ABS(var) var < 0 ? -(var) : var + +using namespace Ship; + +namespace Game { + + bool DeSyncAudio = false; + SoHConfigType Settings; + const std::string ConfSection = DEBUG_SECTION; + const std::string AudioSection = AUDIO_SECTION; + const std::string ControllerSection = CONTROLLER_SECTION; + const std::string EnhancementSection = ENHANCEMENTS_SECTION; + + void UpdateAudio() { + Audio_SetGameVolume(SEQ_BGM_MAIN, Settings.audio.music_main); + Audio_SetGameVolume(SEQ_BGM_SUB, Settings.audio.music_sub); + Audio_SetGameVolume(SEQ_FANFARE, Settings.audio.fanfare); + Audio_SetGameVolume(SEQ_SFX, Settings.audio.sfx); + } + + void LoadSettings() { + + const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ConfigFile& Conf = *pConf; + + // Debug + SohImGui::console->opened = stob(Conf[ConfSection]["console"]); + Settings.debug.menu_bar = stob(Conf[ConfSection]["menu_bar"]); + Settings.debug.soh = stob(Conf[ConfSection]["soh_debug"]); + + Settings.debug.n64mode = stob(Conf[ConfSection]["n64_mode"]); + + // Enhancements + Settings.enhancements.fast_text = stob(Conf[EnhancementSection]["fast_text"]); + CVar_SetS32(const_cast("gFastText"), Settings.enhancements.fast_text); + + Settings.enhancements.disable_lod = stob(Conf[EnhancementSection]["disable_lod"]); + CVar_SetS32(const_cast("gDisableLOD"), Settings.enhancements.disable_lod); + + Settings.enhancements.animated_pause_menu = stob(Conf[EnhancementSection]["animated_pause_menu"]); + CVar_SetS32(const_cast("gPauseLiveLink"), Settings.enhancements.animated_pause_menu); + + Settings.enhancements.debug_mode = stob(Conf[EnhancementSection]["debug_mode"]); + CVar_SetS32(const_cast("gDebugEnabled"), Settings.enhancements.debug_mode); + + Settings.audio.master = Ship::stof(Conf[AudioSection]["master"]); + CVar_SetFloat(const_cast("gGameMasterVolume"), Settings.audio.master); + + Settings.audio.music_main = Ship::stof(Conf[AudioSection]["music_main"]); + CVar_SetFloat(const_cast("gMainMusicVolume"), Settings.audio.music_main); + + Settings.audio.music_sub = Ship::stof(Conf[AudioSection]["music_sub"]); + CVar_SetFloat(const_cast("gSubMusicVolume"), Settings.audio.music_sub); + + Settings.audio.sfx = Ship::stof(Conf[AudioSection]["sfx"]); + CVar_SetFloat(const_cast("gSFXMusicVolume"), Settings.audio.sfx); + + Settings.audio.fanfare = Ship::stof(Conf[AudioSection]["fanfare"]); + CVar_SetFloat(const_cast("gFanfareVolume"), Settings.audio.fanfare); + + Settings.controller.gyro_sensitivity = Ship::stof(Conf[ControllerSection]["gyro_sensitivity"]); + CVar_SetFloat(const_cast("gGyroSensitivity"), Settings.controller.gyro_sensitivity); + + Settings.controller.rumble_strength = Ship::stof(Conf[ControllerSection]["rumble_strength"]); + CVar_SetFloat(const_cast("gRumbleStrength"), Settings.controller.rumble_strength); + + Settings.controller.input_scale = Ship::stof(Conf[ControllerSection]["input_scale"]); + CVar_SetFloat(const_cast("gInputScale"), Settings.controller.input_scale); + + Settings.controller.input_enabled = stob(Conf[ControllerSection]["input_enabled"]); + CVar_SetS32(const_cast("gInputEnabled"), Settings.controller.input_enabled); + + UpdateAudio(); + } + + void SaveSettings() { + const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ConfigFile& Conf = *pConf; + + // Debug + Conf[ConfSection]["console"] = std::to_string(SohImGui::console->opened); + Conf[ConfSection]["menu_bar"] = std::to_string(Settings.debug.menu_bar); + Conf[ConfSection]["soh_debug"] = std::to_string(Settings.debug.soh); + Conf[ConfSection]["n64_mode"] = std::to_string(Settings.debug.n64mode); + + // Audio + Conf[AudioSection]["master"] = std::to_string(Settings.audio.master); + Conf[AudioSection]["music_main"] = std::to_string(Settings.audio.music_main); + Conf[AudioSection]["music_sub"] = std::to_string(Settings.audio.music_sub); + Conf[AudioSection]["sfx"] = std::to_string(Settings.audio.sfx); + Conf[AudioSection]["fanfare"] = std::to_string(Settings.audio.fanfare); + + // Enhancements + Conf[EnhancementSection]["fast_text"] = std::to_string(Settings.enhancements.fast_text); + Conf[EnhancementSection]["disable_lod"] = std::to_string(Settings.enhancements.disable_lod); + Conf[EnhancementSection]["animated_pause_menu"] = std::to_string(Settings.enhancements.animated_pause_menu); + Conf[EnhancementSection]["debug_mode"] = std::to_string(Settings.enhancements.debug_mode); + + Conf[ControllerSection]["gyro_sensitivity"] = std::to_string(Settings.controller.gyro_sensitivity); + Conf[ControllerSection]["rumble_strength"] = std::to_string(Settings.controller.rumble_strength); + Conf[ControllerSection]["input_scale"] = std::to_string(Settings.controller.input_scale); + Conf[ControllerSection]["input_enabled"] = std::to_string(Settings.controller.input_enabled); + + Conf.Save(); + } + + void InitSettings() { + ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) { + UpdateAudio(); + }}); + } + + void SetSeqPlayerVolume(SeqPlayers playerId, float volume) { + Audio_SetGameVolume(playerId, volume); + } +} \ No newline at end of file diff --git a/libultraship/libultraship/GameSettings.h b/libultraship/libultraship/GameSettings.h new file mode 100644 index 000000000..35d948d89 --- /dev/null +++ b/libultraship/libultraship/GameSettings.h @@ -0,0 +1,56 @@ +#pragma once + +struct SoHConfigType { + // Debug + struct { + bool soh = false; + bool n64mode = false; + bool menu_bar = false; + bool soh_sink = true; + } debug; + + // Audio + struct { + float master = 1.0f; + float music_main = 1.0f; + float fanfare = 1.0f; + float sfx = 1.0f; + float music_sub = 1.0f; + } audio; + + // Enhancements + struct { + bool fast_text = false; + bool disable_lod = false; + bool animated_pause_menu = false; + bool debug_mode = false; + } enhancements; + + struct { + float gyro_sensitivity = 1.0f; + float rumble_strength = 1.0f; + float input_scale = 1.0f; + bool input_enabled = false; + } controller; +}; + +enum SeqPlayers { + /* 0 */ SEQ_BGM_MAIN, + /* 1 */ SEQ_FANFARE, + /* 2 */ SEQ_SFX, + /* 3 */ SEQ_BGM_SUB, + /* 4 */ SEQ_MAX + }; + +#define DEBUG_SECTION "DEBUG SETTINGS" +#define AUDIO_SECTION "AUDIO SETTINGS" +#define CONTROLLER_SECTION "CONTROLLER SECTION" +#define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS" + +namespace Game { + extern SoHConfigType Settings; + void InitSettings(); + void LoadSettings(); + void SaveSettings(); + void SetSeqPlayerVolume(SeqPlayers playerId, float volume); +} diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp new file mode 100644 index 000000000..dd8125bcc --- /dev/null +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -0,0 +1,85 @@ +#include "GlobalCtx2.h" +#include +#include +#include "ResourceMgr.h" +#include "Window.h" +#include "spdlog/async.h" +#include "spdlog/sinks/rotating_file_sink.h" +#include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/sinks/sohconsole_sink.h" +#include "ModManager.h" + +namespace Ship { + std::weak_ptr GlobalCtx2::Context; + ModManager* INSTANCE; + std::shared_ptr GlobalCtx2::GetInstance() { + return Context.lock(); + } + + std::shared_ptr GlobalCtx2::CreateInstance(const std::string& Name) { + if (Context.expired()) { + auto Shared = std::make_shared(Name); + Context = Shared; + Shared->InitWindow(); + return Shared; + } else { + SPDLOG_DEBUG("Trying to create a context when it already exists."); + } + + return GetInstance(); + } + + GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") { + + } + + GlobalCtx2::~GlobalCtx2() { + SPDLOG_INFO("destruct GlobalCtx2"); + INSTANCE->Exit(); + } + + void GlobalCtx2::InitWindow() { + InitLogging(); + Config = std::make_shared(GlobalCtx2::GetInstance(), "shipofharkinian.ini"); + MainPath = (*Config)["ARCHIVE"]["Main Archive"]; + if (MainPath.empty()) { + MainPath = "oot.otr"; + } + PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"]; + if (PatchesPath.empty()) { + PatchesPath = "./"; + } + ResMan = std::make_shared(GlobalCtx2::GetInstance(), MainPath, PatchesPath); + Win = std::make_shared(GlobalCtx2::GetInstance()); + + if (!ResMan->DidLoadSuccessfully()) + { + MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK); + exit(1); + } + INSTANCE = new ModManager(ResMan); + INSTANCE->Init(); + } + + void GlobalCtx2::InitLogging() { + try { + // Setup Logging + spdlog::init_thread_pool(8192, 1); + auto SohConsoleSink = std::make_shared(); + auto ConsoleSink = std::make_shared(); + auto FileSink = std::make_shared("logs/" + GetName() + ".log", 1024 * 1024 * 10, 10); + SohConsoleSink->set_level(spdlog::level::trace); + ConsoleSink->set_level(spdlog::level::trace); + FileSink->set_level(spdlog::level::trace); + std::vector Sinks{ ConsoleSink, FileSink, SohConsoleSink }; + Logger = std::make_shared(GetName(), Sinks.begin(), Sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); + GetLogger()->set_level(spdlog::level::trace); + GetLogger()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%@] [%l] %v"); + spdlog::register_logger(GetLogger()); + spdlog::set_default_logger(GetLogger()); + } + catch (const spdlog::spdlog_ex& ex) { + std::cout << "Log initialization failed: " << ex.what() << std::endl; + } + } +} \ No newline at end of file diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h new file mode 100644 index 000000000..a10421ec0 --- /dev/null +++ b/libultraship/libultraship/GlobalCtx2.h @@ -0,0 +1,41 @@ +#pragma once + +#ifdef __cplusplus +#include +#include "spdlog/spdlog.h" +#include "ConfigFile.h" + +namespace Ship { + class ResourceMgr; + class Window; + + class GlobalCtx2 { + public: + static std::shared_ptr GetInstance(); + static std::shared_ptr CreateInstance(const std::string& Name); + + std::string GetName() { return Name; } + std::shared_ptr GetWindow() { return Win; } + std::shared_ptr GetResourceManager() { return ResMan; } + std::shared_ptr GetLogger() { return Logger; } + std::shared_ptr GetConfig() { return Config; } + + GlobalCtx2(const std::string& Name); + ~GlobalCtx2(); + + protected: + void InitWindow(); + void InitLogging(); + + private: + static std::weak_ptr Context; + std::shared_ptr Logger; + std::shared_ptr Win; + std::shared_ptr Config; // Config needs to be after the Window because we call the Window during it's destructor. + std::shared_ptr ResMan; + std::string Name; + std::string MainPath; + std::string PatchesPath; + }; +} +#endif \ No newline at end of file diff --git a/libultraship/libultraship/KeyboardController.cpp b/libultraship/libultraship/KeyboardController.cpp new file mode 100644 index 000000000..6f78a1678 --- /dev/null +++ b/libultraship/libultraship/KeyboardController.cpp @@ -0,0 +1,56 @@ +#include "KeyboardController.h" +#include "GlobalCtx2.h" + +namespace Ship { + KeyboardController::KeyboardController(int32_t dwControllerNumber) : Controller(dwControllerNumber) { + LoadBinding(); + } + + KeyboardController::~KeyboardController() { + + } + + bool KeyboardController::PressButton(int32_t dwScancode) { + if (ButtonMapping.contains(dwScancode)) { + dwPressedButtons |= ButtonMapping[dwScancode]; + return true; + } + + return false; + } + + bool KeyboardController::ReleaseButton(int32_t dwScancode) { + if (ButtonMapping.contains(dwScancode)) { + dwPressedButtons &= ~ButtonMapping[dwScancode]; + return true; + } + + return false; + } + + void KeyboardController::ReleaseAllButtons() { + dwPressedButtons = 0; + } + + void KeyboardController::ReadFromSource() { + wStickX = 0; + wStickY = 0; + } + + void KeyboardController::WriteToSource(ControllerCallback* controller) + { + + } + + std::string KeyboardController::GetControllerType() { + return "KEYBOARD"; + } + + std::string KeyboardController::GetConfSection() { + return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1); + } + + std::string KeyboardController::GetBindingConfSection() { + return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1); + } +} \ No newline at end of file diff --git a/libultraship/libultraship/KeyboardController.h b/libultraship/libultraship/KeyboardController.h new file mode 100644 index 000000000..ab0f98e64 --- /dev/null +++ b/libultraship/libultraship/KeyboardController.h @@ -0,0 +1,23 @@ +#pragma once +#include "Controller.h" +#include + +namespace Ship { + class KeyboardController : public Controller { + public: + KeyboardController(int32_t dwControllerNumber); + ~KeyboardController(); + + void ReadFromSource(); + void WriteToSource(ControllerCallback* controller); + + bool PressButton(int32_t dwScancode); + bool ReleaseButton(int32_t dwScancode); + void ReleaseAllButtons(); + + protected: + std::string GetControllerType(); + std::string GetConfSection(); + std::string GetBindingConfSection(); + }; +} diff --git a/libultraship/libultraship/LUSMacros.h b/libultraship/libultraship/LUSMacros.h new file mode 100644 index 000000000..9e303be26 --- /dev/null +++ b/libultraship/libultraship/LUSMacros.h @@ -0,0 +1,3 @@ +#pragma once + +#define STR(define) (std::string(#define)) \ No newline at end of file diff --git a/libultraship/libultraship/Lib/Fast3D/.gitrepo b/libultraship/libultraship/Lib/Fast3D/.gitrepo new file mode 100644 index 000000000..c58833220 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/Emill/n64-fast3d-engine + branch = master + commit = 7353aa30570682ef3bfe31cffc115f1561163270 + parent = 36d578a78dff501c380e24b2c41fda62c173ea20 + method = merge + cmdver = 0.4.3 diff --git a/libultraship/libultraship/Lib/Fast3D/LICENSE.txt b/libultraship/libultraship/Lib/Fast3D/LICENSE.txt new file mode 100644 index 000000000..5a1a079e0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2020 Emill, MaikelChan + +Redistribution and use in source forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form are not allowed. + +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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. diff --git a/libultraship/libultraship/Lib/Fast3D/README.md b/libultraship/libultraship/Lib/Fast3D/README.md new file mode 100644 index 000000000..3f36b1c3d --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/README.md @@ -0,0 +1,33 @@ +# Nintendo 64 Fast3D renderer + +Implementation of a Fast3D renderer for games built originally for the Nintendo 64 platform. + +For rendering OpenGL, Direct3D 11 and Direct3D 12 are supported. + +Supported windowing systems are GLX (used on Linux), DXGI (used on Windows) and SDL (generic). + +# Usage + +See `gfx_pc.h`. You will also need a copy of `PR/gbi.h`, found in libultra. + +First call `gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, const char *game_name, bool start_in_fullscreen)` and supply the desired backends at program start. + +Some callbacks can be set on `wapi`. See `gfx_window_manager_api.h` for more info. + +Each game main loop iteration should look like this: + +```C +gfx_start_frame(); // Handles input events such as keyboard and window events +// perform game logic here +gfx_run(cmds); // submit display list and render a frame +// do more expensive work here, such as play audio +gfx_end_frame(); // this just waits until the frame is shown on the screen (vsync), to provide correct game timing +``` + +When you are ready to start the main loop, call `wapi->main_loop(one_iteration_func)`. + +For the best experience, please change the Vtx and Mtx structures to use floats instead of fixed point arithmetic (`GBI_FLOATS`). + +# License + +See LICENSE.txt. Redistributions are allowed only in source form, not in binary form. diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/abi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/abi.h new file mode 100644 index 000000000..53f4a9ec3 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/abi.h @@ -0,0 +1,491 @@ +#ifndef ULTRA64_ABI_H +#define ULTRA64_ABI_H + +/* Audio commands: */ +#define A_SPNOOP 0 +#define A_ADPCM 1 +#define A_CLEARBUFF 2 +#define A_UNK3 3 +#define A_ADDMIXER 4 +#define A_RESAMPLE 5 +#define A_RESAMPLE_ZOH 6 +#define A_FILTER 7 +#define A_SETBUFF 8 +#define A_DUPLICATE 9 +#define A_DMEMMOVE 10 +#define A_LOADADPCM 11 +#define A_MIXER 12 +#define A_INTERLEAVE 13 +#define A_HILOGAIN 14 +#define A_SETLOOP 15 +#define A_INTERL 17 +#define A_ENVSETUP1 18 +#define A_ENVMIXER 19 +#define A_LOADBUFF 20 +#define A_SAVEBUFF 21 +#define A_ENVSETUP2 22 +#define A_S8DEC 23 +#define A_UNK19 25 + +#define ACMD_SIZE 32 + +/* + * Audio flags + */ +#define A_INIT 0x01 +#define A_CONTINUE 0x00 +#define A_LOOP 0x02 +#define A_OUT 0x02 +#define A_LEFT 0x02 +#define A_RIGHT 0x00 +#define A_VOL 0x04 +#define A_RATE 0x00 +#define A_AUX 0x08 +#define A_NOAUX 0x00 +#define A_MAIN 0x00 +#define A_MIX 0x10 + +/* + * Data Structures. + */ + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 gain : 16; + u32 addr; +} Aadpcm; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 gain : 16; + u32 addr; +} Apolef; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 pad1 : 16; + u32 addr; +} Aenvelope; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 8; + u32 dmem : 16; + u32 pad2 : 16; + u32 count : 16; +} Aclearbuff; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 8; + u32 pad2 : 16; + u32 inL : 16; + u32 inR : 16; +} Ainterleave; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 24; + u32 addr; +} Aloadbuff; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 pad1 : 16; + u32 addr; +} Aenvmixer; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 gain : 16; + u32 dmemi : 16; + u32 dmemo : 16; +} Amixer; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 dmem2 : 16; + u32 addr; +} Apan; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 pitch : 16; + u32 addr; +} Aresample; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 pad1 : 16; + u32 addr; +} Areverb; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 24; + u32 addr; +} Asavebuff; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 24; + u32 pad2 : 2; + u32 number : 4; + u32 base : 24; +} Asegment; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 dmemin : 16; + u32 dmemout : 16; + u32 count : 16; +} Asetbuff; + +typedef struct { + u32 cmd : 8; + u32 flags : 8; + u32 vol : 16; + u32 voltgt : 16; + u32 volrate : 16; +} Asetvol; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 8; + u32 dmemin : 16; + u32 dmemout : 16; + u32 count : 16; +} Admemmove; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 8; + u32 count : 16; + u32 addr; +} Aloadadpcm; + +typedef struct { + u32 cmd : 8; + u32 pad1 : 8; + u32 pad2 : 16; + u32 addr; +} Asetloop; + +/* + * Generic Acmd Packet + */ + +typedef struct { + u32 w0; + u32 w1; +} Awords; + +typedef union { + Awords words; + Aadpcm adpcm; + Apolef polef; + Aclearbuff clearbuff; + Aenvelope envelope; + Ainterleave interleave; + Aloadbuff loadbuff; + Aenvmixer envmixer; + Aresample resample; + Areverb reverb; + Asavebuff savebuff; + Asegment segment; + Asetbuff setbuff; + Asetvol setvol; + Admemmove dmemmove; + Aloadadpcm loadadpcm; + Amixer mixer; + Asetloop setloop; + long long int force_union_align; /* dummy, force alignment */ +} Acmd; + +/* + * ADPCM State + */ +#define ADPCMVSIZE 8 +#define ADPCMFSIZE 16 +typedef short ADPCM_STATE[ADPCMFSIZE]; + +/* + * Pole filter state + */ +typedef short POLEF_STATE[4]; + +/* + * Resampler state + */ +typedef short RESAMPLE_STATE[16]; + +/* + * Resampler constants + */ +#define UNITY_PITCH 0x8000 +#define MAX_RATIO 1.99996 /* within .03 cents of +1 octave */ + +/* + * Enveloper/Mixer state + */ +typedef short ENVMIX_STATE[40]; + +/* + * Macros to assemble the audio command list + */ + +#define aADPCMdec(pkt, f, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_ADPCM, 24, 8) | _SHIFTL(f, 16, 8); \ + _a->words.w1 = (u32)(s); \ +} + +#define aPoleFilter(pkt, f, g, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_POLEF, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(g, 0, 16)); \ + _a->words.w1 = (u32)(s); \ +} + +#define aHiLoGain(pkt, gain, count, dmem, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_HILOGAIN, 24, 8) | \ + _SHIFTL(gain, 16, 8) | _SHIFTL(count, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmem, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aUnkCmd3(pkt, a1, a2, a3) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_UNK3, 24, 8) | _SHIFTL(a3, 0, 16); \ + _a->words.w1 = _SHIFTL(a1, 16, 16) | _SHIFTL(a2, 0, 16); \ +} + +#define aUnkCmd19(pkt, a1, a2, a3, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_UNK19, 24, 8) | _SHIFTL(a1, 16, 8) | \ + _SHIFTL(a2, 0, 16)); \ + _a->words.w1 = _SHIFTL(a3, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aS8Dec(pkt, a1, a2) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_S8DEC, 24, 8) | _SHIFTL(a1, 16, 8); \ + _a->words.w1 = (u32)(a2); \ +} + +#define aClearBuffer(pkt, d, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_CLEARBUFF, 24, 8) | _SHIFTL(d, 0, 24); \ + _a->words.w1 = (u32)(c); \ +} + +#define aEnvMixer(pkt, dmemi, count, swapLR, x0, x1, x2, x3, m, bits) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (bits | _SHIFTL(dmemi >> 4, 16, 8) | \ + _SHIFTL(count, 8, 8) | _SHIFTL(swapLR, 4, 1) | \ + _SHIFTL(x0, 3, 1) | _SHIFTL(x1, 2, 1) | \ + _SHIFTL(x2, 1, 1) | _SHIFTL(x3, 0, 1)); \ + _a->words.w1 = (u32)(m); \ +} + +#define aInterleave(pkt, o, l, r, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_INTERLEAVE, 24, 8) | \ + _SHIFTL(c >> 4, 16, 8) | _SHIFTL(o, 0, 16)); \ + _a->words.w1 = _SHIFTL(l, 16, 16) | _SHIFTL(r, 0, 16); \ +} + +#define aInterl(pkt, dmemi, dmemo, count) \ +{ \ + Acmd *_a = (Acmd*)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_INTERL, 24, 8) | _SHIFTL(count, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemi, 16, 16) | _SHIFTL(dmemo, 0, 16); \ +} + +#define aLoadBuffer(pkt, s, d, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_LOADBUFF, 24, 8) | \ + _SHIFTL((c) >> 4, 16, 8) | _SHIFTL(d, 0, 16)); \ + _a->words.w1 = (u32)(s); \ +} + +#define aMix(pkt, f, g, i, o) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_MIXER, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(g, 0, 16)); \ + _a->words.w1 = _SHIFTL(i, 16, 16) | _SHIFTL(o, 0, 16); \ +} + +#define aPan(pkt, f, d, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_PAN, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(d, 0, 16)); \ + _a->words.w1 = (u32)(s); \ +} + +#define aResample(pkt, f, p, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_RESAMPLE, 24, 8) | \ + _SHIFTL(f, 16, 8) | _SHIFTL(p, 0, 16)); \ + _a->words.w1 = (u32)(s); \ +} + +#define aSaveBuffer(pkt, s, d, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SAVEBUFF, 24, 8) | \ + _SHIFTL((c) >> 4, 16, 8) | _SHIFTL(s, 0, 16)); \ + _a->words.w1 = (u32)(d); \ +} + +#define aSegment(pkt, s, b) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_SEGMENT, 24, 8); \ + _a->words.w1 = _SHIFTL(s, 24, 8) | _SHIFTL(b, 0, 24); \ +} + +#define aSetBuffer(pkt, f, i, o, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(i, 0, 16)); \ + _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ +} + +#define aSetVolume(pkt, f, v, t, r) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ + _SHIFTL(v, 0, 16)); \ + _a->words.w1 = _SHIFTL(r, 0, 16) | _SHIFTL(t, 16, 16); \ +} + +#define aSetVolume32(pkt, f, v, tr) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ + _SHIFTL(v, 0, 16)); \ + _a->words.w1 = (u32)(tr); \ +} + +#define aSetLoop(pkt, a) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_SETLOOP, 24, 8); \ + _a->words.w1 = (u32)(a); \ +} + +#define aDMEMMove(pkt, i, o, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_DMEMMOVE, 24, 8) | _SHIFTL(i, 0, 24); \ + _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ +} + +#define aLoadADPCM(pkt, c, d) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_LOADADPCM, 24, 8) | _SHIFTL(c, 0, 24); \ + _a->words.w1 = (u32)d; \ +} + +#define aEnvSetup1(pkt, a, b, c, d) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_ENVSETUP1, 24, 8) | \ + _SHIFTL(a, 16, 8) | _SHIFTL(b, 0, 16)); \ + _a->words.w1 = _SHIFTL(c, 16, 16) | _SHIFTL(d, 0, 16); \ +} + +#define aEnvSetup2(pkt, volLeft, volRight) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_ENVSETUP2, 24, 8); \ + _a->words.w1 = (_SHIFTL(volLeft, 16, 16) | \ + _SHIFTL(volRight, 0, 16)); \ +} + +#define aFilter(pkt, f, countOrBuf, addr) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_FILTER, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(countOrBuf, 0, 16)); \ + _a->words.w1 = (u32)(addr); \ +} + +#define aDuplicate(pkt, count, dmemi, dmemo, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_DUPLICATE, 24, 8) | \ + _SHIFTL(count, 16, 8) | _SHIFTL(dmemi, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemo, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aAddMixer(pkt, count, dmemi, dmemo, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_ADDMIXER, 24, 8) | \ + _SHIFTL(count >> 4, 16, 8) | _SHIFTL(a4, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemi, 16, 16) | _SHIFTL(dmemo, 0, 16); \ +} + +#define aResampleZoh(pkt, pitch, pitchAccu) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_RESAMPLE_ZOH, 24, 8) | \ + _SHIFTL(pitch, 0, 16)); \ + _a->words.w1 = _SHIFTL(pitchAccu, 0, 16); \ +} + +#endif /* ULTRA64_ABI_H */ diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h new file mode 100644 index 000000000..c2aafa919 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h @@ -0,0 +1,177 @@ +#ifndef ULTRA64_CONTROLLER_H +#define ULTRA64_CONTROLLER_H + +#include "message.h" + +#define SIAccessQueueSize 2 +#define BLOCKSIZE 32 +#define MAXCONTROLLERS 4 +#define PFS_ONE_PAGE 8 + +#define PFS_PAGE_SIZE (BLOCKSIZE*PFS_ONE_PAGE) + +#define CONT_CMD_REQUEST_STATUS 0 +#define CONT_CMD_READ_BUTTON 1 +#define CONT_CMD_READ_MEMPACK 2 +#define CONT_CMD_WRITE_MEMPACK 3 +#define CONT_CMD_READ_EEPROM 4 +#define CONT_CMD_WRITE_EEPROM 5 +#define CONT_CMD_RESET 0xFF + +#define CONT_CMD_REQUEST_STATUS_TX 1 +#define CONT_CMD_READ_BUTTON_TX 1 +#define CONT_CMD_READ_MEMPACK_TX 3 +#define CONT_CMD_WRITE_MEMPACK_TX 35 +#define CONT_CMD_READ_EEPROM_TX 2 +#define CONT_CMD_WRITE_EEPROM_TX 10 +#define CONT_CMD_RESET_TX 1 + +#define CONT_CMD_REQUEST_STATUS_RX 3 +#define CONT_CMD_READ_BUTTON_RX 4 +#define CONT_CMD_READ_MEMPACK_RX 33 +#define CONT_CMD_WRITE_MEMPACK_RX 1 +#define CONT_CMD_READ_EEPROM_RX 8 +#define CONT_CMD_WRITE_EEPROM_RX 1 +#define CONT_CMD_RESET_RX 3 + +#define CONT_CMD_NOP 0xFF +#define CONT_CMD_END 0xFE // Indicates end of a command +#define CONT_CMD_EXE 1 // Set pif ram status byte to this to do a command + +#define CONT_ERR_NO_CONTROLLER PFS_ERR_NOPACK /* 1 */ +#define CONT_ERR_CONTRFAIL CONT_OVERRUN_ERROR /* 4 */ +#define CONT_ERR_INVALID PFS_ERR_INVALID /* 5 */ +#define CONT_ERR_DEVICE PFS_ERR_DEVICE /* 11 */ +#define CONT_ERR_NOT_READY 12 +#define CONT_ERR_VOICE_MEMORY 13 +#define CONT_ERR_VOICE_WORD 14 +#define CONT_ERR_VOICE_NO_RESPONSE 15 + + +#define DIR_STATUS_EMPTY 0 +#define DIR_STATUS_UNKNOWN 1 +#define DIR_STATUS_OCCUPIED 2 + +#define PFS_FORCE 1 +#define PFS_DELETE 1 + +#define PFS_LABEL_AREA 7 + +#define PFS_ERR_NOPACK 1 + +/* controller errors */ +#define CONT_NO_RESPONSE_ERROR 0x8 +#define CONT_OVERRUN_ERROR 0x4 + +/* Controller type */ +#define CONT_ABSOLUTE 0x0001 +#define CONT_RELATIVE 0x0002 +#define CONT_JOYPORT 0x0004 +#define CONT_EEPROM 0x8000 +#define CONT_EEP16K 0x4000 +#define CONT_TYPE_MASK 0x1F07 +#define CONT_TYPE_NORMAL 0x0005 +#define CONT_TYPE_MOUSE 0x0002 +#define CONT_TYPE_VOICE 0x0100 + +/* Controller status */ +#define CONT_CARD_ON 0x01 +#define CONT_CARD_PULL 0x02 +#define CONT_ADDR_CRC_ER 0x04 +#define CONT_EEPROM_BUSY 0x80 + +/* Buttons */ +#define BTN_CRIGHT 0x0001 +#define BTN_CLEFT 0x0002 +#define BTN_CDOWN 0x0004 +#define BTN_CUP 0x0008 +#define BTN_R 0x0010 +#define BTN_L 0x0020 +#define BTN_DRIGHT 0x0100 +#define BTN_DLEFT 0x0200 +#define BTN_DDOWN 0x0400 +#define BTN_DUP 0x0800 +#define BTN_START 0x1000 +#define BTN_Z 0x2000 +#define BTN_B 0x4000 +#define BTN_A 0x8000 + +typedef struct { + /* 0x00 */ uintptr_t ram[15]; + /* 0x3C */ u32 status; +} OSPifRam; // size = 0x40 + +typedef struct { + /* 0x00 */ u16 type; + /* 0x02 */ u8 status; + /* 0x03 */ u8 err_no; +} OSContStatus; // size = 0x04 + +typedef struct { + /* 0x00 */ u16 button; + /* 0x02 */ s8 stick_x; + /* 0x03 */ s8 stick_y; + /* 0x04 */ u8 err_no; + /* 0x05 */ f32 gyro_x; + /* 0x09 */ f32 gyro_y; +} OSContPad; // size = 0x0D + +typedef struct { + /* 0x00 */ u8 rumble; + /* 0x01 */ u8 ledColor; +} ControllerCallback; // size = 0x02 + +typedef struct { + /* 0x00 */ void* address; + /* 0x04 */ u8 databuffer[32]; + /* 0x24 */ u8 addressCrc; + /* 0x25 */ u8 dataCrc; + /* 0x26 */ u8 CONT_ERR_CONTRFAILno; +} OSContRamIo; // size = 0x28 + +// Original name: __OSContRequesFormat +typedef struct { + /* 0x00 */ u8 align; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 poll; + /* 0x04 */ u8 typeh; + /* 0x05 */ u8 typel; + /* 0x06 */ u8 status; + /* 0x07 */ u8 align1; +} __OSContRequestHeader; // size = 0x8 + +// Original name: __OSContRequesHeaderFormatShort +typedef struct { + /* 0x00 */ u8 txsize; + /* 0x01 */ u8 rxsize; + /* 0x02 */ u8 poll; + /* 0x03 */ u8 typeh; + /* 0x04 */ u8 typel; + /* 0x05 */ u8 status; +} __OSContRequestHeaderAligned; // size = 0x6 + +// Original Name: __OSContRamReadFormat +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 poll; + /* 0x04 */ u8 hi; + /* 0x05 */ u8 lo; + /* 0x06 */ u8 data[BLOCKSIZE]; + /* 0x26 */ u8 datacrc; +} __OSContRamHeader; // size = 0x27 + +// Original name: __OSContReadFormat +typedef struct { + /* 0x00 */ u8 align; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 poll; + /* 0x04 */ u16 button; + /* 0x06 */ s8 joyX; + /* 0x07 */ s8 joyY; +} __OSContReadHeader; // size = 0x8 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/convert.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/convert.h new file mode 100644 index 000000000..1c3160bc2 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/convert.h @@ -0,0 +1,18 @@ +#ifndef ULTRA64_CONVERT_H +#define ULTRA64_CONVERT_H + +#define OS_CLOCK_RATE 62500000LL +#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) + +#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625000LL))/(1000000000LL/15625000LL)) +#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL)) +#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL)) +#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL)) + +#define OS_K0_TO_PHYSICAL(x) (u32)(((char*)(x)-0x80000000)) +#define OS_K1_TO_PHYSICAL(x) (0)//(u32)(((char*)(x)-0xA0000000)) + +#define OS_PHYSICAL_TO_K0(x) (void*)(((u32)(x)+0x80000000)) +#define OS_PHYSICAL_TO_K1(x) (void*)(((u32)(x)+0xA0000000)) + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/exception.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/exception.h new file mode 100644 index 000000000..43a700f34 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/exception.h @@ -0,0 +1,45 @@ +#ifndef ULTRA64_EXCEPTION_H +#define ULTRA64_EXCEPTION_H + +#include "types.h" + +// Interrupt masks +#define OS_IM_NONE 0x00000001 +#define OS_IM_SW1 0x00000501 +#define OS_IM_SW2 0x00000601 +#define OS_IM_CART 0x00000C01 +#define OS_IM_PRENMI 0x00001401 +#define OS_IM_RDBWRITE 0x00002401 +#define OS_IM_RDBREAD 0x00004401 +#define OS_IM_COUNTER 0x00008401 +#define OS_IM_CPU 0x0000FF01 +#define OS_IM_SP 0x00010401 +#define OS_IM_SI 0x00020401 +#define OS_IM_AI 0x00040401 +#define OS_IM_VI 0x00080401 +#define OS_IM_PI 0x00100401 +#define OS_IM_DP 0x00200401 +#define OS_IM_ALL 0x003FFF01 + +#define RCP_IMASK 0x003F0000 +#define RCP_IMASKSHIFT 16 + +typedef u32 OSIntMask; +typedef u32 OSHWIntr; + +typedef struct { + /* 0x00 */ void* callback; + /* 0x04 */ void* sp; +} __osHwInt; // size = 0x08 + +OSIntMask osSetIntMask(OSIntMask); + +void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*callback)(void), void *sp); +void __osGetHWIntrRoutine(OSHWIntr interrupt, s32 (**callbackOut)(void), void **spOut); + +void __osSetGlobalIntMask(OSHWIntr mask); +void __osResetGlobalIntMask(OSHWIntr mask); + +extern __osHwInt __osHwIntTable[]; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h new file mode 100644 index 000000000..843cb3cd6 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h @@ -0,0 +1,4637 @@ +#include "mbi.h" + +#ifndef ULTRA64_GBI_H +#define ULTRA64_GBI_H + +#ifdef _MSC_VER +#ifndef u8 +#define u8 uint8_t +#endif + +#ifndef u16 +#define u16 uint16_t +#endif + +#ifndef u32 +#define u32 uint32_t +#endif + +#ifndef u64 +#define u64 uint64_t +#endif + +#ifndef s8 +#define s8 int8_t +#endif + +#ifndef s16 +#define s16 int16_t +#endif + +#ifndef s32 +#define s32 int32_t +#endif + +#ifndef s64 +#define s64 int64_t +#endif +#endif + +/* To enable Fast3DEX grucode support, define F3DEX_GBI. */ + +/* Types */ + +/* Private macro to wrap other macros in do {...} while (0) */ +#define _DW(macro) do {macro} while (0) + +#define F3DEX_GBI_2 + +#ifdef F3DEX_GBI_2 +# ifndef F3DEX_GBI +# define F3DEX_GBI +# endif +#define G_NOOP 0x00 +#define G_RDPHALF_2 0xf1 +#define G_SETOTHERMODE_H 0xe3 +#define G_SETOTHERMODE_L 0xe2 +#define G_RDPHALF_1 0xe1 +#define G_SPNOOP 0xe0 +#define G_ENDDL 0xdf +#define G_DL 0xde +#define G_LOAD_UCODE 0xdd +#define G_MOVEMEM 0xdc +#define G_MOVEWORD 0xdb +#define G_MTX 0xda +#define G_GEOMETRYMODE 0xd9 +#define G_POPMTX 0xd8 +#define G_TEXTURE 0xd7 +#define G_DMA_IO 0xd6 +#define G_SPECIAL_1 0xd5 +#define G_SPECIAL_2 0xd4 +#define G_SPECIAL_3 0xd3 + +#define G_VTX 0x01 +#define G_MODIFYVTX 0x02 +#define G_CULLDL 0x03 +#define G_BRANCH_Z 0x04 +#define G_TRI1 0x05 +#define G_TRI2 0x06 +#define G_QUAD 0x07 +#define G_LINE3D 0x08 +#else /* F3DEX_GBI_2 */ + +/* DMA commands: */ +#define G_SPNOOP 0 /* handle 0 gracefully */ +#define G_MTX 1 +#define G_RESERVED0 2 /* not implemeted */ +#define G_MOVEMEM 3 /* move a block of memory (up to 4 words) to dmem */ +#define G_VTX 4 +#define G_RESERVED1 5 /* not implemeted */ +#define G_DL 6 +#define G_RESERVED2 7 /* not implemeted */ +#define G_RESERVED3 8 /* not implemeted */ +#define G_SPRITE2D_BASE 9 /* sprite command */ + +/* IMMEDIATE commands: */ +#define G_IMMFIRST -65 +#define G_TRI1 (G_IMMFIRST-0) +#define G_CULLDL (G_IMMFIRST-1) +#define G_POPMTX (G_IMMFIRST-2) +#define G_MOVEWORD (G_IMMFIRST-3) +#define G_TEXTURE (G_IMMFIRST-4) +#define G_SETOTHERMODE_H (G_IMMFIRST-5) +#define G_SETOTHERMODE_L (G_IMMFIRST-6) +#define G_ENDDL (G_IMMFIRST-7) +#define G_SETGEOMETRYMODE (G_IMMFIRST-8) +#define G_CLEARGEOMETRYMODE (G_IMMFIRST-9) +#define G_LINE3D (G_IMMFIRST-10) +#define G_RDPHALF_1 (G_IMMFIRST-11) +#define G_RDPHALF_2 (G_IMMFIRST-12) +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) +# define G_MODIFYVTX (G_IMMFIRST-13) +# define G_TRI2 (G_IMMFIRST-14) +# define G_BRANCH_Z (G_IMMFIRST-15) +# define G_LOAD_UCODE (G_IMMFIRST-16) +#else +# define G_RDPHALF_CONT (G_IMMFIRST-13) +#endif + +/* We are overloading 2 of the immediate commands + to keep the byte alignment of dmem the same */ + +#define G_SPRITE2D_SCALEFLIP (G_IMMFIRST-1) +#define G_SPRITE2D_DRAW (G_IMMFIRST-2) + + /* RDP commands: */ +#define G_NOOP 0xc0 /* 0 */ + +#endif /* F3DEX_GBI_2 */ + +/* RDP commands: */ +#define G_SETCIMG 0xff /* -1 */ +#define G_SETZIMG 0xfe /* -2 */ +#define G_SETTIMG 0xfd /* -3 */ +#define G_SETCOMBINE 0xfc /* -4 */ +#define G_SETENVCOLOR 0xfb /* -5 */ +#define G_SETPRIMCOLOR 0xfa /* -6 */ +#define G_SETBLENDCOLOR 0xf9 /* -7 */ +#define G_SETFOGCOLOR 0xf8 /* -8 */ +#define G_SETFILLCOLOR 0xf7 /* -9 */ +#define G_FILLRECT 0xf6 /* -10 */ +#define G_SETTILE 0xf5 /* -11 */ +#define G_LOADTILE 0xf4 /* -12 */ +#define G_LOADBLOCK 0xf3 /* -13 */ +#define G_SETTILESIZE 0xf2 /* -14 */ +#define G_LOADTLUT 0xf0 /* -16 */ +#define G_RDPSETOTHERMODE 0xef /* -17 */ +#define G_SETPRIMDEPTH 0xee /* -18 */ +#define G_SETSCISSOR 0xed /* -19 */ +#define G_SETCONVERT 0xec /* -20 */ +#define G_SETKEYR 0xeb /* -21 */ +#define G_SETKEYGB 0xea /* -22 */ +#define G_RDPFULLSYNC 0xe9 /* -23 */ +#define G_RDPTILESYNC 0xe8 /* -24 */ +#define G_RDPPIPESYNC 0xe7 /* -25 */ +#define G_RDPLOADSYNC 0xe6 /* -26 */ +#define G_TEXRECTFLIP 0xe5 /* -27 */ +#define G_TEXRECT 0xe4 /* -28 */ + +// CUSTOM OTR COMMANDS +#define G_SETTIMG_OTR 0x20 +#define G_SETFB 0x21 +#define G_RESETFB 0x22 +#define G_SETTIMG_FB 0x23 +#define G_DL_OTR 0x31 +#define G_VTX_OTR 0x32 +#define G_MARKER 0x33 +#define G_INVALTEXCACHE 0x34 +#define G_BRANCH_Z_OTR 0x35 +#define G_MTX_OTR 0x36 +#define G_TEXRECT_WIDE 0x37 +#define G_FILLWIDERECT 0x38 + +/* + * The following commands are the "generated" RDP commands; the user + * never sees them, the RSP microcode generates them. + * + * The layout of the bits is magical, to save work in the ucode. + * These id's are -56, -52, -54, -50, -55, -51, -53, -49, ... + * edge, shade, texture, zbuff bits: estz + */ +#define G_TRI_FILL 0xc8 /* fill triangle: 11001000 */ +#define G_TRI_SHADE 0xcc /* shade triangle: 11001100 */ +#define G_TRI_TXTR 0xca /* texture triangle: 11001010 */ +#define G_TRI_SHADE_TXTR 0xce /* shade, texture triangle: 11001110 */ +#define G_TRI_FILL_ZBUFF 0xc9 /* fill, zbuff triangle: 11001001 */ +#define G_TRI_SHADE_ZBUFF 0xcd /* shade, zbuff triangle: 11001101 */ +#define G_TRI_TXTR_ZBUFF 0xcb /* texture, zbuff triangle: 11001011 */ +#define G_TRI_SHADE_TXTR_ZBUFF 0xcf /* shade, txtr, zbuff trngl: 11001111 */ + + /* + * A TRI_FILL triangle is just the edges. You need to set the DP + * to use primcolor, in order to see anything. (it is NOT a triangle + * that gets rendered in 'fill mode'. Triangles can't be rendered + * in 'fill mode') + * + * A TRI_SHADE is a gouraud triangle that has colors interpolated. + * Flat-shaded triangles (from the software) are still gouraud shaded, + * it's just the colors are all the same and the deltas are 0. + * + * Other triangle types, and combinations are more obvious. + */ + + /* masks to build RDP triangle commands: */ +#define G_RDP_TRI_FILL_MASK 0x08 +#define G_RDP_TRI_SHADE_MASK 0x04 +#define G_RDP_TRI_TXTR_MASK 0x02 +#define G_RDP_TRI_ZBUFF_MASK 0x01 + +/* + * HACK: + * This is a dreadful hack. For version 1.0 hardware, there are still + * some 'bowtie' hangs. This parameter can be increased to avoid + * the hangs. Every increase of 4 chops one scanline off of every + * triangle. Values of 4,8,12 should be sufficient to avoid any + * bowtie hang. + * + * Change this value, then recompile ALL of your program (including static + * display lists!) + * + * THIS WILL BE REMOVED FOR HARDWARE VERSION 2.0! + */ +#define BOWTIE_VAL 0 + + + /* gets added to RDP command, in order to test for addres fixup: */ +#define G_RDP_ADDR_FIXUP 3 /* |RDP cmds| <= this, do addr fixup */ +#ifdef _LANGUAGE_ASSEMBLY +#define G_RDP_TEXRECT_CHECK ((-1*G_TEXRECTFLIP)& 0xff) +#endif + +/* macros for command parsing: */ +#define GDMACMD(x) (x) +#define GIMMCMD(x) (G_IMMFIRST-(x)) +#define GRDPCMD(x) (0xff-(x)) + +#define G_DMACMDSIZ 128 +#define G_IMMCMDSIZ 64 +#define G_RDPCMDSIZ 64 + +/* + * Coordinate shift values, number of bits of fraction + */ +#define G_TEXTURE_IMAGE_FRAC 2 +#define G_TEXTURE_SCALE_FRAC 16 +#define G_SCALE_FRAC 8 +#define G_ROTATE_FRAC 16 + + /* + * Parameters to graphics commands + */ + + /* + * Data packing macros + */ + + /* + * Maximum z-buffer value, used to initialize the z-buffer. + * Note : this number is NOT the viewport z-scale constant. + * See the comment next to G_MAXZ for more info. + */ +#define G_MAXFBZ 0x3fff /* 3b exp, 11b mantissa */ + +#define GPACK_RGBA5551(r, g, b, a) ((((r)<<8) & 0xf800) | \ + (((g)<<3) & 0x7c0) | \ + (((b)>>2) & 0x3e) | ((a) & 0x1)) +#define GPACK_ZDZ(z, dz) ((z) << 2 | (dz)) + + /* + * G_MTX: parameter flags + */ +#ifdef F3DEX_GBI_2 +# define G_MTX_MODELVIEW 0x00 /* matrix types */ +# define G_MTX_PROJECTION 0x04 +# define G_MTX_MUL 0x00 /* concat or load */ +# define G_MTX_LOAD 0x02 +# define G_MTX_NOPUSH 0x00 /* push or not */ +# define G_MTX_PUSH 0x01 +#else /* F3DEX_GBI_2 */ +# define G_MTX_MODELVIEW 0x00 /* matrix types */ +# define G_MTX_PROJECTION 0x01 +# define G_MTX_MUL 0x00 /* concat or load */ +# define G_MTX_LOAD 0x02 +# define G_MTX_NOPUSH 0x00 /* push or not */ +# define G_MTX_PUSH 0x04 +#endif /* F3DEX_GBI_2 */ + + /* + * flags for G_SETGEOMETRYMODE + * (this rendering state is maintained in RSP) + * + * DO NOT USE THE LOW 8 BITS OF GEOMETRYMODE: + * The weird bit-ordering is for the micro-code: the lower byte + * can be OR'd in with G_TRI_SHADE (11001100) to construct + * the triangle command directly. Don't break it... + * + * DO NOT USE THE HIGH 8 BITS OF GEOMETRYMODE: + * The high byte is OR'd with 0x703 to form the clip code mask. + * If it is set to 0x04, this will cause near clipping to occur. + * If it is zero, near clipping will not occur. + * + * Further explanation: + * G_SHADE is necessary in order to see the color that you passed + * down with the vertex. If G_SHADE isn't set, you need to set the DP + * appropriately and use primcolor to see anything. + * + * G_SHADING_SMOOTH enabled means use all 3 colors of the triangle. + * If it is not set, then do 'flat shading', where only one vertex color + * is used (and all 3 vertices are set to that same color by the ucode) + * See the man page for gSP1Triangle(). + * + */ +#define G_ZBUFFER 0x00000001 +#define G_SHADE 0x00000004 /* enable Gouraud interp */ + /* rest of low byte reserved for setup ucode */ +#ifdef F3DEX_GBI_2 +# define G_TEXTURE_ENABLE 0x00000000 /* Ignored */ +# define G_SHADING_SMOOTH 0x00200000 /* flat or smooth shaded */ +# define G_CULL_FRONT 0x00000200 +# define G_CULL_BACK 0x00000400 +# define G_CULL_BOTH 0x00000600 /* To make code cleaner */ +#else +# define G_TEXTURE_ENABLE 0x00000002 /* Microcode use only */ +# define G_SHADING_SMOOTH 0x00000200 /* flat or smooth shaded */ +# define G_CULL_FRONT 0x00001000 +# define G_CULL_BACK 0x00002000 +# define G_CULL_BOTH 0x00003000 /* To make code cleaner */ +#endif +#define G_FOG 0x00010000 +#define G_LIGHTING 0x00020000 +#define G_TEXTURE_GEN 0x00040000 +#define G_TEXTURE_GEN_LINEAR 0x00080000 +#define G_LOD 0x00100000 /* NOT IMPLEMENTED */ +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) +# define G_CLIPPING 0x00800000 +#else +# define G_CLIPPING 0x00000000 +#endif + +#ifdef _LANGUAGE_ASSEMBLY +#define G_FOG_H (G_FOG/0x10000) +#define G_LIGHTING_H (G_LIGHTING/0x10000) +#define G_TEXTURE_GEN_H (G_TEXTURE_GEN/0x10000) +#define G_TEXTURE_GEN_LINEAR_H (G_TEXTURE_GEN_LINEAR/0x10000) +#define G_LOD_H (G_LOD/0x10000) /* NOT IMPLEMENTED */ +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) +# define G_CLIPPING_H (G_CLIPPING/0x10000) +#endif +#endif + +/* Need these defined for Sprite Microcode */ +#ifdef _LANGUAGE_ASSEMBLY +#define G_TX_LOADTILE 7 +#define G_TX_RENDERTILE 0 + +#define G_TX_NOMIRROR 0 +#define G_TX_WRAP 0 +#define G_TX_MIRROR 0x1 +#define G_TX_CLAMP 0x2 +#define G_TX_NOMASK 0 +#define G_TX_NOLOD 0 +#endif + +/* + * G_SETIMG fmt: set image formats + */ +#define G_IM_FMT_RGBA 0 +#define G_IM_FMT_YUV 1 +#define G_IM_FMT_CI 2 +#define G_IM_FMT_IA 3 +#define G_IM_FMT_I 4 + + /* + * G_SETIMG siz: set image pixel size + */ +#define G_IM_SIZ_4b 0 +#define G_IM_SIZ_8b 1 +#define G_IM_SIZ_16b 2 +#define G_IM_SIZ_32b 3 +#define G_IM_SIZ_DD 5 + +#define G_IM_SIZ_4b_BYTES 0 +#define G_IM_SIZ_4b_TILE_BYTES G_IM_SIZ_4b_BYTES +#define G_IM_SIZ_4b_LINE_BYTES G_IM_SIZ_4b_BYTES + +#define G_IM_SIZ_8b_BYTES 1 +#define G_IM_SIZ_8b_TILE_BYTES G_IM_SIZ_8b_BYTES +#define G_IM_SIZ_8b_LINE_BYTES G_IM_SIZ_8b_BYTES + +#define G_IM_SIZ_16b_BYTES 2 +#define G_IM_SIZ_16b_TILE_BYTES G_IM_SIZ_16b_BYTES +#define G_IM_SIZ_16b_LINE_BYTES G_IM_SIZ_16b_BYTES + +#define G_IM_SIZ_32b_BYTES 4 +#define G_IM_SIZ_32b_TILE_BYTES 2 +#define G_IM_SIZ_32b_LINE_BYTES 2 + +#define G_IM_SIZ_4b_LOAD_BLOCK G_IM_SIZ_16b +#define G_IM_SIZ_8b_LOAD_BLOCK G_IM_SIZ_16b +#define G_IM_SIZ_16b_LOAD_BLOCK G_IM_SIZ_16b +#define G_IM_SIZ_32b_LOAD_BLOCK G_IM_SIZ_32b + +#define G_IM_SIZ_4b_SHIFT 2 +#define G_IM_SIZ_8b_SHIFT 1 +#define G_IM_SIZ_16b_SHIFT 0 +#define G_IM_SIZ_32b_SHIFT 0 + +#define G_IM_SIZ_4b_INCR 3 +#define G_IM_SIZ_8b_INCR 1 +#define G_IM_SIZ_16b_INCR 0 +#define G_IM_SIZ_32b_INCR 0 + + /* + * G_SETCOMBINE: color combine modes + */ + /* Color combiner constants: */ +#define G_CCMUX_COMBINED 0 +#define G_CCMUX_TEXEL0 1 +#define G_CCMUX_TEXEL1 2 +#define G_CCMUX_PRIMITIVE 3 +#define G_CCMUX_SHADE 4 +#define G_CCMUX_ENVIRONMENT 5 +#define G_CCMUX_CENTER 6 +#define G_CCMUX_SCALE 6 +#define G_CCMUX_COMBINED_ALPHA 7 +#define G_CCMUX_TEXEL0_ALPHA 8 +#define G_CCMUX_TEXEL1_ALPHA 9 +#define G_CCMUX_PRIMITIVE_ALPHA 10 +#define G_CCMUX_SHADE_ALPHA 11 +#define G_CCMUX_ENV_ALPHA 12 +#define G_CCMUX_LOD_FRACTION 13 +#define G_CCMUX_PRIM_LOD_FRAC 14 +#define G_CCMUX_NOISE 7 +#define G_CCMUX_K4 7 +#define G_CCMUX_K5 15 +#define G_CCMUX_1 6 +#define G_CCMUX_0 31 + +/* Alpha combiner constants: */ +#define G_ACMUX_COMBINED 0 +#define G_ACMUX_TEXEL0 1 +#define G_ACMUX_TEXEL1 2 +#define G_ACMUX_PRIMITIVE 3 +#define G_ACMUX_SHADE 4 +#define G_ACMUX_ENVIRONMENT 5 +#define G_ACMUX_LOD_FRACTION 0 +#define G_ACMUX_PRIM_LOD_FRAC 6 +#define G_ACMUX_1 6 +#define G_ACMUX_0 7 + +/* typical CC cycle 1 modes */ +#define G_CC_PRIMITIVE 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE +#define G_CC_SHADE 0, 0, 0, SHADE, 0, 0, 0, SHADE +#define G_CC_MODULATEI TEXEL0, 0, SHADE, 0, 0, 0, 0, SHADE +#define G_CC_MODULATEIA TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0 +#define G_CC_MODULATEIDECALA TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0 +#define G_CC_MODULATERGB G_CC_MODULATEI +#define G_CC_MODULATERGBA G_CC_MODULATEIA +#define G_CC_MODULATERGBDECALA G_CC_MODULATEIDECALA +#define G_CC_MODULATEI_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE +#define G_CC_MODULATEIA_PRIM TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0 +#define G_CC_MODULATEIDECALA_PRIM TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0 +#define G_CC_MODULATERGB_PRIM G_CC_MODULATEI_PRIM +#define G_CC_MODULATERGBA_PRIM G_CC_MODULATEIA_PRIM +#define G_CC_MODULATERGBDECALA_PRIM G_CC_MODULATEIDECALA_PRIM +#define G_CC_DECALRGB 0, 0, 0, TEXEL0, 0, 0, 0, SHADE +#define G_CC_DECALRGBA 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0 +#define G_CC_BLENDI ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE +#define G_CC_BLENDIA ENVIRONMENT, SHADE, TEXEL0, SHADE, TEXEL0, 0, SHADE, 0 +#define G_CC_BLENDIDECALA ENVIRONMENT, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_BLENDRGBA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, SHADE +#define G_CC_BLENDRGBDECALA TEXEL0, SHADE, TEXEL0_ALPHA, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_ADDRGB 1, 0, TEXEL0, SHADE, 0, 0, 0, SHADE +#define G_CC_ADDRGBDECALA 1, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_REFLECTRGB ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, SHADE +#define G_CC_REFLECTRGBDECALA ENVIRONMENT, 0, TEXEL0, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_HILITERGB PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE +#define G_CC_HILITERGBA PRIMITIVE, SHADE, TEXEL0, SHADE, PRIMITIVE, SHADE, TEXEL0, SHADE +#define G_CC_HILITERGBDECALA PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_SHADEDECALA 0, 0, 0, SHADE, 0, 0, 0, TEXEL0 +#define G_CC_BLENDPE PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, SHADE, 0 +#define G_CC_BLENDPEDECALA PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, TEXEL0 + +/* oddball modes */ +#define _G_CC_BLENDPE ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, TEXEL0, 0, SHADE, 0 +#define _G_CC_BLENDPEDECALA ENVIRONMENT, PRIMITIVE, TEXEL0, PRIMITIVE, 0, 0, 0, TEXEL0 +#define _G_CC_TWOCOLORTEX PRIMITIVE, SHADE, TEXEL0, SHADE, 0, 0, 0, SHADE +/* used for 1-cycle sparse mip-maps, primitive color has color of lowest LOD */ +#define _G_CC_SPARSEST PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0, PRIMITIVE, TEXEL0, LOD_FRACTION, TEXEL0 +#define G_CC_TEMPLERP TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0 + +/* typical CC cycle 1 modes, usually followed by other cycle 2 modes */ +#define G_CC_TRILERP TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0, TEXEL1, TEXEL0, LOD_FRACTION, TEXEL0 +#define G_CC_INTERFERENCE TEXEL0, 0, TEXEL1, 0, TEXEL0, 0, TEXEL1, 0 + +/* + * One-cycle color convert operation + */ +#define G_CC_1CYUV2RGB TEXEL0, K4, K5, TEXEL0, 0, 0, 0, SHADE + + /* + * NOTE: YUV2RGB expects TF step1 color conversion to occur in 2nd clock. + * Therefore, CC looks for step1 results in TEXEL1 + */ +#define G_CC_YUV2RGB TEXEL1, K4, K5, TEXEL1, 0, 0, 0, 0 + + /* typical CC cycle 2 modes */ +#define G_CC_PASS2 0, 0, 0, COMBINED, 0, 0, 0, COMBINED +#define G_CC_MODULATEI2 COMBINED, 0, SHADE, 0, 0, 0, 0, SHADE +#define G_CC_MODULATEIA2 COMBINED, 0, SHADE, 0, COMBINED, 0, SHADE, 0 +#define G_CC_MODULATERGB2 G_CC_MODULATEI2 +#define G_CC_MODULATERGBA2 G_CC_MODULATEIA2 +#define G_CC_MODULATEI_PRIM2 COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE +#define G_CC_MODULATEIA_PRIM2 COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0 +#define G_CC_MODULATERGB_PRIM2 G_CC_MODULATEI_PRIM2 +#define G_CC_MODULATERGBA_PRIM2 G_CC_MODULATEIA_PRIM2 +#define G_CC_DECALRGB2 0, 0, 0, COMBINED, 0, 0, 0, SHADE +/* + * ? +#define G_CC_DECALRGBA2 COMBINED, SHADE, COMBINED_ALPHA, SHADE, 0, 0, 0, SHADE +*/ +#define G_CC_BLENDI2 ENVIRONMENT, SHADE, COMBINED, SHADE, 0, 0, 0, SHADE +#define G_CC_BLENDIA2 ENVIRONMENT, SHADE, COMBINED, SHADE, COMBINED, 0, SHADE, 0 +#define G_CC_CHROMA_KEY2 TEXEL0, CENTER, SCALE, 0, 0, 0, 0, 0 +#define G_CC_HILITERGB2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, SHADE +#define G_CC_HILITERGBA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, ENVIRONMENT, COMBINED, TEXEL0, COMBINED +#define G_CC_HILITERGBDECALA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, TEXEL0 +#define G_CC_HILITERGBPASSA2 ENVIRONMENT, COMBINED, TEXEL0, COMBINED, 0, 0, 0, COMBINED + +/* + * G_SETOTHERMODE_L sft: shift count + */ +#define G_MDSFT_ALPHACOMPARE 0 +#define G_MDSFT_ZSRCSEL 2 +#define G_MDSFT_RENDERMODE 3 +#define G_MDSFT_BLENDER 16 + + /* + * G_SETOTHERMODE_H sft: shift count + */ +#define G_MDSFT_BLENDMASK 0 /* unsupported */ +#define G_MDSFT_ALPHADITHER 4 +#define G_MDSFT_RGBDITHER 6 + +#define G_MDSFT_COMBKEY 8 +#define G_MDSFT_TEXTCONV 9 +#define G_MDSFT_TEXTFILT 12 +#define G_MDSFT_TEXTLUT 14 +#define G_MDSFT_TEXTLOD 16 +#define G_MDSFT_TEXTDETAIL 17 +#define G_MDSFT_TEXTPERSP 19 +#define G_MDSFT_CYCLETYPE 20 +#define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */ +#define G_MDSFT_PIPELINE 23 + + /* G_SETOTHERMODE_H gPipelineMode */ +#define G_PM_1PRIMITIVE (1 << G_MDSFT_PIPELINE) +#define G_PM_NPRIMITIVE (0 << G_MDSFT_PIPELINE) + +/* G_SETOTHERMODE_H gSetCycleType */ +#define G_CYC_1CYCLE (0 << G_MDSFT_CYCLETYPE) +#define G_CYC_2CYCLE (1 << G_MDSFT_CYCLETYPE) +#define G_CYC_COPY (2 << G_MDSFT_CYCLETYPE) +#define G_CYC_FILL (3 << G_MDSFT_CYCLETYPE) + +/* G_SETOTHERMODE_H gSetTexturePersp */ +#define G_TP_NONE (0 << G_MDSFT_TEXTPERSP) +#define G_TP_PERSP (1 << G_MDSFT_TEXTPERSP) + +/* G_SETOTHERMODE_H gSetTextureDetail */ +#define G_TD_CLAMP (0 << G_MDSFT_TEXTDETAIL) +#define G_TD_SHARPEN (1 << G_MDSFT_TEXTDETAIL) +#define G_TD_DETAIL (2 << G_MDSFT_TEXTDETAIL) + +/* G_SETOTHERMODE_H gSetTextureLOD */ +#define G_TL_TILE (0 << G_MDSFT_TEXTLOD) +#define G_TL_LOD (1 << G_MDSFT_TEXTLOD) + +/* G_SETOTHERMODE_H gSetTextureLUT */ +#define G_TT_NONE (0 << G_MDSFT_TEXTLUT) +#define G_TT_RGBA16 (2 << G_MDSFT_TEXTLUT) +#define G_TT_IA16 (3 << G_MDSFT_TEXTLUT) + +/* G_SETOTHERMODE_H gSetTextureFilter */ +#define G_TF_POINT (0 << G_MDSFT_TEXTFILT) +#define G_TF_AVERAGE (3 << G_MDSFT_TEXTFILT) +#define G_TF_BILERP (2 << G_MDSFT_TEXTFILT) + +/* G_SETOTHERMODE_H gSetTextureConvert */ +#define G_TC_CONV (0 << G_MDSFT_TEXTCONV) +#define G_TC_FILTCONV (5 << G_MDSFT_TEXTCONV) +#define G_TC_FILT (6 << G_MDSFT_TEXTCONV) + +/* G_SETOTHERMODE_H gSetCombineKey */ +#define G_CK_NONE (0 << G_MDSFT_COMBKEY) +#define G_CK_KEY (1 << G_MDSFT_COMBKEY) + +/* G_SETOTHERMODE_H gSetColorDither */ +#define G_CD_MAGICSQ (0 << G_MDSFT_RGBDITHER) +#define G_CD_BAYER (1 << G_MDSFT_RGBDITHER) +#define G_CD_NOISE (2 << G_MDSFT_RGBDITHER) + +#ifndef _HW_VERSION_1 +#define G_CD_DISABLE (3 << G_MDSFT_RGBDITHER) +#define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */ +#else +#define G_CD_ENABLE (1 << G_MDSFT_COLORDITHER) +#define G_CD_DISABLE (0 << G_MDSFT_COLORDITHER) +#endif + +/* G_SETOTHERMODE_H gSetAlphaDither */ +#define G_AD_PATTERN (0 << G_MDSFT_ALPHADITHER) +#define G_AD_NOTPATTERN (1 << G_MDSFT_ALPHADITHER) +#define G_AD_NOISE (2 << G_MDSFT_ALPHADITHER) +#define G_AD_DISABLE (3 << G_MDSFT_ALPHADITHER) + +/* G_SETOTHERMODE_L gSetAlphaCompare */ +#define G_AC_NONE (0 << G_MDSFT_ALPHACOMPARE) +#define G_AC_THRESHOLD (1 << G_MDSFT_ALPHACOMPARE) +#define G_AC_DITHER (3 << G_MDSFT_ALPHACOMPARE) + +/* G_SETOTHERMODE_L gSetDepthSource */ +#define G_ZS_PIXEL (0 << G_MDSFT_ZSRCSEL) +#define G_ZS_PRIM (1 << G_MDSFT_ZSRCSEL) + +/* G_SETOTHERMODE_L gSetRenderMode */ +#define AA_EN 0x8 +#define Z_CMP 0x10 +#define Z_UPD 0x20 +#define IM_RD 0x40 +#define CLR_ON_CVG 0x80 +#define CVG_DST_CLAMP 0 +#define CVG_DST_WRAP 0x100 +#define CVG_DST_FULL 0x200 +#define CVG_DST_SAVE 0x300 +#define ZMODE_OPA 0 +#define ZMODE_INTER 0x400 +#define ZMODE_XLU 0x800 +#define ZMODE_DEC 0xc00 +#define CVG_X_ALPHA 0x1000 +#define ALPHA_CVG_SEL 0x2000 +#define FORCE_BL 0x4000 +#define TEX_EDGE 0x0000 /* used to be 0x8000 */ + +#define G_BL_CLR_IN 0 +#define G_BL_CLR_MEM 1 +#define G_BL_CLR_BL 2 +#define G_BL_CLR_FOG 3 +#define G_BL_1MA 0 +#define G_BL_A_MEM 1 +#define G_BL_A_IN 0 +#define G_BL_A_FOG 1 +#define G_BL_A_SHADE 2 +#define G_BL_1 2 +#define G_BL_0 3 + +#define GBL_c1(m1a, m1b, m2a, m2b) \ + (m1a) << 30 | (m1b) << 26 | (m2a) << 22 | (m2b) << 18 +#define GBL_c2(m1a, m1b, m2a, m2b) \ + (m1a) << 28 | (m1b) << 24 | (m2a) << 20 | (m2b) << 16 + +#define RM_AA_ZB_OPA_SURF(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_RA_ZB_OPA_SURF(clk) \ + AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_XLU_SURF(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \ + FORCE_BL | ZMODE_XLU | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_OPA_DECAL(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | ALPHA_CVG_SEL | \ + ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_RA_ZB_OPA_DECAL(clk) \ + AA_EN | Z_CMP | CVG_DST_WRAP | ALPHA_CVG_SEL | \ + ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_XLU_DECAL(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \ + FORCE_BL | ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_OPA_INTER(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + ALPHA_CVG_SEL | ZMODE_INTER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_RA_ZB_OPA_INTER(clk) \ + AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP | \ + ALPHA_CVG_SEL | ZMODE_INTER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_XLU_INTER(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | \ + FORCE_BL | ZMODE_INTER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_XLU_LINE(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \ + ALPHA_CVG_SEL | FORCE_BL | ZMODE_XLU | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_DEC_LINE(clk) \ + AA_EN | Z_CMP | IM_RD | CVG_DST_SAVE | CVG_X_ALPHA | \ + ALPHA_CVG_SEL | FORCE_BL | ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_TEX_EDGE(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_TEX_INTER(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_INTER | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_SUB_SURF(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_ZB_PCL_SURF(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | G_AC_DITHER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_OPA_TERR(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_TEX_TERR(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_ZB_SUB_TERR(clk) \ + AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + + +#define RM_AA_OPA_SURF(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_RA_OPA_SURF(clk) \ + AA_EN | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_XLU_SURF(clk) \ + AA_EN | IM_RD | CVG_DST_WRAP | CLR_ON_CVG | FORCE_BL | \ + ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_XLU_LINE(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | CVG_X_ALPHA | \ + ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_DEC_LINE(clk) \ + AA_EN | IM_RD | CVG_DST_FULL | CVG_X_ALPHA | \ + ALPHA_CVG_SEL | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_TEX_EDGE(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_SUB_SURF(clk) \ + AA_EN | IM_RD | CVG_DST_FULL | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_AA_PCL_SURF(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | G_AC_DITHER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_OPA_TERR(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_TEX_TERR(clk) \ + AA_EN | IM_RD | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_AA_SUB_TERR(clk) \ + AA_EN | IM_RD | CVG_DST_FULL | \ + ZMODE_OPA | ALPHA_CVG_SEL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + + +#define RM_ZB_OPA_SURF(clk) \ + Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL | \ + ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_ZB_XLU_SURF(clk) \ + Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_ZB_OPA_DECAL(clk) \ + Z_CMP | CVG_DST_FULL | ALPHA_CVG_SEL | ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM) + +#define RM_ZB_XLU_DECAL(clk) \ + Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_ZB_CLD_SURF(clk) \ + Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_XLU | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_ZB_OVL_SURF(clk) \ + Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_ZB_PCL_SURF(clk) \ + Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | \ + G_AC_DITHER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + + +#define RM_OPA_SURF(clk) \ + CVG_DST_CLAMP | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + +#define RM_XLU_SURF(clk) \ + IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_TEX_EDGE(clk) \ + CVG_DST_CLAMP | CVG_X_ALPHA | ALPHA_CVG_SEL | FORCE_BL |\ + ZMODE_OPA | TEX_EDGE | AA_EN | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + +#define RM_CLD_SURF(clk) \ + IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define RM_PCL_SURF(clk) \ + CVG_DST_FULL | FORCE_BL | ZMODE_OPA | \ + G_AC_DITHER | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + +#define RM_ADD(clk) \ + IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_1) + +#define RM_NOOP(clk) \ + GBL_c##clk(0, 0, 0, 0) + +#define RM_VISCVG(clk) \ + IM_RD | FORCE_BL | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_BL, G_BL_A_MEM) + +/* for rendering to an 8-bit framebuffer */ +#define RM_OPA_CI(clk) \ + CVG_DST_CLAMP | ZMODE_OPA | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + + + +#define G_RM_AA_ZB_OPA_SURF RM_AA_ZB_OPA_SURF(1) +#define G_RM_AA_ZB_OPA_SURF2 RM_AA_ZB_OPA_SURF(2) +#define G_RM_AA_ZB_XLU_SURF RM_AA_ZB_XLU_SURF(1) +#define G_RM_AA_ZB_XLU_SURF2 RM_AA_ZB_XLU_SURF(2) +#define G_RM_AA_ZB_OPA_DECAL RM_AA_ZB_OPA_DECAL(1) +#define G_RM_AA_ZB_OPA_DECAL2 RM_AA_ZB_OPA_DECAL(2) +#define G_RM_AA_ZB_XLU_DECAL RM_AA_ZB_XLU_DECAL(1) +#define G_RM_AA_ZB_XLU_DECAL2 RM_AA_ZB_XLU_DECAL(2) +#define G_RM_AA_ZB_OPA_INTER RM_AA_ZB_OPA_INTER(1) +#define G_RM_AA_ZB_OPA_INTER2 RM_AA_ZB_OPA_INTER(2) +#define G_RM_AA_ZB_XLU_INTER RM_AA_ZB_XLU_INTER(1) +#define G_RM_AA_ZB_XLU_INTER2 RM_AA_ZB_XLU_INTER(2) +#define G_RM_AA_ZB_XLU_LINE RM_AA_ZB_XLU_LINE(1) +#define G_RM_AA_ZB_XLU_LINE2 RM_AA_ZB_XLU_LINE(2) +#define G_RM_AA_ZB_DEC_LINE RM_AA_ZB_DEC_LINE(1) +#define G_RM_AA_ZB_DEC_LINE2 RM_AA_ZB_DEC_LINE(2) +#define G_RM_AA_ZB_TEX_EDGE RM_AA_ZB_TEX_EDGE(1) +#define G_RM_AA_ZB_TEX_EDGE2 RM_AA_ZB_TEX_EDGE(2) +#define G_RM_AA_ZB_TEX_INTER RM_AA_ZB_TEX_INTER(1) +#define G_RM_AA_ZB_TEX_INTER2 RM_AA_ZB_TEX_INTER(2) +#define G_RM_AA_ZB_SUB_SURF RM_AA_ZB_SUB_SURF(1) +#define G_RM_AA_ZB_SUB_SURF2 RM_AA_ZB_SUB_SURF(2) +#define G_RM_AA_ZB_PCL_SURF RM_AA_ZB_PCL_SURF(1) +#define G_RM_AA_ZB_PCL_SURF2 RM_AA_ZB_PCL_SURF(2) +#define G_RM_AA_ZB_OPA_TERR RM_AA_ZB_OPA_TERR(1) +#define G_RM_AA_ZB_OPA_TERR2 RM_AA_ZB_OPA_TERR(2) +#define G_RM_AA_ZB_TEX_TERR RM_AA_ZB_TEX_TERR(1) +#define G_RM_AA_ZB_TEX_TERR2 RM_AA_ZB_TEX_TERR(2) +#define G_RM_AA_ZB_SUB_TERR RM_AA_ZB_SUB_TERR(1) +#define G_RM_AA_ZB_SUB_TERR2 RM_AA_ZB_SUB_TERR(2) + +#define G_RM_RA_ZB_OPA_SURF RM_RA_ZB_OPA_SURF(1) +#define G_RM_RA_ZB_OPA_SURF2 RM_RA_ZB_OPA_SURF(2) +#define G_RM_RA_ZB_OPA_DECAL RM_RA_ZB_OPA_DECAL(1) +#define G_RM_RA_ZB_OPA_DECAL2 RM_RA_ZB_OPA_DECAL(2) +#define G_RM_RA_ZB_OPA_INTER RM_RA_ZB_OPA_INTER(1) +#define G_RM_RA_ZB_OPA_INTER2 RM_RA_ZB_OPA_INTER(2) + +#define G_RM_AA_OPA_SURF RM_AA_OPA_SURF(1) +#define G_RM_AA_OPA_SURF2 RM_AA_OPA_SURF(2) +#define G_RM_AA_XLU_SURF RM_AA_XLU_SURF(1) +#define G_RM_AA_XLU_SURF2 RM_AA_XLU_SURF(2) +#define G_RM_AA_XLU_LINE RM_AA_XLU_LINE(1) +#define G_RM_AA_XLU_LINE2 RM_AA_XLU_LINE(2) +#define G_RM_AA_DEC_LINE RM_AA_DEC_LINE(1) +#define G_RM_AA_DEC_LINE2 RM_AA_DEC_LINE(2) +#define G_RM_AA_TEX_EDGE RM_AA_TEX_EDGE(1) +#define G_RM_AA_TEX_EDGE2 RM_AA_TEX_EDGE(2) +#define G_RM_AA_SUB_SURF RM_AA_SUB_SURF(1) +#define G_RM_AA_SUB_SURF2 RM_AA_SUB_SURF(2) +#define G_RM_AA_PCL_SURF RM_AA_PCL_SURF(1) +#define G_RM_AA_PCL_SURF2 RM_AA_PCL_SURF(2) +#define G_RM_AA_OPA_TERR RM_AA_OPA_TERR(1) +#define G_RM_AA_OPA_TERR2 RM_AA_OPA_TERR(2) +#define G_RM_AA_TEX_TERR RM_AA_TEX_TERR(1) +#define G_RM_AA_TEX_TERR2 RM_AA_TEX_TERR(2) +#define G_RM_AA_SUB_TERR RM_AA_SUB_TERR(1) +#define G_RM_AA_SUB_TERR2 RM_AA_SUB_TERR(2) + +#define G_RM_RA_OPA_SURF RM_RA_OPA_SURF(1) +#define G_RM_RA_OPA_SURF2 RM_RA_OPA_SURF(2) + +#define G_RM_ZB_OPA_SURF RM_ZB_OPA_SURF(1) +#define G_RM_ZB_OPA_SURF2 RM_ZB_OPA_SURF(2) +#define G_RM_ZB_XLU_SURF RM_ZB_XLU_SURF(1) +#define G_RM_ZB_XLU_SURF2 RM_ZB_XLU_SURF(2) +#define G_RM_ZB_OPA_DECAL RM_ZB_OPA_DECAL(1) +#define G_RM_ZB_OPA_DECAL2 RM_ZB_OPA_DECAL(2) +#define G_RM_ZB_XLU_DECAL RM_ZB_XLU_DECAL(1) +#define G_RM_ZB_XLU_DECAL2 RM_ZB_XLU_DECAL(2) +#define G_RM_ZB_CLD_SURF RM_ZB_CLD_SURF(1) +#define G_RM_ZB_CLD_SURF2 RM_ZB_CLD_SURF(2) +#define G_RM_ZB_OVL_SURF RM_ZB_OVL_SURF(1) +#define G_RM_ZB_OVL_SURF2 RM_ZB_OVL_SURF(2) +#define G_RM_ZB_PCL_SURF RM_ZB_PCL_SURF(1) +#define G_RM_ZB_PCL_SURF2 RM_ZB_PCL_SURF(2) + +#define G_RM_OPA_SURF RM_OPA_SURF(1) +#define G_RM_OPA_SURF2 RM_OPA_SURF(2) +#define G_RM_XLU_SURF RM_XLU_SURF(1) +#define G_RM_XLU_SURF2 RM_XLU_SURF(2) +#define G_RM_CLD_SURF RM_CLD_SURF(1) +#define G_RM_CLD_SURF2 RM_CLD_SURF(2) +#define G_RM_TEX_EDGE RM_TEX_EDGE(1) +#define G_RM_TEX_EDGE2 RM_TEX_EDGE(2) +#define G_RM_PCL_SURF RM_PCL_SURF(1) +#define G_RM_PCL_SURF2 RM_PCL_SURF(2) +#define G_RM_ADD RM_ADD(1) +#define G_RM_ADD2 RM_ADD(2) +#define G_RM_NOOP RM_NOOP(1) +#define G_RM_NOOP2 RM_NOOP(2) +#define G_RM_VISCVG RM_VISCVG(1) +#define G_RM_VISCVG2 RM_VISCVG(2) +#define G_RM_OPA_CI RM_OPA_CI(1) +#define G_RM_OPA_CI2 RM_OPA_CI(2) + + +#define G_RM_FOG_SHADE_A GBL_c1(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA) +#define G_RM_FOG_PRIM_A GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA) +#define G_RM_PASS GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) + +/* + * G_SETCONVERT: K0-5 + */ +#define G_CV_K0 175 +#define G_CV_K1 -43 +#define G_CV_K2 -89 +#define G_CV_K3 222 +#define G_CV_K4 114 +#define G_CV_K5 42 + + /* + * G_SETSCISSOR: interlace mode + */ +#define G_SC_NON_INTERLACE 0 +#define G_SC_ODD_INTERLACE 3 +#define G_SC_EVEN_INTERLACE 2 + + /* flags to inhibit pushing of the display list (on branch) */ +#define G_DL_PUSH 0x00 +#define G_DL_NOPUSH 0x01 + +#if _MSC_VER +#define _LANGUAGE_C +#endif + +/* + * BEGIN C-specific section: (typedef's) + */ +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + + /* + * Data Structures + * + * NOTE: + * The DMA transfer hardware requires 64-bit aligned, 64-bit multiple- + * sized transfers. This important hardware optimization is unfortunately + * reflected in the programming interface, with some structures + * padded and alignment enforced. + * + * Since structures are aligned to the boundary of the "worst-case" + * element, we can't depend on the C compiler to align things + * properly. + * + * 64-bit structure alignment is enforced by wrapping structures with + * unions that contain a dummy "long long int". Why this works is + * explained in the ANSI C Spec, or on page 186 of the second edition + * of K&R, "The C Programming Language". + * + * The price we pay for this is a little awkwardness referencing the + * structures through the union. There is no memory penalty, since + * all the structures are at least 64-bits the dummy alignment field + * does not increase the size of the union. + * + * Static initialization of these union structures works because + * the ANSI C spec states that static initialization for unions + * works by using the first union element. We put the dummy alignment + * field last for this reason. + * + * (it's possible a newer 64-bit compiler from MIPS might make this + * easier with a flag, but we can't wait for it...) + * + */ + + /* + * Vertex (set up for use with colors) + */ +typedef struct { + short ob[3]; /* x, y, z */ + unsigned short flag; + short tc[2]; /* texture coord */ + unsigned char cn[4]; /* color & alpha */ +} Vtx_t; + +/* + * Vertex (set up for use with normals) + */ +typedef struct { + short ob[3]; /* x, y, z */ + unsigned short flag; + short tc[2]; /* texture coord */ + signed char n[3]; /* normal */ + unsigned char a; /* alpha */ +} Vtx_tn; + +typedef union { + Vtx_t v; /* Use this one for colors */ + Vtx_tn n; /* Use this one for normals */ + long long int force_structure_alignment; +} Vtx; + +/* + * Sprite structure + */ + +typedef struct { + void* SourceImagePointer; + void* TlutPointer; + short Stride; + short SubImageWidth; + short SubImageHeight; + char SourceImageType; + char SourceImageBitSize; + short SourceImageOffsetS; + short SourceImageOffsetT; + /* 20 bytes for above */ + + /* padding to bring structure size to 64 bit allignment */ + char dummy[4]; + +} uSprite_t; + +typedef union { + uSprite_t s; + + /* Need to make sure this is 64 bit aligned */ + long long int force_structure_allignment[3]; +} uSprite; + +/* + * Triangle face + */ +typedef struct { + unsigned char flag; + unsigned char v[3]; +} Tri; + +/* + * Viewport + */ + + /* + * + * This magic value is the maximum INTEGER z-range of the hardware + * (there are also 16-bits of fraction, which are introduced during + * any transformations). This is not just a good idea, it's the law. + * Feeding the hardware eventual z-coordinates (after any transforms + * or scaling) bigger than this, will not work. + * + * This number is DIFFERENT than G_MAXFBZ, which is the maximum value + * you want to use to initialize the z-buffer. + * + * The reason these are different is mildly interesting, but too long + * to explain here. It is basically the result of optimizations in the + * hardware. A more generic API might hide this detail from the users, + * but we don't have the ucode to do that... + * + */ +#define G_MAXZ 0x03ff /* 10 bits of integer screen-Z precision */ + + /* + * The viewport structure elements have 2 bits of fraction, necessary + * to accomodate the sub-pixel positioning scaling for the hardware. + * This can also be exploited to handle odd-sized viewports. + * + * Accounting for these fractional bits, using the default projection + * and viewing matrices, the viewport structure is initialized thusly: + * + * (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, G_MAXZ, 0, + * (SCREEN_WD/2)*4, (SCREEN_HT/2)*4, 0, 0, + */ +typedef struct { + short vscale[4]; /* scale, 2 bits fraction */ + short vtrans[4]; /* translate, 2 bits fraction */ + /* both the above arrays are padded to 64-bit boundary */ +} Vp_t; + +typedef union { + Vp_t vp; + long long int force_structure_alignment; +} Vp; + +/* + * MOVEMEM indices + * + * Each of these indexes an entry in a dmem table + * which points to a 1-4 word block of dmem in + * which to store a 1-4 word DMA. + * + */ +#ifdef F3DEX_GBI_2 + /* 0,4 are reserved by G_MTX */ +# define G_MV_MMTX 2 +# define G_MV_PMTX 6 +# define G_MV_VIEWPORT 8 +# define G_MV_LIGHT 10 +# define G_MV_POINT 12 +# define G_MV_MATRIX 14 /* NOTE: this is in moveword table */ +# define G_MVO_LOOKATX (0*24) +# define G_MVO_LOOKATY (1*24) +# define G_MVO_L0 (2*24) +# define G_MVO_L1 (3*24) +# define G_MVO_L2 (4*24) +# define G_MVO_L3 (5*24) +# define G_MVO_L4 (6*24) +# define G_MVO_L5 (7*24) +# define G_MVO_L6 (8*24) +# define G_MVO_L7 (9*24) +#else /* F3DEX_GBI_2 */ +# define G_MV_VIEWPORT 0x80 +# define G_MV_LOOKATY 0x82 +# define G_MV_LOOKATX 0x84 +# define G_MV_L0 0x86 +# define G_MV_L1 0x88 +# define G_MV_L2 0x8a +# define G_MV_L3 0x8c +# define G_MV_L4 0x8e +# define G_MV_L5 0x90 +# define G_MV_L6 0x92 +# define G_MV_L7 0x94 +# define G_MV_TXTATT 0x96 +# define G_MV_MATRIX_1 0x9e /* NOTE: this is in moveword table */ +# define G_MV_MATRIX_2 0x98 +# define G_MV_MATRIX_3 0x9a +# define G_MV_MATRIX_4 0x9c +#endif /* F3DEX_GBI_2 */ + + /* + * MOVEWORD indices + * + * Each of these indexes an entry in a dmem table + * which points to a word in dmem in dmem where + * an immediate word will be stored. + * + */ +#define G_MW_MATRIX 0x00 /* NOTE: also used by movemem */ +#define G_MW_NUMLIGHT 0x02 +#define G_MW_CLIP 0x04 +#define G_MW_SEGMENT 0x06 +#define G_MW_FOG 0x08 +#define G_MW_LIGHTCOL 0x0a +#ifdef F3DEX_GBI_2 +# define G_MW_FORCEMTX 0x0c +#else /* F3DEX_GBI_2 */ +# define G_MW_POINTS 0x0c +#endif /* F3DEX_GBI_2 */ +#define G_MW_PERSPNORM 0x0e + + /* + * These are offsets from the address in the dmem table + */ +#define G_MWO_NUMLIGHT 0x00 +#define G_MWO_CLIP_RNX 0x04 +#define G_MWO_CLIP_RNY 0x0c +#define G_MWO_CLIP_RPX 0x14 +#define G_MWO_CLIP_RPY 0x1c +#define G_MWO_SEGMENT_0 0x00 +#define G_MWO_SEGMENT_1 0x01 +#define G_MWO_SEGMENT_2 0x02 +#define G_MWO_SEGMENT_3 0x03 +#define G_MWO_SEGMENT_4 0x04 +#define G_MWO_SEGMENT_5 0x05 +#define G_MWO_SEGMENT_6 0x06 +#define G_MWO_SEGMENT_7 0x07 +#define G_MWO_SEGMENT_8 0x08 +#define G_MWO_SEGMENT_9 0x09 +#define G_MWO_SEGMENT_A 0x0a +#define G_MWO_SEGMENT_B 0x0b +#define G_MWO_SEGMENT_C 0x0c +#define G_MWO_SEGMENT_D 0x0d +#define G_MWO_SEGMENT_E 0x0e +#define G_MWO_SEGMENT_F 0x0f +#define G_MWO_FOG 0x00 +#define G_MWO_aLIGHT_1 0x00 +#define G_MWO_bLIGHT_1 0x04 +#ifdef F3DEX_GBI_2 +#define G_MWO_aLIGHT_2 0x18 +#define G_MWO_bLIGHT_2 0x1c +#define G_MWO_aLIGHT_3 0x30 +#define G_MWO_bLIGHT_3 0x34 +#define G_MWO_aLIGHT_4 0x48 +#define G_MWO_bLIGHT_4 0x4c +#define G_MWO_aLIGHT_5 0x60 +#define G_MWO_bLIGHT_5 0x64 +#define G_MWO_aLIGHT_6 0x78 +#define G_MWO_bLIGHT_6 0x7c +#define G_MWO_aLIGHT_7 0x90 +#define G_MWO_bLIGHT_7 0x94 +#define G_MWO_aLIGHT_8 0xa8 +#define G_MWO_bLIGHT_8 0xac +#else +#define G_MWO_aLIGHT_2 0x20 +#define G_MWO_bLIGHT_2 0x24 +#define G_MWO_aLIGHT_3 0x40 +#define G_MWO_bLIGHT_3 0x44 +#define G_MWO_aLIGHT_4 0x60 +#define G_MWO_bLIGHT_4 0x64 +#define G_MWO_aLIGHT_5 0x80 +#define G_MWO_bLIGHT_5 0x84 +#define G_MWO_aLIGHT_6 0xa0 +#define G_MWO_bLIGHT_6 0xa4 +#define G_MWO_aLIGHT_7 0xc0 +#define G_MWO_bLIGHT_7 0xc4 +#define G_MWO_aLIGHT_8 0xe0 +#define G_MWO_bLIGHT_8 0xe4 +#endif +#define G_MWO_MATRIX_XX_XY_I 0x00 +#define G_MWO_MATRIX_XZ_XW_I 0x04 +#define G_MWO_MATRIX_YX_YY_I 0x08 +#define G_MWO_MATRIX_YZ_YW_I 0x0c +#define G_MWO_MATRIX_ZX_ZY_I 0x10 +#define G_MWO_MATRIX_ZZ_ZW_I 0x14 +#define G_MWO_MATRIX_WX_WY_I 0x18 +#define G_MWO_MATRIX_WZ_WW_I 0x1c +#define G_MWO_MATRIX_XX_XY_F 0x20 +#define G_MWO_MATRIX_XZ_XW_F 0x24 +#define G_MWO_MATRIX_YX_YY_F 0x28 +#define G_MWO_MATRIX_YZ_YW_F 0x2c +#define G_MWO_MATRIX_ZX_ZY_F 0x30 +#define G_MWO_MATRIX_ZZ_ZW_F 0x34 +#define G_MWO_MATRIX_WX_WY_F 0x38 +#define G_MWO_MATRIX_WZ_WW_F 0x3c +#define G_MWO_POINT_RGBA 0x10 +#define G_MWO_POINT_ST 0x14 +#define G_MWO_POINT_XYSCREEN 0x18 +#define G_MWO_POINT_ZSCREEN 0x1c + + /* + * Light structure. + * + * Note: only directional (infinite) lights are currently supported. + * + * Note: the weird order is for the DMEM alignment benefit of + * the microcode. + * + */ + +typedef struct { + unsigned char col[3]; /* diffuse light value (rgba) */ + char pad1; + unsigned char colc[3]; /* copy of diffuse light value (rgba) */ + char pad2; + signed char dir[3]; /* direction of light (normalized) */ + char pad3; +} Light_t; + +typedef struct { + unsigned char col[3]; /* ambient light value (rgba) */ + char pad1; + unsigned char colc[3]; /* copy of ambient light value (rgba) */ + char pad2; +} Ambient_t; + +typedef struct { + int x1, y1, x2, y2; /* texture offsets for highlight 1/2 */ +} Hilite_t; + +typedef union { + Light_t l; + long long int force_structure_alignment[2]; +} Light; + +typedef union { + Ambient_t l; + long long int force_structure_alignment[1]; +} Ambient; + +typedef struct { + Ambient a; + Light l[7]; +} Lightsn; + +typedef struct { + Ambient a; + Light l[1]; +} Lights0; + +typedef struct { + Ambient a; + Light l[1]; +} Lights1; + +typedef struct { + Ambient a; + Light l[2]; +} Lights2; + +typedef struct { + Ambient a; + Light l[3]; +} Lights3; + +typedef struct { + Ambient a; + Light l[4]; +} Lights4; + +typedef struct { + Ambient a; + Light l[5]; +} Lights5; + +typedef struct { + Ambient a; + Light l[6]; +} Lights6; + +typedef struct { + Ambient a; + Light l[7]; +} Lights7; + +typedef struct { + Light l[2]; +} LookAt; + +typedef union { + Hilite_t h; + long int force_structure_alignment[4]; +} Hilite; + +#define gdSPDefLights0(ar,ag,ab) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ { 0, 0, 0},0,{ 0, 0, 0},0,{ 0, 0, 0},0}}} } +#define gdSPDefLights1(ar,ag,ab,r1,g1,b1,x1,y1,z1) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}} } +#define gdSPDefLights2(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}} } +#define gdSPDefLights3(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ + {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}} } +#define gdSPDefLights4(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ + {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ + {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}} } +#define gdSPDefLights5(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ + {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ + {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ + {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}} } + + +#define gdSPDefLights6(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ + {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ + {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ + {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \ + {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}} } + + +#define gdSPDefLights7(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6,r7,g7,b7,x7,y7,z7) \ + { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ + {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ + {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ + {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ + {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ + {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \ + {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}, \ + {{ {r7,g7,b7},0,{r7,g7,b7},0,{x7,y7,z7},0}}} } + + +#define gdSPDefLookAt(rightx,righty,rightz,upx,upy,upz) \ + { {{ {{0,0,0},0,{0,0,0},0,{rightx,righty,rightz},0}}, \ + { {{0,0x80,0},0,{0,0x80,0},0,{upx,upy,upz},0}}} } + +/* + * Graphics DMA Packet + */ +typedef struct { + int cmd : 8; + unsigned int par : 8; + unsigned int len : 16; + unsigned int addr; +} Gdma; + +/* + * Graphics Immediate Mode Packet types + */ +typedef struct { + int cmd : 8; + int pad : 24; + Tri tri; +} Gtri; + +typedef struct { + int cmd : 8; + int pad1 : 24; + int pad2 : 24; + unsigned char param : 8; +} Gpopmtx; + +/* + * typedef struct { + * int cmd:8; + * int pad0:24; + * int pad1:4; + * int number:4; + * int base:24; + * } Gsegment; + */ +typedef struct { + int cmd : 8; + int pad0 : 8; + int mw_index : 8; + int number : 8; + int pad1 : 8; + int base : 24; +} Gsegment; + +typedef struct { + int cmd : 8; + int pad0 : 8; + int sft : 8; + int len : 8; + unsigned int data : 32; +} GsetothermodeL; + +typedef struct { + int cmd : 8; + int pad0 : 8; + int sft : 8; + int len : 8; + unsigned int data : 32; +} GsetothermodeH; + +typedef struct { + unsigned char cmd; + unsigned char lodscale; + unsigned char tile; + unsigned char on; + unsigned short s; + unsigned short t; +} Gtexture; + +typedef struct { + int cmd : 8; + int pad : 24; + Tri line; +} Gline3D; + +typedef struct { + int cmd : 8; + int pad1 : 24; + short int pad2; + short int scale; +} Gperspnorm; + + +/* + * RDP Packet types + */ +typedef struct { + int cmd : 8; + unsigned int fmt : 3; + unsigned int siz : 2; + unsigned int pad : 7; + unsigned int wd : 12; /* really only 10 bits, extra */ + unsigned int dram; /* to account for 1024 */ +} Gsetimg; + +typedef struct { + int cmd : 8; + unsigned int muxs0 : 24; + unsigned int muxs1 : 32; +} Gsetcombine; + +typedef struct { + int cmd : 8; + unsigned char pad; + unsigned char prim_min_level; + unsigned char prim_level; + unsigned long color; +} Gsetcolor; + +typedef struct { + int cmd : 8; + int x0 : 10; + int x0frac : 2; + int y0 : 10; + int y0frac : 2; + unsigned int pad : 8; + int x1 : 10; + int x1frac : 2; + int y1 : 10; + int y1frac : 2; +} Gfillrect; + +typedef struct { + int cmd : 8; + unsigned int fmt : 3; + unsigned int siz : 2; + unsigned int pad0 : 1; + unsigned int line : 9; + unsigned int tmem : 9; + unsigned int pad1 : 5; + unsigned int tile : 3; + unsigned int palette : 4; + unsigned int ct : 1; + unsigned int mt : 1; + unsigned int maskt : 4; + unsigned int shiftt : 4; + unsigned int cs : 1; + unsigned int ms : 1; + unsigned int masks : 4; + unsigned int shifts : 4; +} Gsettile; + +typedef struct { + int cmd : 8; + unsigned int sl : 12; + unsigned int tl : 12; + int pad : 5; + unsigned int tile : 3; + unsigned int sh : 12; + unsigned int th : 12; +} Gloadtile; + +typedef Gloadtile Gloadblock; + +typedef Gloadtile Gsettilesize; + +typedef Gloadtile Gloadtlut; + +typedef struct { + unsigned int cmd : 8; /* command */ + unsigned int xl : 12; /* X coordinate of upper left */ + unsigned int yl : 12; /* Y coordinate of upper left */ + unsigned int pad1 : 5; /* Padding */ + unsigned int tile : 3; /* Tile descriptor index */ + unsigned int xh : 12; /* X coordinate of lower right */ + unsigned int yh : 12; /* Y coordinate of lower right */ + unsigned int s : 16; /* S texture coord at top left */ + unsigned int t : 16; /* T texture coord at top left */ + unsigned int dsdx : 16;/* Change in S per change in X */ + unsigned int dtdy : 16;/* Change in T per change in Y */ +} Gtexrect; + +#define MakeTexRect(xh,yh,flip,tile,xl,yl,s,t,dsdx,dtdy) \ + G_TEXRECT, xh, yh, 0, flip, 0, tile, xl, yl, s, t, dsdx, dtdy + +/* + * Textured rectangles are 128 bits not 64 bits + */ +typedef struct { + unsigned long w0; + unsigned long w1; + unsigned long w2; + unsigned long w3; +} TexRect; + +/* + * Generic Gfx Packet + */ +typedef struct { + unsigned int w0; + unsigned int w1; + + //unsigned long long w0; + //unsigned long long w1; +} Gwords; + +/* + * This union is the fundamental type of the display list. + * It is, by law, exactly 64 bits in size. + */ +typedef union { + Gwords words; +#if !defined(F3D_OLD) && IS_BIG_ENDIAN && !IS_64_BIT + Gdma dma; + Gtri tri; + Gline3D line; + Gpopmtx popmtx; + Gsegment segment; + GsetothermodeH setothermodeH; + GsetothermodeL setothermodeL; + Gtexture texture; + Gperspnorm perspnorm; + Gsetimg setimg; + Gsetcombine setcombine; + Gsetcolor setcolor; + Gfillrect fillrect; /* use for setscissor also */ + Gsettile settile; + Gloadtile loadtile; /* use for loadblock also, th is dxt */ + Gsettilesize settilesize; + Gloadtlut loadtlut; +#endif + long long int force_structure_alignment; +} Gfx; + +/* + * Macros to assemble the graphics display list + */ + + /* + * DMA macros + */ +#define gDma0p(pkt, c, s, l) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24); \ + _g->words.w1 = (unsigned int)(s); \ +}) + +#define gsDma0p(c, s, l) \ +{ \ + _SHIFTL((c), 24, 8) | _SHIFTL((l), 0, 24), (unsigned int)(s) \ +} + +#define gDma1p(pkt, c, s, l, p) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \ + _SHIFTL((l), 0, 16)); \ + _g->words.w1 = (unsigned int)(s); \ +}) + +#define gsDma1p(c, s, l, p) \ +{ \ + (_SHIFTL((c), 24, 8) | _SHIFTL((p), 16, 8) | \ + _SHIFTL((l), 0, 16)), \ + (unsigned int)(s) \ +} + +#define gDma2p(pkt, c, adrs, len, idx, ofs) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \ + _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)); \ + _g->words.w1 = (unsigned int)(adrs); \ +}) +#define gsDma2p(c, adrs, len, idx, ofs) \ +{ \ + (_SHIFTL((c),24,8)|_SHIFTL(((len)-1)/8,19,5)| \ + _SHIFTL((ofs)/8,8,8)|_SHIFTL((idx),0,8)), \ + (unsigned int)(adrs) \ +} + +#define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0) +#define gsSPNoOp() gsDma0p(G_SPNOOP, 0, 0) + +#ifdef F3DEX_GBI_2 +# define gSPMatrix(pkt, m, p) \ + gDma2p((pkt),G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0) +# define gsSPMatrix(m, p) \ + gsDma2p( G_MTX,(m),sizeof(Mtx),(p)^G_MTX_PUSH,0) +#else /* F3DEX_GBI_2 */ +# define gSPMatrix(pkt, m, p) gDma1p(pkt, G_MTX, m, sizeof(Mtx), p) +# define gsSPMatrix(m, p) gsDma1p(G_MTX, m, sizeof(Mtx), p) +#endif /* F3DEX_GBI_2 */ + +#if defined(F3DEX_GBI_2) + /* + * F3DEX_GBI_2: G_VTX GBI format was changed. + * + * +--------+----+---+---+----+------+-+ + * G_VTX | cmd:8 |0000| n:8 |0000|v0+n:7|0| + * +-+---+--+----+---+---+----+------+-+ + * | |seg| address | + * +-+---+-----------------------------+ + */ +# define __gSPVertex(pkt, v, n, v0) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = \ + _SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7); \ + _g->words.w1 = (unsigned int)(v); \ +}) +# define gsSPVertex(v, n, v0) \ +{ \ + (_SHIFTL(G_VTX,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7)), \ + (unsigned int)(v) \ +} +#elif (defined(F3DEX_GBI)||defined(F3DLP_GBI)) + /* + * F3DEX_GBI: G_VTX GBI format was changed to support 64 vertice. + * + * +--------+--------+------+----------+ + * G_VTX | cmd:8 | v0:8 | n:6 |length:10 | + * +-+---+--+--------+------+----------+ + * | |seg| address | + * +-+---+-----------------------------+ + */ +# define gSPVertex(pkt, v, n, v0) \ + gDma1p((pkt),G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2) +# define gsSPVertex(v, n, v0) \ + gsDma1p(G_VTX,(v),((n)<<10)|(sizeof(Vtx)*(n)-1),(v0)*2) +#else +# define gSPVertex(pkt, v, n, v0) \ + gDma1p(pkt, G_VTX, v, sizeof(Vtx)*(n),((n)-1)<<4|(v0)) +# define gsSPVertex(v, n, v0) \ + gsDma1p(G_VTX, v, sizeof(Vtx)*(n), ((n)-1)<<4|(v0)) +#endif + + +#ifdef F3DEX_GBI_2 +# define gSPViewport(pkt, v) \ + gDma2p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0) +# define gsSPViewport(v) \ + gsDma2p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT, 0) +#else /* F3DEX_GBI_2 */ +# define gSPViewport(pkt,v) \ + gDma1p((pkt), G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT) +# define gsSPViewport(v) \ + gsDma1p( G_MOVEMEM, (v), sizeof(Vp), G_MV_VIEWPORT) +#endif /* F3DEX_GBI_2 */ + +#define __gSPDisplayList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_PUSH) +#define gsSPDisplayList( dl) gsDma1p( G_DL,dl,0,G_DL_PUSH) + +#define gSPBranchList(pkt,dl) gDma1p(pkt,G_DL,dl,0,G_DL_NOPUSH) +#define gsSPBranchList( dl) gsDma1p( G_DL,dl,0,G_DL_NOPUSH) + +#define gSPSprite2DBase(pkt, s) gDma1p(pkt, G_SPRITE2D_BASE, s, sizeof(uSprite), 0) +#define gsSPSprite2DBase(s) gsDma1p(G_SPRITE2D_BASE, s, sizeof(uSprite), 0) + + /* + * RSP short command (no DMA required) macros + */ +#define gImmp0(pkt, c) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL((c), 24, 8); \ +}) + +#define gsImmp0(c) \ +{ \ + _SHIFTL((c), 24, 8) \ +} + +#define gImmp1(pkt, c, p0) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL((c), 24, 8); \ + _g->words.w1 = (unsigned int)(p0); \ +}) + +#define gsImmp1(c, p0) \ +{ \ + _SHIFTL((c), 24, 8), (unsigned int)(p0) \ +} + +#define gImmp2(pkt, c, p0, p1) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL((c), 24, 8); \ + _g->words.w1 = _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8); \ +}) + +#define gsImmp2(c, p0, p1) \ +{ \ + _SHIFTL((c), 24, 8), _SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8)\ +} + +#define gImmp3(pkt, c, p0, p1, p2) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL((c), 24, 8); \ + _g->words.w1 = (_SHIFTL((p0), 16, 16) | _SHIFTL((p1), 8, 8) | \ + _SHIFTL((p2), 0, 8)); \ +}) + +#define gsImmp3(c, p0, p1, p2) \ +{ \ + _SHIFTL((c), 24, 8), (_SHIFTL((p0), 16, 16) | \ + _SHIFTL((p1), 8, 8) | _SHIFTL((p2), 0, 8))\ +} + +#define gImmp21(pkt, c, p0, p1, dat) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | \ + _SHIFTL((p1), 0, 8)); \ + _g->words.w1 = (unsigned int) (dat); \ +}) + +#define gsImmp21(c, p0, p1, dat) \ +{ \ + _SHIFTL((c), 24, 8) | _SHIFTL((p0), 8, 16) | _SHIFTL((p1), 0, 8),\ + (unsigned int) (dat) \ +} + +#ifdef F3DEX_GBI_2 +#define gMoveWd(pkt, index, offset, data) \ + gDma1p((pkt), G_MOVEWORD, data, offset, index) +#define gsMoveWd( index, offset, data) \ + gsDma1p( G_MOVEWORD, data, offset, index) +#else /* F3DEX_GBI_2 */ +#define gMoveWd(pkt, index, offset, data) \ + gImmp21((pkt), G_MOVEWORD, offset, index, data) +#define gsMoveWd( index, offset, data) \ + gsImmp21( G_MOVEWORD, offset, index, data) +#endif /* F3DEX_GBI_2 */ + + /* Sprite immediate macros, there is also a sprite dma macro above */ + +#define gSPSprite2DScaleFlip(pkt, sx, sy, fx, fy) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \ + _SHIFTL((fx), 8, 8) | \ + _SHIFTL((fy), 0, 8)); \ + _g->words.w1 = (_SHIFTL((sx), 16, 16) | \ + _SHIFTL((sy), 0, 16)); \ +}) + +#define gsSPSprite2DScaleFlip(sx, sy, fx, fy) \ +{ \ + (_SHIFTL(G_SPRITE2D_SCALEFLIP, 24, 8) | \ + _SHIFTL((fx), 8, 8) | \ + _SHIFTL((fy), 0, 8)), \ + (_SHIFTL((sx), 16, 16) | \ + _SHIFTL((sy), 0, 16)) \ +} + +#define gSPSprite2DDraw(pkt, px, py) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_SPRITE2D_DRAW, 24, 8)); \ + _g->words.w1 = (_SHIFTL((px), 16, 16) | \ + _SHIFTL((py), 0, 16)); \ +}) + +#define gsSPSprite2DDraw(px, py) \ +{ \ + (_SHIFTL(G_SPRITE2D_DRAW, 24, 8)), \ + (_SHIFTL((px), 16, 16) | \ + _SHIFTL((py), 0, 16)) \ +} + + +/* + * Note: the SP1Triangle() and line macros multiply the vertex indices + * by 10, this is an optimization for the microcode. + */ +#if (defined(F3DLP_GBI)||defined(F3DEX_GBI)) +# define __gsSP1Triangle_w1(v0, v1, v2) \ + (_SHIFTL((v0)*2,16,8)|_SHIFTL((v1)*2,8,8)|_SHIFTL((v2)*2,0,8)) +# define __gsSP1Triangle_w1f(v0, v1, v2, flag) \ + (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \ + ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v0): \ + __gsSP1Triangle_w1(v2, v0, v1)) +# define __gsSPLine3D_w1(v0, v1, wd) \ + (_SHIFTL((v0)*2,16,8)|_SHIFT((v1)*2,8,8)|_SHIFT((wd),0,8)) +# define __gsSPLine3D_w1f(v0, v1, wd, flag) \ + (((flag) == 0) ? __gsSPLine3D_w1(v0, v1, wd): \ + __gsSPLine3D_w1(v1, v0, wd)) +# define __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag) \ + (((flag) == 0) ? __gsSP1Triangle_w1(v0, v1, v2): \ + ((flag) == 1) ? __gsSP1Triangle_w1(v1, v2, v3): \ + ((flag) == 2) ? __gsSP1Triangle_w1(v2, v3, v0): \ + __gsSP1Triangle_w1(v3, v0, v1)) +# define __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \ + (((flag) == 0) ? __gsSP1Triangle_w1(v0, v2, v3): \ + ((flag) == 1) ? __gsSP1Triangle_w1(v1, v3, v0): \ + ((flag) == 2) ? __gsSP1Triangle_w1(v2, v0, v1): \ + __gsSP1Triangle_w1(v3, v1, v2)) +#else +# define __gsSP1Triangle_w1f(v0, v1, v2, flag) \ + (_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \ + _SHIFTL((v1)*10, 8,8)|_SHIFTL((v2)*10, 0,8)) +# define __gsSPLine3D_w1f(v0, v1, wd, flag) \ + (_SHIFTL((flag), 24,8)|_SHIFTL((v0)*10,16,8)| \ + _SHIFTL((v1)*10, 8,8)|_SHIFTL((wd), 0,8)) +#endif + +#ifdef F3DEX_GBI_2 + /*** + *** 1 Triangle + ***/ +#define gSP1Triangle(pkt, v0, v1, v2, flag) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_TRI1, 24, 8)| \ + __gsSP1Triangle_w1f(v0, v1, v2, flag); \ + _g->words.w1 = 0; \ +}) +#define gsSP1Triangle(v0, v1, v2, flag) \ +{ \ + _SHIFTL(G_TRI1, 24, 8)|__gsSP1Triangle_w1f(v0, v1, v2, flag), \ + 0 \ +} + + /*** + *** Line + ***/ +#define gSPLine3D(pkt, v0, v1, flag) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \ + __gsSPLine3D_w1f(v0, v1, 0, flag); \ + _g->words.w1 = 0; \ +}) +#define gsSPLine3D(v0, v1, flag) \ +{ \ + _SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, 0, flag), \ + 0 \ +} + + /*** + *** LineW + ***/ + /* these macros are the same as SPLine3D, except they have an + * additional parameter for width. The width is added to the "minimum" + * thickness, which is 1.5 pixels. The units for width are in + * half-pixel units, so a width of 1 translates to (.5 + 1.5) or + * a 2.0 pixels wide line. + */ +#define gSPLineW3D(pkt, v0, v1, wd, flag) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8)| \ + __gsSPLine3D_w1f(v0, v1, wd, flag); \ + _g->words.w1 = 0; \ +}) +#define gsSPLineW3D(v0, v1, wd, flag) \ +{ \ + _SHIFTL(G_LINE3D, 24, 8)|__gsSPLine3D_w1f(v0, v1, wd, flag), \ + 0 \ +} + + /*** + *** 1 Quadrangle + ***/ +#define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_QUAD, 24, 8)| \ + __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \ + _g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \ +}) + +#define gsSP1Quadrangle(v0, v1, v2, v3, flag) \ +{ \ + (_SHIFTL(G_QUAD, 24, 8)| \ + __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \ + __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \ +} +#else /* F3DEX_GBI_2 */ + + /*** + *** 1 Triangle + ***/ +#define gSP1Triangle(pkt, v0, v1, v2, flag) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_TRI1, 24, 8); \ + _g->words.w1 = __gsSP1Triangle_w1f(v0, v1, v2, flag); \ +} +#define gsSP1Triangle(v0, v1, v2, flag) \ +{ \ + _SHIFTL(G_TRI1, 24, 8), \ + __gsSP1Triangle_w1f(v0, v1, v2, flag) \ +} + + /*** + *** Line + ***/ +#define gSPLine3D(pkt, v0, v1, flag) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \ + _g->words.w1 = __gsSPLine3D_w1f(v0, v1, 0, flag); \ +} +#define gsSPLine3D(v0, v1, flag) \ +{ \ + _SHIFTL(G_LINE3D, 24, 8), \ + __gsSPLine3D_w1f(v0, v1, 0, flag) \ +} + + /*** + *** LineW + ***/ + /* these macros are the same as SPLine3D, except they have an + * additional parameter for width. The width is added to the "minimum" + * thickness, which is 1.5 pixels. The units for width are in + * half-pixel units, so a width of 1 translates to (.5 + 1.5) or + * a 2.0 pixels wide line. + */ +#define gSPLineW3D(pkt, v0, v1, wd, flag) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_LINE3D, 24, 8); \ + _g->words.w1 = __gsSPLine3D_w1f(v0, v1, wd, flag); \ +} +#define gsSPLineW3D(v0, v1, wd, flag) \ +{ \ + _SHIFTL(G_LINE3D, 24, 8), \ + __gsSPLine3D_w1f(v0, v1, wd, flag) \ +} + + /*** + *** 1 Quadrangle + ***/ +#define gSP1Quadrangle(pkt, v0, v1, v2, v3, flag) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \ + __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)); \ + _g->words.w1 = __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag); \ +} + +#define gsSP1Quadrangle(v0, v1, v2, v3, flag) \ +{ \ + (_SHIFTL(G_TRI2, 24, 8)| \ + __gsSP1Quadrangle_w1f(v0, v1, v2, v3, flag)), \ + __gsSP1Quadrangle_w2f(v0, v1, v2, v3, flag) \ +} +#endif /* F3DEX_GBI_2 */ + +#if (defined(F3DLP_GBI)||defined(F3DEX_GBI)) + /*** + *** 2 Triangles + ***/ +#define gSP2Triangles(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TRI2, 24, 8)| \ + __gsSP1Triangle_w1f(v00, v01, v02, flag0)); \ + _g->words.w1 = __gsSP1Triangle_w1f(v10, v11, v12, flag1); \ +}) + +#define gsSP2Triangles(v00, v01, v02, flag0, v10, v11, v12, flag1) \ +{ \ + (_SHIFTL(G_TRI2, 24, 8)| \ + __gsSP1Triangle_w1f(v00, v01, v02, flag0)), \ + __gsSP1Triangle_w1f(v10, v11, v12, flag1) \ +} + +#endif /* F3DEX_GBI/F3DLP_GBI */ + +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) +#define gSPCullDisplayList(pkt,vstart,vend) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \ + _SHIFTL((vstart)*2, 0, 16); \ + _g->words.w1 = _SHIFTL((vend)*2, 0, 16); \ +}) + +#define gsSPCullDisplayList(vstart,vend) \ +{ \ + _SHIFTL(G_CULLDL, 24, 8) | _SHIFTL((vstart)*2, 0, 16), \ + _SHIFTL((vend)*2, 0, 16) \ +} + +#else +#define gSPCullDisplayList(pkt,vstart,vend) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_CULLDL, 24, 8) | \ + ((0x0f & (vstart))*40); \ + _g->words.w1 = (unsigned int)((0x0f & ((vend)+1))*40); \ +} + +#define gsSPCullDisplayList(vstart,vend) \ +{ \ + _SHIFTL(G_CULLDL, 24, 8) | ((0x0f & (vstart))*40), \ + ((0x0f & ((vend)+1))*40) \ +} +#endif + +#define __gSPSegment(pkt, segment, base) \ + gMoveWd(pkt, G_MW_SEGMENT, (segment)*4, base) +#define gsSPSegment(segment, base) \ + gsMoveWd( G_MW_SEGMENT, (segment)*4, base) + + /* + * Clipping Macros + */ +#define FR_NEG_FRUSTRATIO_1 0x00000001 +#define FR_POS_FRUSTRATIO_1 0x0000ffff +#define FR_NEG_FRUSTRATIO_2 0x00000002 +#define FR_POS_FRUSTRATIO_2 0x0000fffe +#define FR_NEG_FRUSTRATIO_3 0x00000003 +#define FR_POS_FRUSTRATIO_3 0x0000fffd +#define FR_NEG_FRUSTRATIO_4 0x00000004 +#define FR_POS_FRUSTRATIO_4 0x0000fffc +#define FR_NEG_FRUSTRATIO_5 0x00000005 +#define FR_POS_FRUSTRATIO_5 0x0000fffb +#define FR_NEG_FRUSTRATIO_6 0x00000006 +#define FR_POS_FRUSTRATIO_6 0x0000fffa + /* + * r should be one of: FRUSTRATIO_1, FRUSTRATIO_2, FRUSTRATIO_3, ... FRUSTRATIO_6 + */ +#define gSPClipRatio(pkt, r) \ +_DW({ \ + gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r); \ + gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r); \ + gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r); \ + gMoveWd(pkt, G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r); \ +}) + +#define gsSPClipRatio(r) \ + gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNX, FR_NEG_##r), \ + gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RNY, FR_NEG_##r), \ + gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPX, FR_POS_##r), \ + gsMoveWd(G_MW_CLIP, G_MWO_CLIP_RPY, FR_POS_##r) + + /* + * Insert values into Matrix + * + * where = element of matrix (byte offset) + * num = new element (32 bit value replacing 2 int or 2 frac matrix + * componants + */ +#ifdef F3DEX_GBI_2 +#define gSPInsertMatrix(pkt, where, num) \ + ERROR!! gSPInsertMatrix is no longer supported. +#define gsSPInsertMatrix(where, num) \ + ERROR!! gsSPInsertMatrix is no longer supported. +#else +#define gSPInsertMatrix(pkt, where, num) \ + gMoveWd(pkt, G_MW_MATRIX, where, num) +#define gsSPInsertMatrix(where, num) \ + gsMoveWd(G_MW_MATRIX, where, num) +#endif + + /* + * Load new matrix directly + * + * mptr = pointer to matrix + */ +#ifdef F3DEX_GBI_2 +#define gSPForceMatrix(pkt, mptr) \ +_DW({ \ + gDma2p((pkt),G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0); \ + gMoveWd((pkt), G_MW_FORCEMTX,0,0x00010000); \ +}) +#define gsSPForceMatrix(mptr) \ + gsDma2p(G_MOVEMEM,(mptr),sizeof(Mtx),G_MV_MATRIX,0), \ + gsMoveWd(G_MW_FORCEMTX,0,0x00010000) + +#else /* F3DEX_GBI_2 */ +#define gSPForceMatrix(pkt, mptr) \ +{ \ + gDma1p(pkt, G_MOVEMEM, mptr, 16, G_MV_MATRIX_1); \ + gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2); \ + gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3); \ + gDma1p(pkt, G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4); \ +} +#define gsSPForceMatrix(mptr) \ + gsDma1p( G_MOVEMEM, mptr, 16, G_MV_MATRIX_1), \ + gsDma1p( G_MOVEMEM, (char *)(mptr)+16, 16, G_MV_MATRIX_2), \ + gsDma1p( G_MOVEMEM, (char *)(mptr)+32, 16, G_MV_MATRIX_3), \ + gsDma1p( G_MOVEMEM, (char *)(mptr)+48, 16, G_MV_MATRIX_4) +#endif /* F3DEX_GBI_2 */ + + /* + * Insert values into Points + * + * point = point number 0-15 + * where = which element of point to modify (byte offset into point) + * num = new value (32 bit) + */ +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) +# define gSPModifyVertex(pkt, vtx, where, val) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL(G_MODIFYVTX,24,8)| \ + _SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16)); \ + _g->words.w1 = (unsigned int)(val); \ +}) +# define gsSPModifyVertex(vtx, where, val) \ +{ \ + _SHIFTL(G_MODIFYVTX,24,8)| \ + _SHIFTL((where),16,8)|_SHIFTL((vtx)*2,0,16), \ + (unsigned int)(val) \ +} +#else +# define gSPModifyVertex(pkt, vtx, where, val) \ + gMoveWd(pkt, G_MW_POINTS, (vtx)*40+(where), val) +# define gsSPModifyVertex(vtx, where, val) \ + gsMoveWd(G_MW_POINTS, (vtx)*40+(where), val) +#endif + +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)) + /* + * gSPBranchLessZ Branch DL if (vtx.z) less than or equal (zval). + * + * dl = DL branch to + * vtx = Vertex + * zval = Screen depth + * near = Near plane + * far = Far plane + * flag = G_BZ_PERSP or G_BZ_ORTHO + */ + +#define G_BZ_PERSP 0 +#define G_BZ_ORTHO 1 + +#define G_DEPTOZSrg(zval, near, far, flag, zmin, zmax) \ +(((unsigned int)FTOFIX32(((flag) == G_BZ_PERSP ? \ + (1.0f-(float)(near)/(float)(zval)) / \ + (1.0f-(float)(near)/(float)(far )) : \ + ((float)(zval) - (float)(near)) / \ + ((float)(far ) - (float)(near))))) * \ + (((int)((zmax) - (zmin)))&~1) + (int)FTOFIX32(zmin)) + +#define G_DEPTOZS(zval, near, far, flag) \ + G_DEPTOZSrg(zval, near, far, flag, 0, G_MAXZ) + +#define gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, zmin, zmax) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \ + _g->words.w1 = (unsigned int)(dl); \ + _g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \ + _SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \ + _g->words.w1 = G_DEPTOZSrg(zval, near, far, flag, zmin, zmax); \ +}) + +#define gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, zmin, zmax) \ +{ _SHIFTL(G_RDPHALF_1,24,8), \ + (unsigned int)(dl), }, \ +{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\ + G_DEPTOZSrg(zval, near, far, flag, zmin, zmax), } + +#define gSPBranchLessZ(pkt, dl, vtx, zval, near, far, flag) \ + gSPBranchLessZrg(pkt, dl, vtx, zval, near, far, flag, 0, G_MAXZ) +#define gsSPBranchLessZ(dl, vtx, zval, near, far, flag) \ + gsSPBranchLessZrg(dl, vtx, zval, near, far, flag, 0, G_MAXZ) + + /* + * gSPBranchLessZraw Branch DL if (vtx.z) less than or equal (raw zval). + * + * dl = DL branch to + * vtx = Vertex + * zval = Raw value of screen depth + */ +#define gSPBranchLessZraw(pkt, dl, vtx, zval) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \ + _g->words.w1 = (unsigned int)(dl); \ + _g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL(G_BRANCH_Z,24,8)| \ + _SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12)); \ + _g->words.w1 = (unsigned int)(zval); \ +}) + +#define gsSPBranchLessZraw(dl, vtx, zval) \ +{ _SHIFTL(G_RDPHALF_1,24,8), \ + (unsigned int)(dl), }, \ +{ _SHIFTL(G_BRANCH_Z,24,8)|_SHIFTL((vtx)*5,12,12)|_SHIFTL((vtx)*2,0,12),\ + (unsigned int)(zval), } + + /* + * gSPLoadUcode RSP loads specified ucode. + * + * uc_start = ucode text section start + * uc_dstart = ucode data section start + */ +#define gSPLoadUcodeEx(pkt, uc_start, uc_dstart, uc_dsize) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = _SHIFTL(G_RDPHALF_1,24,8); \ + _g->words.w1 = (unsigned int)(uc_dstart); \ + _g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL(G_LOAD_UCODE,24,8)| \ + _SHIFTL((int)(uc_dsize)-1,0,16)); \ + _g->words.w1 = (unsigned int)(uc_start); \ +}) + +#define gsSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize) \ +{ _SHIFTL(G_RDPHALF_1,24,8), \ + (unsigned int)(uc_dstart), }, \ +{ _SHIFTL(G_LOAD_UCODE,24,8)| \ + _SHIFTL((int)(uc_dsize)-1,0,16), \ + (unsigned int)(uc_start), } + +#define gSPLoadUcode(pkt, uc_start, uc_dstart) \ + gSPLoadUcodeEx((pkt), (uc_start), (uc_dstart), SP_UCODE_DATA_SIZE) +#define gsSPLoadUcode(uc_start, uc_dstart) \ + gsSPLoadUcodeEx((uc_start), (uc_dstart), SP_UCODE_DATA_SIZE) + +#define gSPLoadUcodeL(pkt, ucode) \ + gSPLoadUcode((pkt), OS_K0_TO_PHYSICAL(&##ucode##TextStart), \ + OS_K0_TO_PHYSICAL(&##ucode##DataStart)) +#define gsSPLoadUcodeL(ucode) \ + gsSPLoadUcode(OS_K0_TO_PHYSICAL(&##ucode##TextStart), \ + OS_K0_TO_PHYSICAL(&##ucode##DataStart)) +#endif + +#ifdef F3DEX_GBI_2 + /* + * gSPDma_io DMA to/from DMEM/IMEM for DEBUG. + */ +#define gSPDma_io(pkt, flag, dmem, dram, size) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = _SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \ + _SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12); \ + _g->words.w1 = (unsigned int)(dram); \ +}) + +#define gsSPDma_io(flag, dmem, dram, size) \ +{ \ + _SHIFTL(G_DMA_IO,24,8)|_SHIFTL((flag),23,1)| \ + _SHIFTL((dmem)/8,13,10)|_SHIFTL((size)-1,0,12), \ + (unsigned int)(dram) \ +} + +#define gSPDmaRead(pkt,dmem,dram,size) gSPDma_io((pkt),0,(dmem),(dram),(size)) +#define gsSPDmaRead(dmem,dram,size) gsSPDma_io(0,(dmem),(dram),(size)) +#define gSPDmaWrite(pkt,dmem,dram,size) gSPDma_io((pkt),1,(dmem),(dram),(size)) +#define gsSPDmaWrite(dmem,dram,size) gsSPDma_io(1,(dmem),(dram),(size)) +#endif + + /* + * Lighting Macros + */ +#ifdef F3DEX_GBI_2 +# define NUML(n) ((n)*24) +#else +# define NUML(n) (((n)+1)*32 + 0x80000000) +#endif +#define NUMLIGHTS_0 1 +#define NUMLIGHTS_1 1 +#define NUMLIGHTS_2 2 +#define NUMLIGHTS_3 3 +#define NUMLIGHTS_4 4 +#define NUMLIGHTS_5 5 +#define NUMLIGHTS_6 6 +#define NUMLIGHTS_7 7 + /* + * n should be one of: NUMLIGHTS_0, NUMLIGHTS_1, ..., NUMLIGHTS_7 + * NOTE: in addition to the number of directional lights specified, + * there is always 1 ambient light + */ +#define gSPNumLights(pkt, n) \ + gMoveWd(pkt, G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n)) +#define gsSPNumLights(n) \ + gsMoveWd( G_MW_NUMLIGHT, G_MWO_NUMLIGHT, NUML(n)) + +#define LIGHT_1 1 +#define LIGHT_2 2 +#define LIGHT_3 3 +#define LIGHT_4 4 +#define LIGHT_5 5 +#define LIGHT_6 6 +#define LIGHT_7 7 +#define LIGHT_8 8 + /* + * l should point to a Light struct + * n should be one of: LIGHT_1, LIGHT_2, ..., LIGHT_8 + * NOTE: the highest numbered light is always the ambient light (eg if there are + * 3 directional lights defined: gsSPNumLights(NUMLIGHTS_3), then lights + * LIGHT_1 through LIGHT_3 will be the directional lights and light + * LIGHT_4 will be the ambient light. + */ +#ifdef F3DEX_GBI_2 +# define gSPLight(pkt, l, n) \ + gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24) +# define gsSPLight(l, n) \ + gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,(n)*24+24) +#else /* F3DEX_GBI_2 */ +# define gSPLight(pkt, l, n) \ + gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0) +# define gsSPLight(l, n) \ + gsDma1p( G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0) +#endif /* F3DEX_GBI_2 */ + + /* + * gSPLightColor changes color of light without recalculating light direction + * col is a 32 bit word with r,g,b,a (alpha is ignored) + * n should be one of LIGHT_1, LIGHT_2, ..., LIGHT_8 + */ +#define gSPLightColor(pkt, n, col) \ +_DW({ \ + gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_a##n, col); \ + gMoveWd(pkt, G_MW_LIGHTCOL, G_MWO_b##n, col); \ +}) +#define gsSPLightColor(n, col) \ + gsMoveWd(G_MW_LIGHTCOL, G_MWO_a##n, col), \ + gsMoveWd(G_MW_LIGHTCOL, G_MWO_b##n, col) + + /* These macros use a structure "name" which is init'd with the gdSPDefLights macros*/ + +#define gSPSetLights0(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_0); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.a,2); \ +}) +#define gsSPSetLights0(name) \ + gsSPNumLights(NUMLIGHTS_0), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.a,2) + +#define gSPSetLights1(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_1); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.a,2); \ +}) +#define gsSPSetLights1(name) \ + gsSPNumLights(NUMLIGHTS_1), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.a,2) + +#define gSPSetLights2(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_2); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.a,3); \ +}) +#define gsSPSetLights2(name) \ + gsSPNumLights(NUMLIGHTS_2), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.a,3) + +#define gSPSetLights3(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_3); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.l[2],3); \ + gSPLight(pkt,&name.a,4); \ +}) +#define gsSPSetLights3(name) \ + gsSPNumLights(NUMLIGHTS_3), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.l[2],3), \ + gsSPLight(&name.a,4) + +#define gSPSetLights4(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_4); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.l[2],3); \ + gSPLight(pkt,&name.l[3],4); \ + gSPLight(pkt,&name.a,5); \ +}) +#define gsSPSetLights4(name) \ + gsSPNumLights(NUMLIGHTS_4), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.l[2],3), \ + gsSPLight(&name.l[3],4), \ + gsSPLight(&name.a,5) + +#define gSPSetLights5(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_5); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.l[2],3); \ + gSPLight(pkt,&name.l[3],4); \ + gSPLight(pkt,&name.l[4],5); \ + gSPLight(pkt,&name.a,6); \ +}) + +#define gsSPSetLights5(name) \ + gsSPNumLights(NUMLIGHTS_5), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.l[2],3), \ + gsSPLight(&name.l[3],4), \ + gsSPLight(&name.l[4],5), \ + gsSPLight(&name.a,6) + +#define gSPSetLights6(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_6); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.l[2],3); \ + gSPLight(pkt,&name.l[3],4); \ + gSPLight(pkt,&name.l[4],5); \ + gSPLight(pkt,&name.l[5],6); \ + gSPLight(pkt,&name.a,7); \ +}) + +#define gsSPSetLights6(name) \ + gsSPNumLights(NUMLIGHTS_6), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.l[2],3), \ + gsSPLight(&name.l[3],4), \ + gsSPLight(&name.l[4],5), \ + gsSPLight(&name.l[5],6), \ + gsSPLight(&name.a,7) + +#define gSPSetLights7(pkt,name) \ +_DW({ \ + gSPNumLights(pkt,NUMLIGHTS_7); \ + gSPLight(pkt,&name.l[0],1); \ + gSPLight(pkt,&name.l[1],2); \ + gSPLight(pkt,&name.l[2],3); \ + gSPLight(pkt,&name.l[3],4); \ + gSPLight(pkt,&name.l[4],5); \ + gSPLight(pkt,&name.l[5],6); \ + gSPLight(pkt,&name.l[6],7); \ + gSPLight(pkt,&name.a,8); \ +}) + +#define gsSPSetLights7(name) \ + gsSPNumLights(NUMLIGHTS_7), \ + gsSPLight(&name.l[0],1), \ + gsSPLight(&name.l[1],2), \ + gsSPLight(&name.l[2],3), \ + gsSPLight(&name.l[3],4), \ + gsSPLight(&name.l[4],5), \ + gsSPLight(&name.l[5],6), \ + gsSPLight(&name.l[6],7), \ + gsSPLight(&name.a,8) + +/* + * Reflection/Hiliting Macros + */ +#ifdef F3DEX_GBI_2 +# define gSPLookAtX(pkt, l) \ + gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX) +# define gsSPLookAtX(l) \ + gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATX) +# define gSPLookAtY(pkt, l) \ + gDma2p((pkt),G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY) +# define gsSPLookAtY(l) \ + gsDma2p( G_MOVEMEM,(l),sizeof(Light),G_MV_LIGHT,G_MVO_LOOKATY) +#else /* F3DEX_GBI_2 */ +# define gSPLookAtX(pkt, l) \ + gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX) +# define gsSPLookAtX(l) \ + gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATX) +# define gSPLookAtY(pkt, l) \ + gDma1p(pkt, G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY) +# define gsSPLookAtY(l) \ + gsDma1p( G_MOVEMEM, l, sizeof(Light),G_MV_LOOKATY) +#endif /* F3DEX_GBI_2 */ + +#define gSPLookAt(pkt, la) \ +_DW({ \ + gSPLookAtX(pkt,la); \ + gSPLookAtY(pkt,(char *)(la)+16); \ +}) +#define gsSPLookAt(la) \ + gsSPLookAtX(la), \ + gsSPLookAtY((char *)(la)+16) + +#define gDPSetHilite1Tile(pkt, tile, hilite, width, height) \ + gDPSetTileSize(pkt, tile, (hilite)->h.x1 & 0xfff, (hilite)->h.y1 & 0xfff, \ + ((((width)-1)*4)+(hilite)->h.x1) & 0xfff, ((((height)-1)*4)+(hilite)->h.y1) & 0xfff) +#define gsDPSetHilite1Tile(tile, hilite, width, height) \ + gsDPSetTileSize(tile, (hilite)->h.x1 & 0xfff, (hilite)->h.y1 & 0xfff, \ + ((((width)-1)*4)+(hilite)->h.x1) & 0xfff, ((((height)-1)*4)+(hilite)->h.y1) & 0xfff) + +#define gDPSetHilite2Tile(pkt, tile, hilite, width, height) \ + gDPSetTileSize(pkt, tile, (hilite)->h.x2 & 0xfff, (hilite)->h.y2 & 0xfff, \ + ((((width)-1)*4)+(hilite)->h.x2) & 0xfff, ((((height)-1)*4)+(hilite)->h.y2) & 0xfff) +#define gsDPSetHilite2Tile(tile, hilite, width, height) \ + gsDPSetTileSize(tile, (hilite)->h.x2 & 0xfff, (hilite)->h.y2 & 0xfff, \ + ((((width)-1)*4)+(hilite)->h.x2) & 0xfff, ((((height)-1)*4)+(hilite)->h.y2) & 0xfff) + + /* + * FOG macros + * fm = z multiplier + * fo = z offset + * FOG FORMULA: alpha(fog) = (eyespace z) * fm + fo CLAMPED 0 to 255 + * note: (eyespace z) ranges -1 to 1 + * + * Alternate method of setting fog: + * min, max: range 0 to 1000: 0=nearplane, 1000=farplane + * min is where fog begins (usually less than max and often 0) + * max is where fog is thickest (usually 1000) + * + */ +#define gSPFogFactor(pkt, fm, fo) \ + gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \ + (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16))) + +#define gsSPFogFactor(fm, fo) \ + gsMoveWd(G_MW_FOG, G_MWO_FOG, \ + (_SHIFTL(fm,16,16) | _SHIFTL(fo,0,16))) + +#define gSPFogPosition(pkt, min, max) \ + gMoveWd(pkt, G_MW_FOG, G_MWO_FOG, \ + (_SHIFTL((128000/((max)-(min))),16,16) | \ + _SHIFTL(((500-(min))*256/((max)-(min))),0,16))) + +#define gsSPFogPosition(min, max) \ + gsMoveWd(G_MW_FOG, G_MWO_FOG, \ + (_SHIFTL((128000/((max)-(min))),16,16) | \ + _SHIFTL(((500-(min))*256/((max)-(min))),0,16))) + +#ifdef F3DEX_GBI_2 + /* + * Macros to turn texture on/off + */ +# define gSPTexture(pkt, s, t, level, tile, on) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \ + _SHIFTL(BOWTIE_VAL,16,8) | \ + _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \ + _SHIFTL((on),1,7)); \ + _g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \ +}) +# define gsSPTexture(s, t, level, tile, on) \ +{ \ + (_SHIFTL(G_TEXTURE,24,8) | _SHIFTL(BOWTIE_VAL,16,8) | \ + _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\ + (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \ +} + /* + * Different version of SPTexture macro, has an additional parameter + * which is currently reserved in the microcode. + */ +# define gSPTextureL(pkt, s, t, level, xparam, tile, on) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8) | \ + _SHIFTL((xparam),16,8) | \ + _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | \ + _SHIFTL((on),1,7)); \ + _g->words.w1 = (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)); \ +}) +# define gsSPTextureL(s, t, level, xparam, tile, on) \ +{ \ + (_SHIFTL(G_TEXTURE,24,8) | _SHIFTL((xparam),16,8) | \ + _SHIFTL((level),11,3) | _SHIFTL((tile),8,3) | _SHIFTL((on),1,7)),\ + (_SHIFTL((s),16,16) | _SHIFTL((t),0,16)) \ +} +#else + /* + * Macros to turn texture on/off + */ +# define gSPTexture(pkt, s, t, level, tile, on) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)|\ + _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \ + _SHIFTL((on),0,8)); \ + _g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \ +} +# define gsSPTexture(s, t, level, tile, on) \ +{ \ + (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL(BOWTIE_VAL,16,8)| \ + _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \ + (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \ +} + /* + * Different version of SPTexture macro, has an additional parameter + * which is currently reserved in the microcode. + */ +# define gSPTextureL(pkt, s, t, level, xparam, tile, on) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \ + _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)| \ + _SHIFTL((on),0,8)); \ + _g->words.w1 = (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)); \ +} +# define gsSPTextureL(s, t, level, xparam, tile, on) \ +{ \ + (_SHIFTL(G_TEXTURE,24,8)|_SHIFTL((xparam),16,8)| \ + _SHIFTL((level),11,3)|_SHIFTL((tile),8,3)|_SHIFTL((on),0,8)), \ + (_SHIFTL((s),16,16)|_SHIFTL((t),0,16)) \ +} +#endif + +#define gSPPerspNormalize(pkt, s) gMoveWd(pkt, G_MW_PERSPNORM, 0, (s)) +#define gsSPPerspNormalize(s) gsMoveWd( G_MW_PERSPNORM, 0, (s)) + +#ifdef F3DEX_GBI_2 +# define gSPPopMatrixN(pkt, n, num) gDma2p((pkt),G_POPMTX,(num)*64,64,2,0) +# define gsSPPopMatrixN(n, num) gsDma2p( G_POPMTX,(num)*64,64,2,0) +# define gSPPopMatrix(pkt, n) gSPPopMatrixN((pkt), (n), 1) +# define gsSPPopMatrix(n) gsSPPopMatrixN( (n), 1) +#else /* F3DEX_GBI_2 */ +# define gSPPopMatrix(pkt, n) gImmp1(pkt, G_POPMTX, n) +# define gsSPPopMatrix(n) gsImmp1( G_POPMTX, n) +#endif /* F3DEX_GBI_2 */ + +#define gSPEndDisplayList(pkt) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_ENDDL, 24, 8); \ + _g->words.w1 = 0; \ +}) + +#define gsSPEndDisplayList() \ +{ \ + _SHIFTL(G_ENDDL, 24, 8), 0 \ +} + +#define __gSPInvalidateTexCache(pkt, addr) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_INVALTEXCACHE, 24, 8); \ + _g->words.w1 = addr; \ +}) + +#define gsSPInvalidateTexCache() \ +{ \ + _SHIFTL(G_INVALTEXCACHE, 24, 8), 0 \ +} + +#define gsSPSetFB(pkt, fb) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETFB, 24, 8); \ + _g->words.w1 = fb; \ +} + +#define gsSPResetFB(pkt) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_RESETFB, 24, 8); \ + _g->words.w1 = 0; \ +} + +#ifdef F3DEX_GBI_2 + /* + * One gSPGeometryMode(pkt,c,s) GBI is equal to these two GBIs. + * + * gSPClearGeometryMode(pkt,c) + * gSPSetGeometryMode(pkt,s) + * + * gSPLoadGeometryMode(pkt, word) sets GeometryMode directly. + */ +#define gSPGeometryMode(pkt, c, s) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = _SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24);\ + _g->words.w1 = (u32)(s); \ +}) + +#define gsSPGeometryMode(c, s) \ +{ \ + (_SHIFTL(G_GEOMETRYMODE,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(s) \ +} +#define gSPSetGeometryMode(pkt, word) gSPGeometryMode((pkt),0,(word)) +#define gsSPSetGeometryMode(word) gsSPGeometryMode(0,(word)) +#define gSPClearGeometryMode(pkt, word) gSPGeometryMode((pkt),(word),0) +#define gsSPClearGeometryMode(word) gsSPGeometryMode((word),0) +#define gSPLoadGeometryMode(pkt, word) gSPGeometryMode((pkt),-1,(word)) +#define gsSPLoadGeometryMode(word) gsSPGeometryMode(-1,(word)) + +#else /* F3DEX_GBI_2 */ +#define gSPSetGeometryMode(pkt, word) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETGEOMETRYMODE, 24, 8); \ + _g->words.w1 = (unsigned int)(word); \ +} + +#define gsSPSetGeometryMode(word) \ +{ \ + _SHIFTL(G_SETGEOMETRYMODE, 24, 8), (unsigned int)(word) \ +} + +#define gSPClearGeometryMode(pkt, word) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8); \ + _g->words.w1 = (unsigned int)(word); \ +} + +#define gsSPClearGeometryMode(word) \ +{ \ + _SHIFTL(G_CLEARGEOMETRYMODE, 24, 8), (unsigned int)(word) \ +} +#endif /* F3DEX_GBI_2 */ + +#ifdef F3DEX_GBI_2 +#define gSPSetOtherMode(pkt, cmd, sft, len, data) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = (_SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)| \ + _SHIFTL((len)-1,0,8)); \ + _g->words.w1 = (unsigned int)(data); \ +}) + +#define gsSPSetOtherMode(cmd, sft, len, data) \ +{ \ + _SHIFTL(cmd,24,8)|_SHIFTL(32-(sft)-(len),8,8)|_SHIFTL((len)-1,0,8), \ + (unsigned int)(data) \ +} +#else +#define gSPSetOtherMode(pkt, cmd, sft, len, data) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | \ + _SHIFTL(len, 0, 8)); \ + _g->words.w1 = (unsigned int)(data); \ +} + +#define gsSPSetOtherMode(cmd, sft, len, data) \ +{ \ + _SHIFTL(cmd, 24, 8) | _SHIFTL(sft, 8, 8) | _SHIFTL(len, 0, 8), \ + (unsigned int)(data) \ +} +#endif + + /* + * RDP setothermode register commands - register shadowed in RSP + */ +#define gDPPipelineMode(pkt, mode) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode) +#define gsDPPipelineMode(mode) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_PIPELINE, 1, mode) + +#define gDPSetCycleType(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type) +#define gsDPSetCycleType(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_CYCLETYPE, 2, type) + +#define gDPSetTexturePersp(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type) +#define gsDPSetTexturePersp(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTPERSP, 1, type) + +#define gDPSetTextureDetail(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type) +#define gsDPSetTextureDetail(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTDETAIL, 2, type) + +#define gDPSetTextureLOD(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type) +#define gsDPSetTextureLOD(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLOD, 1, type) + +#define gDPSetTextureLUT(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type) +#define gsDPSetTextureLUT(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTLUT, 2, type) + +#define gDPSetTextureFilter(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type) +#define gsDPSetTextureFilter(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTFILT, 2, type) + +#define gDPSetTextureConvert(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type) +#define gsDPSetTextureConvert(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_TEXTCONV, 3, type) + +#define gDPSetCombineKey(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type) +#define gsDPSetCombineKey(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COMBKEY, 1, type) + +#ifndef _HW_VERSION_1 +#define gDPSetColorDither(pkt, mode) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode) +#define gsDPSetColorDither(mode) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_RGBDITHER, 2, mode) +#else +#define gDPSetColorDither(pkt, mode) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode) +#define gsDPSetColorDither(mode) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, mode) +#endif + +#ifndef _HW_VERSION_1 +#define gDPSetAlphaDither(pkt, mode) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode) +#define gsDPSetAlphaDither(mode) \ + gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode) +#endif + + /* 'blendmask' is not supported anymore. + * The bits are reserved for future use. + * Fri May 26 13:45:55 PDT 1995 + */ +#define gDPSetBlendMask(pkt, mask) gDPNoOp(pkt) +#define gsDPSetBlendMask(mask) gsDPNoOp() + +#define gDPSetAlphaCompare(pkt, type) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type) +#define gsDPSetAlphaCompare(type) \ + gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ALPHACOMPARE, 2, type) + +#define gDPSetDepthSource(pkt, src) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src) +#define gsDPSetDepthSource(src) \ + gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_ZSRCSEL, 1, src) + +#define gDPSetRenderMode(pkt, c0, c1) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \ + (c0) | (c1)) +#define gsDPSetRenderMode(c0, c1) \ + gsSPSetOtherMode(G_SETOTHERMODE_L, G_MDSFT_RENDERMODE, 29, \ + (c0) | (c1)) + +#define gSetImage(pkt, cmd, fmt, siz, width, i) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \ + _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12); \ + _g->words.w1 = (unsigned int)(i); \ +}) + +#define gsSetImage(cmd, fmt, siz, width, i) \ +{ \ + _SHIFTL(cmd, 24, 8) | _SHIFTL(fmt, 21, 3) | \ + _SHIFTL(siz, 19, 2) | _SHIFTL((width)-1, 0, 12), \ + (unsigned int)(i) \ +} + +#define gDPSetColorImage(pkt, f, s, w, i) gSetImage(pkt, G_SETCIMG, f, s, w, i) +#define gsDPSetColorImage(f, s, w, i) gsSetImage(G_SETCIMG, f, s, w, i) + + + /* use these for new code */ +#define gDPSetDepthImage(pkt, i) gSetImage(pkt, G_SETZIMG, 0, 0, 1, i) +#define gsDPSetDepthImage(i) gsSetImage(G_SETZIMG, 0, 0, 1, i) +/* kept for compatibility */ +#define gDPSetMaskImage(pkt, i) gDPSetDepthImage(pkt, i) +#define gsDPSetMaskImage(i) gsDPSetDepthImage(i) + +#define __gDPSetTextureImage(pkt, f, s, w, i) gSetImage(pkt, G_SETTIMG, f, s, w, i) +#define gsDPSetTextureImage(f, s, w, i) gsSetImage(G_SETTIMG, f, s, w, i) +#define __gDPSetTextureImageFB(pkt, f, s, w, i) gSetImage(pkt, G_SETTIMG_FB, f, s, w, i) + +/* + * RDP macros + */ + +#define gDPSetCombine(pkt, muxs0, muxs1) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24);\ + _g->words.w1 = (unsigned int)(muxs1); \ +}) + +#define gsDPSetCombine(muxs0, muxs1) \ +{ \ + _SHIFTL(G_SETCOMBINE, 24, 8) | _SHIFTL(muxs0, 0, 24), \ + (unsigned int)(muxs1) \ +} + +#define GCCc0w0(saRGB0, mRGB0, saA0, mA0) \ + (_SHIFTL((saRGB0), 20, 4) | _SHIFTL((mRGB0), 15, 5) | \ + _SHIFTL((saA0), 12, 3) | _SHIFTL((mA0), 9, 3)) + +#define GCCc1w0(saRGB1, mRGB1) \ + (_SHIFTL((saRGB1), 5, 4) | _SHIFTL((mRGB1), 0, 5)) + +#define GCCc0w1(sbRGB0, aRGB0, sbA0, aA0) \ + (_SHIFTL((sbRGB0), 28, 4) | _SHIFTL((aRGB0), 15, 3) | \ + _SHIFTL((sbA0), 12, 3) | _SHIFTL((aA0), 9, 3)) + +#define GCCc1w1(sbRGB1, saA1, mA1, aRGB1, sbA1, aA1) \ + (_SHIFTL((sbRGB1), 24, 4) | _SHIFTL((saA1), 21, 3) | \ + _SHIFTL((mA1), 18, 3) | _SHIFTL((aRGB1), 6, 3) | \ + _SHIFTL((sbA1), 3, 3) | _SHIFTL((aA1), 0, 3)) + +#define gDPSetCombineLERP(pkt, a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \ + a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETCOMBINE, 24, 8) | \ + _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \ + G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \ + GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), \ + 0, 24); \ + _g->words.w1 = (unsigned int)(GCCc0w1(G_CCMUX_##b0, \ + G_CCMUX_##d0, \ + G_ACMUX_##Ab0, \ + G_ACMUX_##Ad0) | \ + GCCc1w1(G_CCMUX_##b1, \ + G_ACMUX_##Aa1, \ + G_ACMUX_##Ac1, \ + G_CCMUX_##d1, \ + G_ACMUX_##Ab1, \ + G_ACMUX_##Ad1)); \ +}) + +#define gsDPSetCombineLERP(a0, b0, c0, d0, Aa0, Ab0, Ac0, Ad0, \ + a1, b1, c1, d1, Aa1, Ab1, Ac1, Ad1) \ +{ \ + _SHIFTL(G_SETCOMBINE, 24, 8) | \ + _SHIFTL(GCCc0w0(G_CCMUX_##a0, G_CCMUX_##c0, \ + G_ACMUX_##Aa0, G_ACMUX_##Ac0) | \ + GCCc1w0(G_CCMUX_##a1, G_CCMUX_##c1), 0, 24), \ + (unsigned int)(GCCc0w1(G_CCMUX_##b0, G_CCMUX_##d0, \ + G_ACMUX_##Ab0, G_ACMUX_##Ad0) | \ + GCCc1w1(G_CCMUX_##b1, G_ACMUX_##Aa1, \ + G_ACMUX_##Ac1, G_CCMUX_##d1, \ + G_ACMUX_##Ab1, G_ACMUX_##Ad1)) \ +} + + /* + * SetCombineMode macros are NOT redunant. It allow the C preprocessor + * to substitute single parameter which includes commas in the token and + * rescan for higher parameter count macro substitution. + * + * eg. gsDPSetCombineMode(G_CC_MODULATE, G_CC_MODULATE) turns into + * gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0, + * TEXEL0, 0, SHADE, 0, TEXEL0, 0, SHADE, 0) + */ + + /* + #if _MSC_VER + #define gDPSetCombineMode(pkt, a, b) gDPNoParam(pkt, G_NOOP) + #else + #define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, a, b) + //#define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, ##a, b) + #endif + */ + +#ifdef _MSC_VER +#define CALL_2(A,B) A B +#define CALL_3(A,B,C) A B C + +#define gDPSetCombineMode(pkt, a, b) CALL_3(gDPSetCombineLERP, (pkt, a, b)) +#define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b)) +#else +#define gDPSetCombineMode(pkt, a, b) gDPSetCombineLERP(pkt, a, b) +#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b) +#endif + +#if _MSC_VER +#define CALL_2(A,B) A B +#define CALL_3(A,B,C) A B C + +#define gsDPSetCombineMode(a, b) CALL_2(gsDPSetCombineLERP, (a, b)) + //#define gsDPSetCombineMode(a, b) _SHIFTL(0, 24, 8), 0 +#else +#define gsDPSetCombineMode(a, b) gsDPSetCombineLERP(a, b) +#endif + +#define gDPSetColor(pkt, c, d) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(c, 24, 8); \ + _g->words.w1 = (unsigned int)(d); \ +}) + +#define gsDPSetColor(c, d) \ +{ \ + _SHIFTL(c, 24, 8), (unsigned int)(d) \ +} + +#define DPRGBColor(pkt, cmd, r, g, b, a) \ + gDPSetColor(pkt, cmd, \ + (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \ + _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8))) +#define sDPRGBColor(cmd, r, g, b, a) \ + gsDPSetColor(cmd, \ + (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \ + _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8))) + +#define gDPSetEnvColor(pkt, r, g, b, a) \ + DPRGBColor(pkt, G_SETENVCOLOR, r,g,b,a) +#define gsDPSetEnvColor(r, g, b, a) \ + sDPRGBColor(G_SETENVCOLOR, r,g,b,a) +#define gDPSetBlendColor(pkt, r, g, b, a) \ + DPRGBColor(pkt, G_SETBLENDCOLOR, r,g,b,a) +#define gsDPSetBlendColor(r, g, b, a) \ + sDPRGBColor(G_SETBLENDCOLOR, r,g,b,a) +#define gDPSetFogColor(pkt, r, g, b, a) \ + DPRGBColor(pkt, G_SETFOGCOLOR, r,g,b,a) +#define gsDPSetFogColor(r, g, b, a) \ + sDPRGBColor(G_SETFOGCOLOR, r,g,b,a) +#define gDPSetFillColor(pkt, d) \ + gDPSetColor(pkt, G_SETFILLCOLOR, (d)) +#define gsDPSetFillColor(d) \ + gsDPSetColor(G_SETFILLCOLOR, (d)) + +#define gDPSetPrimDepth(pkt, z, dz) \ + gDPSetColor(pkt, G_SETPRIMDEPTH, \ + _SHIFTL(z, 16, 16) | _SHIFTL(dz, 0, 16)) +#define gsDPSetPrimDepth(z, dz) \ + gsDPSetColor(G_SETPRIMDEPTH, _SHIFTL(z, 16, 16) | \ + _SHIFTL(dz, 0, 16)) + +#define gDPSetPrimColor(pkt, m, l, r, g, b, a) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | \ + _SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8)); \ + _g->words.w1 = (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | \ + _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8)); \ +}) + +#define gsDPSetPrimColor(m, l, r, g, b, a) \ +{ \ + (_SHIFTL(G_SETPRIMCOLOR, 24, 8) | _SHIFTL(m, 8, 8) | \ + _SHIFTL(l, 0, 8)), \ + (_SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | \ + _SHIFTL(a, 0, 8)) \ +} + + /* + * gDPSetOtherMode (This is for expert user.) + * + * This command makes all othermode parameters set. + * Do not use this command in the same DL with another g*SPSetOtherMode DLs. + * + * [Usage] + * gDPSetOtherMode(pkt, modeA, modeB) + * + * 'modeA' is described all parameters of GroupA GBI command. + * 'modeB' is also described all parameters of GroupB GBI command. + * + * GroupA: + * gDPPipelineMode, gDPSetCycleType, gSPSetTexturePersp, + * gDPSetTextureDetail, gDPSetTextureLOD, gDPSetTextureLUT, + * gDPSetTextureFilter, gDPSetTextureConvert, gDPSetCombineKey, + * gDPSetColorDither, gDPSetAlphaDither + * + * GroupB: + * gDPSetAlphaCompare, gDPSetDepthSource, gDPSetRenderMode + * + * Use 'OR' operation to get modeA and modeB. + * + * modeA = G_PM_* | G_CYC_* | G_TP_* | G_TD_* | G_TL_* | G_TT_* | G_TF_* + * G_TC_* | G_CK_* | G_CD_* | G_AD_*; + * + * modeB = G_AC_* | G_ZS_* | G_RM_* | G_RM_*2; + */ +#define gDPSetOtherMode(pkt, mode0, mode1) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24);\ + _g->words.w1 = (unsigned int)(mode1); \ +}) + +#define gsDPSetOtherMode(mode0, mode1) \ +{ \ + _SHIFTL(G_RDPSETOTHERMODE,24,8)|_SHIFTL(mode0,0,24), \ + (unsigned int)(mode1) \ +} + + /* + * Texturing macros + */ + + /* These are also defined defined above for Sprite Microcode */ + +#define G_TX_LOADTILE 7 +#define G_TX_RENDERTILE 0 + +#define G_TX_NOMIRROR 0 +#define G_TX_WRAP 0 +#define G_TX_MIRROR 0x1 +#define G_TX_CLAMP 0x2 +#define G_TX_NOMASK 0 +#define G_TX_NOLOD 0 + + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +/* + * Dxt is the inverse of the number of 64-bit words in a line of + * the texture being loaded using the load_block command. If + * there are any 1's to the right of the 11th fractional bit, + * dxt should be rounded up. The following macros accomplish + * this. The 4b macros are a special case since 4-bit textures + * are loaded as 8-bit textures. Dxt is fixed point 1.11. RJM + */ +#define G_TX_DXT_FRAC 11 + + /* + * For RCP 2.0, the maximum number of texels that can be loaded + * using a load_block command is 2048. In order to load the total + * 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b, + * then change the tile to the proper texel size after the load. + * The g*DPLoadTextureBlock macros already do this, so this change + * will be transparent if you use these macros. If you use + * the g*DPLoadBlock macros directly, you will need to handle this + * tile manipulation yourself. RJM. + */ +#ifdef _HW_VERSION_1 +#define G_TX_LDBLK_MAX_TXL 4095 +#else +#define G_TX_LDBLK_MAX_TXL 2047 +#endif /* _HW_VERSION_1 */ + +#define TXL2WORDS(txls, b_txl) MAX(1, ((txls)*(b_txl)/8)) +#define CALC_DXT(width, b_txl) \ + (((1 << G_TX_DXT_FRAC) + TXL2WORDS(width, b_txl) - 1) / \ + TXL2WORDS(width, b_txl)) + +#define TXL2WORDS_4b(txls) MAX(1, ((txls)/16)) +#define CALC_DXT_4b(width) \ + (((1 << G_TX_DXT_FRAC) + TXL2WORDS_4b(width) - 1) / \ + TXL2WORDS_4b(width)) + +#define gDPLoadTileGeneric(pkt, c, tile, uls, ult, lrs, lrt) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | \ + _SHIFTL(ult, 0, 12); \ + _g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | \ + _SHIFTL(lrt, 0, 12); \ +}) + +#define gsDPLoadTileGeneric(c, tile, uls, ult, lrs, lrt) \ +{ \ + _SHIFTL(c, 24, 8) | _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12), \ + _SHIFTL(tile, 24, 3) | _SHIFTL(lrs, 12, 12) | _SHIFTL(lrt, 0, 12)\ +} + +#define gDPSetTileSize(pkt, t, uls, ult, lrs, lrt) \ + gDPLoadTileGeneric(pkt, G_SETTILESIZE, t, uls, ult, lrs, lrt) +#define gsDPSetTileSize(t, uls, ult, lrs, lrt) \ + gsDPLoadTileGeneric(G_SETTILESIZE, t, uls, ult, lrs, lrt) +#define gDPLoadTile(pkt, t, uls, ult, lrs, lrt) \ + gDPLoadTileGeneric(pkt, G_LOADTILE, t, uls, ult, lrs, lrt) +#define gsDPLoadTile(t, uls, ult, lrs, lrt) \ + gsDPLoadTileGeneric(G_LOADTILE, t, uls, ult, lrs, lrt) + +#define gDPSetTile(pkt, fmt, siz, line, tmem, tile, palette, cmt, \ + maskt, shiftt, cms, masks, shifts) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) |\ + _SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | \ + _SHIFTL(tmem, 0, 9); \ + _g->words.w1 = _SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \ + _SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \ + _SHIFTL(shiftt, 10, 4) |_SHIFTL(cms, 8, 2) | \ + _SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4); \ +}) + +#define gsDPSetTile(fmt, siz, line, tmem, tile, palette, cmt, \ + maskt, shiftt, cms, masks, shifts) \ +{ \ + (_SHIFTL(G_SETTILE, 24, 8) | _SHIFTL(fmt, 21, 3) | \ + _SHIFTL(siz, 19, 2) | _SHIFTL(line, 9, 9) | _SHIFTL(tmem, 0, 9)),\ + (_SHIFTL(tile, 24, 3) | _SHIFTL(palette, 20, 4) | \ + _SHIFTL(cmt, 18, 2) | _SHIFTL(maskt, 14, 4) | \ + _SHIFTL(shiftt, 10, 4) | _SHIFTL(cms, 8, 2) | \ + _SHIFTL(masks, 4, 4) | _SHIFTL(shifts, 0, 4)) \ +} + + /* + * For RCP 2.0, the maximum number of texels that can be loaded + * using a load_block command is 2048. In order to load the total + * 4kB of Tmem, change the texel size when loading to be G_IM_SIZ_16b, + * then change the tile to the proper texel size after the load. + * The g*DPLoadTextureBlock macros already do this, so this change + * will be transparent if you use these macros. If you use + * the g*DPLoadBlock macros directly, you will need to handle this + * tile manipulation yourself. RJM. + */ +#define gDPLoadBlock(pkt, tile, uls, ult, lrs, dxt) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_LOADBLOCK, 24, 8) | \ + _SHIFTL(uls, 12, 12) | _SHIFTL(ult, 0, 12)); \ + _g->words.w1 = (_SHIFTL(tile, 24, 3) | \ + _SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) |\ + _SHIFTL(dxt, 0, 12)); \ +}) + +#define gsDPLoadBlock(tile, uls, ult, lrs, dxt) \ +{ \ + (_SHIFTL(G_LOADBLOCK, 24, 8) | _SHIFTL(uls, 12, 12) | \ + _SHIFTL(ult, 0, 12)), \ + (_SHIFTL(tile, 24, 3) | \ + _SHIFTL((MIN(lrs,G_TX_LDBLK_MAX_TXL)), 12, 12) | \ + _SHIFTL(dxt, 0, 12)) \ +} + +#define gDPLoadTLUTCmd(pkt, tile, count) \ +_DW({ \ + Gfx *_g = (Gfx *)pkt; \ + \ + _g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8); \ + _g->words.w1 = _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10);\ +}) + +#define gsDPLoadTLUTCmd(tile, count) \ +{ \ + _SHIFTL(G_LOADTLUT, 24, 8), \ + _SHIFTL((tile), 24, 3) | _SHIFTL((count), 14, 10) \ +} + +#define gDPLoadTextureBlock(pkt, timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * siz##_LINE_BYTES)+7)>>3, 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + +#define gDPLoadTextureBlockYuv(pkt, timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * 1)+7)>>3, 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* Load fix rww 27jun95 */ + /* The S at the end means odd lines are already word Swapped */ + +#define gDPLoadTextureBlockS(pkt, timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * siz##_LINE_BYTES)+7)>>3, 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + +/* + * Allow tmem address and render tile to be specified. + * The S at the end means odd lines are already word Swapped + */ +#define gDPLoadMultiBlockS(pkt, timg, tmem, rtile, fmt, siz, width, \ + height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * siz##_LINE_BYTES)+7)>>3, tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + +#define gDPLoadTextureBlockYuvS(pkt, timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1,0); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * 1)+7)>>3, 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* + * allows tmem address to be specified + */ +#define _gDPLoadTextureBlock(pkt, timg, tmem, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \ + 0, cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \ + tmem, G_TX_RENDERTILE, pal, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* + * allows tmem address and render tile to be specified + */ +#define _gDPLoadTextureBlockTile(pkt, timg, tmem, rtile, fmt, siz, width, \ + height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0,\ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \ + tmem, rtile, pal, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPSetTileSize(pkt, rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* + * allows tmem address and render tile to be specified + */ +#define gDPLoadMultiBlock(pkt, timg, tmem, rtile, fmt, siz, width, \ + height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0,\ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width) * siz##_LINE_BYTES)+7)>>3, \ + tmem, rtile, pal, cmt, \ + maskt, shiftt, cms, masks, shifts); \ + gDPSetTileSize(pkt, rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + +#define gsDPLoadTextureBlock(timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \ + masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + /* Here is the static form of the pre-swapped texture block loading */ + /* See gDPLoadTextureBlockS() for reference. Basically, just don't + calculate DxT, use 0 */ + +#define gsDPLoadTextureBlockS(timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, 0 , \ + cmt, maskt,shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + /* + * Allow tmem address to be specified + */ +#define _gsDPLoadTextureBlock(timg, tmem, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, \ + ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + + /* + * Allow tmem address and render_tile to be specified + */ +#define _gsDPLoadTextureBlockTile(timg, tmem, rtile, fmt, siz, width, \ + height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, \ + ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + + /* + * Allow tmem address and render_tile to be specified, useful when loading + * mutilple tiles at a time. + */ +#define gsDPLoadMultiBlock(timg, tmem, rtile, fmt, siz, width, \ + height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, \ + CALC_DXT(width, siz##_BYTES)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, \ + ((((width) * siz##_LINE_BYTES)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + /* + * Allows tmem and render tile to be specified. Useful when loading + * several tiles at a time. + * + * Here is the static form of the pre-swapped texture block loading + * See gDPLoadTextureBlockS() for reference. Basically, just don't + * calculate DxT, use 0 + */ + +#define gsDPLoadMultiBlockS(timg, tmem, rtile, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, siz##_LOAD_BLOCK, 1, timg), \ + gsDPSetTile(fmt, siz##_LOAD_BLOCK, 0, tmem, G_TX_LOADTILE, 0 , \ + cmt, maskt,shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT)-1, 0 ),\ + gsDPPipeSync(), \ + gsDPSetTile(fmt, siz, ((((width) * siz##_LINE_BYTES)+7)>>3), tmem,\ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + +#define gDPLoadTextureBlock_4b(pkt, timg, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* Load fix rww 27jun95 */ + /* The S at the end means odd lines are already word Swapped */ + +#define gDPLoadTextureBlock_4bS(pkt, timg, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, \ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height)+3)>>2)-1, 0 ); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + +/* + * 4-bit load block. Useful when loading multiple tiles + */ +#define gDPLoadMultiBlock_4b(pkt, timg, tmem, rtile, fmt, width, height,\ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + /* + * 4-bit load block. Allows tmem and render tile to be specified. Useful when + * loading multiple tiles. The S means odd lines are already word swapped. + */ +#define gDPLoadMultiBlock_4bS(pkt, timg, tmem, rtile, fmt, width, height,\ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height)+3)>>2)-1, 0 ); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + + +#define _gDPLoadTextureBlock_4b(pkt, timg, tmem, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, G_IM_SIZ_16b, 1, timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0, \ + cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ +}) + +#define gsDPLoadTextureBlock_4b(timg, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \ + gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \ + maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + +#define gsDPLoadTextureBlock_4bS(timg, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \ + gsDPSetTile(fmt, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0 , cmt, \ + maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + /* + * 4-bit load block. Allows tmem address and render tile to be specified. + * Useful when loading multiple tiles. + */ +#define gsDPLoadMultiBlock_4b(timg, tmem, rtile, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \ + gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \ + maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + + /* + * 4-bit load block. Allows tmem address and render tile to be specified. + * Useful when loading multiple tiles. S means odd lines are already swapped. + */ +#define gsDPLoadMultiBlock_4bS(timg, tmem, rtile, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \ + gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \ + maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1,0),\ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + + + /* + * Allows tmem address to be specified + */ +#define _gsDPLoadTextureBlock_4b(timg, tmem, fmt, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ + \ + gsDPSetTextureImage(fmt, G_IM_SIZ_16b, 1, timg), \ + gsDPSetTile(fmt, G_IM_SIZ_16b, 0, tmem, G_TX_LOADTILE, 0 , cmt, \ + maskt, shiftt, cms, masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, (((width)*(height)+3)>>2)-1, \ + CALC_DXT_4b(width)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, ((((width)>>1)+7)>>3), tmem, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) + +#ifndef _HW_VERSION_1 + +#define gDPLoadTextureTile(pkt, timg, fmt, siz, width, height, \ + uls, ult, lrs, lrt, pal, \ + cms, cmt, masks, maskt, shifts, shiftt) \ +_DW({ \ + gDPSetTextureImage(pkt, fmt, siz, width, timg); \ + gDPSetTile(pkt, fmt, siz, \ + (((((lrs)-(uls)+1) * siz##_TILE_BYTES)+7)>>3), 0, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile( pkt, G_TX_LOADTILE, \ + (uls)<>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, \ + (uls)<>3), tmem, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile( pkt, G_TX_LOADTILE, \ + (uls)<>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, rtile, \ + (uls)<>3), 0, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPLoadSync(), \ + gsDPLoadTile( G_TX_LOADTILE, \ + (uls)<>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks,\ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, \ + (uls)<>3), \ + tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \ + masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadTile( G_TX_LOADTILE, \ + (uls)<>3), \ + tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, \ + (uls)<>1), timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \ + (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile( pkt, G_TX_LOADTILE, \ + (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (ult)<<(G_TEXTURE_IMAGE_FRAC), \ + (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (lrt)<<(G_TEXTURE_IMAGE_FRAC)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \ + (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, \ + masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, \ + (uls)<>1), timg); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_8b, \ + (((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPLoadSync(pkt); \ + gDPLoadTile( pkt, G_TX_LOADTILE, \ + (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (ult)<<(G_TEXTURE_IMAGE_FRAC), \ + (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (lrt)<<(G_TEXTURE_IMAGE_FRAC)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, G_IM_SIZ_4b, \ + (((((lrs)-(uls)+1)>>1)+7)>>3), tmem, \ + rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, rtile, \ + (uls)<>1), timg), \ + gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \ + G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPLoadSync(), \ + gsDPLoadTile( G_TX_LOADTILE, \ + (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (ult)<<(G_TEXTURE_IMAGE_FRAC), \ + (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (lrt)<<(G_TEXTURE_IMAGE_FRAC)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(G_TX_RENDERTILE, \ + (uls)<>1), timg), \ + gsDPSetTile(fmt, G_IM_SIZ_8b, (((((lrs)-(uls)+1)>>1)+7)>>3), \ + tmem, G_TX_LOADTILE, 0 , cmt, maskt, shiftt, cms, \ + masks, shifts), \ + gsDPLoadSync(), \ + gsDPLoadTile( G_TX_LOADTILE, \ + (uls)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (ult)<<(G_TEXTURE_IMAGE_FRAC), \ + (lrs)<<(G_TEXTURE_IMAGE_FRAC-1), \ + (lrt)<<(G_TEXTURE_IMAGE_FRAC)), \ + gsDPPipeSync(), \ + gsDPSetTile(fmt, G_IM_SIZ_4b, (((((lrs)-(uls)+1)>>1)+7)>>3), \ + tmem, rtile, pal, cmt, maskt, shiftt, cms, masks, \ + shifts), \ + gsDPSetTileSize(rtile, \ + (uls)<words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \ + _SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \ + _SHIFTL((int)((float)(uly)*4.0F), 0, 12); \ + _g->words.w1 = _SHIFTL(mode, 24, 2) | \ + _SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \ + _SHIFTL((int)((float)(lry)*4.0F), 0, 12); \ +}) + + +#define gDPSetScissorFrac(pkt, mode, ulx, uly, lrx, lry) \ +_DW({ \ + Gfx *_g = (Gfx *)pkt; \ + \ + _g->words.w0 = _SHIFTL(G_SETSCISSOR, 24, 8) | \ + _SHIFTL((int)((ulx)), 12, 12) | \ + _SHIFTL((int)((uly)), 0, 12); \ + _g->words.w1 = _SHIFTL(mode, 24, 2) | \ + _SHIFTL((int)((lrx)), 12, 12) | \ + _SHIFTL((int)((lry)), 0, 12); \ +}) + +#define gsDPSetScissor(mode, ulx, uly, lrx, lry) \ +{ \ + _SHIFTL(G_SETSCISSOR, 24, 8) | \ + _SHIFTL((int)((float)(ulx)*4.0F), 12, 12) | \ + _SHIFTL((int)((float)(uly)*4.0F), 0, 12), \ + _SHIFTL(mode, 24, 2) | \ + _SHIFTL((int)((float)(lrx)*4.0F), 12, 12) | \ + _SHIFTL((int)((float)(lry)*4.0F), 0, 12) \ +} + +#define gsDPSetScissorFrac(mode, ulx, uly, lrx, lry) \ +{ \ + _SHIFTL(G_SETSCISSOR, 24, 8) | \ + _SHIFTL((int)((ulx)), 12, 12) | \ + _SHIFTL((int)((uly)), 0, 12), \ + _SHIFTL(mode, 24, 2) | \ + _SHIFTL((int)(lrx), 12, 12) | \ + _SHIFTL((int)(lry), 0, 12) \ +} + +#define gDPFillWideRectangle(pkt, ulx, uly, lrx, lry) \ +{ \ + Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt); \ + _g0->words.w0 = _SHIFTL(G_FILLWIDERECT, 24, 8) | \ + _SHIFTL((lrx), 2, 22); \ + _g0->words.w1 = _SHIFTL((lry), 2, 22); \ + _g1->words.w0 = _SHIFTL((ulx), 2, 22); \ + _g1->words.w1 = _SHIFTL((uly), 2, 22); \ +} + + /* Fraction never used in fill */ +#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \ + _SHIFTL((lrx), 14, 10) | _SHIFTL((lry), 2, 10));\ + _g->words.w1 = (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10));\ +}) + +#define gsDPFillRectangle(ulx, uly, lrx, lry) \ +{ \ + (_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 14, 10) | \ + _SHIFTL((lry), 2, 10)), \ + (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10)) \ +} + +/* like gDPFillRectangle but accepts negative arguments */ +#define gDPScisFillRectangle(pkt, ulx, uly, lrx, lry) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_FILLRECT, 24, 8) | \ + _SHIFTL(MAX((lrx),0), 14, 10) | \ + _SHIFTL(MAX((lry),0), 2, 10)); \ + _g->words.w1 = (_SHIFTL(MAX((ulx),0), 14, 10) | \ + _SHIFTL(MAX((uly),0), 2, 10)); \ +}) + +#define gDPSetConvert(pkt, k0, k1, k2, k3, k4, k5) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_SETCONVERT, 24, 8) | \ + _SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | \ + _SHIFTR(k2, 5, 4)); \ + _g->words.w1 = (_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | \ + _SHIFTL(k4, 9, 9) | _SHIFTL(k5, 0, 9)); \ +}) + +#define gsDPSetConvert(k0, k1, k2, k3, k4, k5) \ +{ \ + (_SHIFTL(G_SETCONVERT, 24, 8) | \ + _SHIFTL(k0, 13, 9) | _SHIFTL(k1, 4, 9) | _SHIFTL(k2, 5, 4)), \ + (_SHIFTL(k2, 27, 5) | _SHIFTL(k3, 18, 9) | _SHIFTL(k4, 9, 9) | \ + _SHIFTL(k5, 0, 9)) \ +} + +#define gDPSetKeyR(pkt, cR, sR, wR) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(G_SETKEYR, 24, 8); \ + _g->words.w1 = (_SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | \ + _SHIFTL(sR, 0, 8)); \ +}) + +#define gsDPSetKeyR(cR, sR, wR) \ +{ \ + _SHIFTL(G_SETKEYR, 24, 8), \ + _SHIFTL(wR, 16, 12) | _SHIFTL(cR, 8, 8) | _SHIFTL(sR, 0, 8) \ +} + +#define gDPSetKeyGB(pkt, cG, sG, wG, cB, sB, wB) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_SETKEYGB, 24, 8) | \ + _SHIFTL(wG, 12, 12) | _SHIFTL(wB, 0, 12)); \ + _g->words.w1 = (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | \ + _SHIFTL(cB, 8, 8) | _SHIFTL(sB, 0, 8)); \ +}) + +#define gsDPSetKeyGB(cG, sG, wG, cB, sB, wB) \ +{ \ + (_SHIFTL(G_SETKEYGB, 24, 8) | _SHIFTL(wG, 12, 12) | \ + _SHIFTL(wB, 0, 12)), \ + (_SHIFTL(cG, 24, 8) | _SHIFTL(sG, 16, 8) | _SHIFTL(cB, 8, 8) | \ + _SHIFTL(sB, 0, 8)) \ +} + +#define gDPNoParam(pkt, cmd) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(cmd, 24, 8); \ + _g->words.w1 = 0; \ +}) + +#define gsDPNoParam(cmd) \ +{ \ + _SHIFTL(cmd, 24, 8), 0 \ +} + +#define gDPParam(pkt, cmd, param) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = _SHIFTL(cmd, 24, 8); \ + _g->words.w1 = (param); \ +}) + +#define gsDPParam(cmd, param) \ +{ \ + _SHIFTL(cmd, 24, 8), (param) \ +} + +/* Notice that textured rectangles are 128-bit commands, therefore + * gsDPTextureRectangle() should not be used in display lists + * under normal circumstances (use gsSPTextureRectangle()). + * That is also why there is no gDPTextureRectangle() macros. + */ +#define gsDPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ +{ \ + (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)), \ + (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \ +}, \ +{ \ + _SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \ + _SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \ +} + +#define gDPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + if (pkt); \ + _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)); \ + _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \ + _SHIFTL(yl, 0, 12)); \ + _g ++; \ + _g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \ + _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \ +}) + +#define gsDPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ +{ \ + (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)), \ + (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \ +}, \ +{ \ + _SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \ + _SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \ +} + +#define gDPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + if (pkt); \ + _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)); \ + _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \ + _SHIFTL(yl, 0, 12)); \ + _g ++; \ + _g->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \ + _g->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \ +}) + +#define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ + (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | _SHIFTL(yh, 0, 12)),\ + (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \ + gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \ + gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))) + +#define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)); \ + _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \ + _SHIFTL(yl, 0, 12)); \ + gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \ + gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)));\ +}) + +#define gSPWideTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\ +{ \ + Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt), *_g2 = (Gfx *)(pkt); \ + \ + _g0->words.w0 = _SHIFTL(G_TEXRECT_WIDE, 24, 8) | \ + _SHIFTL((xh), 0, 24); \ + _g0->words.w1 = _SHIFTL((yh), 0, 24); \ + _g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \ + _g1->words.w1 = _SHIFTL((yl), 0, 24); \ + _g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \ + _g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \ +} + + /* like gSPTextureRectangle but accepts negative position arguments */ +#define gSPScisTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXRECT, 24, 8) | \ + _SHIFTL(MAX((s16)(xh),0), 12, 12) | \ + _SHIFTL(MAX((s16)(yh),0), 0, 12)); \ + _g->words.w1 = (_SHIFTL((tile), 24, 3) | \ + _SHIFTL(MAX((s16)(xl),0), 12, 12) | \ + _SHIFTL(MAX((s16)(yl),0), 0, 12)); \ + gImmp1(pkt, G_RDPHALF_1, \ + (_SHIFTL(((s) - \ + (((s16)(xl) < 0) ? \ + (((s16)(dsdx) < 0) ? \ + (MAX((((s16)(xl)*(s16)(dsdx))>>7),0)) : \ + (MIN((((s16)(xl)*(s16)(dsdx))>>7),0))) : 0)), \ + 16, 16) | \ + _SHIFTL(((t) - \ + (((yl) < 0) ? \ + (((s16)(dtdy) < 0) ? \ + (MAX((((s16)(yl)*(s16)(dtdy))>>7),0)) : \ + (MIN((((s16)(yl)*(s16)(dtdy))>>7),0))) : 0)), \ + 0, 16))); \ + gImmp1(pkt, G_RDPHALF_2, (_SHIFTL((dsdx), 16, 16) | \ + _SHIFTL((dtdy), 0, 16))); \ +}) + +#define gsSPTextureRectangleFlip(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ + (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) | \ + _SHIFTL(yh, 0, 12)), \ + (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | _SHIFTL(yl, 0, 12)), \ + gsImmp1(G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))), \ + gsImmp1(G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))) + +#define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_TEXRECTFLIP, 24, 8) | _SHIFTL(xh, 12, 12) |\ + _SHIFTL(yh, 0, 12)); \ + _g->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL(xl, 12, 12) | \ + _SHIFTL(yl, 0, 12)); \ + gImmp1(pkt, G_RDPHALF_1, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \ + gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \ +}) + +#define gsDPWord(wordhi, wordlo) \ + gsImmp1(G_RDPHALF_1, (unsigned int)(wordhi)), \ + gsImmp1(G_RDPHALF_2, (unsigned int)(wordlo)) + +#define gDPWord(pkt, wordhi, wordlo) \ +_DW({ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + gImmp1(pkt, G_RDPHALF_1, (unsigned int)(wordhi)); \ + gImmp1(pkt, G_RDPHALF_2, (unsigned int)(wordlo)); \ +}) + +#define gDPFullSync(pkt) gDPNoParam(pkt, G_RDPFULLSYNC) +#define gsDPFullSync() gsDPNoParam(G_RDPFULLSYNC) +#define gDPTileSync(pkt) gDPNoParam(pkt, G_RDPTILESYNC) +#define gsDPTileSync() gsDPNoParam(G_RDPTILESYNC) +#define gDPPipeSync(pkt) gDPNoParam(pkt, G_RDPPIPESYNC) +#define gsDPPipeSync() gsDPNoParam(G_RDPPIPESYNC) +#define gDPLoadSync(pkt) gDPNoParam(pkt, G_RDPLOADSYNC) +#define gsDPLoadSync() gsDPNoParam(G_RDPLOADSYNC) +#define gDPNoOp(pkt) gDPNoParam(pkt, G_NOOP) +#define gsDPNoOp() gsDPNoParam(G_NOOP) +#define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag) +#define gsDPNoOpTag(tag) gsDPParam(G_NOOP, tag) + +#define gDPNoOpHere(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 1) +#define gDPNoOpString(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 2) +#define gDPNoOpWord(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 3) +#define gDPNoOpFloat(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 4) +#define gDPNoOpQuiet(pkt) gDma1p(pkt, G_NOOP, 0, 0, 5) +#define gDPNoOpVerbose(pkt, n) gDma1p(pkt, G_NOOP, 0, n, 5) +#define gDPNoOpCallBack(pkt, callback, arg) gDma1p(pkt, G_NOOP, callback, arg, 6) +#define gDPNoOpOpenDisp(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 7) +#define gDPNoOpCloseDisp(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 8) +#define gDPNoOpTag3(pkt, type, data, n) gDma1p(pkt, G_NOOP, data, n, type) + +#endif + +#endif \ No newline at end of file diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gs2dex.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gs2dex.h new file mode 100644 index 000000000..5c0bc7175 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gs2dex.h @@ -0,0 +1,379 @@ +#ifndef GS2DEX_H +#define GS2DEX_H + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +/*===========================================================================* + * Macro + *===========================================================================*/ +#define GS_CALC_DXT(line) (((1<< G_TX_DXT_FRAC)-1)/(line)+1) +#define GS_PIX2TMEM(pix, siz) ((pix)>>(4-(siz))) +#define GS_PIX2DXT(pix, siz) GS_CALC_DXT(GS_PIX2TMEM((pix), (siz))) + +/*===========================================================================* + * Data structures for S2DEX microcode + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * Background + *---------------------------------------------------------------------------*/ +#define G_BGLT_LOADBLOCK 0x0033 +#define G_BGLT_LOADTILE 0xfff4 + +#define G_BG_FLAG_FLIPS 0x01 +#define G_BG_FLAG_FLIPT 0x10 + +/* Non scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of the texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of the texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64 *imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* which to use, LoadBlock or LoadTile */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + /* The following is set in the initialization routine guS2DInitBg(). There is no need for the user to set it. */ + u16 tmemW; /* TMEM width and Word size of frame 1 line. + At LoadBlock, GS_PIX2TMEM(imageW/4,imageSiz) + At LoadTile GS_PIX2TMEM(frameW/4,imageSiz)+1 */ + u16 tmemH; /* height of TMEM loadable at a time (s13.2) 4 times value + When the normal texture, 512/tmemW*4 + When the CI texture, 256/tmemW*4 */ + u16 tmemLoadSH; /* SH value + At LoadBlock, tmemSize/2-1 + At LoadTile, tmemW*16-1 */ + u16 tmemLoadTH; /* TH value or Stride value + At LoadBlock, GS_CALC_DXT(tmemW) + At LoadTile, tmemH-1 */ + u16 tmemSizeW; /* skip value of imagePtr for image 1-line + At LoadBlock, tmemW*2 + At LoadTile, GS_PIX2TMEM(imageW/4,imageSiz)*2 */ + u16 tmemSize; /* skip value of imagePtr for 1-loading + = tmemSizeW*tmemH */ +} uObjBg_t; /* 40 bytes */ + +/* Scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64 *imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* Which to use, LoadBlock or LoadTile? */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + u16 scaleW; /* scale value of X-direction (u5.10) */ + u16 scaleH; /* scale value of Y-direction (u5.10) */ + s32 imageYorig; /* start point of drawing on image (s20.5) */ + + u8 padding[4]; + +} uObjScaleBg_t; /* 40 bytes */ + +typedef union { + uObjBg_t b; + uObjScaleBg_t s; + long long int force_structure_alignment; +} uObjBg; + +/*---------------------------------------------------------------------------* + * 2D Objects + *---------------------------------------------------------------------------*/ +#define G_OBJ_FLAG_FLIPS 1<<0 /* inversion to S-direction */ +#define G_OBJ_FLAG_FLIPT 1<<4 /* nversion to T-direction */ + +typedef struct { + s16 objX; /* s10.2 OBJ x-coordinate of upper-left end */ + u16 scaleW; /* u5.10 Scaling of u5.10 width direction */ + u16 imageW; /* u10.5 width of u10.5 texture (length of S-direction) */ + u16 paddingX; /* Unused - Always 0 */ + s16 objY; /* s10.2 OBJ y-coordinate of s10.2 OBJ upper-left end */ + u16 scaleH; /* u5.10 Scaling of u5.10 height direction */ + u16 imageH; /* u10.5 height of u10.5 texture (length of T-direction) */ + u16 paddingY; /* Unused - Always 0 */ + u16 imageStride; /* folding width of texel (In units of 64bit word) */ + u16 imageAdrs; /* texture header position in TMEM (In units of 64bit word) */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u8 imagePal; /* pallet number (0-7) */ + u8 imageFlags; /* The display flag - G_OBJ_FLAG_FLIP* */ +} uObjSprite_t; /* 24 bytes */ + +typedef union { + uObjSprite_t s; + long long int force_structure_alignment; +} uObjSprite; + +/*---------------------------------------------------------------------------* + * 2D Matrix + *---------------------------------------------------------------------------*/ +typedef struct { + s32 A, B, C, D; /* s15.16 */ + s16 X, Y; /* s10.2 */ + u16 BaseScaleX; /* u5.10 */ + u16 BaseScaleY; /* u5.10 */ +} uObjMtx_t; /* 24 bytes */ + +typedef union { + uObjMtx_t m; + long long int force_structure_alignment; +} uObjMtx; + +typedef struct { + s16 X, Y; /* s10.2 */ + u16 BaseScaleX; /* u5.10 */ + u16 BaseScaleY; /* u5.10 */ +} uObjSubMtx_t; /* 8 bytes */ + +typedef union { + uObjSubMtx_t m; + long long int force_structure_alignment; +} uObjSubMtx; + +/*---------------------------------------------------------------------------* + * Loading into TMEM + *---------------------------------------------------------------------------*/ +#define G_OBJLT_TXTRBLOCK 0x00001033 +#define G_OBJLT_TXTRTILE 0x00fc1034 +#define G_OBJLT_TLUT 0x00000030 + +#define GS_TB_TSIZE(pix,siz) (GS_PIX2TMEM((pix),(siz))-1) +#define GS_TB_TLINE(pix,siz) (GS_CALC_DXT(GS_PIX2TMEM((pix),(siz)))) + +typedef struct { + u32 type; /* G_OBJLT_TXTRBLOCK divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 tmem; /* loaded TMEM word address (8byteWORD) */ + u16 tsize; /* Texture size, Specified by macro GS_TB_TSIZE() */ + u16 tline; /* width of Texture 1-line, Specified by macro GS_TB_TLINE() */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12) */ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrBlock_t; /* 24 bytes */ + +#define GS_TT_TWIDTH(pix,siz) ((GS_PIX2TMEM((pix), (siz))<<2)-1) +#define GS_TT_THEIGHT(pix,siz) (((pix)<<2)-1) + +typedef struct { + u32 type; /* G_OBJLT_TXTRTILE divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 tmem; /* loaded TMEM word address (8byteWORD)*/ + u16 twidth; /* width of Texture (Specified by macro GS_TT_TWIDTH()) */ + u16 theight; /* height of Texture (Specified by macro GS_TT_THEIGHT()) */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12) */ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrTile_t; /* 24 bytes */ + +#define GS_PAL_HEAD(head) ((head)+256) +#define GS_PAL_NUM(num) ((num)-1) + +typedef struct { + u32 type; /* G_OBJLT_TLUT divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 phead; /* pallet number of load header (Between 256 and 511) */ + u16 pnum; /* loading pallet number -1 */ + u16 zero; /* Assign 0 all the time */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12)*/ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrTLUT_t; /* 24 bytes */ + +typedef union { + uObjTxtrBlock_t block; + uObjTxtrTile_t tile; + uObjTxtrTLUT_t tlut; + long long int force_structure_alignment; +} uObjTxtr; + +/*---------------------------------------------------------------------------* + * Loading into TMEM & 2D Objects + *---------------------------------------------------------------------------*/ +typedef struct { + uObjTxtr txtr; + uObjSprite sprite; +} uObjTxSprite; /* 48 bytes */ + +/*===========================================================================* + * GBI Commands for S2DEX microcode + *===========================================================================*/ +/* GBI Header */ +#ifdef F3DEX_GBI_2 +#define G_OBJ_RECTANGLE_R 0xda +#define G_OBJ_MOVEMEM 0xdc +#define G_RDPHALF_0 0xe4 +#define G_OBJ_RECTANGLE 0x01 +#define G_OBJ_SPRITE 0x02 +#define G_SELECT_DL 0x04 +#define G_OBJ_LOADTXTR 0x05 +#define G_OBJ_LDTX_SPRITE 0x06 +#define G_OBJ_LDTX_RECT 0x07 +#define G_OBJ_LDTX_RECT_R 0x08 +#define G_BG_1CYC 0x09 +#define G_BG_COPY 0x0a +#define G_OBJ_RENDERMODE 0x0b +#else +#define G_BG_1CYC 0x01 +#define G_BG_COPY 0x02 +#define G_OBJ_RECTANGLE 0x03 +#define G_OBJ_SPRITE 0x04 +#define G_OBJ_MOVEMEM 0x05 +#define G_SELECT_DL 0xb0 +#define G_OBJ_RENDERMODE 0xb1 +#define G_OBJ_RECTANGLE_R 0xb2 +#define G_OBJ_LOADTXTR 0xc1 +#define G_OBJ_LDTX_SPRITE 0xc2 +#define G_OBJ_LDTX_RECT 0xc3 +#define G_OBJ_LDTX_RECT_R 0xc4 +#define G_RDPHALF_0 0xe4 +#endif + +/*---------------------------------------------------------------------------* + * Background wrapped screen + *---------------------------------------------------------------------------*/ +#define gSPBgRectangle(pkt, m, mptr) gDma0p((pkt),(m),(mptr),0) +#define gsSPBgRectangle(m, mptr) gsDma0p( (m),(mptr),0) +#define gSPBgRectCopy(pkt, mptr) gSPBgRectangle((pkt), G_BG_COPY, (mptr)) +#define gsSPBgRectCopy(mptr) gsSPBgRectangle( G_BG_COPY, (mptr)) +#define gSPBgRect1Cyc(pkt, mptr) gSPBgRectangle((pkt), G_BG_1CYC, (mptr)) +#define gsSPBgRect1Cyc(mptr) gsSPBgRectangle( G_BG_1CYC, (mptr)) + +/*---------------------------------------------------------------------------* + * 2D Objects + *---------------------------------------------------------------------------*/ +#define gSPObjSprite(pkt, mptr) gDma0p((pkt),G_OBJ_SPRITE, (mptr),0) +#define gsSPObjSprite(mptr) gsDma0p( G_OBJ_SPRITE, (mptr),0) +#define gSPObjRectangle(pkt, mptr) gDma0p((pkt),G_OBJ_RECTANGLE, (mptr),0) +#define gsSPObjRectangle(mptr) gsDma0p( G_OBJ_RECTANGLE, (mptr),0) +#define gSPObjRectangleR(pkt, mptr) gDma0p((pkt),G_OBJ_RECTANGLE_R,(mptr),0) +#define gsSPObjRectangleR(mptr) gsDma0p( G_OBJ_RECTANGLE_R,(mptr),0) + +/*---------------------------------------------------------------------------* + * 2D Matrix + *---------------------------------------------------------------------------*/ +#define gSPObjMatrix(pkt, mptr) gDma1p((pkt),G_OBJ_MOVEMEM,(mptr),0,23) +#define gsSPObjMatrix(mptr) gsDma1p( G_OBJ_MOVEMEM,(mptr),0,23) +#define gSPObjSubMatrix(pkt, mptr) gDma1p((pkt),G_OBJ_MOVEMEM,(mptr),2, 7) +#define gsSPObjSubMatrix(mptr) gsDma1p( G_OBJ_MOVEMEM,(mptr),2, 7) + +/*---------------------------------------------------------------------------* + * Loading into TMEM + *---------------------------------------------------------------------------*/ +#define gSPObjLoadTxtr(pkt, tptr) gDma0p((pkt),G_OBJ_LOADTXTR, (tptr),23) +#define gsSPObjLoadTxtr(tptr) gsDma0p( G_OBJ_LOADTXTR, (tptr),23) +#define gSPObjLoadTxSprite(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_SPRITE,(tptr),47) +#define gsSPObjLoadTxSprite(tptr) gsDma0p( G_OBJ_LDTX_SPRITE,(tptr),47) +#define gSPObjLoadTxRect(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_RECT, (tptr),47) +#define gsSPObjLoadTxRect(tptr) gsDma0p( G_OBJ_LDTX_RECT, (tptr),47) +#define gSPObjLoadTxRectR(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_RECT_R,(tptr),47) +#define gsSPObjLoadTxRectR(tptr) gsDma0p( G_OBJ_LDTX_RECT_R,(tptr),47) + +/*---------------------------------------------------------------------------* + * Select Display List + *---------------------------------------------------------------------------*/ +#define gSPSelectDL(pkt, mptr, sid, flag, mask) \ +{ gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); } +#define gsSPSelectDL(mptr, sid, flag, mask) \ +{ gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); } +#define gSPSelectBranchDL(pkt, mptr, sid, flag, mask) \ +{ gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); } +#define gsSPSelectBranchDL(mptr, sid, flag, mask) \ +{ gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); } + +/*---------------------------------------------------------------------------* + * Set general status + *---------------------------------------------------------------------------*/ +#define G_MW_GENSTAT 0x08 /* Note that it is the same value of G_MW_FOG */ + +#define gSPSetStatus(pkt, sid, val) \ + gMoveWd((pkt), G_MW_GENSTAT, (sid), (val)) +#define gsSPSetStatus(sid, val) \ + gsMoveWd( G_MW_GENSTAT, (sid), (val)) + +/*---------------------------------------------------------------------------* + * Set Object Render Mode + *---------------------------------------------------------------------------*/ +#define G_OBJRM_NOTXCLAMP 0x01 +#define G_OBJRM_XLU 0x02 /* Ignored */ +#define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ +#define G_OBJRM_BILERP 0x08 +#define G_OBJRM_SHRINKSIZE_1 0x10 +#define G_OBJRM_SHRINKSIZE_2 0x20 +#define G_OBJRM_WIDEN 0x40 + +#define gSPObjRenderMode(pkt, mode) gImmp1((pkt),G_OBJ_RENDERMODE,(mode)) +#define gsSPObjRenderMode(mode) gsImmp1( G_OBJ_RENDERMODE,(mode)) + +/*===========================================================================* + * Render Mode Macro + *===========================================================================*/ +#define RM_RA_SPRITE(clk) \ + AA_EN | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define G_RM_SPRITE G_RM_OPA_SURF +#define G_RM_SPRITE2 G_RM_OPA_SURF2 +#define G_RM_RA_SPRITE RM_RA_SPRITE(1) +#define G_RM_RA_SPRITE2 RM_RA_SPRITE(2) +#define G_RM_AA_SPRITE G_RM_AA_TEX_TERR +#define G_RM_AA_SPRITE2 G_RM_AA_TEX_TERR2 +#define G_RM_XLU_SPRITE G_RM_XLU_SURF +#define G_RM_XLU_SPRITE2 G_RM_XLU_SURF2 +#define G_RM_AA_XLU_SPRITE G_RM_AA_XLU_SURF +#define G_RM_AA_XLU_SPRITE2 G_RM_AA_XLU_SURF2 + +/*===========================================================================* + * External functions + *===========================================================================*/ +extern u64 gspS2DEX_fifoTextStart[], gspS2DEX_fifoTextEnd[]; +extern u64 gspS2DEX_fifoDataStart[], gspS2DEX_fifoDataEnd[]; +extern u64 gspS2DEX_fifo_dTextStart[], gspS2DEX_fifo_dTextEnd[]; +extern u64 gspS2DEX_fifo_dDataStart[], gspS2DEX_fifo_dDataEnd[]; +extern u64 gspS2DEX2_fifoTextStart[], gspS2DEX2_fifoTextEnd[]; +extern u64 gspS2DEX2_fifoDataStart[], gspS2DEX2_fifoDataEnd[]; +extern u64 gspS2DEX2_xbusTextStart[], gspS2DEX2_xbusTextEnd[]; +extern u64 gspS2DEX2_xbusDataStart[], gspS2DEX2_xbusDataEnd[]; +extern void guS2DInitBg(uObjBg *); + +#ifdef F3DEX_GBI_2 +# define guS2DEmuBgRect1Cyc guS2D2EmuBgRect1Cyc /*Wrapper*/ +# define guS2DEmuSetScissor guS2D2EmuSetScissor /*Wrapper*/ + extern void guS2D2EmuSetScissor(u32, u32, u32, u32, u8); + extern void guS2D2EmuBgRect1Cyc(Gfx **, uObjBg *); +#else + extern void guS2DEmuSetScissor(u32, u32, u32, u32, u8); + extern void guS2DEmuBgRect1Cyc(Gfx **, uObjBg *); +#endif + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif +#endif /* GS2DEX_H */ + +/*======== End of gs2dex.h ========*/ diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gu.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gu.h new file mode 100644 index 000000000..8fc9e0291 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gu.h @@ -0,0 +1,8 @@ +#ifndef ULTRA64_GU_H +#define ULTRA64_GU_H + +#define GU_PI 3.1415926 + +#define ROUND(x) (s32)(((x) >= 0.0) ? ((x) + 0.5) : ((x) - 0.5)) + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/hardware.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/hardware.h new file mode 100644 index 000000000..48247b473 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/hardware.h @@ -0,0 +1,90 @@ +#ifndef ULTRA64_HARDWARE_H +#define ULTRA64_HARDWARE_H + +#define HW_REG(reg, type) *(volatile type*)((reg) | 0xa0000000) + +#define AI_DRAM_ADDR_REG 0x04500000 +#define AI_LEN_REG 0x04500004 +#define AI_CONTROL_REG 0x04500008 +#define AI_STATUS_REG 0x0450000C +#define AI_STATUS_AI_FULL (1 << 31) +#define AI_STATUS_AI_BUSY (1 << 30) +#define AI_DACRATE_REG 0x04500010 +#define AI_BITRATE_REG 0x04500014 + +#define VI_STATUS_REG 0x04400000 +#define VI_CONTROL_REG 0x04400000 +#define VI_ORIGIN_REG 0x04400004 +#define VI_DRAM_ADDR_REG 0x04400004 +#define VI_WIDTH_REG 0x04400008 +#define VI_H_WIDTH_REG 0x04400008 +#define VI_INTR_REG 0x0440000C +#define VI_V_INTER_REG 0x0440000C +#define VI_CURRENT_REG 0x04400010 +#define VI_V_CURRENT_LINE_REG 0x04400010 +#define VI_BURST_REG 0x04400014 +#define VI_TIMING_REG 0x04400014 +#define VI_V_SYNC_REG 0x04400018 //VI vertical sync +#define VI_H_SYNC_REG 0x0440001C //VI horizontal sync +#define VI_LEAP_REG 0x04400020 //VI horizontal sync leap +#define VI_H_SYNC_LEAP_REG 0x04400020 +#define VI_H_START_REG 0x04400024 //VI horizontal video +#define VI_H_VIDEO_REG 0x04400024 +#define VI_V_START_REG 0x04400028 //VI vertical video +#define VI_V_VIDEO_REG 0x04400028 +#define VI_V_BURST_REG 0x0440002C //VI vertical burst +#define VI_X_SCALE_REG 0x04400030 //VI x-scale +#define VI_Y_SCALE_REG 0x04400034 //VI y-scale + +#define SP_IMEM_START 0x04001000 +#define SP_DMEM_START 0x04000000 + +#define SP_MEM_ADDR_REG 0x04040000 +#define SP_DRAM_ADDR_REG 0x04040004 +#define SP_RD_LEN_REG 0x04040008 +#define SP_WR_LEN_REG 0x0404000C +#define SP_STATUS_REG 0x04040010 +#define SP_PC_REG 0x04080000 + +#define PI_DRAM_ADDR_REG 0x04600000 //PI DRAM address +#define PI_CART_ADDR_REG 0x04600004 //PI pbus (cartridge) address +#define PI_RD_LEN_REG 0x04600008 //PI read length +#define PI_WR_LEN_REG 0x0460000C //PI write length +#define PI_STATUS_REG 0x04600010 //PI status +#define PI_BSD_DOM1_LAT_REG 0x04600014 //PI dom1 latency +#define PI_DOMAIN1_REG 0x04600014 +#define PI_BSD_DOM1_PWD_REG 0x04600018 //PI dom1 pulse width +#define PI_BSD_DOM1_PGS_REG 0x0460001C //PI dom1 page size +#define PI_BSD_DOM1_RLS_REG 0x04600020 //PI dom1 release +#define PI_BSD_DOM2_LAT_REG 0x04600024 //PI dom2 latency +#define PI_DOMAIN2_REG 0x04600024 +#define PI_BSD_DOM2_PWD_REG 0x04600028 //PI dom2 pulse width +#define PI_BSD_DOM2_PGS_REG 0x0460002C //PI dom2 page size +#define PI_BSD_DOM2_RLS_REG 0x04600030 //PI dom2 release + +#define PI_STATUS_BUSY 0x1 +#define PI_STATUS_IOBUSY 0x2 +#define PI_STATUS_ERROR 0x3 + +#define PI_STATUS_RESET_CONTROLLER 0x1 +#define PI_STATUS_CLEAR_INTR 0x2 + +#define SI_DRAM_ADDR_REG 0x04800000 +#define SI_PIF_ADDR_RD64B_REG 0x04800004 +#define SI_PIF_ADDR_WR64B_REG 0x04800010 +#define SI_STATUS_REG 0x04800018 + +#define SI_STATUS_DMA_BUSY 0x1 +#define SI_STATUS_IO_READ_BUSY 0x2 +#define SI_STATUS_DMA_ERROR 0x8 +#define SI_STATUS_INTERRUPT (1 << 12) + +#define PIF_RAM_START 0x1FC007C0 + +#define MI_INIT_MODE_REG 0x04300000 +#define MI_MODE_REG MI_INIT_MODE_REG +#define MI_VERSION_REG 0x04300004 +#define MI_INTR_REG 0x04300008 +#define MI_INTR_MASK_REG 0x0430000C + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/internal.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/internal.h new file mode 100644 index 000000000..a301f4a70 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/internal.h @@ -0,0 +1,24 @@ +#ifndef ULTRA64_INTERNAL_H +#define ULTRA64_INTERNAL_H + +#include "pi.h" + +typedef struct { + /* 0x00 */ u32 initialized; + /* 0x04 */ OSThread* mgrThread; + /* 0x08 */ OSMesgQueue* cmdQueue; + /* 0x0C */ OSMesgQueue* eventQueue; + /* 0x10 */ OSMesgQueue* acccessQueue; + /* 0x14 */ s32 (*piDmaCallback)(s32, u32, void*, size_t); + /* 0x18 */ s32 (*epiDmaCallback)(OSPiHandle*, s32, u32, void*, size_t); +} OSMgrArgs; // size = 0x1C + +typedef struct { + /* 0x00 */ OSMesgQueue* queue; + /* 0x04 */ OSMesg msg; +} __OSEventState; // size = 0x08 + +extern OSMgrArgs __osPiDevMgr; +extern __OSEventState __osEventStateTab[]; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/interrupt.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/interrupt.h new file mode 100644 index 000000000..7c669c170 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/interrupt.h @@ -0,0 +1,6 @@ +#ifndef ULTRA64_INTERRUPT_H +#define ULTRA64_INTERRUPT_H + +typedef u32 OSIntMask; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h new file mode 100644 index 000000000..fd6042ff5 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h @@ -0,0 +1,44 @@ +#ifndef ULTRA64_MBI_H +#define ULTRA64_MBI_H + +/* + * Header file for the Media Binary Interface + * + * NOTE: This file is included by the RSP microcode, so any C-specific + * constructs must be bracketed by #ifdef _LANGUAGE_C + * + */ + + +/* + * the SHIFT macros are used to build display list commands, inserting + * bit-fields into a 32-bit word. They take a value, a shift amount, + * and a width. + * + * For the left shift, the lower bits of the value are masked, + * then shifted left. + * + * For the right shift, the value is shifted right, then the lower bits + * are masked. + * + * (NOTE: _SHIFTL(v, 0, 32) won't work, just use an assignment) + * + */ +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) +#define _SHIFTR(v, s, w) \ + ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) + +#define G_ON (1) +#define G_OFF (0) + +#include +#include "gbi.h" +#include "abi.h" + +#define NUM_SEGMENTS (16) +#define SEGMENT_OFFSET(a) ((u32)(a) & 0x00FFFFFF) +#define SEGMENT_NUMBER(a) (((u32)(a) << 4) >> 28) +#define SEGMENT_ADDR(num, off) (((num) << 24) + (off)) + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/message.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/message.h new file mode 100644 index 000000000..d463ec4c6 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/message.h @@ -0,0 +1,39 @@ +#ifndef ULTRA64_MESSAGE_H +#define ULTRA64_MESSAGE_H + +#include "thread.h" + +#define OS_MESG_NOBLOCK 0 +#define OS_MESG_BLOCK 1 + +typedef void* OSMesg; +typedef u32 OSEvent; + +#define OS_NUM_EVENTS 15 + +#define OS_EVENT_SW1 0 /* CPU SW1 interrupt */ +#define OS_EVENT_SW2 1 /* CPU SW2 interrupt */ +#define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */ +#define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */ +#define OS_EVENT_SP 4 /* SP task done interrupt */ +#define OS_EVENT_SI 5 /* SI (controller) interrupt */ +#define OS_EVENT_AI 6 /* AI interrupt */ +#define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */ +#define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */ +#define OS_EVENT_DP 9 /* DP full sync interrupt */ +#define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */ +#define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */ +#define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */ +#define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */ +#define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */ + +typedef struct OSMesgQueue { + /* 0x00 */ OSThread* mtqueue; + /* 0x04 */ OSThread* fullqueue; + /* 0x08 */ s32 validCount; + /* 0x0C */ s32 first; + /* 0x10 */ s32 msgCount; + /* 0x14 */ OSMesg* msg; +} OSMesgQueue; // size = 0x18 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/motor.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/motor.h new file mode 100644 index 000000000..6f584fefd --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/motor.h @@ -0,0 +1,15 @@ +#ifndef ULTRA64_MOTOR_H +#define ULTRA64_MOTOR_H + +#include "pfs.h" + +#define MOTOR_START 1 +#define MOTOR_STOP 0 + +#define osMotorStart(x) __osMotorAccess((x), MOTOR_START) +#define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP) + +s32 __osMotorAccess(OSPfs* pfs, u32 vibrate); +s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel); + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pfs.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pfs.h new file mode 100644 index 000000000..8c13a3b45 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pfs.h @@ -0,0 +1,137 @@ +#ifndef ULTRA64_PFS_H +#define ULTRA64_PFS_H + +#include "message.h" + +/* File System size */ +#define OS_PFS_VERSION 0x0200 +#define OS_PFS_VERSION_HI (OS_PFS_VERSION >> 8) +#define OS_PFS_VERSION_LO (OS_PFS_VERSION & 255) + +#define PFS_INODE_SIZE_PER_PAGE 128 +#define PFS_FILE_NAME_LEN 16 +#define PFS_FILE_EXT_LEN 4 +#define BLOCKSIZE 32 +#define PFS_ONE_PAGE 8 +#define PFS_MAX_BANKS 62 + +/* File System flag */ + +#define PFS_READ 0 +#define PFS_WRITE 1 +#define PFS_CREATE 2 + +/* File System status */ +#define PFS_INITIALIZED 0x1 +#define PFS_CORRUPTED 0x2 +#define PFS_ID_BROKEN 0x4 +#define PFS_MOTOR_INITIALIZED 0x8 +#define PFS_GBPAK_INITIALIZED 0x10 + +/* Definition for page usage */ +#define PFS_EOF 1 +#define PFS_PAGE_NOT_EXIST 2 +#define PFS_PAGE_NOT_USED 3 + +/* File System error number */ + +#define PFS_ERR_NOPACK 1 /* no memory card is plugged or */ +#define PFS_ERR_NEW_PACK 2 /* ram pack has been changed to a different one */ +#define PFS_ERR_INCONSISTENT 3 /* need to run Pfschecker*/ +#define PFS_ERR_CONTRFAIL CONT_OVERRUN_ERROR +#define PFS_ERR_INVALID 5 /* invalid parameter or file not exist*/ +#define PFS_ERR_BAD_DATA 6 /* the data read from pack are bad*/ +#define PFS_DATA_FULL 7 /* no free pages on ram pack*/ +#define PFS_DIR_FULL 8 /* no free directories on ram pack*/ +#define PFS_ERR_EXIST 9 /* file exists*/ +#define PFS_ERR_ID_FATAL 10 /* dead ram pack */ +#define PFS_ERR_DEVICE 11 /* wrong device type*/ +#define PFS_ERR_NO_GBCART 12 /* no gb cartridge (64GB-PAK) */ +#define PFS_ERR_NEW_GBCART 13 /* gb cartridge may be changed */ + +/* Definition for bank */ +#define PFS_ID_BANK_256K 0 +#define PFS_ID_BANK_1M 4 +#define PFS_BANKS_256K 1 + +#define PFS_WRITTEN 2 +#define DEF_DIR_PAGES 2 + +#define PFS_ID_0AREA 1 +#define PFS_ID_1AREA 3 +#define PFS_ID_2AREA 4 +#define PFS_ID_3AREA 6 +#define PFS_LABEL_AREA 7 +#define PFS_ID_PAGE PFS_ONE_PAGE * 0 + +#define PFS_BANK_LAPPED_BY 8 /* => u8 */ +#define PFS_SECTOR_PER_BANK 32 +#define PFS_INODE_DIST_MAP (PFS_BANK_LAPPED_BY * PFS_SECTOR_PER_BANK) +#define PFS_SECTOR_SIZE (PFS_INODE_SIZE_PER_PAGE/PFS_SECTOR_PER_BANK) + +typedef struct { + /* 0x00 */ s32 status; + /* 0x04 */ OSMesgQueue* queue; + /* 0x08 */ s32 channel; + /* 0x0C */ u8 id[32]; + /* 0x2C */ u8 label[32]; + /* 0x4C */ s32 version; + /* 0x50 */ s32 dir_size; + /* 0x54 */ s32 inode_table; /* block location */ + /* 0x58 */ s32 minode_table; /* mirrioring inode_table */ + /* 0x5C */ s32 dir_table; /* block location */ + /* 0x60 */ s32 inodeStartPage; /* page # */ + /* 0x64 */ u8 banks; + /* 0x65 */ u8 activebank; +} OSPfs; // size = 0x68 + +typedef struct { + /* 0x00 */ u32 file_size; /* bytes */ + /* 0x04 */ u32 game_code; + /* 0x08 */ u16 company_code; + /* 0x0C */ char ext_name[4]; + /* 0x10 */ char game_name[16]; +} OSPfsState; // size = 0x20 + +typedef union { + struct { + /* 0x00 */ u8 bank; + /* 0x01 */ u8 page; + } inode_t; + /* 0x00 */ u16 ipage; +} __OSInodeUnit; // size = 0x02 + +typedef struct { + /* 0x00 */ __OSInodeUnit inodePage[128]; +} __OSInode; // size = 0x100 + +typedef struct { + /* 0x00 */ u32 game_code; + /* 0x04 */ u16 company_code; + /* 0x06 */ __OSInodeUnit start_page; + /* 0x08 */ u8 status; + /* 0x09 */ s8 reserved; + /* 0x0A */ u16 data_sum; + /* 0x0C */ u8 ext_name[PFS_FILE_EXT_LEN]; + /* 0x10 */ u8 game_name[PFS_FILE_NAME_LEN]; +} __OSDir; // size = 0x20 + +typedef struct { + /* 0x00 */ u32 repaired; + /* 0x04 */ u32 random; + /* 0x08 */ u64 serialMid; + /* 0x10 */ u64 serialLow; + /* 0x18 */ u16 deviceid; + /* 0x1A */ u8 banks; + /* 0x1B */ u8 version; + /* 0x1C */ u16 checksum; + /* 0x1E */ u16 invertedChecksum; +} __OSPackId; // size = 0x20 + +typedef struct { + /* 0x000 */ __OSInode inode; + /* 0x100 */ u8 bank; + /* 0x101 */ u8 map[PFS_INODE_DIST_MAP]; +} __OSInodeCache; // size = 0x202 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pi.h new file mode 100644 index 000000000..855718995 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pi.h @@ -0,0 +1,83 @@ +#ifndef ULTRA64_PI_H +#define ULTRA64_PI_H + +#include "message.h" + +typedef struct { + /* 0x00 */ u32 errStatus; + /* 0x04 */ void* dramAddr; + /* 0x08 */ void* C2Addr; + /* 0x0C */ u32 sectorSize; + /* 0x10 */ u32 C1ErrNum; + /* 0x14 */ u32 C1ErrSector[4]; +} __OSBlockInfo; // size = 0x24 + +typedef struct { + /* 0x00 */ u32 cmdType; + /* 0x04 */ u16 transferMode; + /* 0x06 */ u16 blockNum; + /* 0x08 */ s32 sectorNum; + /* 0x0C */ u32 devAddr; + /* 0x10 */ u32 bmCtlShadow; + /* 0x14 */ u32 seqCtlShadow; + /* 0x18 */ __OSBlockInfo block[2]; +} __OSTranxInfo; // size = 0x60 + +typedef struct OSPiHandle { + /* 0x00 */ struct OSPiHandle* next; + /* 0x04 */ u8 type; + /* 0x05 */ u8 latency; + /* 0x06 */ u8 pageSize; + /* 0x07 */ u8 relDuration; + /* 0x08 */ u8 pulse; + /* 0x09 */ u8 domain; + /* 0x0C */ u32 baseAddress; + /* 0x10 */ u32 speed; + /* 0x14 */ __OSTranxInfo transferInfo; +} OSPiHandle; // size = 0x74 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x04 */ u32 address; +} OSPiInfo; // size = 0x08 + +typedef struct { + /* 0x00 */ u16 type; + /* 0x02 */ u8 pri; + /* 0x03 */ u8 status; + /* 0x04 */ OSMesgQueue* retQueue; +} OSIoMesgHdr; // size = 0x08 + +typedef struct { + /* 0x00 */ OSIoMesgHdr hdr; + /* 0x08 */ void* dramAddr; + /* 0x0C */ u32 devAddr; + /* 0x10 */ size_t size; + /* 0x14 */ OSPiHandle* piHandle; +} OSIoMesg; // size = 0x18 + +#define OS_READ 0 // device -> RDRAM +#define OS_WRITE 1 // device <- RDRAM +#define OS_OTHERS 2 // for disk drive transfers + +#define PI_DOMAIN1 0 +#define PI_DOMAIN2 1 + +#define OS_MESG_TYPE_LOOPBACK 10 +#define OS_MESG_TYPE_DMAREAD 11 +#define OS_MESG_TYPE_DMAWRITE 12 +#define OS_MESG_TYPE_VRETRACE 13 +#define OS_MESG_TYPE_COUNTER 14 +#define OS_MESG_TYPE_EDMAREAD 15 +#define OS_MESG_TYPE_EDMAWRITE 16 + +#define OS_MESG_PRI_NORMAL 0 +#define OS_MESG_PRI_HIGH 1 + +#define DEVICE_TYPE_CART 0 /* ROM cartridge */ +#define DEVICE_TYPE_BULK 1 /* ROM bulk */ +#define DEVICE_TYPE_64DD 2 /* 64 Disk Drive */ +#define DEVICE_TYPE_SRAM 3 /* SRAM */ +#define DEVICE_TYPE_INIT 7 /* initial value */ + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/printf.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/printf.h new file mode 100644 index 000000000..7724432f6 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/printf.h @@ -0,0 +1,33 @@ +#ifndef ULTRA64_PRINTF_H +#define ULTRA64_PRINTF_H + +#include "types.h" + +typedef struct { + /* 0x0 */ union { + /* 0x0 */ s64 ll; + /* 0x0 */ f64 ld; + } v; + /* 0x8 */ char* s; + /* 0xC */ s32 n0; + /* 0x10 */ s32 nz0; + /* 0x14 */ s32 n1; + /* 0x18 */ s32 nz1; + /* 0x1C */ s32 n2; + /* 0x20 */ s32 nz2; + /* 0x24 */ s32 prec; + /* 0x28 */ s32 width; + /* 0x2C */ u32 nchar; + /* 0x30 */ u32 flags; + /* 0x34 */ u8 qual; +} _Pft; // size = 0x38 + +typedef void* (*PrintCallback)(void*, const char*, u32); + +#define FLAGS_SPACE 1 +#define FLAGS_PLUS 2 +#define FLAGS_MINUS 4 +#define FLAGS_HASH 8 +#define FLAGS_ZERO 16 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/r4300.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/r4300.h new file mode 100644 index 000000000..7f77dd4a7 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/r4300.h @@ -0,0 +1,367 @@ +#ifndef ULTRA64_R4300_H +#define ULTRA64_R4300_H + +#ifdef _LANGUAGE_C +#include "types.h" +#define U32(x) ((u32)x) +#define C_REG(x) (x) +#else +#define U32(x) (x) +#define C_REG(x) $x +#endif + +// Segment base addresses and sizes +#define KUBASE 0 +#define KUSIZE 0x80000000 +#define K0BASE 0x80000000 +#define K0SIZE 0x20000000 +#define K1BASE 0xA0000000 +#define K1SIZE 0x20000000 +#define K2BASE 0xC0000000 +#define K2SIZE 0x20000000 + +// Exception vectors +#define SIZE_EXCVEC 0x80 // Size of an exc. vec +#define UT_VEC K0BASE // utlbmiss vector +#define R_VEC (K1BASE + 0x1FC00000) // reset vector +#define XUT_VEC (K0BASE + 0x80) // extended address tlbmiss +#define ECC_VEC (K0BASE + 0x100) // Ecc exception vector +#define E_VEC (K0BASE + 0x180) // Gen. exception vector + +// Address conversion macros +#define K0_TO_K1(x) (U32(x) | 0xA0000000) // kseg0 to kseg1 +#define K1_TO_K0(x) (U32(x) & 0x9FFFFFFF) // kseg1 to kseg0 +#define K0_TO_PHYS(x) (U32(x) & 0x1FFFFFFF) // kseg0 to physical +#define K1_TO_PHYS(x) (U32(x) & 0x1FFFFFFF) // kseg1 to physical +#define KDM_TO_PHYS(x) (U32(x) & 0x1FFFFFFF) // direct mapped to physical +#define PHYS_TO_K0(x) (U32(x) | 0x80000000) // physical to kseg0 +#define PHYS_TO_K1(x) (U32(x) | 0xA0000000) // physical to kseg1 + +// Address predicates +#define IS_KSEG0(x) (U32(x) >= K0BASE && U32(x) < K1BASE) +#define IS_KSEG1(x) (U32(x) >= K1BASE && U32(x) < K2BASE) +#define IS_KSEGDM(x) (U32(x) >= K0BASE && U32(x) < K2BASE) +#define IS_KSEG2(x) (U32(x) >= K2BASE && U32(x) < KPTE_SHDUBASE) +#define IS_KPTESEG(x) (U32(x) >= KPTE_SHDUBASE) +#define IS_KUSEG(x) (U32(x) < K0BASE) + +// TLB size constants +#define NTLBENTRIES 31 /* entry 31 is reserved by rdb */ + +#define TLBHI_VPN2MASK 0xFFFFE000 +#define TLBHI_VPN2SHIFT 13 +#define TLBHI_PIDMASK 0xFF +#define TLBHI_PIDSHIFT 0 +#define TLBHI_NPID 255 // 255 to fit in 8 bits + +#define TLBLO_PFNMASK 0x3FFFFFC0 +#define TLBLO_PFNSHIFT 6 +#define TLBLO_CACHMASK 0x38 // cache coherency algorithm +#define TLBLO_CACHSHIFT 3 +#define TLBLO_UNCACHED 0x10 // not cached +#define TLBLO_NONCOHRNT 0x18 // Cacheable non-coherent +#define TLBLO_EXLWR 0x28 // Exclusive write +#define TLBLO_D 0x4 // writeable +#define TLBLO_V 0x2 // valid bit +#define TLBLO_G 0x1 // global access bit + +#define TLBINX_PROBE 0x80000000 +#define TLBINX_INXMASK 0x3F +#define TLBINX_INXSHIFT 0 + +#define TLBRAND_RANDMASK 0x3F +#define TLBRAND_RANDSHIFT 0 + +#define TLBWIRED_WIREDMASK 0x3F + +#define TLBCTXT_BASEMASK 0xFF800000 +#define TLBCTXT_BASESHIFT 23 +#define TLBCTXT_BASEBITS 9 + +#define TLBCTXT_VPNMASK 0x7FFFF0 +#define TLBCTXT_VPNSHIFT 4 + +#define TLBPGMASK_4K 0x0 +#define TLBPGMASK_16K 0x6000 +#define TLBPGMASK_64K 0x1E000 + +/* + * Status register + */ +#define SR_CUMASK 0xF0000000 // coproc usable bits + +#define SR_CU3 0x80000000 // Coprocessor 3 usable +#define SR_CU2 0x40000000 // Coprocessor 2 usable +#define SR_CU1 0x20000000 // Coprocessor 1 usable +#define SR_CU0 0x10000000 // Coprocessor 0 usable +#define SR_RP 0x08000000 // Reduced power (quarter speed) +#define SR_FR 0x04000000 // MIPS III FP register mode +#define SR_RE 0x02000000 // Reverse endian +#define SR_ITS 0x01000000 // Instruction trace support +#define SR_BEV 0x00400000 // Use boot exception vectors +#define SR_TS 0x00200000 // TLB shutdown +#define SR_SR 0x00100000 // Soft reset occured +#define SR_CH 0x00040000 // Cache hit for last 'cache' op +#define SR_CE 0x00020000 // Create ECC +#define SR_DE 0x00010000 // ECC of parity does not cause error + +// Interrupt enable bits +// (NOTE: bits set to 1 enable the corresponding level interrupt) +#define SR_IMASK 0x0000FF00 // Interrupt mask +#define SR_IMASK8 0x00000000 // mask level 8 +#define SR_IMASK7 0x00008000 // mask level 7 +#define SR_IMASK6 0x0000C000 // mask level 6 +#define SR_IMASK5 0x0000E000 // mask level 5 +#define SR_IMASK4 0x0000F000 // mask level 4 +#define SR_IMASK3 0x0000F800 // mask level 3 +#define SR_IMASK2 0x0000FC00 // mask level 2 +#define SR_IMASK1 0x0000FE00 // mask level 1 +#define SR_IMASK0 0x0000FF00 // mask level 0 + +#define SR_IBIT8 0x00008000 // bit level 8 +#define SR_IBIT7 0x00004000 // bit level 7 +#define SR_IBIT6 0x00002000 // bit level 6 +#define SR_IBIT5 0x00001000 // bit level 5 +#define SR_IBIT4 0x00000800 // bit level 4 +#define SR_IBIT3 0x00000400 // bit level 3 +#define SR_IBIT2 0x00000200 // bit level 2 +#define SR_IBIT1 0x00000100 // bit level 1 + +#define SR_IMASKSHIFT 8 + +#define SR_KX 0x00000080 // extended-addr TLB vec in kernel +#define SR_SX 0x00000040 // xtended-addr TLB vec supervisor +#define SR_UX 0x00000020 // xtended-addr TLB vec in user mode +#define SR_KSU_MASK 0x00000018 // mode mask +#define SR_KSU_USR 0x00000010 // user mode +#define SR_KSU_SUP 0x00000008 // supervisor mode +#define SR_KSU_KER 0x00000000 // kernel mode +#define SR_ERL 0x00000004 // Error level, 1=>cache error +#define SR_EXL 0x00000002 // Exception level, 1=>exception +#define SR_IE 0x00000001 // interrupt enable, 1=>enable + +// Cause Register +#define CAUSE_BD 0x80000000 // Branch delay slot +#define CAUSE_CEMASK 0x30000000 // coprocessor error +#define CAUSE_CESHIFT 28 + +// Interrupt pending bits +#define CAUSE_IP8 0x00008000 // External level 8 pending - COMPARE +#define CAUSE_IP7 0x00004000 // External level 7 pending - INT4 +#define CAUSE_IP6 0x00002000 // External level 6 pending - INT3 +#define CAUSE_IP5 0x00001000 // External level 5 pending - INT2 +#define CAUSE_IP4 0x00000800 // External level 4 pending - INT1 +#define CAUSE_IP3 0x00000400 // External level 3 pending - INT0 +#define CAUSE_SW2 0x00000200 // Software level 2 pending +#define CAUSE_SW1 0x00000100 // Software level 1 pending + +#define CAUSE_IPMASK 0x0000FF00 // Pending interrupt mask +#define CAUSE_IPSHIFT 8 + +#define CAUSE_EXCMASK 0x0000007C // Cause code bits +#define CAUSE_EXCSHIFT 2 + +// Cause register exception codes + +#define EXC_CODE(x) ((x) << 2) + +// Hardware exception codes +#define EXC_INT EXC_CODE(0) // interrupt +#define EXC_MOD EXC_CODE(1) // TLB mod +#define EXC_RMISS EXC_CODE(2) // Read TLB Miss +#define EXC_WMISS EXC_CODE(3) // Write TLB Miss +#define EXC_RADE EXC_CODE(4) // Read Address Error +#define EXC_WADE EXC_CODE(5) // Write Address Error +#define EXC_IBE EXC_CODE(6) // Instruction Bus Error +#define EXC_DBE EXC_CODE(7) // Data Bus Error +#define EXC_SYSCALL EXC_CODE(8) // SYSCALL +#define EXC_BREAK EXC_CODE(9) // BREAKpoint +#define EXC_II EXC_CODE(10) // Illegal Instruction +#define EXC_CPU EXC_CODE(11) // CoProcessor Unusable +#define EXC_OV EXC_CODE(12) // OVerflow +#define EXC_TRAP EXC_CODE(13) // Trap exception +#define EXC_VCEI EXC_CODE(14) // Virt. Coherency on Inst. fetch +#define EXC_FPE EXC_CODE(15) // Floating Point Exception +#define EXC_WATCH EXC_CODE(23) // Watchpoint reference +#define EXC_VCED EXC_CODE(31) // Virt. Coherency on data read + +// C0_PRID Defines +#define C0_IMPMASK 0xFF00 +#define C0_IMPSHIFT 8 +#define C0_REVMASK 0xFF +#define C0_MAJREVMASK 0xF0 +#define C0_MAJREVSHIFT 4 +#define C0_MINREVMASK 0xF + +// Coprocessor 0 operations +#define C0_READI 0x1 // read ITLB entry addressed by C0_INDEX +#define C0_WRITEI 0x2 // write ITLB entry addressed by C0_INDEX +#define C0_WRITER 0x6 // write ITLB entry addressed by C0_RAND +#define C0_PROBE 0x8 // probe for ITLB entry addressed by TLBHI +#define C0_RFE 0x10 // restore for exception + +// 'cache' instruction definitions + +// Target cache +#define CACH_PI 0x0 // specifies primary inst. cache +#define CACH_PD 0x1 // primary data cache +#define CACH_SI 0x2 // secondary instruction cache +#define CACH_SD 0x3 // secondary data cache + +// Cache operations +#define C_IINV 0x0 // index invalidate (inst, 2nd inst) +#define C_IWBINV 0x0 // index writeback inval (d, sd) +#define C_ILT 0x4 // index load tag (all) +#define C_IST 0x8 // index store tag (all) +#define C_CDX 0xC // create dirty exclusive (d, sd) +#define C_HINV 0x10 // hit invalidate (all) +#define C_HWBINV 0x14 // hit writeback inv. (d, sd) +#define C_FILL 0x14 // fill (i) +#define C_HWB 0x18 // hit writeback (i, d, sd) +#define C_HSV 0x1C // hit set virt. (si, sd) + +// Cache size definitions +#define ICACHE_SIZE 0x4000 // 16K +#define ICACHE_LINESIZE 32 // 8 words +#define ICACHE_LINEMASK (ICACHE_LINESIZE - 1) + +#define DCACHE_SIZE 0x2000 // 8K +#define DCACHE_LINESIZE 16 // 4 words +#define DCACHE_LINEMASK (DCACHE_LINESIZE - 1) + +// C0_CONFIG register definitions +#define CONFIG_CM 0x80000000 // 1 == Master-Checker enabled +#define CONFIG_EC 0x70000000 // System Clock ratio +#define CONFIG_EC_1_1 0x6 // System Clock ratio 1 :1 +#define CONFIG_EC_3_2 0x7 // System Clock ratio 1.5 :1 +#define CONFIG_EC_2_1 0x0 // System Clock ratio 2 :1 +#define CONFIG_EC_3_1 0x1 // System Clock ratio 3 :1 +#define CONFIG_EP 0x0F000000 // Transmit Data Pattern +#define CONFIG_SB 0x00C00000 // Secondary cache block size + +#define CONFIG_SS 0x00200000 // Split scache: 0 == I&D combined +#define CONFIG_SW 0x00100000 // scache port: 0==128, 1==64 +#define CONFIG_EW 0x000C0000 // System Port width: 0==64, 1==32 +#define CONFIG_SC 0x00020000 // 0 -> 2nd cache present +#define CONFIG_SM 0x00010000 // 0 -> Dirty Shared Coherency enable +#define CONFIG_BE 0x00008000 // Endian-ness: 1 --> BE +#define CONFIG_EM 0x00004000 // 1 -> ECC mode, 0 -> parity +#define CONFIG_EB 0x00002000 // Block order:1->sequent,0->subblock + +#define CONFIG_IC 0x00000E00 // Primary Icache size +#define CONFIG_DC 0x000001C0 // Primary Dcache size +#define CONFIG_IB 0x00000020 // Icache block size +#define CONFIG_DB 0x00000010 // Dcache block size +#define CONFIG_CU 0x00000008 // Update on Store-conditional +#define CONFIG_K0 0x00000007 // K0SEG Coherency algorithm + +#define CONFIG_UNCACHED 0x00000002 // K0 is uncached +#define CONFIG_NONCOHRNT 0x00000003 +#define CONFIG_COHRNT_EXLWR 0x00000005 +#define CONFIG_SB_SHFT 22 // shift SB to bit position 0 +#define CONFIG_IC_SHFT 9 // shift IC to bit position 0 +#define CONFIG_DC_SHFT 6 // shift DC to bit position 0 +#define CONFIG_BE_SHFT 15 // shift BE to bit position 0 + +// C0_TAGLO definitions for setting/getting cache states and physaddr bits +#define SADDRMASK 0xFFFFE000 // 31..13 -> scache paddr bits 35..17 +#define SVINDEXMASK 0x00000380 // 9..7: prim virt index bits 14..12 +#define SSTATEMASK 0x00001C00 // bits 12..10 hold scache line state +#define SINVALID 0x00000000 // invalid --> 000 == state 0 +#define SCLEANEXCL 0x00001000 // clean exclusive --> 100 == state 4 +#define SDIRTYEXCL 0x00001400 // dirty exclusive --> 101 == state 5 +#define SECC_MASK 0x0000007F // low 7 bits are ecc for the tag +#define SADDR_SHIFT 4 // shift STagLo (31..13) to 35..17 + +#define PADDRMASK 0xFFFFFF00 // PTagLo31..8->prim paddr bits35..12 +#define PADDR_SHIFT 4 // roll bits 35..12 down to 31..8 +#define PSTATEMASK 0x00C0 // bits 7..6 hold primary line state +#define PINVALID 0x0000 // invalid --> 000 == state 0 +#define PCLEANEXCL 0x0080 // clean exclusive --> 10 == state 2 +#define PDIRTYEXCL 0x00C0 // dirty exclusive --> 11 == state 3 +#define PPARITY_MASK 0x0001 // low bit is parity bit (even). + +// C0_CACHE_ERR definitions. +#define CACHERR_ER 0x80000000 // 0: inst ref, 1: data ref +#define CACHERR_EC 0x40000000 // 0: primary, 1: secondary +#define CACHERR_ED 0x20000000 // 1: data error +#define CACHERR_ET 0x10000000 // 1: tag error +#define CACHERR_ES 0x08000000 // 1: external ref, e.g. snoo +#define CACHERR_EE 0x04000000 // error on SysAD bus +#define CACHERR_EB 0x02000000 // complicated, see spec. +#define CACHERR_EI 0x01000000 // complicated, see spec. +#define CACHERR_SIDX_MASK 0x003FFFF8 // secondary cache index +#define CACHERR_PIDX_MASK 0x00000007 // primary cache index +#define CACHERR_PIDX_SHIFT 12 // bits 2..0 are paddr14..12 + +/* + * R4000 family supports hardware watchpoints: + * C0_WATCHLO: + * bits 31..3 are bits 31..3 of physaddr to watch + * bit 2: reserved; must be written as 0. + * bit 1: when set causes a watchpoint trap on load accesses to paddr. + * bit 0: when set traps on stores to paddr; + * C0_WATCHHI + * bits 31..4 are reserved and must be written as zeros. + * bits 3..0 are bits 35..32 of the physaddr to watch + */ +#define WATCHLO_WTRAP 0x00000001 +#define WATCHLO_RTRAP 0x00000002 +#define WATCHLO_ADDRMASK 0xFFFFFFF8 +#define WATCHLO_VALIDMASK 0xFFFFFFFB +#define WATCHHI_VALIDMASK 0x0000000F + +// Coprocessor 0 registers +#define C0_INX C_REG(0) +#define C0_RAND C_REG(1) +#define C0_ENTRYLO0 C_REG(2) +#define C0_ENTRYLO1 C_REG(3) +#define C0_CONTEXT C_REG(4) +#define C0_PAGEMASK C_REG(5) // page mask +#define C0_WIRED C_REG(6) // # wired entries in tlb +#define C0_BADVADDR C_REG(8) +#define C0_COUNT C_REG(9) // free-running counter +#define C0_ENTRYHI C_REG(10) +#define C0_COMPARE C_REG(11) // counter comparison reg. +#define C0_SR C_REG(12) +#define C0_CAUSE C_REG(13) +#define C0_EPC C_REG(14) +#define C0_PRID C_REG(15) // revision identifier +#define C0_CONFIG C_REG(16) // hardware configuration +#define C0_LLADDR C_REG(17) // load linked address +#define C0_WATCHLO C_REG(18) // watchpoint +#define C0_WATCHHI C_REG(19) // watchpoint +#define C0_ECC C_REG(26) // S-cache ECC and primary parity +#define C0_CACHE_ERR C_REG(27) // cache error status +#define C0_TAGLO C_REG(28) // cache operations +#define C0_TAGHI C_REG(29) // cache operations +#define C0_ERROR_EPC C_REG(30) // ECC error prg. counter + +// floating-point status register +#define C1_FPCSR C_REG(31) + +#define FPCSR_FS 0x01000000 // flush denorm to zero +#define FPCSR_C 0x00800000 // condition bit +#define FPCSR_CE 0x00020000 // cause: unimplemented operation +#define FPCSR_CV 0x00010000 // cause: invalid operation +#define FPCSR_CZ 0x00008000 // cause: division by zero +#define FPCSR_CO 0x00004000 // cause: overflow +#define FPCSR_CU 0x00002000 // cause: underflow +#define FPCSR_CI 0x00001000 // cause: inexact operation +#define FPCSR_EV 0x00000800 // enable: invalid operation +#define FPCSR_EZ 0x00000400 // enable: division by zero +#define FPCSR_EO 0x00000200 // enable: overflow +#define FPCSR_EU 0x00000100 // enable: underflow +#define FPCSR_EI 0x00000080 // enable: inexact operation +#define FPCSR_FV 0x00000040 // flag: invalid operation +#define FPCSR_FZ 0x00000020 // flag: division by zero +#define FPCSR_FO 0x00000010 // flag: overflow +#define FPCSR_FU 0x00000008 // flag: underflow +#define FPCSR_FI 0x00000004 // flag: inexact operation +#define FPCSR_RM_MASK 0x00000003 // rounding mode mask +#define FPCSR_RM_RN 0x00000000 // round to nearest +#define FPCSR_RM_RZ 0x00000001 // round to zero +#define FPCSR_RM_RP 0x00000002 // round to positive infinity +#define FPCSR_RM_RM 0x00000003 // round to negative infinity + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rcp.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rcp.h new file mode 100644 index 000000000..c68232fa0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rcp.h @@ -0,0 +1,95 @@ +#ifndef ULTRA64_RCP_H +#define ULTRA64_RCP_H + +#define HW_REG(reg, type) *(volatile type*)((reg) | 0xA0000000) + +#define AI_DRAM_ADDR_REG 0x04500000 +#define AI_LEN_REG 0x04500004 +#define AI_CONTROL_REG 0x04500008 +#define AI_STATUS_REG 0x0450000C +#define AI_DACRATE_REG 0x04500010 +#define AI_BITRATE_REG 0x04500014 + +#define AI_STATUS_AI_FULL (1 << 31) +#define AI_STATUS_AI_BUSY (1 << 30) + +#define VI_STATUS_REG 0x04400000 +#define VI_CONTROL_REG VI_STATUS_REG +#define VI_ORIGIN_REG 0x04400004 +#define VI_DRAM_ADDR_REG VI_ORIGIN_REG +#define VI_WIDTH_REG 0x04400008 +#define VI_H_WIDTH_REG VI_WIDTH_REG +#define VI_INTR_REG 0x0440000C +#define VI_V_INTER_REG VI_H_WIDTH_REG +#define VI_CURRENT_REG 0x04400010 +#define VI_V_CURRENT_LINE_REG VI_CURRENT_REG +#define VI_BURST_REG 0x04400014 +#define VI_TIMING_REG VI_BURST_REG +#define VI_V_SYNC_REG 0x04400018 //VI vertical sync +#define VI_H_SYNC_REG 0x0440001C //VI horizontal sync +#define VI_LEAP_REG 0x04400020 //VI horizontal sync leap +#define VI_H_SYNC_LEAP_REG VI_LEAP_REG +#define VI_H_START_REG 0x04400024 //VI horizontal video +#define VI_H_VIDEO_REG VI_H_START_REG +#define VI_V_START_REG 0x04400028 //VI vertical video +#define VI_V_VIDEO_REG VI_V_START_REG +#define VI_V_BURST_REG 0x0440002C //VI vertical burst +#define VI_X_SCALE_REG 0x04400030 //VI x-scale +#define VI_Y_SCALE_REG 0x04400034 //VI y-scale + +#define SP_IMEM_START 0x04001000 +#define SP_DMEM_START 0x04000000 + +#define SP_MEM_ADDR_REG 0x04040000 +#define SP_DRAM_ADDR_REG 0x04040004 +#define SP_RD_LEN_REG 0x04040008 +#define SP_WR_LEN_REG 0x0404000C +#define SP_STATUS_REG 0x04040010 +#define SP_PC_REG 0x04080000 + +#define PI_DRAM_ADDR_REG 0x04600000 //PI DRAM address +#define PI_CART_ADDR_REG 0x04600004 //PI pbus (cartridge) address +#define PI_RD_LEN_REG 0x04600008 //PI read length +#define PI_WR_LEN_REG 0x0460000C //PI write length +#define PI_STATUS_REG 0x04600010 //PI status +#define PI_BSD_DOM1_LAT_REG 0x04600014 //PI dom1 latency +#define PI_DOMAIN1_REG 0x04600014 +#define PI_BSD_DOM1_PWD_REG 0x04600018 //PI dom1 pulse width +#define PI_BSD_DOM1_PGS_REG 0x0460001C //PI dom1 page size +#define PI_BSD_DOM1_RLS_REG 0x04600020 //PI dom1 release +#define PI_BSD_DOM2_LAT_REG 0x04600024 //PI dom2 latency +#define PI_DOMAIN2_REG 0x04600024 +#define PI_BSD_DOM2_PWD_REG 0x04600028 //PI dom2 pulse width +#define PI_BSD_DOM2_PGS_REG 0x0460002C //PI dom2 page size +#define PI_BSD_DOM2_RLS_REG 0x04600030 //PI dom2 release + +#define PI_STATUS_BUSY 0x1 +#define PI_STATUS_IOBUSY 0x2 +#define PI_STATUS_ERROR 0x4 + +#define PI_STATUS_RESET_CONTROLLER 0x1 +#define PI_STATUS_CLEAR_INTR 0x2 + +#define SI_DRAM_ADDR_REG 0x04800000 +#define SI_PIF_ADDR_RD64B_REG 0x04800004 +#define SI_PIF_ADDR_WR64B_REG 0x04800010 +#define SI_STATUS_REG 0x04800018 + +#define SI_STATUS_DMA_BUSY 0x1 +#define SI_STATUS_IO_READ_BUSY 0x2 +#define SI_STATUS_DMA_ERROR 0x8 +#define SI_STATUS_INTERRUPT (1 << 12) + +#define PIF_RAM_START 0x1FC007C0 + +#define MI_INIT_MODE_REG 0x04300000 +#define MI_MODE_REG MI_INIT_MODE_REG +#define MI_VERSION_REG 0x04300004 +#define MI_INTR_REG 0x04300008 +#define MI_INTR_MASK_REG 0x0430000C + +#define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */ +#define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */ +#define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */ + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rdp.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rdp.h new file mode 100644 index 000000000..8729a3fa8 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rdp.h @@ -0,0 +1,51 @@ +#ifndef ULTRA64_RDP_H +#define ULTRA64_RDP_H + +/* DP Command Registers */ + +#define DPC_REG_BASE 0xA4100000 + +#define DPC_START_REG (*(vu32*)(DPC_REG_BASE + 0x00)) +#define DPC_END_REG (*(vu32*)(DPC_REG_BASE + 0x04)) +#define DPC_CURRENT_REG (*(vu32*)(DPC_REG_BASE + 0x08)) +#define DPC_STATUS_REG (*(vu32*)(DPC_REG_BASE + 0x0C)) +#define DPC_CLOCK_REG (*(vu32*)(DPC_REG_BASE + 0x10)) +#define DPC_BUFBUSY_REG (*(vu32*)(DPC_REG_BASE + 0x14)) +#define DPC_PIPEBUSY_REG (*(vu32*)(DPC_REG_BASE + 0x18)) +#define DPC_TMEM_REG (*(vu32*)(DPC_REG_BASE + 0x1C)) + +/* DP Span Registers */ + +#define DPS_REG_BASE 0xA4200000 + +#define DPS_TBIST_REG (*(vu32*)(DPS_REG_BASE + 0x00)) +#define DPS_TEST_MODE_REG (*(vu32*)(DPS_REG_BASE + 0x04)) +#define DPS_BUFTEST_ADDR_REG (*(vu32*)(DPS_REG_BASE + 0x08)) +#define DPS_BUFTEST_DATA_REG (*(vu32*)(DPS_REG_BASE + 0x0C)) + +/* DP Status Read Flags */ +#define DPC_STATUS_XBUS_DMEM_DMA 0x001 +#define DPC_STATUS_FREEZE 0x002 +#define DPC_STATUS_FLUSH 0x004 +#define DPC_STATUS_START_GCLK 0x008 +#define DPC_STATUS_TMEM_BUSY 0x010 +#define DPC_STATUS_PIPE_BUSY 0x020 +#define DPC_STATUS_CMD_BUSY 0x040 +#define DPC_STATUS_CBUF_READY 0x080 +#define DPC_STATUS_DMA_BUSY 0x100 +#define DPC_STATUS_END_VALID 0x200 +#define DPC_STATUS_START_VALID 0x400 + +/* DP Status Write Flags */ +#define DPC_CLR_XBUS_DMEM_DMA 0x0001 +#define DPC_SET_XBUS_DMEM_DMA 0x0002 +#define DPC_CLR_FREEZE 0x0004 +#define DPC_SET_FREEZE 0x0008 +#define DPC_CLR_FLUSH 0x0010 +#define DPC_SET_FLUSH 0x0020 +#define DPC_CLR_TMEM_CTR 0x0040 +#define DPC_CLR_PIPE_CTR 0x0080 +#define DPC_CLR_CMD_CTR 0x0100 +#define DPC_CLR_CLOCK_CTR 0x0200 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rsp.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rsp.h new file mode 100644 index 000000000..dcc9dadc7 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rsp.h @@ -0,0 +1,50 @@ +#ifndef ULTRA64_RSP_H +#define ULTRA64_RSP_H + +/* SP Status Flags */ +#define SP_STATUS_HALT 0x001 +#define SP_STATUS_BROKE 0x002 +#define SP_STATUS_DMA_BUSY 0x004 +#define SP_STATUS_DMA_FULL 0x008 +#define SP_STATUS_IO_FULL 0x010 +#define SP_STATUS_SSTEP 0x020 +#define SP_STATUS_INTR_BREAK 0x040 +#define SP_STATUS_YIELD 0x080 +#define SP_STATUS_YIELDED 0x100 +#define SP_STATUS_TASKDONE 0x200 +//#define SP_STATUS_SIG0 0x080 +//#define SP_STATUS_SIG1 0x100 +//#define SP_STATUS_SIG2 0x200 +#define SP_STATUS_SIG3 0x400 +#define SP_STATUS_SIG4 0x800 +#define SP_STATUS_SIG5 0x1000 +#define SP_STATUS_SIG6 0x2000 +#define SP_STATUS_SIG7 0x4000 + +#define SP_CLR_HALT 0x00001 +#define SP_SET_HALT 0x00002 +#define SP_CLR_BROKE 0x00004 +#define SP_CLR_INTR 0x00008 +#define SP_SET_INTR 0x00010 +#define SP_CLR_SSTEP 0x00020 +#define SP_SET_SSTEP 0x00040 +#define SP_CLR_INTR_BREAK 0x00080 +#define SP_SET_INTR_BREAK 0x00100 +#define SP_CLR_SIG0 0x00200 +#define SP_SET_SIG0 0x00400 +#define SP_CLR_SIG1 0x00800 +#define SP_SET_SIG1 0x01000 +#define SP_CLR_SIG2 0x02000 +#define SP_SET_SIG2 0x04000 +#define SP_CLR_SIG3 0x08000 +#define SP_SET_SIG3 0x10000 +#define SP_CLR_SIG4 0x20000 +#define SP_SET_SIG4 0x40000 +#define SP_CLR_SIG5 0x80000 +#define SP_SET_SIG5 0x100000 +#define SP_CLR_SIG6 0x200000 +#define SP_SET_SIG6 0x400000 +#define SP_CLR_SIG7 0x800000 +#define SP_SET_SIG7 0x1000000 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/sptask.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/sptask.h new file mode 100644 index 000000000..06b4f7709 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/sptask.h @@ -0,0 +1,68 @@ +#ifndef ULTRA64_SPTASK_H +#define ULTRA64_SPTASK_H + +#include "types.h" + +/* Task Types */ +#define M_NULTASK 0 +#define M_GFXTASK 1 +#define M_AUDTASK 2 +#define M_VIDTASK 3 +#define M_NJPEGTASK 4 +#define M_HVQTASK 6 +#define M_HVQMTASK 7 + +/* Task Flags */ +#define M_TASK_FLAG0 1 +#define M_TASK_FLAG1 2 + +/* Task Flag Fields */ +#define OS_TASK_YIELDED 0x0001 +#define OS_TASK_DP_WAIT 0x0002 +#define OS_TASK_LOADABLE 0x0004 +#define OS_TASK_SP_ONLY 0x0008 +#define OS_TASK_USR0 0x0010 +#define OS_TASK_USR1 0x0020 +#define OS_TASK_USR2 0x0040 +#define OS_TASK_USR3 0x0080 + +#define OS_YIELD_DATA_SIZE 0xC00 + +typedef struct { + /* 0x00 */ u32 type; + /* 0x04 */ u32 flags; + + /* 0x08 */ u64* ucode_boot; + /* 0x0C */ u32 ucode_boot_size; + + /* 0x10 */ u64* ucode; + /* 0x14 */ u32 ucode_size; + + /* 0x18 */ u64* ucode_data; + /* 0x1C */ u32 ucode_data_size; + + /* 0x20 */ u64* dram_stack; + /* 0x24 */ u32 dram_stack_size; + + /* 0x28 */ u64* output_buff; + /* 0x2C */ u64* output_buff_size; + + /* 0x30 */ u64* data_ptr; + /* 0x34 */ u32 data_size; + + /* 0x38 */ u64* yield_data_ptr; + /* 0x3C */ u32 yield_data_size; +} OSTask_t; // size = 0x40 + +typedef union { + OSTask_t t; + long long int force_structure_alignment; +} OSTask; + +typedef u32 OSYieldResult; + +#define osSpTaskStart(p) \ + osSpTaskLoad(p); \ + osSpTaskStartGo(p); + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/thread.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/thread.h new file mode 100644 index 000000000..69cbc775f --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/thread.h @@ -0,0 +1,64 @@ +#ifndef ULTRA64_THREAD_H +#define ULTRA64_THREAD_H + +#include "types.h" + +#define OS_PRIORITY_MAX 255 +#define OS_PRIORITY_VIMGR 254 +#define OS_PRIORITY_RMON 250 +#define OS_PRIORITY_RMONSPIN 200 +#define OS_PRIORITY_PIMGR 150 +#define OS_PRIORITY_SIMGR 140 +#define OS_PRIORITY_APPMAX 127 +#define OS_PRIORITY_IDLE 0 + +#define OS_STATE_STOPPED 1 +#define OS_STATE_RUNNABLE 2 +#define OS_STATE_RUNNING 4 +#define OS_STATE_WAITING 8 + +#define OS_FLAG_CPU_BREAK 1 +#define OS_FLAG_FAULT 2 + +typedef s32 OSPri; +typedef s32 OSId; + +typedef union { + struct { + /* 0x00 */ f32 f_odd; + /* 0x04 */ f32 f_even; + } f; +} __OSfp; // size = 0x08 + +typedef struct { + /* 0x000 */ u64 at, v0, v1, a0, a1, a2, a3; + /* 0x038 */ u64 t0, t1, t2, t3, t4, t5, t6, t7; + /* 0x078 */ u64 s0, s1, s2, s3, s4, s5, s6, s7; + /* 0x0B8 */ u64 t8, t9, gp, sp, s8, ra; + /* 0x0E8 */ u64 lo, hi; + /* 0x0F8 */ u32 sr, pc, cause, badvaddr, rcp; + /* 0x10C */ u32 fpcsr; + /* 0x110 */ __OSfp fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14; + /* 0x150 */ __OSfp fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30; +} __OSThreadContext; // size = 0x190 + +typedef struct { + /* 0x00 */ u32 flag; + /* 0x04 */ u32 count; + /* 0x08 */ u64 time; +} __OSThreadprofile; // size = 0x10 + +typedef struct OSThread { + /* 0x00 */ struct OSThread* next; + /* 0x04 */ OSPri priority; + /* 0x08 */ struct OSThread** queue; + /* 0x0C */ struct OSThread* tlnext; + /* 0x10 */ u16 state; + /* 0x12 */ u16 flags; + /* 0x14 */ OSId id; + /* 0x18 */ s32 fp; + /* 0x1C */ __OSThreadprofile* thprof; + /* 0x20 */ __OSThreadContext context; +} OSThread; // size = 0x1B0 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/time.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/time.h new file mode 100644 index 000000000..5c6650b7d --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/time.h @@ -0,0 +1,17 @@ +#ifndef ULTRA64_TIME_H +#define ULTRA64_TIME_H + +#include "message.h" + +typedef u64 OSTime; + +typedef struct OSTimer { + /* 0x00 */ struct OSTimer* next; + /* 0x04 */ struct OSTimer* prev; + /* 0x08 */ OSTime interval; + /* 0x10 */ OSTime value; + /* 0x18 */ OSMesgQueue* mq; + /* 0x1C */ OSMesg msg; +} OSTimer; // size = 0x20 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/types.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/types.h new file mode 100644 index 000000000..96ccc37d0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/types.h @@ -0,0 +1,54 @@ +#ifndef ULTRA64_TYPES_H +#define ULTRA64_TYPES_H + +#include + +typedef signed char s8; +typedef unsigned char u8; +typedef signed short int s16; +typedef unsigned short int u16; +typedef signed int s32; +typedef unsigned int u32; +typedef signed long long int s64; +typedef unsigned long long int u64; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; + +typedef float f32; +typedef double f64; +#if 0 + +typedef s32 ptrdiff_t; +typedef s32 intptr_t; +typedef u32 uintptr_t; +#endif + +typedef int Mtx_t[4][4]; +typedef union { + Mtx_t m; + struct { + u16 intPart[4][4]; + u16 fracPart[4][4]; + }; + long long int forc_structure_alignment; +} Mtx; + +typedef float MtxF_t[4][4]; +typedef union { + MtxF_t mf; + struct { + float xx, yx, zx, wx, + xy, yy, zy, wy, + xz, yz, zz, wz, + xw, yw, zw, ww; + }; +} MtxF; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/vi.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/vi.h new file mode 100644 index 000000000..f54bb3b65 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/vi.h @@ -0,0 +1,137 @@ +#ifndef ULTRA64_VI_H +#define ULTRA64_VI_H + +#include "message.h" + +/* Special Features */ +#define OS_VI_GAMMA_ON 0x0001 +#define OS_VI_GAMMA_OFF 0x0002 +#define OS_VI_GAMMA_DITHER_ON 0x0004 +#define OS_VI_GAMMA_DITHER_OFF 0x0008 +#define OS_VI_DIVOT_ON 0x0010 +#define OS_VI_DIVOT_OFF 0x0020 +#define OS_VI_DITHER_FILTER_ON 0x0040 +#define OS_VI_DITHER_FILTER_OFF 0x0080 + +#define OS_VI_GAMMA 0x08 +#define OS_VI_GAMMA_DITHER 0x04 +#define OS_VI_DIVOT 0x10 +#define OS_VI_DITHER_FILTER 0x10000 +#define OS_VI_UNK1 0x1 +#define OS_VI_UNK2 0x2 +#define OS_VI_UNK40 0x40 +#define OS_VI_UNK100 0x100 +#define OS_VI_UNK200 0x200 +#define OS_VI_UNK1000 0x1000 +#define OS_VI_UNK2000 0x2000 + +typedef struct { + /* 0x00 */ u32 ctrl; + /* 0x04 */ u32 width; + /* 0x08 */ u32 burst; + /* 0x0C */ u32 vSync; + /* 0x10 */ u32 hSync; + /* 0x14 */ u32 leap; + /* 0x18 */ u32 hStart; + /* 0x1C */ u32 xScale; + /* 0x20 */ u32 vCurrent; +} OSViCommonRegs; // size = 0x20 + +typedef struct { + /* 0x00 */ u32 origin; + /* 0x04 */ u32 yScale; + /* 0x08 */ u32 vStart; + /* 0x0C */ u32 vBurst; + /* 0x10 */ u32 vIntr; +} OSViFieldRegs; // size = 0x14 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x04 */ OSViCommonRegs comRegs; + /* 0x24 */ OSViFieldRegs fldRegs[2]; +} OSViMode; // size = 0x4C + +typedef struct { + /* 0x0 */ f32 factor; + /* 0x4 */ u16 offset; + /* 0x8 */ u32 scale; +} __OSViScale; // size = 0x0C + +typedef struct { + /* 0x00 */ u16 state; + /* 0x02 */ u16 retraceCount; + /* 0x04 */ void* buffer; + /* 0x08 */ OSViMode* modep; + /* 0x0C */ u32 features; + /* 0x10 */ OSMesgQueue* mq; + /* 0x14 */ OSMesg* msg; + /* 0x18 */ __OSViScale x; + /* 0x24 */ __OSViScale y; +} OSViContext; // size = 0x30 + +#define OS_VI_NTSC_LPN1 0 /* NTSC */ +#define OS_VI_NTSC_LPF1 1 +#define OS_VI_NTSC_LAN1 2 +#define OS_VI_NTSC_LAF1 3 +#define OS_VI_NTSC_LPN2 4 +#define OS_VI_NTSC_LPF2 5 +#define OS_VI_NTSC_LAN2 6 +#define OS_VI_NTSC_LAF2 7 +#define OS_VI_NTSC_HPN1 8 +#define OS_VI_NTSC_HPF1 9 +#define OS_VI_NTSC_HAN1 10 +#define OS_VI_NTSC_HAF1 11 +#define OS_VI_NTSC_HPN2 12 +#define OS_VI_NTSC_HPF2 13 + +#define OS_VI_PAL_LPN1 14 /* PAL */ +#define OS_VI_PAL_LPF1 15 +#define OS_VI_PAL_LAN1 16 +#define OS_VI_PAL_LAF1 17 +#define OS_VI_PAL_LPN2 18 +#define OS_VI_PAL_LPF2 19 +#define OS_VI_PAL_LAN2 20 +#define OS_VI_PAL_LAF2 21 +#define OS_VI_PAL_HPN1 22 +#define OS_VI_PAL_HPF1 23 +#define OS_VI_PAL_HAN1 24 +#define OS_VI_PAL_HAF1 25 +#define OS_VI_PAL_HPN2 26 +#define OS_VI_PAL_HPF2 27 + +#define OS_VI_MPAL_LPN1 28 /* MPAL - mainly Brazil */ +#define OS_VI_MPAL_LPF1 29 +#define OS_VI_MPAL_LAN1 30 +#define OS_VI_MPAL_LAF1 31 +#define OS_VI_MPAL_LPN2 32 +#define OS_VI_MPAL_LPF2 33 +#define OS_VI_MPAL_LAN2 34 +#define OS_VI_MPAL_LAF2 35 +#define OS_VI_MPAL_HPN1 36 +#define OS_VI_MPAL_HPF1 37 +#define OS_VI_MPAL_HAN1 38 +#define OS_VI_MPAL_HAF1 39 +#define OS_VI_MPAL_HPN2 40 +#define OS_VI_MPAL_HPF2 41 + +#define OS_VI_FPAL_LPN1 42 /* FPAL - Full screen PAL */ +#define OS_VI_FPAL_LPF1 43 +#define OS_VI_FPAL_LAN1 44 +#define OS_VI_FPAL_LAF1 45 +#define OS_VI_FPAL_LPN2 46 +#define OS_VI_FPAL_LPF2 47 +#define OS_VI_FPAL_LAN2 48 +#define OS_VI_FPAL_LAF2 49 +#define OS_VI_FPAL_HPN1 50 +#define OS_VI_FPAL_HPF1 51 +#define OS_VI_FPAL_HAN1 52 +#define OS_VI_FPAL_HAF1 53 +#define OS_VI_FPAL_HPN2 54 +#define OS_VI_FPAL_HPF2 55 + +#define OS_TV_PAL 0 +#define OS_TV_NTSC 1 +#define OS_TV_MPAL 2 +#define OS_VI_UNK28 28 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12.h b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12.h new file mode 100644 index 000000000..06e98dcc0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12.h @@ -0,0 +1,17258 @@ +/*------------------------------------------------------------------------------------- + * + * Copyright (c) Microsoft Corporation + * + *-------------------------------------------------------------------------------------*/ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0622 */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d12_h__ +#define __d3d12_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D12Object_FWD_DEFINED__ +#define __ID3D12Object_FWD_DEFINED__ +typedef interface ID3D12Object ID3D12Object; + +#endif /* __ID3D12Object_FWD_DEFINED__ */ + + +#ifndef __ID3D12DeviceChild_FWD_DEFINED__ +#define __ID3D12DeviceChild_FWD_DEFINED__ +typedef interface ID3D12DeviceChild ID3D12DeviceChild; + +#endif /* __ID3D12DeviceChild_FWD_DEFINED__ */ + + +#ifndef __ID3D12RootSignature_FWD_DEFINED__ +#define __ID3D12RootSignature_FWD_DEFINED__ +typedef interface ID3D12RootSignature ID3D12RootSignature; + +#endif /* __ID3D12RootSignature_FWD_DEFINED__ */ + + +#ifndef __ID3D12RootSignatureDeserializer_FWD_DEFINED__ +#define __ID3D12RootSignatureDeserializer_FWD_DEFINED__ +typedef interface ID3D12RootSignatureDeserializer ID3D12RootSignatureDeserializer; + +#endif /* __ID3D12RootSignatureDeserializer_FWD_DEFINED__ */ + + +#ifndef __ID3D12VersionedRootSignatureDeserializer_FWD_DEFINED__ +#define __ID3D12VersionedRootSignatureDeserializer_FWD_DEFINED__ +typedef interface ID3D12VersionedRootSignatureDeserializer ID3D12VersionedRootSignatureDeserializer; + +#endif /* __ID3D12VersionedRootSignatureDeserializer_FWD_DEFINED__ */ + + +#ifndef __ID3D12Pageable_FWD_DEFINED__ +#define __ID3D12Pageable_FWD_DEFINED__ +typedef interface ID3D12Pageable ID3D12Pageable; + +#endif /* __ID3D12Pageable_FWD_DEFINED__ */ + + +#ifndef __ID3D12Heap_FWD_DEFINED__ +#define __ID3D12Heap_FWD_DEFINED__ +typedef interface ID3D12Heap ID3D12Heap; + +#endif /* __ID3D12Heap_FWD_DEFINED__ */ + + +#ifndef __ID3D12Resource_FWD_DEFINED__ +#define __ID3D12Resource_FWD_DEFINED__ +typedef interface ID3D12Resource ID3D12Resource; + +#endif /* __ID3D12Resource_FWD_DEFINED__ */ + + +#ifndef __ID3D12CommandAllocator_FWD_DEFINED__ +#define __ID3D12CommandAllocator_FWD_DEFINED__ +typedef interface ID3D12CommandAllocator ID3D12CommandAllocator; + +#endif /* __ID3D12CommandAllocator_FWD_DEFINED__ */ + + +#ifndef __ID3D12Fence_FWD_DEFINED__ +#define __ID3D12Fence_FWD_DEFINED__ +typedef interface ID3D12Fence ID3D12Fence; + +#endif /* __ID3D12Fence_FWD_DEFINED__ */ + + +#ifndef __ID3D12Fence1_FWD_DEFINED__ +#define __ID3D12Fence1_FWD_DEFINED__ +typedef interface ID3D12Fence1 ID3D12Fence1; + +#endif /* __ID3D12Fence1_FWD_DEFINED__ */ + + +#ifndef __ID3D12PipelineState_FWD_DEFINED__ +#define __ID3D12PipelineState_FWD_DEFINED__ +typedef interface ID3D12PipelineState ID3D12PipelineState; + +#endif /* __ID3D12PipelineState_FWD_DEFINED__ */ + + +#ifndef __ID3D12DescriptorHeap_FWD_DEFINED__ +#define __ID3D12DescriptorHeap_FWD_DEFINED__ +typedef interface ID3D12DescriptorHeap ID3D12DescriptorHeap; + +#endif /* __ID3D12DescriptorHeap_FWD_DEFINED__ */ + + +#ifndef __ID3D12QueryHeap_FWD_DEFINED__ +#define __ID3D12QueryHeap_FWD_DEFINED__ +typedef interface ID3D12QueryHeap ID3D12QueryHeap; + +#endif /* __ID3D12QueryHeap_FWD_DEFINED__ */ + + +#ifndef __ID3D12CommandSignature_FWD_DEFINED__ +#define __ID3D12CommandSignature_FWD_DEFINED__ +typedef interface ID3D12CommandSignature ID3D12CommandSignature; + +#endif /* __ID3D12CommandSignature_FWD_DEFINED__ */ + + +#ifndef __ID3D12CommandList_FWD_DEFINED__ +#define __ID3D12CommandList_FWD_DEFINED__ +typedef interface ID3D12CommandList ID3D12CommandList; + +#endif /* __ID3D12CommandList_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList ID3D12GraphicsCommandList; + +#endif /* __ID3D12GraphicsCommandList_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList1_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList1_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList1 ID3D12GraphicsCommandList1; + +#endif /* __ID3D12GraphicsCommandList1_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList2_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList2_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList2 ID3D12GraphicsCommandList2; + +#endif /* __ID3D12GraphicsCommandList2_FWD_DEFINED__ */ + + +#ifndef __ID3D12CommandQueue_FWD_DEFINED__ +#define __ID3D12CommandQueue_FWD_DEFINED__ +typedef interface ID3D12CommandQueue ID3D12CommandQueue; + +#endif /* __ID3D12CommandQueue_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device_FWD_DEFINED__ +#define __ID3D12Device_FWD_DEFINED__ +typedef interface ID3D12Device ID3D12Device; + +#endif /* __ID3D12Device_FWD_DEFINED__ */ + + +#ifndef __ID3D12PipelineLibrary_FWD_DEFINED__ +#define __ID3D12PipelineLibrary_FWD_DEFINED__ +typedef interface ID3D12PipelineLibrary ID3D12PipelineLibrary; + +#endif /* __ID3D12PipelineLibrary_FWD_DEFINED__ */ + + +#ifndef __ID3D12PipelineLibrary1_FWD_DEFINED__ +#define __ID3D12PipelineLibrary1_FWD_DEFINED__ +typedef interface ID3D12PipelineLibrary1 ID3D12PipelineLibrary1; + +#endif /* __ID3D12PipelineLibrary1_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device1_FWD_DEFINED__ +#define __ID3D12Device1_FWD_DEFINED__ +typedef interface ID3D12Device1 ID3D12Device1; + +#endif /* __ID3D12Device1_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device2_FWD_DEFINED__ +#define __ID3D12Device2_FWD_DEFINED__ +typedef interface ID3D12Device2 ID3D12Device2; + +#endif /* __ID3D12Device2_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device3_FWD_DEFINED__ +#define __ID3D12Device3_FWD_DEFINED__ +typedef interface ID3D12Device3 ID3D12Device3; + +#endif /* __ID3D12Device3_FWD_DEFINED__ */ + + +#ifndef __ID3D12ProtectedSession_FWD_DEFINED__ +#define __ID3D12ProtectedSession_FWD_DEFINED__ +typedef interface ID3D12ProtectedSession ID3D12ProtectedSession; + +#endif /* __ID3D12ProtectedSession_FWD_DEFINED__ */ + + +#ifndef __ID3D12ProtectedResourceSession_FWD_DEFINED__ +#define __ID3D12ProtectedResourceSession_FWD_DEFINED__ +typedef interface ID3D12ProtectedResourceSession ID3D12ProtectedResourceSession; + +#endif /* __ID3D12ProtectedResourceSession_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device4_FWD_DEFINED__ +#define __ID3D12Device4_FWD_DEFINED__ +typedef interface ID3D12Device4 ID3D12Device4; + +#endif /* __ID3D12Device4_FWD_DEFINED__ */ + + +#ifndef __ID3D12LifetimeOwner_FWD_DEFINED__ +#define __ID3D12LifetimeOwner_FWD_DEFINED__ +typedef interface ID3D12LifetimeOwner ID3D12LifetimeOwner; + +#endif /* __ID3D12LifetimeOwner_FWD_DEFINED__ */ + + +#ifndef __ID3D12SwapChainAssistant_FWD_DEFINED__ +#define __ID3D12SwapChainAssistant_FWD_DEFINED__ +typedef interface ID3D12SwapChainAssistant ID3D12SwapChainAssistant; + +#endif /* __ID3D12SwapChainAssistant_FWD_DEFINED__ */ + + +#ifndef __ID3D12LifetimeTracker_FWD_DEFINED__ +#define __ID3D12LifetimeTracker_FWD_DEFINED__ +typedef interface ID3D12LifetimeTracker ID3D12LifetimeTracker; + +#endif /* __ID3D12LifetimeTracker_FWD_DEFINED__ */ + + +#ifndef __ID3D12StateObject_FWD_DEFINED__ +#define __ID3D12StateObject_FWD_DEFINED__ +typedef interface ID3D12StateObject ID3D12StateObject; + +#endif /* __ID3D12StateObject_FWD_DEFINED__ */ + + +#ifndef __ID3D12StateObjectProperties_FWD_DEFINED__ +#define __ID3D12StateObjectProperties_FWD_DEFINED__ +typedef interface ID3D12StateObjectProperties ID3D12StateObjectProperties; + +#endif /* __ID3D12StateObjectProperties_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device5_FWD_DEFINED__ +#define __ID3D12Device5_FWD_DEFINED__ +typedef interface ID3D12Device5 ID3D12Device5; + +#endif /* __ID3D12Device5_FWD_DEFINED__ */ + + +#ifndef __ID3D12DeviceRemovedExtendedDataSettings_FWD_DEFINED__ +#define __ID3D12DeviceRemovedExtendedDataSettings_FWD_DEFINED__ +typedef interface ID3D12DeviceRemovedExtendedDataSettings ID3D12DeviceRemovedExtendedDataSettings; + +#endif /* __ID3D12DeviceRemovedExtendedDataSettings_FWD_DEFINED__ */ + + +#ifndef __ID3D12DeviceRemovedExtendedData_FWD_DEFINED__ +#define __ID3D12DeviceRemovedExtendedData_FWD_DEFINED__ +typedef interface ID3D12DeviceRemovedExtendedData ID3D12DeviceRemovedExtendedData; + +#endif /* __ID3D12DeviceRemovedExtendedData_FWD_DEFINED__ */ + + +#ifndef __ID3D12Device6_FWD_DEFINED__ +#define __ID3D12Device6_FWD_DEFINED__ +typedef interface ID3D12Device6 ID3D12Device6; + +#endif /* __ID3D12Device6_FWD_DEFINED__ */ + + +#ifndef __ID3D12Resource1_FWD_DEFINED__ +#define __ID3D12Resource1_FWD_DEFINED__ +typedef interface ID3D12Resource1 ID3D12Resource1; + +#endif /* __ID3D12Resource1_FWD_DEFINED__ */ + + +#ifndef __ID3D12Heap1_FWD_DEFINED__ +#define __ID3D12Heap1_FWD_DEFINED__ +typedef interface ID3D12Heap1 ID3D12Heap1; + +#endif /* __ID3D12Heap1_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList3_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList3_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3; + +#endif /* __ID3D12GraphicsCommandList3_FWD_DEFINED__ */ + + +#ifndef __ID3D12MetaCommand_FWD_DEFINED__ +#define __ID3D12MetaCommand_FWD_DEFINED__ +typedef interface ID3D12MetaCommand ID3D12MetaCommand; + +#endif /* __ID3D12MetaCommand_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList4_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList4_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList4 ID3D12GraphicsCommandList4; + +#endif /* __ID3D12GraphicsCommandList4_FWD_DEFINED__ */ + + +#ifndef __ID3D12Tools_FWD_DEFINED__ +#define __ID3D12Tools_FWD_DEFINED__ +typedef interface ID3D12Tools ID3D12Tools; + +#endif /* __ID3D12Tools_FWD_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList5_FWD_DEFINED__ +#define __ID3D12GraphicsCommandList5_FWD_DEFINED__ +typedef interface ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5; + +#endif /* __ID3D12GraphicsCommandList5_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "dxgicommon.h" +#include "dxgiformat.h" +#include "d3dcommon.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d12_0000_0000 */ +/* [local] */ + +#include +#pragma region App Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) +#ifndef _D3D12_CONSTANTS +#define _D3D12_CONSTANTS +#define D3D12_16BIT_INDEX_STRIP_CUT_VALUE ( 0xffff ) + +#define D3D12_32BIT_INDEX_STRIP_CUT_VALUE ( 0xffffffff ) + +#define D3D12_8BIT_INDEX_STRIP_CUT_VALUE ( 0xff ) + +#define D3D12_APPEND_ALIGNED_ELEMENT ( 0xffffffff ) + +#define D3D12_ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT ( 9 ) + +#define D3D12_CLIP_OR_CULL_DISTANCE_COUNT ( 8 ) + +#define D3D12_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT ( 2 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ( 14 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS ( 4 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT ( 15 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_PARTIAL_UPDATE_EXTENTS_BYTE_ALIGNMENT ( 16 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT ( 15 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_COMMONSHADER_FLOWCONTROL_NESTING_LIMIT ( 64 ) + +#define D3D12_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT ( 1 ) + +#define D3D12_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT ( 128 ) + +#define D3D12_COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT ( 128 ) + +#define D3D12_COMMONSHADER_SAMPLER_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_COMMONSHADER_SAMPLER_REGISTER_COUNT ( 16 ) + +#define D3D12_COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_COMMONSHADER_SAMPLER_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_COMMONSHADER_SAMPLER_SLOT_COUNT ( 16 ) + +#define D3D12_COMMONSHADER_SUBROUTINE_NESTING_LIMIT ( 32 ) + +#define D3D12_COMMONSHADER_TEMP_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_COMMONSHADER_TEMP_REGISTER_COUNT ( 4096 ) + +#define D3D12_COMMONSHADER_TEMP_REGISTER_READS_PER_INST ( 3 ) + +#define D3D12_COMMONSHADER_TEMP_REGISTER_READ_PORTS ( 3 ) + +#define D3D12_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX ( 10 ) + +#define D3D12_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN ( -10 ) + +#define D3D12_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE ( -8 ) + +#define D3D12_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE ( 7 ) + +#define D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT ( 256 ) + +#define D3D12_CS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 256 ) + +#define D3D12_CS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP ( 64 ) + +#define D3D12_CS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 240 ) + +#define D3D12_CS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP ( 68 ) + +#define D3D12_CS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 224 ) + +#define D3D12_CS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP ( 72 ) + +#define D3D12_CS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 208 ) + +#define D3D12_CS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP ( 76 ) + +#define D3D12_CS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 192 ) + +#define D3D12_CS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP ( 84 ) + +#define D3D12_CS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 176 ) + +#define D3D12_CS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP ( 92 ) + +#define D3D12_CS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 160 ) + +#define D3D12_CS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP ( 100 ) + +#define D3D12_CS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 144 ) + +#define D3D12_CS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP ( 112 ) + +#define D3D12_CS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 128 ) + +#define D3D12_CS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP ( 128 ) + +#define D3D12_CS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 112 ) + +#define D3D12_CS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP ( 144 ) + +#define D3D12_CS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 96 ) + +#define D3D12_CS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP ( 168 ) + +#define D3D12_CS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 80 ) + +#define D3D12_CS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP ( 204 ) + +#define D3D12_CS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 64 ) + +#define D3D12_CS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP ( 256 ) + +#define D3D12_CS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 48 ) + +#define D3D12_CS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP ( 340 ) + +#define D3D12_CS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 32 ) + +#define D3D12_CS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP ( 512 ) + +#define D3D12_CS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD ( 16 ) + +#define D3D12_CS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP ( 768 ) + +#define D3D12_CS_4_X_DISPATCH_MAX_THREAD_GROUPS_IN_Z_DIMENSION ( 1 ) + +#define D3D12_CS_4_X_RAW_UAV_BYTE_ALIGNMENT ( 256 ) + +#define D3D12_CS_4_X_THREAD_GROUP_MAX_THREADS_PER_GROUP ( 768 ) + +#define D3D12_CS_4_X_THREAD_GROUP_MAX_X ( 768 ) + +#define D3D12_CS_4_X_THREAD_GROUP_MAX_Y ( 768 ) + +#define D3D12_CS_4_X_UAV_REGISTER_COUNT ( 1 ) + +#define D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION ( 65535 ) + +#define D3D12_CS_TGSM_REGISTER_COUNT ( 8192 ) + +#define D3D12_CS_TGSM_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_CS_TGSM_RESOURCE_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_CS_TGSM_RESOURCE_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_CS_THREADGROUPID_REGISTER_COMPONENTS ( 3 ) + +#define D3D12_CS_THREADGROUPID_REGISTER_COUNT ( 1 ) + +#define D3D12_CS_THREADIDINGROUPFLATTENED_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_CS_THREADIDINGROUPFLATTENED_REGISTER_COUNT ( 1 ) + +#define D3D12_CS_THREADIDINGROUP_REGISTER_COMPONENTS ( 3 ) + +#define D3D12_CS_THREADIDINGROUP_REGISTER_COUNT ( 1 ) + +#define D3D12_CS_THREADID_REGISTER_COMPONENTS ( 3 ) + +#define D3D12_CS_THREADID_REGISTER_COUNT ( 1 ) + +#define D3D12_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP ( 1024 ) + +#define D3D12_CS_THREAD_GROUP_MAX_X ( 1024 ) + +#define D3D12_CS_THREAD_GROUP_MAX_Y ( 1024 ) + +#define D3D12_CS_THREAD_GROUP_MAX_Z ( 64 ) + +#define D3D12_CS_THREAD_GROUP_MIN_X ( 1 ) + +#define D3D12_CS_THREAD_GROUP_MIN_Y ( 1 ) + +#define D3D12_CS_THREAD_GROUP_MIN_Z ( 1 ) + +#define D3D12_CS_THREAD_LOCAL_TEMP_REGISTER_POOL ( 16384 ) + +#define D3D12_DEFAULT_BLEND_FACTOR_ALPHA ( 1.0f ) +#define D3D12_DEFAULT_BLEND_FACTOR_BLUE ( 1.0f ) +#define D3D12_DEFAULT_BLEND_FACTOR_GREEN ( 1.0f ) +#define D3D12_DEFAULT_BLEND_FACTOR_RED ( 1.0f ) +#define D3D12_DEFAULT_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D12_DEFAULT_DEPTH_BIAS ( 0 ) + +#define D3D12_DEFAULT_DEPTH_BIAS_CLAMP ( 0.0f ) +#define D3D12_DEFAULT_MAX_ANISOTROPY ( 16 ) + +#define D3D12_DEFAULT_MIP_LOD_BIAS ( 0.0f ) +#define D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT ( 4194304 ) + +#define D3D12_DEFAULT_RENDER_TARGET_ARRAY_INDEX ( 0 ) + +#define D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT ( 65536 ) + +#define D3D12_DEFAULT_SAMPLE_MASK ( 0xffffffff ) + +#define D3D12_DEFAULT_SCISSOR_ENDX ( 0 ) + +#define D3D12_DEFAULT_SCISSOR_ENDY ( 0 ) + +#define D3D12_DEFAULT_SCISSOR_STARTX ( 0 ) + +#define D3D12_DEFAULT_SCISSOR_STARTY ( 0 ) + +#define D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS ( 0.0f ) +#define D3D12_DEFAULT_STENCIL_READ_MASK ( 0xff ) + +#define D3D12_DEFAULT_STENCIL_REFERENCE ( 0 ) + +#define D3D12_DEFAULT_STENCIL_WRITE_MASK ( 0xff ) + +#define D3D12_DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX ( 0 ) + +#define D3D12_DEFAULT_VIEWPORT_HEIGHT ( 0 ) + +#define D3D12_DEFAULT_VIEWPORT_MAX_DEPTH ( 0.0f ) +#define D3D12_DEFAULT_VIEWPORT_MIN_DEPTH ( 0.0f ) +#define D3D12_DEFAULT_VIEWPORT_TOPLEFTX ( 0 ) + +#define D3D12_DEFAULT_VIEWPORT_TOPLEFTY ( 0 ) + +#define D3D12_DEFAULT_VIEWPORT_WIDTH ( 0 ) + +#define D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ( 0xffffffff ) + +#define D3D12_DRIVER_RESERVED_REGISTER_SPACE_VALUES_END ( 0xfffffff7 ) + +#define D3D12_DRIVER_RESERVED_REGISTER_SPACE_VALUES_START ( 0xfffffff0 ) + +#define D3D12_DS_INPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS ( 3968 ) + +#define D3D12_DS_INPUT_CONTROL_POINT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_DS_INPUT_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_DS_INPUT_CONTROL_POINT_REGISTER_COUNT ( 32 ) + +#define D3D12_DS_INPUT_CONTROL_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_DS_INPUT_CONTROL_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENTS ( 3 ) + +#define D3D12_DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_DS_INPUT_DOMAIN_POINT_REGISTER_COUNT ( 1 ) + +#define D3D12_DS_INPUT_DOMAIN_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_DS_INPUT_DOMAIN_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_DS_INPUT_PATCH_CONSTANT_REGISTER_COUNT ( 32 ) + +#define D3D12_DS_INPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_DS_INPUT_PATCH_CONSTANT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_DS_INPUT_PRIMITIVE_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_DS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_DS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_DS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_DS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_DS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_FLOAT16_FUSED_TOLERANCE_IN_ULP ( 0.6 ) +#define D3D12_FLOAT32_MAX ( 3.402823466e+38f ) +#define D3D12_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP ( 0.6f ) +#define D3D12_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR ( 2.4f ) +#define D3D12_FLOAT_TO_SRGB_EXPONENT_NUMERATOR ( 1.0f ) +#define D3D12_FLOAT_TO_SRGB_OFFSET ( 0.055f ) +#define D3D12_FLOAT_TO_SRGB_SCALE_1 ( 12.92f ) +#define D3D12_FLOAT_TO_SRGB_SCALE_2 ( 1.055f ) +#define D3D12_FLOAT_TO_SRGB_THRESHOLD ( 0.0031308f ) +#define D3D12_FTOI_INSTRUCTION_MAX_INPUT ( 2147483647.999f ) +#define D3D12_FTOI_INSTRUCTION_MIN_INPUT ( -2147483648.999f ) +#define D3D12_FTOU_INSTRUCTION_MAX_INPUT ( 4294967295.999f ) +#define D3D12_FTOU_INSTRUCTION_MIN_INPUT ( 0.0f ) +#define D3D12_GS_INPUT_INSTANCE_ID_READS_PER_INST ( 2 ) + +#define D3D12_GS_INPUT_INSTANCE_ID_READ_PORTS ( 1 ) + +#define D3D12_GS_INPUT_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_GS_INPUT_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_GS_INPUT_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_GS_INPUT_PRIM_CONST_REGISTER_COUNT ( 1 ) + +#define D3D12_GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_GS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_GS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_GS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_GS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_GS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_GS_INPUT_REGISTER_VERTICES ( 32 ) + +#define D3D12_GS_MAX_INSTANCE_COUNT ( 32 ) + +#define D3D12_GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES ( 1024 ) + +#define D3D12_GS_OUTPUT_ELEMENTS ( 32 ) + +#define D3D12_GS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_GS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_HS_CONTROL_POINT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_HS_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_CONTROL_POINT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_CONTROL_POINT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_FORK_PHASE_INSTANCE_COUNT_UPPER_BOUND ( 0xffffffff ) + +#define D3D12_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_INPUT_FORK_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_HS_INPUT_FORK_INSTANCE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_INPUT_FORK_INSTANCE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_INPUT_PRIMITIVE_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_HS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_JOIN_PHASE_INSTANCE_COUNT_UPPER_BOUND ( 0xffffffff ) + +#define D3D12_HS_MAXTESSFACTOR_LOWER_BOUND ( 1.0f ) +#define D3D12_HS_MAXTESSFACTOR_UPPER_BOUND ( 64.0f ) +#define D3D12_HS_OUTPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS ( 3968 ) + +#define D3D12_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COUNT ( 1 ) + +#define D3D12_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT ( 32 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_HS_OUTPUT_PATCH_CONSTANT_REGISTER_SCALAR_COMPONENTS ( 128 ) + +#define D3D12_IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D12_IA_DEFAULT_PRIMITIVE_TOPOLOGY ( 0 ) + +#define D3D12_IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES ( 0 ) + +#define D3D12_IA_INDEX_INPUT_RESOURCE_SLOT_COUNT ( 1 ) + +#define D3D12_IA_INSTANCE_ID_BIT_COUNT ( 32 ) + +#define D3D12_IA_INTEGER_ARITHMETIC_BIT_COUNT ( 32 ) + +#define D3D12_IA_PATCH_MAX_CONTROL_POINT_COUNT ( 32 ) + +#define D3D12_IA_PRIMITIVE_ID_BIT_COUNT ( 32 ) + +#define D3D12_IA_VERTEX_ID_BIT_COUNT ( 32 ) + +#define D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ( 32 ) + +#define D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS ( 128 ) + +#define D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ( 32 ) + +#define D3D12_INTEGER_DIVIDE_BY_ZERO_QUOTIENT ( 0xffffffff ) + +#define D3D12_INTEGER_DIVIDE_BY_ZERO_REMAINDER ( 0xffffffff ) + +#define D3D12_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL ( 0xffffffff ) + +#define D3D12_KEEP_UNORDERED_ACCESS_VIEWS ( 0xffffffff ) + +#define D3D12_LINEAR_GAMMA ( 1.0f ) +#define D3D12_MAJOR_VERSION ( 12 ) + +#define D3D12_MAX_BORDER_COLOR_COMPONENT ( 1.0f ) +#define D3D12_MAX_DEPTH ( 1.0f ) +#define D3D12_MAX_LIVE_STATIC_SAMPLERS ( 2032 ) + +#define D3D12_MAX_MAXANISOTROPY ( 16 ) + +#define D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT ( 32 ) + +#define D3D12_MAX_POSITION_VALUE ( 3.402823466e+34f ) +#define D3D12_MAX_ROOT_COST ( 64 ) + +#define D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1 ( 1000000 ) + +#define D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_2 ( 1000000 ) + +#define D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE ( 2048 ) + +#define D3D12_MAX_TEXTURE_DIMENSION_2_TO_EXP ( 17 ) + +#define D3D12_MAX_VIEW_INSTANCE_COUNT ( 4 ) + +#define D3D12_MINOR_VERSION ( 0 ) + +#define D3D12_MIN_BORDER_COLOR_COMPONENT ( 0.0f ) +#define D3D12_MIN_DEPTH ( 0.0f ) +#define D3D12_MIN_MAXANISOTROPY ( 0 ) + +#define D3D12_MIP_LOD_BIAS_MAX ( 15.99f ) +#define D3D12_MIP_LOD_BIAS_MIN ( -16.0f ) +#define D3D12_MIP_LOD_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D12_MIP_LOD_RANGE_BIT_COUNT ( 8 ) + +#define D3D12_MULTISAMPLE_ANTIALIAS_LINE_WIDTH ( 1.4f ) +#define D3D12_NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT ( 0 ) + +#define D3D12_OS_RESERVED_REGISTER_SPACE_VALUES_END ( 0xffffffff ) + +#define D3D12_OS_RESERVED_REGISTER_SPACE_VALUES_START ( 0xfffffff8 ) + +#define D3D12_PACKED_TILE ( 0xffffffff ) + +#define D3D12_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 15 ) + +#define D3D12_PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT ( 16 ) + +#define D3D12_PS_CS_UAV_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_PS_CS_UAV_REGISTER_COUNT ( 8 ) + +#define D3D12_PS_CS_UAV_REGISTER_READS_PER_INST ( 1 ) + +#define D3D12_PS_CS_UAV_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_PS_FRONTFACING_DEFAULT_VALUE ( 0xffffffff ) + +#define D3D12_PS_FRONTFACING_FALSE_VALUE ( 0 ) + +#define D3D12_PS_FRONTFACING_TRUE_VALUE ( 0xffffffff ) + +#define D3D12_PS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_PS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_PS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_PS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_PS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.0f ) +#define D3D12_PS_OUTPUT_DEPTH_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_PS_OUTPUT_DEPTH_REGISTER_COUNT ( 1 ) + +#define D3D12_PS_OUTPUT_MASK_REGISTER_COMPONENTS ( 1 ) + +#define D3D12_PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_PS_OUTPUT_MASK_REGISTER_COUNT ( 1 ) + +#define D3D12_PS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_PS_OUTPUT_REGISTER_COUNT ( 8 ) + +#define D3D12_PS_PIXEL_CENTER_FRACTIONAL_COMPONENT ( 0.5f ) +#define D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT ( 16 ) + +#define D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT ( 8 ) + +#define D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT ( 256 ) + +#define D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT ( 16 ) + +#define D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES ( 32 ) + +#define D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH ( 31 ) + +#define D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE ( 16777216 ) + +#define D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE ( 16777216 ) + +#define D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE ( 536870912 ) + +#define D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS ( 1073741824 ) + +#define D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE ( 4096 ) + +#define D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT ( 32 ) + +#define D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT ( 64 ) + +#define D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT ( 16 ) + +#define D3D12_REQ_BLEND_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP ( 27 ) + +#define D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D12_REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D12_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D12_REQ_DRAW_VERTEX_COUNT_2_TO_EXP ( 32 ) + +#define D3D12_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION ( 16384 ) + +#define D3D12_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT ( 1024 ) + +#define D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT ( 4096 ) + +#define D3D12_REQ_MAXANISOTROPY ( 16 ) + +#define D3D12_REQ_MIP_LEVELS ( 15 ) + +#define D3D12_REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES ( 2048 ) + +#define D3D12_REQ_RASTERIZER_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D12_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH ( 16384 ) + +#define D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM ( 128 ) + +#define D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_B_TERM ( 0.25f ) +#define D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_C_TERM ( 2048 ) + +#define D3D12_REQ_RESOURCE_VIEW_COUNT_PER_DEVICE_2_TO_EXP ( 20 ) + +#define D3D12_REQ_SAMPLER_OBJECT_COUNT_PER_DEVICE ( 4096 ) + +#define D3D12_REQ_SUBRESOURCES ( 30720 ) + +#define D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION ( 2048 ) + +#define D3D12_REQ_TEXTURE1D_U_DIMENSION ( 16384 ) + +#define D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION ( 2048 ) + +#define D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION ( 16384 ) + +#define D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION ( 2048 ) + +#define D3D12_REQ_TEXTURECUBE_DIMENSION ( 16384 ) + +#define D3D12_RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL ( 0 ) + +#define D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES ( 0xffffffff ) + +#define D3D12_RS_SET_SHADING_RATE_COMBINER_COUNT ( 2 ) + +#define D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES ( 32 ) + +#define D3D12_SHADER_MAJOR_VERSION ( 5 ) + +#define D3D12_SHADER_MAX_INSTANCES ( 65535 ) + +#define D3D12_SHADER_MAX_INTERFACES ( 253 ) + +#define D3D12_SHADER_MAX_INTERFACE_CALL_SITES ( 4096 ) + +#define D3D12_SHADER_MAX_TYPES ( 65535 ) + +#define D3D12_SHADER_MINOR_VERSION ( 1 ) + +#define D3D12_SHIFT_INSTRUCTION_PAD_VALUE ( 0 ) + +#define D3D12_SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT ( 5 ) + +#define D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT ( 8 ) + +#define D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT ( 65536 ) + +#define D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT ( 4096 ) + +#define D3D12_SO_BUFFER_MAX_STRIDE_IN_BYTES ( 2048 ) + +#define D3D12_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES ( 512 ) + +#define D3D12_SO_BUFFER_SLOT_COUNT ( 4 ) + +#define D3D12_SO_DDI_REGISTER_INDEX_DENOTING_GAP ( 0xffffffff ) + +#define D3D12_SO_NO_RASTERIZED_STREAM ( 0xffffffff ) + +#define D3D12_SO_OUTPUT_COMPONENT_COUNT ( 128 ) + +#define D3D12_SO_STREAM_COUNT ( 4 ) + +#define D3D12_SPEC_DATE_DAY ( 14 ) + +#define D3D12_SPEC_DATE_MONTH ( 11 ) + +#define D3D12_SPEC_DATE_YEAR ( 2014 ) + +#define D3D12_SPEC_VERSION ( 1.16 ) +#define D3D12_SRGB_GAMMA ( 2.2f ) +#define D3D12_SRGB_TO_FLOAT_DENOMINATOR_1 ( 12.92f ) +#define D3D12_SRGB_TO_FLOAT_DENOMINATOR_2 ( 1.055f ) +#define D3D12_SRGB_TO_FLOAT_EXPONENT ( 2.4f ) +#define D3D12_SRGB_TO_FLOAT_OFFSET ( 0.055f ) +#define D3D12_SRGB_TO_FLOAT_THRESHOLD ( 0.04045f ) +#define D3D12_SRGB_TO_FLOAT_TOLERANCE_IN_ULP ( 0.5f ) +#define D3D12_STANDARD_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_STANDARD_COMPONENT_BIT_COUNT_DOUBLED ( 64 ) + +#define D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE ( 4 ) + +#define D3D12_STANDARD_PIXEL_COMPONENT_COUNT ( 128 ) + +#define D3D12_STANDARD_PIXEL_ELEMENT_COUNT ( 32 ) + +#define D3D12_STANDARD_VECTOR_SIZE ( 4 ) + +#define D3D12_STANDARD_VERTEX_ELEMENT_COUNT ( 32 ) + +#define D3D12_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT ( 64 ) + +#define D3D12_SUBPIXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D12_SUBTEXEL_FRACTIONAL_BIT_COUNT ( 8 ) + +#define D3D12_SYSTEM_RESERVED_REGISTER_SPACE_VALUES_END ( 0xffffffff ) + +#define D3D12_SYSTEM_RESERVED_REGISTER_SPACE_VALUES_START ( 0xfffffff0 ) + +#define D3D12_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR ( 64 ) + +#define D3D12_TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR ( 64 ) + +#define D3D12_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR ( 63 ) + +#define D3D12_TESSELLATOR_MAX_TESSELLATION_FACTOR ( 64 ) + +#define D3D12_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR ( 2 ) + +#define D3D12_TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR ( 1 ) + +#define D3D12_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR ( 1 ) + +#define D3D12_TEXEL_ADDRESS_RANGE_BIT_COUNT ( 16 ) + +#define D3D12_TEXTURE_DATA_PITCH_ALIGNMENT ( 256 ) + +#define D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT ( 512 ) + +#define D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES ( 65536 ) + +#define D3D12_TRACKED_WORKLOAD_MAX_INSTANCES ( 32 ) + +#define D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT ( 4096 ) + +#define D3D12_UAV_SLOT_COUNT ( 64 ) + +#define D3D12_UNBOUND_MEMORY_ACCESS_RESULT ( 0 ) + +#define D3D12_VIDEO_DECODE_MAX_ARGUMENTS ( 10 ) + +#define D3D12_VIDEO_DECODE_MAX_HISTOGRAM_COMPONENTS ( 4 ) + +#define D3D12_VIDEO_DECODE_MIN_BITSTREAM_OFFSET_ALIGNMENT ( 256 ) + +#define D3D12_VIDEO_DECODE_MIN_HISTOGRAM_OFFSET_ALIGNMENT ( 256 ) + +#define D3D12_VIDEO_DECODE_STATUS_MACROBLOCKS_AFFECTED_UNKNOWN ( 0xffffffff ) + +#define D3D12_VIDEO_PROCESS_MAX_FILTERS ( 32 ) + +#define D3D12_VIDEO_PROCESS_STEREO_VIEWS ( 2 ) + +#define D3D12_VIEWPORT_AND_SCISSORRECT_MAX_INDEX ( 15 ) + +#define D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE ( 16 ) + +#define D3D12_VIEWPORT_BOUNDS_MAX ( 32767 ) + +#define D3D12_VIEWPORT_BOUNDS_MIN ( -32768 ) + +#define D3D12_VS_INPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_VS_INPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_VS_INPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_VS_INPUT_REGISTER_READS_PER_INST ( 2 ) + +#define D3D12_VS_INPUT_REGISTER_READ_PORTS ( 1 ) + +#define D3D12_VS_OUTPUT_REGISTER_COMPONENTS ( 4 ) + +#define D3D12_VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT ( 32 ) + +#define D3D12_VS_OUTPUT_REGISTER_COUNT ( 32 ) + +#define D3D12_WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT ( 10 ) + +#define D3D12_WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ( 25 ) + +#define D3D12_WHQL_DRAW_VERTEX_COUNT_2_TO_EXP ( 25 ) + +#endif + +typedef UINT64 D3D12_GPU_VIRTUAL_ADDRESS; + +typedef +enum D3D12_COMMAND_LIST_TYPE + { + D3D12_COMMAND_LIST_TYPE_DIRECT = 0, + D3D12_COMMAND_LIST_TYPE_BUNDLE = 1, + D3D12_COMMAND_LIST_TYPE_COMPUTE = 2, + D3D12_COMMAND_LIST_TYPE_COPY = 3, + D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE = 4, + D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS = 5, + D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE = 6 + } D3D12_COMMAND_LIST_TYPE; + +typedef +enum D3D12_COMMAND_QUEUE_FLAGS + { + D3D12_COMMAND_QUEUE_FLAG_NONE = 0, + D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1 + } D3D12_COMMAND_QUEUE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMMAND_QUEUE_FLAGS ); +typedef +enum D3D12_COMMAND_QUEUE_PRIORITY + { + D3D12_COMMAND_QUEUE_PRIORITY_NORMAL = 0, + D3D12_COMMAND_QUEUE_PRIORITY_HIGH = 100, + D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME = 10000 + } D3D12_COMMAND_QUEUE_PRIORITY; + +typedef struct D3D12_COMMAND_QUEUE_DESC + { + D3D12_COMMAND_LIST_TYPE Type; + INT Priority; + D3D12_COMMAND_QUEUE_FLAGS Flags; + UINT NodeMask; + } D3D12_COMMAND_QUEUE_DESC; + +typedef +enum D3D12_PRIMITIVE_TOPOLOGY_TYPE + { + D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED = 0, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT = 1, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE = 2, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE = 3, + D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH = 4 + } D3D12_PRIMITIVE_TOPOLOGY_TYPE; + +typedef +enum D3D12_INPUT_CLASSIFICATION + { + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA = 0, + D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA = 1 + } D3D12_INPUT_CLASSIFICATION; + +typedef struct D3D12_INPUT_ELEMENT_DESC + { + LPCSTR SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D12_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; + } D3D12_INPUT_ELEMENT_DESC; + +typedef +enum D3D12_FILL_MODE + { + D3D12_FILL_MODE_WIREFRAME = 2, + D3D12_FILL_MODE_SOLID = 3 + } D3D12_FILL_MODE; + +typedef D3D_PRIMITIVE_TOPOLOGY D3D12_PRIMITIVE_TOPOLOGY; + +typedef D3D_PRIMITIVE D3D12_PRIMITIVE; + +typedef +enum D3D12_CULL_MODE + { + D3D12_CULL_MODE_NONE = 1, + D3D12_CULL_MODE_FRONT = 2, + D3D12_CULL_MODE_BACK = 3 + } D3D12_CULL_MODE; + +typedef struct D3D12_SO_DECLARATION_ENTRY + { + UINT Stream; + LPCSTR SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; + } D3D12_SO_DECLARATION_ENTRY; + +typedef struct D3D12_VIEWPORT + { + FLOAT TopLeftX; + FLOAT TopLeftY; + FLOAT Width; + FLOAT Height; + FLOAT MinDepth; + FLOAT MaxDepth; + } D3D12_VIEWPORT; + +typedef RECT D3D12_RECT; + +typedef struct D3D12_BOX + { + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; + } D3D12_BOX; + +typedef +enum D3D12_COMPARISON_FUNC + { + D3D12_COMPARISON_FUNC_NEVER = 1, + D3D12_COMPARISON_FUNC_LESS = 2, + D3D12_COMPARISON_FUNC_EQUAL = 3, + D3D12_COMPARISON_FUNC_LESS_EQUAL = 4, + D3D12_COMPARISON_FUNC_GREATER = 5, + D3D12_COMPARISON_FUNC_NOT_EQUAL = 6, + D3D12_COMPARISON_FUNC_GREATER_EQUAL = 7, + D3D12_COMPARISON_FUNC_ALWAYS = 8 + } D3D12_COMPARISON_FUNC; + +typedef +enum D3D12_DEPTH_WRITE_MASK + { + D3D12_DEPTH_WRITE_MASK_ZERO = 0, + D3D12_DEPTH_WRITE_MASK_ALL = 1 + } D3D12_DEPTH_WRITE_MASK; + +typedef +enum D3D12_STENCIL_OP + { + D3D12_STENCIL_OP_KEEP = 1, + D3D12_STENCIL_OP_ZERO = 2, + D3D12_STENCIL_OP_REPLACE = 3, + D3D12_STENCIL_OP_INCR_SAT = 4, + D3D12_STENCIL_OP_DECR_SAT = 5, + D3D12_STENCIL_OP_INVERT = 6, + D3D12_STENCIL_OP_INCR = 7, + D3D12_STENCIL_OP_DECR = 8 + } D3D12_STENCIL_OP; + +typedef struct D3D12_DEPTH_STENCILOP_DESC + { + D3D12_STENCIL_OP StencilFailOp; + D3D12_STENCIL_OP StencilDepthFailOp; + D3D12_STENCIL_OP StencilPassOp; + D3D12_COMPARISON_FUNC StencilFunc; + } D3D12_DEPTH_STENCILOP_DESC; + +typedef struct D3D12_DEPTH_STENCIL_DESC + { + BOOL DepthEnable; + D3D12_DEPTH_WRITE_MASK DepthWriteMask; + D3D12_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D12_DEPTH_STENCILOP_DESC FrontFace; + D3D12_DEPTH_STENCILOP_DESC BackFace; + } D3D12_DEPTH_STENCIL_DESC; + +typedef struct D3D12_DEPTH_STENCIL_DESC1 + { + BOOL DepthEnable; + D3D12_DEPTH_WRITE_MASK DepthWriteMask; + D3D12_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D12_DEPTH_STENCILOP_DESC FrontFace; + D3D12_DEPTH_STENCILOP_DESC BackFace; + BOOL DepthBoundsTestEnable; + } D3D12_DEPTH_STENCIL_DESC1; + +typedef +enum D3D12_BLEND + { + D3D12_BLEND_ZERO = 1, + D3D12_BLEND_ONE = 2, + D3D12_BLEND_SRC_COLOR = 3, + D3D12_BLEND_INV_SRC_COLOR = 4, + D3D12_BLEND_SRC_ALPHA = 5, + D3D12_BLEND_INV_SRC_ALPHA = 6, + D3D12_BLEND_DEST_ALPHA = 7, + D3D12_BLEND_INV_DEST_ALPHA = 8, + D3D12_BLEND_DEST_COLOR = 9, + D3D12_BLEND_INV_DEST_COLOR = 10, + D3D12_BLEND_SRC_ALPHA_SAT = 11, + D3D12_BLEND_BLEND_FACTOR = 14, + D3D12_BLEND_INV_BLEND_FACTOR = 15, + D3D12_BLEND_SRC1_COLOR = 16, + D3D12_BLEND_INV_SRC1_COLOR = 17, + D3D12_BLEND_SRC1_ALPHA = 18, + D3D12_BLEND_INV_SRC1_ALPHA = 19 + } D3D12_BLEND; + +typedef +enum D3D12_BLEND_OP + { + D3D12_BLEND_OP_ADD = 1, + D3D12_BLEND_OP_SUBTRACT = 2, + D3D12_BLEND_OP_REV_SUBTRACT = 3, + D3D12_BLEND_OP_MIN = 4, + D3D12_BLEND_OP_MAX = 5 + } D3D12_BLEND_OP; + +typedef +enum D3D12_COLOR_WRITE_ENABLE + { + D3D12_COLOR_WRITE_ENABLE_RED = 1, + D3D12_COLOR_WRITE_ENABLE_GREEN = 2, + D3D12_COLOR_WRITE_ENABLE_BLUE = 4, + D3D12_COLOR_WRITE_ENABLE_ALPHA = 8, + D3D12_COLOR_WRITE_ENABLE_ALL = ( ( ( D3D12_COLOR_WRITE_ENABLE_RED | D3D12_COLOR_WRITE_ENABLE_GREEN ) | D3D12_COLOR_WRITE_ENABLE_BLUE ) | D3D12_COLOR_WRITE_ENABLE_ALPHA ) + } D3D12_COLOR_WRITE_ENABLE; + +typedef +enum D3D12_LOGIC_OP + { + D3D12_LOGIC_OP_CLEAR = 0, + D3D12_LOGIC_OP_SET = ( D3D12_LOGIC_OP_CLEAR + 1 ) , + D3D12_LOGIC_OP_COPY = ( D3D12_LOGIC_OP_SET + 1 ) , + D3D12_LOGIC_OP_COPY_INVERTED = ( D3D12_LOGIC_OP_COPY + 1 ) , + D3D12_LOGIC_OP_NOOP = ( D3D12_LOGIC_OP_COPY_INVERTED + 1 ) , + D3D12_LOGIC_OP_INVERT = ( D3D12_LOGIC_OP_NOOP + 1 ) , + D3D12_LOGIC_OP_AND = ( D3D12_LOGIC_OP_INVERT + 1 ) , + D3D12_LOGIC_OP_NAND = ( D3D12_LOGIC_OP_AND + 1 ) , + D3D12_LOGIC_OP_OR = ( D3D12_LOGIC_OP_NAND + 1 ) , + D3D12_LOGIC_OP_NOR = ( D3D12_LOGIC_OP_OR + 1 ) , + D3D12_LOGIC_OP_XOR = ( D3D12_LOGIC_OP_NOR + 1 ) , + D3D12_LOGIC_OP_EQUIV = ( D3D12_LOGIC_OP_XOR + 1 ) , + D3D12_LOGIC_OP_AND_REVERSE = ( D3D12_LOGIC_OP_EQUIV + 1 ) , + D3D12_LOGIC_OP_AND_INVERTED = ( D3D12_LOGIC_OP_AND_REVERSE + 1 ) , + D3D12_LOGIC_OP_OR_REVERSE = ( D3D12_LOGIC_OP_AND_INVERTED + 1 ) , + D3D12_LOGIC_OP_OR_INVERTED = ( D3D12_LOGIC_OP_OR_REVERSE + 1 ) + } D3D12_LOGIC_OP; + +typedef struct D3D12_RENDER_TARGET_BLEND_DESC + { + BOOL BlendEnable; + BOOL LogicOpEnable; + D3D12_BLEND SrcBlend; + D3D12_BLEND DestBlend; + D3D12_BLEND_OP BlendOp; + D3D12_BLEND SrcBlendAlpha; + D3D12_BLEND DestBlendAlpha; + D3D12_BLEND_OP BlendOpAlpha; + D3D12_LOGIC_OP LogicOp; + UINT8 RenderTargetWriteMask; + } D3D12_RENDER_TARGET_BLEND_DESC; + +typedef struct D3D12_BLEND_DESC + { + BOOL AlphaToCoverageEnable; + BOOL IndependentBlendEnable; + D3D12_RENDER_TARGET_BLEND_DESC RenderTarget[ 8 ]; + } D3D12_BLEND_DESC; + +/* Note, the array size for RenderTarget[] above is D3D12_SIMULTANEOUS_RENDERTARGET_COUNT. + IDL processing/generation of this header replaces the define; this comment is merely explaining what happened. */ +typedef +enum D3D12_CONSERVATIVE_RASTERIZATION_MODE + { + D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF = 0, + D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON = 1 + } D3D12_CONSERVATIVE_RASTERIZATION_MODE; + +typedef struct D3D12_RASTERIZER_DESC + { + D3D12_FILL_MODE FillMode; + D3D12_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; + UINT ForcedSampleCount; + D3D12_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster; + } D3D12_RASTERIZER_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D12Object_INTERFACE_DEFINED__ +#define __ID3D12Object_INTERFACE_DEFINED__ + +/* interface ID3D12Object */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Object; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c4fec28f-7966-4e95-9f94-f431cb56c3b8") + ID3D12Object : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetName( + _In_z_ LPCWSTR Name) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12ObjectVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Object * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Object * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Object * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Object * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Object * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Object * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Object * This, + _In_z_ LPCWSTR Name); + + END_INTERFACE + } ID3D12ObjectVtbl; + + interface ID3D12Object + { + CONST_VTBL struct ID3D12ObjectVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Object_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Object_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Object_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Object_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Object_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Object_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Object_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Object_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DeviceChild_INTERFACE_DEFINED__ +#define __ID3D12DeviceChild_INTERFACE_DEFINED__ + +/* interface ID3D12DeviceChild */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DeviceChild; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("905db94b-a00c-4140-9df5-2b64ca9ea357") + ID3D12DeviceChild : public ID3D12Object + { + public: + virtual HRESULT STDMETHODCALLTYPE GetDevice( + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DeviceChildVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DeviceChild * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DeviceChild * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DeviceChild * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12DeviceChild * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12DeviceChild * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12DeviceChild * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12DeviceChild * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12DeviceChild * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12DeviceChildVtbl; + + interface ID3D12DeviceChild + { + CONST_VTBL struct ID3D12DeviceChildVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DeviceChild_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DeviceChild_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DeviceChild_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DeviceChild_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12DeviceChild_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12DeviceChild_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12DeviceChild_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12DeviceChild_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DeviceChild_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12RootSignature_INTERFACE_DEFINED__ +#define __ID3D12RootSignature_INTERFACE_DEFINED__ + +/* interface ID3D12RootSignature */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12RootSignature; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c54a6b66-72df-4ee8-8be5-a946a1429214") + ID3D12RootSignature : public ID3D12DeviceChild + { + public: + }; + + +#else /* C style interface */ + + typedef struct ID3D12RootSignatureVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12RootSignature * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12RootSignature * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12RootSignature * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12RootSignature * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12RootSignature * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12RootSignature * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12RootSignature * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12RootSignature * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12RootSignatureVtbl; + + interface ID3D12RootSignature + { + CONST_VTBL struct ID3D12RootSignatureVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12RootSignature_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12RootSignature_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12RootSignature_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12RootSignature_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12RootSignature_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12RootSignature_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12RootSignature_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12RootSignature_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12RootSignature_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0001 */ +/* [local] */ + +typedef struct D3D12_SHADER_BYTECODE + { + _Field_size_bytes_full_(BytecodeLength) const void *pShaderBytecode; + SIZE_T BytecodeLength; + } D3D12_SHADER_BYTECODE; + +typedef struct D3D12_STREAM_OUTPUT_DESC + { + _Field_size_full_(NumEntries) const D3D12_SO_DECLARATION_ENTRY *pSODeclaration; + UINT NumEntries; + _Field_size_full_(NumStrides) const UINT *pBufferStrides; + UINT NumStrides; + UINT RasterizedStream; + } D3D12_STREAM_OUTPUT_DESC; + +typedef struct D3D12_INPUT_LAYOUT_DESC + { + _Field_size_full_(NumElements) const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs; + UINT NumElements; + } D3D12_INPUT_LAYOUT_DESC; + +typedef +enum D3D12_INDEX_BUFFER_STRIP_CUT_VALUE + { + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED = 0, + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF = 1, + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF = 2 + } D3D12_INDEX_BUFFER_STRIP_CUT_VALUE; + +typedef struct D3D12_CACHED_PIPELINE_STATE + { + _Field_size_bytes_full_(CachedBlobSizeInBytes) const void *pCachedBlob; + SIZE_T CachedBlobSizeInBytes; + } D3D12_CACHED_PIPELINE_STATE; + +typedef +enum D3D12_PIPELINE_STATE_FLAGS + { + D3D12_PIPELINE_STATE_FLAG_NONE = 0, + D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG = 0x1 + } D3D12_PIPELINE_STATE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_PIPELINE_STATE_FLAGS ); +typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC + { + ID3D12RootSignature *pRootSignature; + D3D12_SHADER_BYTECODE VS; + D3D12_SHADER_BYTECODE PS; + D3D12_SHADER_BYTECODE DS; + D3D12_SHADER_BYTECODE HS; + D3D12_SHADER_BYTECODE GS; + D3D12_STREAM_OUTPUT_DESC StreamOutput; + D3D12_BLEND_DESC BlendState; + UINT SampleMask; + D3D12_RASTERIZER_DESC RasterizerState; + D3D12_DEPTH_STENCIL_DESC DepthStencilState; + D3D12_INPUT_LAYOUT_DESC InputLayout; + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; + UINT NumRenderTargets; + DXGI_FORMAT RTVFormats[ 8 ]; + DXGI_FORMAT DSVFormat; + DXGI_SAMPLE_DESC SampleDesc; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; + } D3D12_GRAPHICS_PIPELINE_STATE_DESC; + +typedef struct D3D12_COMPUTE_PIPELINE_STATE_DESC + { + ID3D12RootSignature *pRootSignature; + D3D12_SHADER_BYTECODE CS; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; + } D3D12_COMPUTE_PIPELINE_STATE_DESC; + +struct D3D12_RT_FORMAT_ARRAY + { + DXGI_FORMAT RTFormats[ 8 ]; + UINT NumRenderTargets; + } ; +typedef struct D3D12_PIPELINE_STATE_STREAM_DESC + { + _In_ SIZE_T SizeInBytes; + _In_reads_(_Inexpressible_("Dependent on size of subobjects")) void *pPipelineStateSubobjectStream; + } D3D12_PIPELINE_STATE_STREAM_DESC; + +typedef +enum D3D12_PIPELINE_STATE_SUBOBJECT_TYPE + { + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE = 0, + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1 = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1 + 1 ) , + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID = ( D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING + 1 ) + } D3D12_PIPELINE_STATE_SUBOBJECT_TYPE; + +typedef +enum D3D12_FEATURE + { + D3D12_FEATURE_D3D12_OPTIONS = 0, + D3D12_FEATURE_ARCHITECTURE = 1, + D3D12_FEATURE_FEATURE_LEVELS = 2, + D3D12_FEATURE_FORMAT_SUPPORT = 3, + D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS = 4, + D3D12_FEATURE_FORMAT_INFO = 5, + D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT = 6, + D3D12_FEATURE_SHADER_MODEL = 7, + D3D12_FEATURE_D3D12_OPTIONS1 = 8, + D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT = 10, + D3D12_FEATURE_ROOT_SIGNATURE = 12, + D3D12_FEATURE_ARCHITECTURE1 = 16, + D3D12_FEATURE_D3D12_OPTIONS2 = 18, + D3D12_FEATURE_SHADER_CACHE = 19, + D3D12_FEATURE_COMMAND_QUEUE_PRIORITY = 20, + D3D12_FEATURE_D3D12_OPTIONS3 = 21, + D3D12_FEATURE_EXISTING_HEAPS = 22, + D3D12_FEATURE_D3D12_OPTIONS4 = 23, + D3D12_FEATURE_SERIALIZATION = 24, + D3D12_FEATURE_CROSS_NODE = 25, + D3D12_FEATURE_D3D12_OPTIONS5 = 27, + D3D12_FEATURE_D3D12_OPTIONS6 = 30, + D3D12_FEATURE_QUERY_META_COMMAND = 31 + } D3D12_FEATURE; + +typedef +enum D3D12_SHADER_MIN_PRECISION_SUPPORT + { + D3D12_SHADER_MIN_PRECISION_SUPPORT_NONE = 0, + D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT = 0x1, + D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT = 0x2 + } D3D12_SHADER_MIN_PRECISION_SUPPORT; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_SHADER_MIN_PRECISION_SUPPORT ); +typedef +enum D3D12_TILED_RESOURCES_TIER + { + D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED = 0, + D3D12_TILED_RESOURCES_TIER_1 = 1, + D3D12_TILED_RESOURCES_TIER_2 = 2, + D3D12_TILED_RESOURCES_TIER_3 = 3, + D3D12_TILED_RESOURCES_TIER_4 = 4 + } D3D12_TILED_RESOURCES_TIER; + +typedef +enum D3D12_RESOURCE_BINDING_TIER + { + D3D12_RESOURCE_BINDING_TIER_1 = 1, + D3D12_RESOURCE_BINDING_TIER_2 = 2, + D3D12_RESOURCE_BINDING_TIER_3 = 3 + } D3D12_RESOURCE_BINDING_TIER; + +typedef +enum D3D12_CONSERVATIVE_RASTERIZATION_TIER + { + D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED = 0, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_1 = 1, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_2 = 2, + D3D12_CONSERVATIVE_RASTERIZATION_TIER_3 = 3 + } D3D12_CONSERVATIVE_RASTERIZATION_TIER; + +typedef +enum D3D12_FORMAT_SUPPORT1 + { + D3D12_FORMAT_SUPPORT1_NONE = 0, + D3D12_FORMAT_SUPPORT1_BUFFER = 0x1, + D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER = 0x2, + D3D12_FORMAT_SUPPORT1_IA_INDEX_BUFFER = 0x4, + D3D12_FORMAT_SUPPORT1_SO_BUFFER = 0x8, + D3D12_FORMAT_SUPPORT1_TEXTURE1D = 0x10, + D3D12_FORMAT_SUPPORT1_TEXTURE2D = 0x20, + D3D12_FORMAT_SUPPORT1_TEXTURE3D = 0x40, + D3D12_FORMAT_SUPPORT1_TEXTURECUBE = 0x80, + D3D12_FORMAT_SUPPORT1_SHADER_LOAD = 0x100, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE = 0x200, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON = 0x400, + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_MONO_TEXT = 0x800, + D3D12_FORMAT_SUPPORT1_MIP = 0x1000, + D3D12_FORMAT_SUPPORT1_RENDER_TARGET = 0x4000, + D3D12_FORMAT_SUPPORT1_BLENDABLE = 0x8000, + D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL = 0x10000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE = 0x40000, + D3D12_FORMAT_SUPPORT1_DISPLAY = 0x80000, + D3D12_FORMAT_SUPPORT1_CAST_WITHIN_BIT_LAYOUT = 0x100000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET = 0x200000, + D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD = 0x400000, + D3D12_FORMAT_SUPPORT1_SHADER_GATHER = 0x800000, + D3D12_FORMAT_SUPPORT1_BACK_BUFFER_CAST = 0x1000000, + D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW = 0x2000000, + D3D12_FORMAT_SUPPORT1_SHADER_GATHER_COMPARISON = 0x4000000, + D3D12_FORMAT_SUPPORT1_DECODER_OUTPUT = 0x8000000, + D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_OUTPUT = 0x10000000, + D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_INPUT = 0x20000000, + D3D12_FORMAT_SUPPORT1_VIDEO_ENCODER = 0x40000000 + } D3D12_FORMAT_SUPPORT1; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_FORMAT_SUPPORT1 ); +typedef +enum D3D12_FORMAT_SUPPORT2 + { + D3D12_FORMAT_SUPPORT2_NONE = 0, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x1, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x2, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x4, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x8, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x10, + D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x20, + D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40, + D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80, + D3D12_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x100, + D3D12_FORMAT_SUPPORT2_TILED = 0x200, + D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x4000 + } D3D12_FORMAT_SUPPORT2; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_FORMAT_SUPPORT2 ); +typedef +enum D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS + { + D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE = 0, + D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE = 0x1 + } D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS ); +typedef +enum D3D12_CROSS_NODE_SHARING_TIER + { + D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED = 0, + D3D12_CROSS_NODE_SHARING_TIER_1_EMULATED = 1, + D3D12_CROSS_NODE_SHARING_TIER_1 = 2, + D3D12_CROSS_NODE_SHARING_TIER_2 = 3, + D3D12_CROSS_NODE_SHARING_TIER_3 = 4 + } D3D12_CROSS_NODE_SHARING_TIER; + +typedef +enum D3D12_RESOURCE_HEAP_TIER + { + D3D12_RESOURCE_HEAP_TIER_1 = 1, + D3D12_RESOURCE_HEAP_TIER_2 = 2 + } D3D12_RESOURCE_HEAP_TIER; + +typedef +enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER + { + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0, + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 1, + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 2 + } D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER; + +typedef +enum D3D12_VIEW_INSTANCING_TIER + { + D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED = 0, + D3D12_VIEW_INSTANCING_TIER_1 = 1, + D3D12_VIEW_INSTANCING_TIER_2 = 2, + D3D12_VIEW_INSTANCING_TIER_3 = 3 + } D3D12_VIEW_INSTANCING_TIER; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS + { + _Out_ BOOL DoublePrecisionFloatShaderOps; + _Out_ BOOL OutputMergerLogicOp; + _Out_ D3D12_SHADER_MIN_PRECISION_SUPPORT MinPrecisionSupport; + _Out_ D3D12_TILED_RESOURCES_TIER TiledResourcesTier; + _Out_ D3D12_RESOURCE_BINDING_TIER ResourceBindingTier; + _Out_ BOOL PSSpecifiedStencilRefSupported; + _Out_ BOOL TypedUAVLoadAdditionalFormats; + _Out_ BOOL ROVsSupported; + _Out_ D3D12_CONSERVATIVE_RASTERIZATION_TIER ConservativeRasterizationTier; + _Out_ UINT MaxGPUVirtualAddressBitsPerResource; + _Out_ BOOL StandardSwizzle64KBSupported; + _Out_ D3D12_CROSS_NODE_SHARING_TIER CrossNodeSharingTier; + _Out_ BOOL CrossAdapterRowMajorTextureSupported; + _Out_ BOOL VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation; + _Out_ D3D12_RESOURCE_HEAP_TIER ResourceHeapTier; + } D3D12_FEATURE_DATA_D3D12_OPTIONS; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1 + { + _Out_ BOOL WaveOps; + _Out_ UINT WaveLaneCountMin; + _Out_ UINT WaveLaneCountMax; + _Out_ UINT TotalLaneCount; + _Out_ BOOL ExpandedComputeResourceStates; + _Out_ BOOL Int64ShaderOps; + } D3D12_FEATURE_DATA_D3D12_OPTIONS1; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2 + { + _Out_ BOOL DepthBoundsTestSupported; + _Out_ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier; + } D3D12_FEATURE_DATA_D3D12_OPTIONS2; + +typedef +enum D3D_ROOT_SIGNATURE_VERSION + { + D3D_ROOT_SIGNATURE_VERSION_1 = 0x1, + D3D_ROOT_SIGNATURE_VERSION_1_0 = 0x1, + D3D_ROOT_SIGNATURE_VERSION_1_1 = 0x2 + } D3D_ROOT_SIGNATURE_VERSION; + +typedef struct D3D12_FEATURE_DATA_ROOT_SIGNATURE + { + _Inout_ D3D_ROOT_SIGNATURE_VERSION HighestVersion; + } D3D12_FEATURE_DATA_ROOT_SIGNATURE; + +typedef struct D3D12_FEATURE_DATA_ARCHITECTURE + { + _In_ UINT NodeIndex; + _Out_ BOOL TileBasedRenderer; + _Out_ BOOL UMA; + _Out_ BOOL CacheCoherentUMA; + } D3D12_FEATURE_DATA_ARCHITECTURE; + +typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1 + { + _In_ UINT NodeIndex; + _Out_ BOOL TileBasedRenderer; + _Out_ BOOL UMA; + _Out_ BOOL CacheCoherentUMA; + _Out_ BOOL IsolatedMMU; + } D3D12_FEATURE_DATA_ARCHITECTURE1; + +typedef struct D3D12_FEATURE_DATA_FEATURE_LEVELS + { + _In_ UINT NumFeatureLevels; + _In_reads_(NumFeatureLevels) const D3D_FEATURE_LEVEL *pFeatureLevelsRequested; + _Out_ D3D_FEATURE_LEVEL MaxSupportedFeatureLevel; + } D3D12_FEATURE_DATA_FEATURE_LEVELS; + +typedef +enum D3D_SHADER_MODEL + { + D3D_SHADER_MODEL_5_1 = 0x51, + D3D_SHADER_MODEL_6_0 = 0x60, + D3D_SHADER_MODEL_6_1 = 0x61, + D3D_SHADER_MODEL_6_2 = 0x62, + D3D_SHADER_MODEL_6_3 = 0x63, + D3D_SHADER_MODEL_6_4 = 0x64, + D3D_SHADER_MODEL_6_5 = 0x65 + } D3D_SHADER_MODEL; + +typedef struct D3D12_FEATURE_DATA_SHADER_MODEL + { + _Inout_ D3D_SHADER_MODEL HighestShaderModel; + } D3D12_FEATURE_DATA_SHADER_MODEL; + +typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT + { + _In_ DXGI_FORMAT Format; + _Out_ D3D12_FORMAT_SUPPORT1 Support1; + _Out_ D3D12_FORMAT_SUPPORT2 Support2; + } D3D12_FEATURE_DATA_FORMAT_SUPPORT; + +typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS + { + _In_ DXGI_FORMAT Format; + _In_ UINT SampleCount; + _In_ D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS Flags; + _Out_ UINT NumQualityLevels; + } D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS; + +typedef struct D3D12_FEATURE_DATA_FORMAT_INFO + { + DXGI_FORMAT Format; + UINT8 PlaneCount; + } D3D12_FEATURE_DATA_FORMAT_INFO; + +typedef struct D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT + { + UINT MaxGPUVirtualAddressBitsPerResource; + UINT MaxGPUVirtualAddressBitsPerProcess; + } D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT; + +typedef +enum D3D12_SHADER_CACHE_SUPPORT_FLAGS + { + D3D12_SHADER_CACHE_SUPPORT_NONE = 0, + D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO = 0x1, + D3D12_SHADER_CACHE_SUPPORT_LIBRARY = 0x2, + D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4, + D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8 + } D3D12_SHADER_CACHE_SUPPORT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_SHADER_CACHE_SUPPORT_FLAGS ); +typedef struct D3D12_FEATURE_DATA_SHADER_CACHE + { + _Out_ D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags; + } D3D12_FEATURE_DATA_SHADER_CACHE; + +typedef struct D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY + { + _In_ D3D12_COMMAND_LIST_TYPE CommandListType; + _In_ UINT Priority; + _Out_ BOOL PriorityForTypeIsSupported; + } D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY; + +typedef +enum D3D12_COMMAND_LIST_SUPPORT_FLAGS + { + D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0, + D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT = ( 1 << D3D12_COMMAND_LIST_TYPE_DIRECT ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_BUNDLE = ( 1 << D3D12_COMMAND_LIST_TYPE_BUNDLE ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE = ( 1 << D3D12_COMMAND_LIST_TYPE_COMPUTE ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = ( 1 << D3D12_COMMAND_LIST_TYPE_COPY ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_DECODE = ( 1 << D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_PROCESS = ( 1 << D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS ) , + D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_ENCODE = ( 1 << D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE ) + } D3D12_COMMAND_LIST_SUPPORT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMMAND_LIST_SUPPORT_FLAGS ); +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS3 + { + _Out_ BOOL CopyQueueTimestampQueriesSupported; + _Out_ BOOL CastingFullyTypedFormatSupported; + _Out_ D3D12_COMMAND_LIST_SUPPORT_FLAGS WriteBufferImmediateSupportFlags; + _Out_ D3D12_VIEW_INSTANCING_TIER ViewInstancingTier; + _Out_ BOOL BarycentricsSupported; + } D3D12_FEATURE_DATA_D3D12_OPTIONS3; + +typedef struct D3D12_FEATURE_DATA_EXISTING_HEAPS + { + _Out_ BOOL Supported; + } D3D12_FEATURE_DATA_EXISTING_HEAPS; + +typedef +enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER + { + D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0, + D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = ( D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 + 1 ) + } D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS4 + { + _Out_ BOOL MSAA64KBAlignedTextureSupported; + _Out_ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier; + _Out_ BOOL Native16BitShaderOpsSupported; + } D3D12_FEATURE_DATA_D3D12_OPTIONS4; + +typedef +enum D3D12_HEAP_SERIALIZATION_TIER + { + D3D12_HEAP_SERIALIZATION_TIER_0 = 0, + D3D12_HEAP_SERIALIZATION_TIER_10 = 10 + } D3D12_HEAP_SERIALIZATION_TIER; + +typedef struct D3D12_FEATURE_DATA_SERIALIZATION + { + _In_ UINT NodeIndex; + _Out_ D3D12_HEAP_SERIALIZATION_TIER HeapSerializationTier; + } D3D12_FEATURE_DATA_SERIALIZATION; + +typedef struct D3D12_FEATURE_DATA_CROSS_NODE + { + D3D12_CROSS_NODE_SHARING_TIER SharingTier; + BOOL AtomicShaderInstructions; + } D3D12_FEATURE_DATA_CROSS_NODE; + +typedef +enum D3D12_RENDER_PASS_TIER + { + D3D12_RENDER_PASS_TIER_0 = 0, + D3D12_RENDER_PASS_TIER_1 = 1, + D3D12_RENDER_PASS_TIER_2 = 2 + } D3D12_RENDER_PASS_TIER; + +typedef +enum D3D12_RAYTRACING_TIER + { + D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0, + D3D12_RAYTRACING_TIER_1_0 = 10 + } D3D12_RAYTRACING_TIER; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS5 + { + _Out_ BOOL SRVOnlyTiledResourceTier3; + _Out_ D3D12_RENDER_PASS_TIER RenderPassesTier; + _Out_ D3D12_RAYTRACING_TIER RaytracingTier; + } D3D12_FEATURE_DATA_D3D12_OPTIONS5; + +typedef +enum D3D12_VARIABLE_SHADING_RATE_TIER + { + D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED = 0, + D3D12_VARIABLE_SHADING_RATE_TIER_1 = 1, + D3D12_VARIABLE_SHADING_RATE_TIER_2 = 2 + } D3D12_VARIABLE_SHADING_RATE_TIER; + +typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS6 + { + _Out_ BOOL AdditionalShadingRatesSupported; + _Out_ BOOL PerPrimitiveShadingRateSupportedWithViewportIndexing; + _Out_ D3D12_VARIABLE_SHADING_RATE_TIER VariableShadingRateTier; + _Out_ UINT ShadingRateImageTileSize; + _Out_ BOOL BackgroundProcessingSupported; + } D3D12_FEATURE_DATA_D3D12_OPTIONS6; + +typedef struct D3D12_FEATURE_DATA_QUERY_META_COMMAND + { + _In_ GUID CommandId; + _In_ UINT NodeMask; + _Field_size_bytes_full_opt_( QueryInputDataSizeInBytes ) const void *pQueryInputData; + _In_ SIZE_T QueryInputDataSizeInBytes; + _Field_size_bytes_full_( QueryOutputDataSizeInBytes ) void *pQueryOutputData; + _In_ SIZE_T QueryOutputDataSizeInBytes; + } D3D12_FEATURE_DATA_QUERY_META_COMMAND; + +typedef struct D3D12_RESOURCE_ALLOCATION_INFO + { + UINT64 SizeInBytes; + UINT64 Alignment; + } D3D12_RESOURCE_ALLOCATION_INFO; + +typedef struct D3D12_RESOURCE_ALLOCATION_INFO1 + { + UINT64 Offset; + UINT64 Alignment; + UINT64 SizeInBytes; + } D3D12_RESOURCE_ALLOCATION_INFO1; + +typedef +enum D3D12_HEAP_TYPE + { + D3D12_HEAP_TYPE_DEFAULT = 1, + D3D12_HEAP_TYPE_UPLOAD = 2, + D3D12_HEAP_TYPE_READBACK = 3, + D3D12_HEAP_TYPE_CUSTOM = 4 + } D3D12_HEAP_TYPE; + +typedef +enum D3D12_CPU_PAGE_PROPERTY + { + D3D12_CPU_PAGE_PROPERTY_UNKNOWN = 0, + D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE = 1, + D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE = 2, + D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3 + } D3D12_CPU_PAGE_PROPERTY; + +typedef +enum D3D12_MEMORY_POOL + { + D3D12_MEMORY_POOL_UNKNOWN = 0, + D3D12_MEMORY_POOL_L0 = 1, + D3D12_MEMORY_POOL_L1 = 2 + } D3D12_MEMORY_POOL; + +typedef struct D3D12_HEAP_PROPERTIES + { + D3D12_HEAP_TYPE Type; + D3D12_CPU_PAGE_PROPERTY CPUPageProperty; + D3D12_MEMORY_POOL MemoryPoolPreference; + UINT CreationNodeMask; + UINT VisibleNodeMask; + } D3D12_HEAP_PROPERTIES; + +typedef +enum D3D12_HEAP_FLAGS + { + D3D12_HEAP_FLAG_NONE = 0, + D3D12_HEAP_FLAG_SHARED = 0x1, + D3D12_HEAP_FLAG_DENY_BUFFERS = 0x4, + D3D12_HEAP_FLAG_ALLOW_DISPLAY = 0x8, + D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER = 0x20, + D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES = 0x40, + D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES = 0x80, + D3D12_HEAP_FLAG_HARDWARE_PROTECTED = 0x100, + D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH = 0x200, + D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS = 0x400, + D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES = 0, + D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS = 0xc0, + D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44, + D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES = 0x84 + } D3D12_HEAP_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_HEAP_FLAGS ); +typedef struct D3D12_HEAP_DESC + { + UINT64 SizeInBytes; + D3D12_HEAP_PROPERTIES Properties; + UINT64 Alignment; + D3D12_HEAP_FLAGS Flags; + } D3D12_HEAP_DESC; + +typedef +enum D3D12_RESOURCE_DIMENSION + { + D3D12_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D12_RESOURCE_DIMENSION_BUFFER = 1, + D3D12_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D12_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D12_RESOURCE_DIMENSION_TEXTURE3D = 4 + } D3D12_RESOURCE_DIMENSION; + +typedef +enum D3D12_TEXTURE_LAYOUT + { + D3D12_TEXTURE_LAYOUT_UNKNOWN = 0, + D3D12_TEXTURE_LAYOUT_ROW_MAJOR = 1, + D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE = 2, + D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE = 3 + } D3D12_TEXTURE_LAYOUT; + +typedef +enum D3D12_RESOURCE_FLAGS + { + D3D12_RESOURCE_FLAG_NONE = 0, + D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET = 0x1, + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL = 0x2, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS = 0x4, + D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE = 0x8, + D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER = 0x10, + D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS = 0x20, + D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY = 0x40 + } D3D12_RESOURCE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RESOURCE_FLAGS ); +typedef struct D3D12_RESOURCE_DESC + { + D3D12_RESOURCE_DIMENSION Dimension; + UINT64 Alignment; + UINT64 Width; + UINT Height; + UINT16 DepthOrArraySize; + UINT16 MipLevels; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D12_TEXTURE_LAYOUT Layout; + D3D12_RESOURCE_FLAGS Flags; + } D3D12_RESOURCE_DESC; + +typedef struct D3D12_DEPTH_STENCIL_VALUE + { + FLOAT Depth; + UINT8 Stencil; + } D3D12_DEPTH_STENCIL_VALUE; + +typedef struct D3D12_CLEAR_VALUE + { + DXGI_FORMAT Format; + union + { + FLOAT Color[ 4 ]; + D3D12_DEPTH_STENCIL_VALUE DepthStencil; + } ; + } D3D12_CLEAR_VALUE; + +typedef struct D3D12_RANGE + { + SIZE_T Begin; + SIZE_T End; + } D3D12_RANGE; + +typedef struct D3D12_RANGE_UINT64 + { + UINT64 Begin; + UINT64 End; + } D3D12_RANGE_UINT64; + +typedef struct D3D12_SUBRESOURCE_RANGE_UINT64 + { + UINT Subresource; + D3D12_RANGE_UINT64 Range; + } D3D12_SUBRESOURCE_RANGE_UINT64; + +typedef struct D3D12_SUBRESOURCE_INFO + { + UINT64 Offset; + UINT RowPitch; + UINT DepthPitch; + } D3D12_SUBRESOURCE_INFO; + +typedef struct D3D12_TILED_RESOURCE_COORDINATE + { + UINT X; + UINT Y; + UINT Z; + UINT Subresource; + } D3D12_TILED_RESOURCE_COORDINATE; + +typedef struct D3D12_TILE_REGION_SIZE + { + UINT NumTiles; + BOOL UseBox; + UINT Width; + UINT16 Height; + UINT16 Depth; + } D3D12_TILE_REGION_SIZE; + +typedef +enum D3D12_TILE_RANGE_FLAGS + { + D3D12_TILE_RANGE_FLAG_NONE = 0, + D3D12_TILE_RANGE_FLAG_NULL = 1, + D3D12_TILE_RANGE_FLAG_SKIP = 2, + D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE = 4 + } D3D12_TILE_RANGE_FLAGS; + +typedef struct D3D12_SUBRESOURCE_TILING + { + UINT WidthInTiles; + UINT16 HeightInTiles; + UINT16 DepthInTiles; + UINT StartTileIndexInOverallResource; + } D3D12_SUBRESOURCE_TILING; + +typedef struct D3D12_TILE_SHAPE + { + UINT WidthInTexels; + UINT HeightInTexels; + UINT DepthInTexels; + } D3D12_TILE_SHAPE; + +typedef struct D3D12_PACKED_MIP_INFO + { + UINT8 NumStandardMips; + UINT8 NumPackedMips; + UINT NumTilesForPackedMips; + UINT StartTileIndexInOverallResource; + } D3D12_PACKED_MIP_INFO; + +typedef +enum D3D12_TILE_MAPPING_FLAGS + { + D3D12_TILE_MAPPING_FLAG_NONE = 0, + D3D12_TILE_MAPPING_FLAG_NO_HAZARD = 0x1 + } D3D12_TILE_MAPPING_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_TILE_MAPPING_FLAGS ); +typedef +enum D3D12_TILE_COPY_FLAGS + { + D3D12_TILE_COPY_FLAG_NONE = 0, + D3D12_TILE_COPY_FLAG_NO_HAZARD = 0x1, + D3D12_TILE_COPY_FLAG_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2, + D3D12_TILE_COPY_FLAG_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4 + } D3D12_TILE_COPY_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_TILE_COPY_FLAGS ); +typedef +enum D3D12_RESOURCE_STATES + { + D3D12_RESOURCE_STATE_COMMON = 0, + D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER = 0x1, + D3D12_RESOURCE_STATE_INDEX_BUFFER = 0x2, + D3D12_RESOURCE_STATE_RENDER_TARGET = 0x4, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS = 0x8, + D3D12_RESOURCE_STATE_DEPTH_WRITE = 0x10, + D3D12_RESOURCE_STATE_DEPTH_READ = 0x20, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE = 0x40, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE = 0x80, + D3D12_RESOURCE_STATE_STREAM_OUT = 0x100, + D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT = 0x200, + D3D12_RESOURCE_STATE_COPY_DEST = 0x400, + D3D12_RESOURCE_STATE_COPY_SOURCE = 0x800, + D3D12_RESOURCE_STATE_RESOLVE_DEST = 0x1000, + D3D12_RESOURCE_STATE_RESOLVE_SOURCE = 0x2000, + D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE = 0x400000, + D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE = 0x1000000, + D3D12_RESOURCE_STATE_GENERIC_READ = ( ( ( ( ( 0x1 | 0x2 ) | 0x40 ) | 0x80 ) | 0x200 ) | 0x800 ) , + D3D12_RESOURCE_STATE_PRESENT = 0, + D3D12_RESOURCE_STATE_PREDICATION = 0x200, + D3D12_RESOURCE_STATE_VIDEO_DECODE_READ = 0x10000, + D3D12_RESOURCE_STATE_VIDEO_DECODE_WRITE = 0x20000, + D3D12_RESOURCE_STATE_VIDEO_PROCESS_READ = 0x40000, + D3D12_RESOURCE_STATE_VIDEO_PROCESS_WRITE = 0x80000, + D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ = 0x200000, + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE = 0x800000 + } D3D12_RESOURCE_STATES; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RESOURCE_STATES ); +typedef +enum D3D12_RESOURCE_BARRIER_TYPE + { + D3D12_RESOURCE_BARRIER_TYPE_TRANSITION = 0, + D3D12_RESOURCE_BARRIER_TYPE_ALIASING = ( D3D12_RESOURCE_BARRIER_TYPE_TRANSITION + 1 ) , + D3D12_RESOURCE_BARRIER_TYPE_UAV = ( D3D12_RESOURCE_BARRIER_TYPE_ALIASING + 1 ) + } D3D12_RESOURCE_BARRIER_TYPE; + + +typedef struct D3D12_RESOURCE_TRANSITION_BARRIER + { + ID3D12Resource *pResource; + UINT Subresource; + D3D12_RESOURCE_STATES StateBefore; + D3D12_RESOURCE_STATES StateAfter; + } D3D12_RESOURCE_TRANSITION_BARRIER; + +typedef struct D3D12_RESOURCE_ALIASING_BARRIER + { + ID3D12Resource *pResourceBefore; + ID3D12Resource *pResourceAfter; + } D3D12_RESOURCE_ALIASING_BARRIER; + +typedef struct D3D12_RESOURCE_UAV_BARRIER + { + ID3D12Resource *pResource; + } D3D12_RESOURCE_UAV_BARRIER; + +typedef +enum D3D12_RESOURCE_BARRIER_FLAGS + { + D3D12_RESOURCE_BARRIER_FLAG_NONE = 0, + D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY = 0x1, + D3D12_RESOURCE_BARRIER_FLAG_END_ONLY = 0x2 + } D3D12_RESOURCE_BARRIER_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RESOURCE_BARRIER_FLAGS ); +typedef struct D3D12_RESOURCE_BARRIER + { + D3D12_RESOURCE_BARRIER_TYPE Type; + D3D12_RESOURCE_BARRIER_FLAGS Flags; + union + { + D3D12_RESOURCE_TRANSITION_BARRIER Transition; + D3D12_RESOURCE_ALIASING_BARRIER Aliasing; + D3D12_RESOURCE_UAV_BARRIER UAV; + } ; + } D3D12_RESOURCE_BARRIER; + +typedef struct D3D12_SUBRESOURCE_FOOTPRINT + { + DXGI_FORMAT Format; + UINT Width; + UINT Height; + UINT Depth; + UINT RowPitch; + } D3D12_SUBRESOURCE_FOOTPRINT; + +typedef struct D3D12_PLACED_SUBRESOURCE_FOOTPRINT + { + UINT64 Offset; + D3D12_SUBRESOURCE_FOOTPRINT Footprint; + } D3D12_PLACED_SUBRESOURCE_FOOTPRINT; + +typedef +enum D3D12_TEXTURE_COPY_TYPE + { + D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX = 0, + D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT = 1 + } D3D12_TEXTURE_COPY_TYPE; + +typedef struct D3D12_TEXTURE_COPY_LOCATION + { + ID3D12Resource *pResource; + D3D12_TEXTURE_COPY_TYPE Type; + union + { + D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint; + UINT SubresourceIndex; + } ; + } D3D12_TEXTURE_COPY_LOCATION; + +typedef +enum D3D12_RESOLVE_MODE + { + D3D12_RESOLVE_MODE_DECOMPRESS = 0, + D3D12_RESOLVE_MODE_MIN = 1, + D3D12_RESOLVE_MODE_MAX = 2, + D3D12_RESOLVE_MODE_AVERAGE = 3 + } D3D12_RESOLVE_MODE; + +typedef struct D3D12_SAMPLE_POSITION + { + INT8 X; + INT8 Y; + } D3D12_SAMPLE_POSITION; + +typedef struct D3D12_VIEW_INSTANCE_LOCATION + { + UINT ViewportArrayIndex; + UINT RenderTargetArrayIndex; + } D3D12_VIEW_INSTANCE_LOCATION; + +typedef +enum D3D12_VIEW_INSTANCING_FLAGS + { + D3D12_VIEW_INSTANCING_FLAG_NONE = 0, + D3D12_VIEW_INSTANCING_FLAG_ENABLE_VIEW_INSTANCE_MASKING = 0x1 + } D3D12_VIEW_INSTANCING_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_VIEW_INSTANCING_FLAGS ); +typedef struct D3D12_VIEW_INSTANCING_DESC + { + UINT ViewInstanceCount; + _Field_size_full_(ViewInstanceCount) const D3D12_VIEW_INSTANCE_LOCATION *pViewInstanceLocations; + D3D12_VIEW_INSTANCING_FLAGS Flags; + } D3D12_VIEW_INSTANCING_DESC; + +typedef +enum D3D12_SHADER_COMPONENT_MAPPING + { + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 = 0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1 = 1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2 = 2, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3 = 3, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0 = 4, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1 = 5 + } D3D12_SHADER_COMPONENT_MAPPING; + +#define D3D12_SHADER_COMPONENT_MAPPING_MASK 0x7 +#define D3D12_SHADER_COMPONENT_MAPPING_SHIFT 3 +#define D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES (1<<(D3D12_SHADER_COMPONENT_MAPPING_SHIFT*4)) +#define D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(Src0,Src1,Src2,Src3) ((((Src0)&D3D12_SHADER_COMPONENT_MAPPING_MASK)| \ + (((Src1)&D3D12_SHADER_COMPONENT_MAPPING_MASK)<> (D3D12_SHADER_COMPONENT_MAPPING_SHIFT*ComponentToExtract) & D3D12_SHADER_COMPONENT_MAPPING_MASK)) +#define D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(0,1,2,3) +typedef +enum D3D12_BUFFER_SRV_FLAGS + { + D3D12_BUFFER_SRV_FLAG_NONE = 0, + D3D12_BUFFER_SRV_FLAG_RAW = 0x1 + } D3D12_BUFFER_SRV_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_BUFFER_SRV_FLAGS ); +typedef struct D3D12_BUFFER_SRV + { + UINT64 FirstElement; + UINT NumElements; + UINT StructureByteStride; + D3D12_BUFFER_SRV_FLAGS Flags; + } D3D12_BUFFER_SRV; + +typedef struct D3D12_TEX1D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; + } D3D12_TEX1D_SRV; + +typedef struct D3D12_TEX1D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + FLOAT ResourceMinLODClamp; + } D3D12_TEX1D_ARRAY_SRV; + +typedef struct D3D12_TEX2D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT PlaneSlice; + FLOAT ResourceMinLODClamp; + } D3D12_TEX2D_SRV; + +typedef struct D3D12_TEX2D_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; + FLOAT ResourceMinLODClamp; + } D3D12_TEX2D_ARRAY_SRV; + +typedef struct D3D12_TEX3D_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; + } D3D12_TEX3D_SRV; + +typedef struct D3D12_TEXCUBE_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + FLOAT ResourceMinLODClamp; + } D3D12_TEXCUBE_SRV; + +typedef struct D3D12_TEXCUBE_ARRAY_SRV + { + UINT MostDetailedMip; + UINT MipLevels; + UINT First2DArrayFace; + UINT NumCubes; + FLOAT ResourceMinLODClamp; + } D3D12_TEXCUBE_ARRAY_SRV; + +typedef struct D3D12_TEX2DMS_SRV + { + UINT UnusedField_NothingToDefine; + } D3D12_TEX2DMS_SRV; + +typedef struct D3D12_TEX2DMS_ARRAY_SRV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX2DMS_ARRAY_SRV; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV + { + D3D12_GPU_VIRTUAL_ADDRESS Location; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV; + +typedef +enum D3D12_SRV_DIMENSION + { + D3D12_SRV_DIMENSION_UNKNOWN = 0, + D3D12_SRV_DIMENSION_BUFFER = 1, + D3D12_SRV_DIMENSION_TEXTURE1D = 2, + D3D12_SRV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_SRV_DIMENSION_TEXTURE2D = 4, + D3D12_SRV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_SRV_DIMENSION_TEXTURE2DMS = 6, + D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D12_SRV_DIMENSION_TEXTURE3D = 8, + D3D12_SRV_DIMENSION_TEXTURECUBE = 9, + D3D12_SRV_DIMENSION_TEXTURECUBEARRAY = 10, + D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE = 11 + } D3D12_SRV_DIMENSION; + +typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC + { + DXGI_FORMAT Format; + D3D12_SRV_DIMENSION ViewDimension; + UINT Shader4ComponentMapping; + union + { + D3D12_BUFFER_SRV Buffer; + D3D12_TEX1D_SRV Texture1D; + D3D12_TEX1D_ARRAY_SRV Texture1DArray; + D3D12_TEX2D_SRV Texture2D; + D3D12_TEX2D_ARRAY_SRV Texture2DArray; + D3D12_TEX2DMS_SRV Texture2DMS; + D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D12_TEX3D_SRV Texture3D; + D3D12_TEXCUBE_SRV TextureCube; + D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV RaytracingAccelerationStructure; + } ; + } D3D12_SHADER_RESOURCE_VIEW_DESC; + +typedef struct D3D12_CONSTANT_BUFFER_VIEW_DESC + { + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; + } D3D12_CONSTANT_BUFFER_VIEW_DESC; + +typedef +enum D3D12_FILTER + { + D3D12_FILTER_MIN_MAG_MIP_POINT = 0, + D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1, + D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4, + D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5, + D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D12_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D12_FILTER_ANISOTROPIC = 0x55, + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D12_FILTER_COMPARISON_ANISOTROPIC = 0xd5, + D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT = 0x100, + D3D12_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x101, + D3D12_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x104, + D3D12_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x105, + D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x110, + D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x111, + D3D12_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x114, + D3D12_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR = 0x115, + D3D12_FILTER_MINIMUM_ANISOTROPIC = 0x155, + D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT = 0x180, + D3D12_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x181, + D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x184, + D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x185, + D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x190, + D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x191, + D3D12_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x194, + D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR = 0x195, + D3D12_FILTER_MAXIMUM_ANISOTROPIC = 0x1d5 + } D3D12_FILTER; + +typedef +enum D3D12_FILTER_TYPE + { + D3D12_FILTER_TYPE_POINT = 0, + D3D12_FILTER_TYPE_LINEAR = 1 + } D3D12_FILTER_TYPE; + +typedef +enum D3D12_FILTER_REDUCTION_TYPE + { + D3D12_FILTER_REDUCTION_TYPE_STANDARD = 0, + D3D12_FILTER_REDUCTION_TYPE_COMPARISON = 1, + D3D12_FILTER_REDUCTION_TYPE_MINIMUM = 2, + D3D12_FILTER_REDUCTION_TYPE_MAXIMUM = 3 + } D3D12_FILTER_REDUCTION_TYPE; + +#define D3D12_FILTER_REDUCTION_TYPE_MASK ( 0x3 ) + +#define D3D12_FILTER_REDUCTION_TYPE_SHIFT ( 7 ) + +#define D3D12_FILTER_TYPE_MASK ( 0x3 ) + +#define D3D12_MIN_FILTER_SHIFT ( 4 ) + +#define D3D12_MAG_FILTER_SHIFT ( 2 ) + +#define D3D12_MIP_FILTER_SHIFT ( 0 ) + +#define D3D12_ANISOTROPIC_FILTERING_BIT ( 0x40 ) + +#define D3D12_ENCODE_BASIC_FILTER( min, mag, mip, reduction ) \ + ( ( D3D12_FILTER ) ( \ + ( ( ( min ) & D3D12_FILTER_TYPE_MASK ) << D3D12_MIN_FILTER_SHIFT ) | \ + ( ( ( mag ) & D3D12_FILTER_TYPE_MASK ) << D3D12_MAG_FILTER_SHIFT ) | \ + ( ( ( mip ) & D3D12_FILTER_TYPE_MASK ) << D3D12_MIP_FILTER_SHIFT ) | \ + ( ( ( reduction ) & D3D12_FILTER_REDUCTION_TYPE_MASK ) << D3D12_FILTER_REDUCTION_TYPE_SHIFT ) ) ) +#define D3D12_ENCODE_ANISOTROPIC_FILTER( reduction ) \ + ( ( D3D12_FILTER ) ( \ + D3D12_ANISOTROPIC_FILTERING_BIT | \ + D3D12_ENCODE_BASIC_FILTER( D3D12_FILTER_TYPE_LINEAR, \ + D3D12_FILTER_TYPE_LINEAR, \ + D3D12_FILTER_TYPE_LINEAR, \ + reduction ) ) ) +#define D3D12_DECODE_MIN_FILTER( D3D12Filter ) \ + ( ( D3D12_FILTER_TYPE ) \ + ( ( ( D3D12Filter ) >> D3D12_MIN_FILTER_SHIFT ) & D3D12_FILTER_TYPE_MASK ) ) +#define D3D12_DECODE_MAG_FILTER( D3D12Filter ) \ + ( ( D3D12_FILTER_TYPE ) \ + ( ( ( D3D12Filter ) >> D3D12_MAG_FILTER_SHIFT ) & D3D12_FILTER_TYPE_MASK ) ) +#define D3D12_DECODE_MIP_FILTER( D3D12Filter ) \ + ( ( D3D12_FILTER_TYPE ) \ + ( ( ( D3D12Filter ) >> D3D12_MIP_FILTER_SHIFT ) & D3D12_FILTER_TYPE_MASK ) ) +#define D3D12_DECODE_FILTER_REDUCTION( D3D12Filter ) \ + ( ( D3D12_FILTER_REDUCTION_TYPE ) \ + ( ( ( D3D12Filter ) >> D3D12_FILTER_REDUCTION_TYPE_SHIFT ) & D3D12_FILTER_REDUCTION_TYPE_MASK ) ) +#define D3D12_DECODE_IS_COMPARISON_FILTER( D3D12Filter ) \ + ( D3D12_DECODE_FILTER_REDUCTION( D3D12Filter ) == D3D12_FILTER_REDUCTION_TYPE_COMPARISON ) +#define D3D12_DECODE_IS_ANISOTROPIC_FILTER( D3D12Filter ) \ + ( ( ( D3D12Filter ) & D3D12_ANISOTROPIC_FILTERING_BIT ) && \ + ( D3D12_FILTER_TYPE_LINEAR == D3D12_DECODE_MIN_FILTER( D3D12Filter ) ) && \ + ( D3D12_FILTER_TYPE_LINEAR == D3D12_DECODE_MAG_FILTER( D3D12Filter ) ) && \ + ( D3D12_FILTER_TYPE_LINEAR == D3D12_DECODE_MIP_FILTER( D3D12Filter ) ) ) +typedef +enum D3D12_TEXTURE_ADDRESS_MODE + { + D3D12_TEXTURE_ADDRESS_MODE_WRAP = 1, + D3D12_TEXTURE_ADDRESS_MODE_MIRROR = 2, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP = 3, + D3D12_TEXTURE_ADDRESS_MODE_BORDER = 4, + D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE = 5 + } D3D12_TEXTURE_ADDRESS_MODE; + +typedef struct D3D12_SAMPLER_DESC + { + D3D12_FILTER Filter; + D3D12_TEXTURE_ADDRESS_MODE AddressU; + D3D12_TEXTURE_ADDRESS_MODE AddressV; + D3D12_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D12_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[ 4 ]; + FLOAT MinLOD; + FLOAT MaxLOD; + } D3D12_SAMPLER_DESC; + +typedef +enum D3D12_BUFFER_UAV_FLAGS + { + D3D12_BUFFER_UAV_FLAG_NONE = 0, + D3D12_BUFFER_UAV_FLAG_RAW = 0x1 + } D3D12_BUFFER_UAV_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_BUFFER_UAV_FLAGS ); +typedef struct D3D12_BUFFER_UAV + { + UINT64 FirstElement; + UINT NumElements; + UINT StructureByteStride; + UINT64 CounterOffsetInBytes; + D3D12_BUFFER_UAV_FLAGS Flags; + } D3D12_BUFFER_UAV; + +typedef struct D3D12_TEX1D_UAV + { + UINT MipSlice; + } D3D12_TEX1D_UAV; + +typedef struct D3D12_TEX1D_ARRAY_UAV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX1D_ARRAY_UAV; + +typedef struct D3D12_TEX2D_UAV + { + UINT MipSlice; + UINT PlaneSlice; + } D3D12_TEX2D_UAV; + +typedef struct D3D12_TEX2D_ARRAY_UAV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; + } D3D12_TEX2D_ARRAY_UAV; + +typedef struct D3D12_TEX3D_UAV + { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; + } D3D12_TEX3D_UAV; + +typedef +enum D3D12_UAV_DIMENSION + { + D3D12_UAV_DIMENSION_UNKNOWN = 0, + D3D12_UAV_DIMENSION_BUFFER = 1, + D3D12_UAV_DIMENSION_TEXTURE1D = 2, + D3D12_UAV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_UAV_DIMENSION_TEXTURE2D = 4, + D3D12_UAV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_UAV_DIMENSION_TEXTURE3D = 8 + } D3D12_UAV_DIMENSION; + +typedef struct D3D12_UNORDERED_ACCESS_VIEW_DESC + { + DXGI_FORMAT Format; + D3D12_UAV_DIMENSION ViewDimension; + union + { + D3D12_BUFFER_UAV Buffer; + D3D12_TEX1D_UAV Texture1D; + D3D12_TEX1D_ARRAY_UAV Texture1DArray; + D3D12_TEX2D_UAV Texture2D; + D3D12_TEX2D_ARRAY_UAV Texture2DArray; + D3D12_TEX3D_UAV Texture3D; + } ; + } D3D12_UNORDERED_ACCESS_VIEW_DESC; + +typedef struct D3D12_BUFFER_RTV + { + UINT64 FirstElement; + UINT NumElements; + } D3D12_BUFFER_RTV; + +typedef struct D3D12_TEX1D_RTV + { + UINT MipSlice; + } D3D12_TEX1D_RTV; + +typedef struct D3D12_TEX1D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX1D_ARRAY_RTV; + +typedef struct D3D12_TEX2D_RTV + { + UINT MipSlice; + UINT PlaneSlice; + } D3D12_TEX2D_RTV; + +typedef struct D3D12_TEX2DMS_RTV + { + UINT UnusedField_NothingToDefine; + } D3D12_TEX2DMS_RTV; + +typedef struct D3D12_TEX2D_ARRAY_RTV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + UINT PlaneSlice; + } D3D12_TEX2D_ARRAY_RTV; + +typedef struct D3D12_TEX2DMS_ARRAY_RTV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX2DMS_ARRAY_RTV; + +typedef struct D3D12_TEX3D_RTV + { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; + } D3D12_TEX3D_RTV; + +typedef +enum D3D12_RTV_DIMENSION + { + D3D12_RTV_DIMENSION_UNKNOWN = 0, + D3D12_RTV_DIMENSION_BUFFER = 1, + D3D12_RTV_DIMENSION_TEXTURE1D = 2, + D3D12_RTV_DIMENSION_TEXTURE1DARRAY = 3, + D3D12_RTV_DIMENSION_TEXTURE2D = 4, + D3D12_RTV_DIMENSION_TEXTURE2DARRAY = 5, + D3D12_RTV_DIMENSION_TEXTURE2DMS = 6, + D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D12_RTV_DIMENSION_TEXTURE3D = 8 + } D3D12_RTV_DIMENSION; + +typedef struct D3D12_RENDER_TARGET_VIEW_DESC + { + DXGI_FORMAT Format; + D3D12_RTV_DIMENSION ViewDimension; + union + { + D3D12_BUFFER_RTV Buffer; + D3D12_TEX1D_RTV Texture1D; + D3D12_TEX1D_ARRAY_RTV Texture1DArray; + D3D12_TEX2D_RTV Texture2D; + D3D12_TEX2D_ARRAY_RTV Texture2DArray; + D3D12_TEX2DMS_RTV Texture2DMS; + D3D12_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D12_TEX3D_RTV Texture3D; + } ; + } D3D12_RENDER_TARGET_VIEW_DESC; + +typedef struct D3D12_TEX1D_DSV + { + UINT MipSlice; + } D3D12_TEX1D_DSV; + +typedef struct D3D12_TEX1D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX1D_ARRAY_DSV; + +typedef struct D3D12_TEX2D_DSV + { + UINT MipSlice; + } D3D12_TEX2D_DSV; + +typedef struct D3D12_TEX2D_ARRAY_DSV + { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX2D_ARRAY_DSV; + +typedef struct D3D12_TEX2DMS_DSV + { + UINT UnusedField_NothingToDefine; + } D3D12_TEX2DMS_DSV; + +typedef struct D3D12_TEX2DMS_ARRAY_DSV + { + UINT FirstArraySlice; + UINT ArraySize; + } D3D12_TEX2DMS_ARRAY_DSV; + +typedef +enum D3D12_DSV_FLAGS + { + D3D12_DSV_FLAG_NONE = 0, + D3D12_DSV_FLAG_READ_ONLY_DEPTH = 0x1, + D3D12_DSV_FLAG_READ_ONLY_STENCIL = 0x2 + } D3D12_DSV_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_DSV_FLAGS ); +typedef +enum D3D12_DSV_DIMENSION + { + D3D12_DSV_DIMENSION_UNKNOWN = 0, + D3D12_DSV_DIMENSION_TEXTURE1D = 1, + D3D12_DSV_DIMENSION_TEXTURE1DARRAY = 2, + D3D12_DSV_DIMENSION_TEXTURE2D = 3, + D3D12_DSV_DIMENSION_TEXTURE2DARRAY = 4, + D3D12_DSV_DIMENSION_TEXTURE2DMS = 5, + D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY = 6 + } D3D12_DSV_DIMENSION; + +typedef struct D3D12_DEPTH_STENCIL_VIEW_DESC + { + DXGI_FORMAT Format; + D3D12_DSV_DIMENSION ViewDimension; + D3D12_DSV_FLAGS Flags; + union + { + D3D12_TEX1D_DSV Texture1D; + D3D12_TEX1D_ARRAY_DSV Texture1DArray; + D3D12_TEX2D_DSV Texture2D; + D3D12_TEX2D_ARRAY_DSV Texture2DArray; + D3D12_TEX2DMS_DSV Texture2DMS; + D3D12_TEX2DMS_ARRAY_DSV Texture2DMSArray; + } ; + } D3D12_DEPTH_STENCIL_VIEW_DESC; + +typedef +enum D3D12_CLEAR_FLAGS + { + D3D12_CLEAR_FLAG_DEPTH = 0x1, + D3D12_CLEAR_FLAG_STENCIL = 0x2 + } D3D12_CLEAR_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_CLEAR_FLAGS ); +typedef +enum D3D12_FENCE_FLAGS + { + D3D12_FENCE_FLAG_NONE = 0, + D3D12_FENCE_FLAG_SHARED = 0x1, + D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x2, + D3D12_FENCE_FLAG_NON_MONITORED = 0x4 + } D3D12_FENCE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_FENCE_FLAGS ); +typedef +enum D3D12_DESCRIPTOR_HEAP_TYPE + { + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV = 0, + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + 1 ) , + D3D12_DESCRIPTOR_HEAP_TYPE_RTV = ( D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1 ) , + D3D12_DESCRIPTOR_HEAP_TYPE_DSV = ( D3D12_DESCRIPTOR_HEAP_TYPE_RTV + 1 ) , + D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES = ( D3D12_DESCRIPTOR_HEAP_TYPE_DSV + 1 ) + } D3D12_DESCRIPTOR_HEAP_TYPE; + +typedef +enum D3D12_DESCRIPTOR_HEAP_FLAGS + { + D3D12_DESCRIPTOR_HEAP_FLAG_NONE = 0, + D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE = 0x1 + } D3D12_DESCRIPTOR_HEAP_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_DESCRIPTOR_HEAP_FLAGS ); +typedef struct D3D12_DESCRIPTOR_HEAP_DESC + { + D3D12_DESCRIPTOR_HEAP_TYPE Type; + UINT NumDescriptors; + D3D12_DESCRIPTOR_HEAP_FLAGS Flags; + UINT NodeMask; + } D3D12_DESCRIPTOR_HEAP_DESC; + +typedef +enum D3D12_DESCRIPTOR_RANGE_TYPE + { + D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, + D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) , + D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) , + D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) + } D3D12_DESCRIPTOR_RANGE_TYPE; + +typedef struct D3D12_DESCRIPTOR_RANGE + { + D3D12_DESCRIPTOR_RANGE_TYPE RangeType; + UINT NumDescriptors; + UINT BaseShaderRegister; + UINT RegisterSpace; + UINT OffsetInDescriptorsFromTableStart; + } D3D12_DESCRIPTOR_RANGE; + +typedef struct D3D12_ROOT_DESCRIPTOR_TABLE + { + UINT NumDescriptorRanges; + _Field_size_full_(NumDescriptorRanges) const D3D12_DESCRIPTOR_RANGE *pDescriptorRanges; + } D3D12_ROOT_DESCRIPTOR_TABLE; + +typedef struct D3D12_ROOT_CONSTANTS + { + UINT ShaderRegister; + UINT RegisterSpace; + UINT Num32BitValues; + } D3D12_ROOT_CONSTANTS; + +typedef struct D3D12_ROOT_DESCRIPTOR + { + UINT ShaderRegister; + UINT RegisterSpace; + } D3D12_ROOT_DESCRIPTOR; + +typedef +enum D3D12_SHADER_VISIBILITY + { + D3D12_SHADER_VISIBILITY_ALL = 0, + D3D12_SHADER_VISIBILITY_VERTEX = 1, + D3D12_SHADER_VISIBILITY_HULL = 2, + D3D12_SHADER_VISIBILITY_DOMAIN = 3, + D3D12_SHADER_VISIBILITY_GEOMETRY = 4, + D3D12_SHADER_VISIBILITY_PIXEL = 5 + } D3D12_SHADER_VISIBILITY; + +typedef +enum D3D12_ROOT_PARAMETER_TYPE + { + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE = 0, + D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS = ( D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE + 1 ) , + D3D12_ROOT_PARAMETER_TYPE_CBV = ( D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS + 1 ) , + D3D12_ROOT_PARAMETER_TYPE_SRV = ( D3D12_ROOT_PARAMETER_TYPE_CBV + 1 ) , + D3D12_ROOT_PARAMETER_TYPE_UAV = ( D3D12_ROOT_PARAMETER_TYPE_SRV + 1 ) + } D3D12_ROOT_PARAMETER_TYPE; + +typedef struct D3D12_ROOT_PARAMETER + { + D3D12_ROOT_PARAMETER_TYPE ParameterType; + union + { + D3D12_ROOT_DESCRIPTOR_TABLE DescriptorTable; + D3D12_ROOT_CONSTANTS Constants; + D3D12_ROOT_DESCRIPTOR Descriptor; + } ; + D3D12_SHADER_VISIBILITY ShaderVisibility; + } D3D12_ROOT_PARAMETER; + +typedef +enum D3D12_ROOT_SIGNATURE_FLAGS + { + D3D12_ROOT_SIGNATURE_FLAG_NONE = 0, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x1, + D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS = 0x2, + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS = 0x4, + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x8, + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, + D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40, + D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE = 0x80 + } D3D12_ROOT_SIGNATURE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_ROOT_SIGNATURE_FLAGS ); +typedef +enum D3D12_STATIC_BORDER_COLOR + { + D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK = 0, + D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK = ( D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK + 1 ) , + D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE = ( D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK + 1 ) + } D3D12_STATIC_BORDER_COLOR; + +typedef struct D3D12_STATIC_SAMPLER_DESC + { + D3D12_FILTER Filter; + D3D12_TEXTURE_ADDRESS_MODE AddressU; + D3D12_TEXTURE_ADDRESS_MODE AddressV; + D3D12_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D12_COMPARISON_FUNC ComparisonFunc; + D3D12_STATIC_BORDER_COLOR BorderColor; + FLOAT MinLOD; + FLOAT MaxLOD; + UINT ShaderRegister; + UINT RegisterSpace; + D3D12_SHADER_VISIBILITY ShaderVisibility; + } D3D12_STATIC_SAMPLER_DESC; + +typedef struct D3D12_ROOT_SIGNATURE_DESC + { + UINT NumParameters; + _Field_size_full_(NumParameters) const D3D12_ROOT_PARAMETER *pParameters; + UINT NumStaticSamplers; + _Field_size_full_(NumStaticSamplers) const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; + D3D12_ROOT_SIGNATURE_FLAGS Flags; + } D3D12_ROOT_SIGNATURE_DESC; + +typedef +enum D3D12_DESCRIPTOR_RANGE_FLAGS + { + D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0, + D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8, + D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000 + } D3D12_DESCRIPTOR_RANGE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_DESCRIPTOR_RANGE_FLAGS ); +typedef struct D3D12_DESCRIPTOR_RANGE1 + { + D3D12_DESCRIPTOR_RANGE_TYPE RangeType; + UINT NumDescriptors; + UINT BaseShaderRegister; + UINT RegisterSpace; + D3D12_DESCRIPTOR_RANGE_FLAGS Flags; + UINT OffsetInDescriptorsFromTableStart; + } D3D12_DESCRIPTOR_RANGE1; + +typedef struct D3D12_ROOT_DESCRIPTOR_TABLE1 + { + UINT NumDescriptorRanges; + _Field_size_full_(NumDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1 *pDescriptorRanges; + } D3D12_ROOT_DESCRIPTOR_TABLE1; + +typedef +enum D3D12_ROOT_DESCRIPTOR_FLAGS + { + D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0, + D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2, + D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, + D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8 + } D3D12_ROOT_DESCRIPTOR_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_ROOT_DESCRIPTOR_FLAGS ); +typedef struct D3D12_ROOT_DESCRIPTOR1 + { + UINT ShaderRegister; + UINT RegisterSpace; + D3D12_ROOT_DESCRIPTOR_FLAGS Flags; + } D3D12_ROOT_DESCRIPTOR1; + +typedef struct D3D12_ROOT_PARAMETER1 + { + D3D12_ROOT_PARAMETER_TYPE ParameterType; + union + { + D3D12_ROOT_DESCRIPTOR_TABLE1 DescriptorTable; + D3D12_ROOT_CONSTANTS Constants; + D3D12_ROOT_DESCRIPTOR1 Descriptor; + } ; + D3D12_SHADER_VISIBILITY ShaderVisibility; + } D3D12_ROOT_PARAMETER1; + +typedef struct D3D12_ROOT_SIGNATURE_DESC1 + { + UINT NumParameters; + _Field_size_full_(NumParameters) const D3D12_ROOT_PARAMETER1 *pParameters; + UINT NumStaticSamplers; + _Field_size_full_(NumStaticSamplers) const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; + D3D12_ROOT_SIGNATURE_FLAGS Flags; + } D3D12_ROOT_SIGNATURE_DESC1; + +typedef struct D3D12_VERSIONED_ROOT_SIGNATURE_DESC + { + D3D_ROOT_SIGNATURE_VERSION Version; + union + { + D3D12_ROOT_SIGNATURE_DESC Desc_1_0; + D3D12_ROOT_SIGNATURE_DESC1 Desc_1_1; + } ; + } D3D12_VERSIONED_ROOT_SIGNATURE_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3D12RootSignatureDeserializer_INTERFACE_DEFINED__ +#define __ID3D12RootSignatureDeserializer_INTERFACE_DEFINED__ + +/* interface ID3D12RootSignatureDeserializer */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12RootSignatureDeserializer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("34AB647B-3CC8-46AC-841B-C0965645C046") + ID3D12RootSignatureDeserializer : public IUnknown + { + public: + virtual const D3D12_ROOT_SIGNATURE_DESC *STDMETHODCALLTYPE GetRootSignatureDesc( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12RootSignatureDeserializerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12RootSignatureDeserializer * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12RootSignatureDeserializer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12RootSignatureDeserializer * This); + + const D3D12_ROOT_SIGNATURE_DESC *( STDMETHODCALLTYPE *GetRootSignatureDesc )( + ID3D12RootSignatureDeserializer * This); + + END_INTERFACE + } ID3D12RootSignatureDeserializerVtbl; + + interface ID3D12RootSignatureDeserializer + { + CONST_VTBL struct ID3D12RootSignatureDeserializerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12RootSignatureDeserializer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12RootSignatureDeserializer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12RootSignatureDeserializer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12RootSignatureDeserializer_GetRootSignatureDesc(This) \ + ( (This)->lpVtbl -> GetRootSignatureDesc(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12RootSignatureDeserializer_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12VersionedRootSignatureDeserializer_INTERFACE_DEFINED__ +#define __ID3D12VersionedRootSignatureDeserializer_INTERFACE_DEFINED__ + +/* interface ID3D12VersionedRootSignatureDeserializer */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12VersionedRootSignatureDeserializer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7F91CE67-090C-4BB7-B78E-ED8FF2E31DA0") + ID3D12VersionedRootSignatureDeserializer : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetRootSignatureDescAtVersion( + D3D_ROOT_SIGNATURE_VERSION convertToVersion, + _Out_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC **ppDesc) = 0; + + virtual const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *STDMETHODCALLTYPE GetUnconvertedRootSignatureDesc( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12VersionedRootSignatureDeserializerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12VersionedRootSignatureDeserializer * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12VersionedRootSignatureDeserializer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12VersionedRootSignatureDeserializer * This); + + HRESULT ( STDMETHODCALLTYPE *GetRootSignatureDescAtVersion )( + ID3D12VersionedRootSignatureDeserializer * This, + D3D_ROOT_SIGNATURE_VERSION convertToVersion, + _Out_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC **ppDesc); + + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *( STDMETHODCALLTYPE *GetUnconvertedRootSignatureDesc )( + ID3D12VersionedRootSignatureDeserializer * This); + + END_INTERFACE + } ID3D12VersionedRootSignatureDeserializerVtbl; + + interface ID3D12VersionedRootSignatureDeserializer + { + CONST_VTBL struct ID3D12VersionedRootSignatureDeserializerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12VersionedRootSignatureDeserializer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12VersionedRootSignatureDeserializer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12VersionedRootSignatureDeserializer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12VersionedRootSignatureDeserializer_GetRootSignatureDescAtVersion(This,convertToVersion,ppDesc) \ + ( (This)->lpVtbl -> GetRootSignatureDescAtVersion(This,convertToVersion,ppDesc) ) + +#define ID3D12VersionedRootSignatureDeserializer_GetUnconvertedRootSignatureDesc(This) \ + ( (This)->lpVtbl -> GetUnconvertedRootSignatureDesc(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12VersionedRootSignatureDeserializer_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0003 */ +/* [local] */ + +typedef HRESULT (WINAPI* PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)( + _In_ const D3D12_ROOT_SIGNATURE_DESC* pRootSignature, + _In_ D3D_ROOT_SIGNATURE_VERSION Version, + _Out_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); + +HRESULT WINAPI D3D12SerializeRootSignature( + _In_ const D3D12_ROOT_SIGNATURE_DESC* pRootSignature, + _In_ D3D_ROOT_SIGNATURE_VERSION Version, + _Out_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); + +typedef HRESULT (WINAPI* PFN_D3D12_CREATE_ROOT_SIGNATURE_DESERIALIZER)( + _In_reads_bytes_(SrcDataSizeInBytes) LPCVOID pSrcData, + _In_ SIZE_T SrcDataSizeInBytes, + _In_ REFIID pRootSignatureDeserializerInterface, + _Out_ void** ppRootSignatureDeserializer); + +HRESULT WINAPI D3D12CreateRootSignatureDeserializer( + _In_reads_bytes_(SrcDataSizeInBytes) LPCVOID pSrcData, + _In_ SIZE_T SrcDataSizeInBytes, + _In_ REFIID pRootSignatureDeserializerInterface, + _Out_ void** ppRootSignatureDeserializer); + +typedef HRESULT (WINAPI* PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)( + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, + _Out_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); + +HRESULT WINAPI D3D12SerializeVersionedRootSignature( + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, + _Out_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); + +typedef HRESULT (WINAPI* PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER)( + _In_reads_bytes_(SrcDataSizeInBytes) LPCVOID pSrcData, + _In_ SIZE_T SrcDataSizeInBytes, + _In_ REFIID pRootSignatureDeserializerInterface, + _Out_ void** ppRootSignatureDeserializer); + +HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer( + _In_reads_bytes_(SrcDataSizeInBytes) LPCVOID pSrcData, + _In_ SIZE_T SrcDataSizeInBytes, + _In_ REFIID pRootSignatureDeserializerInterface, + _Out_ void** ppRootSignatureDeserializer); + +typedef struct D3D12_CPU_DESCRIPTOR_HANDLE + { + SIZE_T ptr; + } D3D12_CPU_DESCRIPTOR_HANDLE; + +typedef struct D3D12_GPU_DESCRIPTOR_HANDLE + { + UINT64 ptr; + } D3D12_GPU_DESCRIPTOR_HANDLE; + +// If rects are supplied in D3D12_DISCARD_REGION, below, the resource +// must have 2D subresources with all specified subresources the same dimension. +typedef struct D3D12_DISCARD_REGION + { + UINT NumRects; + _In_reads_(NumRects) const D3D12_RECT *pRects; + UINT FirstSubresource; + UINT NumSubresources; + } D3D12_DISCARD_REGION; + +typedef +enum D3D12_QUERY_HEAP_TYPE + { + D3D12_QUERY_HEAP_TYPE_OCCLUSION = 0, + D3D12_QUERY_HEAP_TYPE_TIMESTAMP = 1, + D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS = 2, + D3D12_QUERY_HEAP_TYPE_SO_STATISTICS = 3, + D3D12_QUERY_HEAP_TYPE_VIDEO_DECODE_STATISTICS = 4, + D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP = 5 + } D3D12_QUERY_HEAP_TYPE; + +typedef struct D3D12_QUERY_HEAP_DESC + { + D3D12_QUERY_HEAP_TYPE Type; + UINT Count; + UINT NodeMask; + } D3D12_QUERY_HEAP_DESC; + +typedef +enum D3D12_QUERY_TYPE + { + D3D12_QUERY_TYPE_OCCLUSION = 0, + D3D12_QUERY_TYPE_BINARY_OCCLUSION = 1, + D3D12_QUERY_TYPE_TIMESTAMP = 2, + D3D12_QUERY_TYPE_PIPELINE_STATISTICS = 3, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 = 4, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 = 5, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 = 6, + D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 = 7, + D3D12_QUERY_TYPE_VIDEO_DECODE_STATISTICS = 8 + } D3D12_QUERY_TYPE; + +typedef +enum D3D12_PREDICATION_OP + { + D3D12_PREDICATION_OP_EQUAL_ZERO = 0, + D3D12_PREDICATION_OP_NOT_EQUAL_ZERO = 1 + } D3D12_PREDICATION_OP; + +typedef struct D3D12_QUERY_DATA_PIPELINE_STATISTICS + { + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; + UINT64 HSInvocations; + UINT64 DSInvocations; + UINT64 CSInvocations; + } D3D12_QUERY_DATA_PIPELINE_STATISTICS; + +typedef struct D3D12_QUERY_DATA_SO_STATISTICS + { + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; + } D3D12_QUERY_DATA_SO_STATISTICS; + +typedef struct D3D12_STREAM_OUTPUT_BUFFER_VIEW + { + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT64 SizeInBytes; + D3D12_GPU_VIRTUAL_ADDRESS BufferFilledSizeLocation; + } D3D12_STREAM_OUTPUT_BUFFER_VIEW; + +typedef struct D3D12_DRAW_ARGUMENTS + { + UINT VertexCountPerInstance; + UINT InstanceCount; + UINT StartVertexLocation; + UINT StartInstanceLocation; + } D3D12_DRAW_ARGUMENTS; + +typedef struct D3D12_DRAW_INDEXED_ARGUMENTS + { + UINT IndexCountPerInstance; + UINT InstanceCount; + UINT StartIndexLocation; + INT BaseVertexLocation; + UINT StartInstanceLocation; + } D3D12_DRAW_INDEXED_ARGUMENTS; + +typedef struct D3D12_DISPATCH_ARGUMENTS + { + UINT ThreadGroupCountX; + UINT ThreadGroupCountY; + UINT ThreadGroupCountZ; + } D3D12_DISPATCH_ARGUMENTS; + +typedef struct D3D12_VERTEX_BUFFER_VIEW + { + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; + UINT StrideInBytes; + } D3D12_VERTEX_BUFFER_VIEW; + +typedef struct D3D12_INDEX_BUFFER_VIEW + { + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; + UINT SizeInBytes; + DXGI_FORMAT Format; + } D3D12_INDEX_BUFFER_VIEW; + +typedef +enum D3D12_INDIRECT_ARGUMENT_TYPE + { + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW = 0, + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED = ( D3D12_INDIRECT_ARGUMENT_TYPE_DRAW + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH = ( D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW = ( D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW = ( D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT = ( D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW = ( D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW = ( D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW + 1 ) , + D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW = ( D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW + 1 ) + } D3D12_INDIRECT_ARGUMENT_TYPE; + +typedef struct D3D12_INDIRECT_ARGUMENT_DESC + { + D3D12_INDIRECT_ARGUMENT_TYPE Type; + union + { + struct + { + UINT Slot; + } VertexBuffer; + struct + { + UINT RootParameterIndex; + UINT DestOffsetIn32BitValues; + UINT Num32BitValuesToSet; + } Constant; + struct + { + UINT RootParameterIndex; + } ConstantBufferView; + struct + { + UINT RootParameterIndex; + } ShaderResourceView; + struct + { + UINT RootParameterIndex; + } UnorderedAccessView; + } ; + } D3D12_INDIRECT_ARGUMENT_DESC; + +typedef struct D3D12_COMMAND_SIGNATURE_DESC + { + UINT ByteStride; + UINT NumArgumentDescs; + _Field_size_full_(NumArgumentDescs) const D3D12_INDIRECT_ARGUMENT_DESC *pArgumentDescs; + UINT NodeMask; + } D3D12_COMMAND_SIGNATURE_DESC; + + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0003_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0003_v0_0_s_ifspec; + +#ifndef __ID3D12Pageable_INTERFACE_DEFINED__ +#define __ID3D12Pageable_INTERFACE_DEFINED__ + +/* interface ID3D12Pageable */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Pageable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("63ee58fb-1268-4835-86da-f008ce62f0d6") + ID3D12Pageable : public ID3D12DeviceChild + { + public: + }; + + +#else /* C style interface */ + + typedef struct ID3D12PageableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Pageable * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Pageable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Pageable * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Pageable * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Pageable * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Pageable * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Pageable * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Pageable * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12PageableVtbl; + + interface ID3D12Pageable + { + CONST_VTBL struct ID3D12PageableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Pageable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Pageable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Pageable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Pageable_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Pageable_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Pageable_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Pageable_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Pageable_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Pageable_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Heap_INTERFACE_DEFINED__ +#define __ID3D12Heap_INTERFACE_DEFINED__ + +/* interface ID3D12Heap */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Heap; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6b3b2502-6e51-45b3-90ee-9884265e8df3") + ID3D12Heap : public ID3D12Pageable + { + public: + virtual D3D12_HEAP_DESC STDMETHODCALLTYPE GetDesc( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12HeapVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Heap * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Heap * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Heap * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Heap * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Heap * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Heap * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Heap * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Heap * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_HEAP_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12Heap * This); + + END_INTERFACE + } ID3D12HeapVtbl; + + interface ID3D12Heap + { + CONST_VTBL struct ID3D12HeapVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Heap_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Heap_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Heap_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Heap_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Heap_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Heap_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Heap_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Heap_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Heap_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12Heap_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Resource_INTERFACE_DEFINED__ +#define __ID3D12Resource_INTERFACE_DEFINED__ + +/* interface ID3D12Resource */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Resource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("696442be-a72e-4059-bc79-5b5c98040fad") + ID3D12Resource : public ID3D12Pageable + { + public: + virtual HRESULT STDMETHODCALLTYPE Map( + UINT Subresource, + _In_opt_ const D3D12_RANGE *pReadRange, + _Outptr_opt_result_bytebuffer_(_Inexpressible_("Dependent on resource")) void **ppData) = 0; + + virtual void STDMETHODCALLTYPE Unmap( + UINT Subresource, + _In_opt_ const D3D12_RANGE *pWrittenRange) = 0; + + virtual D3D12_RESOURCE_DESC STDMETHODCALLTYPE GetDesc( void) = 0; + + virtual D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE GetGPUVirtualAddress( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteToSubresource( + UINT DstSubresource, + _In_opt_ const D3D12_BOX *pDstBox, + _In_ const void *pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadFromSubresource( + _Out_ void *pDstData, + UINT DstRowPitch, + UINT DstDepthPitch, + UINT SrcSubresource, + _In_opt_ const D3D12_BOX *pSrcBox) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHeapProperties( + _Out_opt_ D3D12_HEAP_PROPERTIES *pHeapProperties, + _Out_opt_ D3D12_HEAP_FLAGS *pHeapFlags) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12ResourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Resource * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Resource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Resource * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Resource * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Resource * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Resource * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Resource * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Resource * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D12Resource * This, + UINT Subresource, + _In_opt_ const D3D12_RANGE *pReadRange, + _Outptr_opt_result_bytebuffer_(_Inexpressible_("Dependent on resource")) void **ppData); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D12Resource * This, + UINT Subresource, + _In_opt_ const D3D12_RANGE *pWrittenRange); + + D3D12_RESOURCE_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12Resource * This); + + D3D12_GPU_VIRTUAL_ADDRESS ( STDMETHODCALLTYPE *GetGPUVirtualAddress )( + ID3D12Resource * This); + + HRESULT ( STDMETHODCALLTYPE *WriteToSubresource )( + ID3D12Resource * This, + UINT DstSubresource, + _In_opt_ const D3D12_BOX *pDstBox, + _In_ const void *pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch); + + HRESULT ( STDMETHODCALLTYPE *ReadFromSubresource )( + ID3D12Resource * This, + _Out_ void *pDstData, + UINT DstRowPitch, + UINT DstDepthPitch, + UINT SrcSubresource, + _In_opt_ const D3D12_BOX *pSrcBox); + + HRESULT ( STDMETHODCALLTYPE *GetHeapProperties )( + ID3D12Resource * This, + _Out_opt_ D3D12_HEAP_PROPERTIES *pHeapProperties, + _Out_opt_ D3D12_HEAP_FLAGS *pHeapFlags); + + END_INTERFACE + } ID3D12ResourceVtbl; + + interface ID3D12Resource + { + CONST_VTBL struct ID3D12ResourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Resource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Resource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Resource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Resource_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Resource_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Resource_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Resource_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Resource_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Resource_Map(This,Subresource,pReadRange,ppData) \ + ( (This)->lpVtbl -> Map(This,Subresource,pReadRange,ppData) ) + +#define ID3D12Resource_Unmap(This,Subresource,pWrittenRange) \ + ( (This)->lpVtbl -> Unmap(This,Subresource,pWrittenRange) ) + +#define ID3D12Resource_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#define ID3D12Resource_GetGPUVirtualAddress(This) \ + ( (This)->lpVtbl -> GetGPUVirtualAddress(This) ) + +#define ID3D12Resource_WriteToSubresource(This,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) \ + ( (This)->lpVtbl -> WriteToSubresource(This,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) ) + +#define ID3D12Resource_ReadFromSubresource(This,pDstData,DstRowPitch,DstDepthPitch,SrcSubresource,pSrcBox) \ + ( (This)->lpVtbl -> ReadFromSubresource(This,pDstData,DstRowPitch,DstDepthPitch,SrcSubresource,pSrcBox) ) + +#define ID3D12Resource_GetHeapProperties(This,pHeapProperties,pHeapFlags) \ + ( (This)->lpVtbl -> GetHeapProperties(This,pHeapProperties,pHeapFlags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12Resource_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12CommandAllocator_INTERFACE_DEFINED__ +#define __ID3D12CommandAllocator_INTERFACE_DEFINED__ + +/* interface ID3D12CommandAllocator */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12CommandAllocator; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6102dee4-af59-4b09-b999-b44d73f09b24") + ID3D12CommandAllocator : public ID3D12Pageable + { + public: + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12CommandAllocatorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12CommandAllocator * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12CommandAllocator * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12CommandAllocator * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12CommandAllocator * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12CommandAllocator * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12CommandAllocator * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12CommandAllocator * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12CommandAllocator * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12CommandAllocator * This); + + END_INTERFACE + } ID3D12CommandAllocatorVtbl; + + interface ID3D12CommandAllocator + { + CONST_VTBL struct ID3D12CommandAllocatorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12CommandAllocator_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12CommandAllocator_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12CommandAllocator_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12CommandAllocator_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12CommandAllocator_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12CommandAllocator_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12CommandAllocator_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12CommandAllocator_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12CommandAllocator_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12CommandAllocator_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Fence_INTERFACE_DEFINED__ +#define __ID3D12Fence_INTERFACE_DEFINED__ + +/* interface ID3D12Fence */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Fence; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0a753dcf-c4d8-4b91-adf6-be5a60d95a76") + ID3D12Fence : public ID3D12Pageable + { + public: + virtual UINT64 STDMETHODCALLTYPE GetCompletedValue( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetEventOnCompletion( + UINT64 Value, + HANDLE hEvent) = 0; + + virtual HRESULT STDMETHODCALLTYPE Signal( + UINT64 Value) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12FenceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Fence * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Fence * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Fence * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Fence * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Fence * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Fence * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Fence * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Fence * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + UINT64 ( STDMETHODCALLTYPE *GetCompletedValue )( + ID3D12Fence * This); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnCompletion )( + ID3D12Fence * This, + UINT64 Value, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *Signal )( + ID3D12Fence * This, + UINT64 Value); + + END_INTERFACE + } ID3D12FenceVtbl; + + interface ID3D12Fence + { + CONST_VTBL struct ID3D12FenceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Fence_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Fence_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Fence_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Fence_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Fence_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Fence_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Fence_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Fence_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Fence_GetCompletedValue(This) \ + ( (This)->lpVtbl -> GetCompletedValue(This) ) + +#define ID3D12Fence_SetEventOnCompletion(This,Value,hEvent) \ + ( (This)->lpVtbl -> SetEventOnCompletion(This,Value,hEvent) ) + +#define ID3D12Fence_Signal(This,Value) \ + ( (This)->lpVtbl -> Signal(This,Value) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Fence_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Fence1_INTERFACE_DEFINED__ +#define __ID3D12Fence1_INTERFACE_DEFINED__ + +/* interface ID3D12Fence1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Fence1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a") + ID3D12Fence1 : public ID3D12Fence + { + public: + virtual D3D12_FENCE_FLAGS STDMETHODCALLTYPE GetCreationFlags( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Fence1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Fence1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Fence1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Fence1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Fence1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Fence1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Fence1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Fence1 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Fence1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + UINT64 ( STDMETHODCALLTYPE *GetCompletedValue )( + ID3D12Fence1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnCompletion )( + ID3D12Fence1 * This, + UINT64 Value, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *Signal )( + ID3D12Fence1 * This, + UINT64 Value); + + D3D12_FENCE_FLAGS ( STDMETHODCALLTYPE *GetCreationFlags )( + ID3D12Fence1 * This); + + END_INTERFACE + } ID3D12Fence1Vtbl; + + interface ID3D12Fence1 + { + CONST_VTBL struct ID3D12Fence1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Fence1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Fence1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Fence1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Fence1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Fence1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Fence1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Fence1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Fence1_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Fence1_GetCompletedValue(This) \ + ( (This)->lpVtbl -> GetCompletedValue(This) ) + +#define ID3D12Fence1_SetEventOnCompletion(This,Value,hEvent) \ + ( (This)->lpVtbl -> SetEventOnCompletion(This,Value,hEvent) ) + +#define ID3D12Fence1_Signal(This,Value) \ + ( (This)->lpVtbl -> Signal(This,Value) ) + + +#define ID3D12Fence1_GetCreationFlags(This) \ + ( (This)->lpVtbl -> GetCreationFlags(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Fence1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12PipelineState_INTERFACE_DEFINED__ +#define __ID3D12PipelineState_INTERFACE_DEFINED__ + +/* interface ID3D12PipelineState */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12PipelineState; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("765a30f3-f624-4c6f-a828-ace948622445") + ID3D12PipelineState : public ID3D12Pageable + { + public: + virtual HRESULT STDMETHODCALLTYPE GetCachedBlob( + _COM_Outptr_ ID3DBlob **ppBlob) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12PipelineStateVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12PipelineState * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12PipelineState * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12PipelineState * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12PipelineState * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12PipelineState * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12PipelineState * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12PipelineState * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12PipelineState * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *GetCachedBlob )( + ID3D12PipelineState * This, + _COM_Outptr_ ID3DBlob **ppBlob); + + END_INTERFACE + } ID3D12PipelineStateVtbl; + + interface ID3D12PipelineState + { + CONST_VTBL struct ID3D12PipelineStateVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12PipelineState_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12PipelineState_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12PipelineState_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12PipelineState_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12PipelineState_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12PipelineState_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12PipelineState_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12PipelineState_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12PipelineState_GetCachedBlob(This,ppBlob) \ + ( (This)->lpVtbl -> GetCachedBlob(This,ppBlob) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12PipelineState_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DescriptorHeap_INTERFACE_DEFINED__ +#define __ID3D12DescriptorHeap_INTERFACE_DEFINED__ + +/* interface ID3D12DescriptorHeap */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DescriptorHeap; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8efb471d-616c-4f49-90f7-127bb763fa51") + ID3D12DescriptorHeap : public ID3D12Pageable + { + public: + virtual D3D12_DESCRIPTOR_HEAP_DESC STDMETHODCALLTYPE GetDesc( void) = 0; + + virtual D3D12_CPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE GetCPUDescriptorHandleForHeapStart( void) = 0; + + virtual D3D12_GPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE GetGPUDescriptorHandleForHeapStart( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DescriptorHeapVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DescriptorHeap * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DescriptorHeap * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DescriptorHeap * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12DescriptorHeap * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12DescriptorHeap * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12DescriptorHeap * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12DescriptorHeap * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12DescriptorHeap * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_DESCRIPTOR_HEAP_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12DescriptorHeap * This); + + D3D12_CPU_DESCRIPTOR_HANDLE ( STDMETHODCALLTYPE *GetCPUDescriptorHandleForHeapStart )( + ID3D12DescriptorHeap * This); + + D3D12_GPU_DESCRIPTOR_HANDLE ( STDMETHODCALLTYPE *GetGPUDescriptorHandleForHeapStart )( + ID3D12DescriptorHeap * This); + + END_INTERFACE + } ID3D12DescriptorHeapVtbl; + + interface ID3D12DescriptorHeap + { + CONST_VTBL struct ID3D12DescriptorHeapVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DescriptorHeap_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DescriptorHeap_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DescriptorHeap_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DescriptorHeap_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12DescriptorHeap_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12DescriptorHeap_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12DescriptorHeap_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12DescriptorHeap_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12DescriptorHeap_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#define ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(This) \ + ( (This)->lpVtbl -> GetCPUDescriptorHandleForHeapStart(This) ) + +#define ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(This) \ + ( (This)->lpVtbl -> GetGPUDescriptorHandleForHeapStart(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + + + + + + + + + +#endif /* __ID3D12DescriptorHeap_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12QueryHeap_INTERFACE_DEFINED__ +#define __ID3D12QueryHeap_INTERFACE_DEFINED__ + +/* interface ID3D12QueryHeap */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12QueryHeap; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0d9658ae-ed45-469e-a61d-970ec583cab4") + ID3D12QueryHeap : public ID3D12Pageable + { + public: + }; + + +#else /* C style interface */ + + typedef struct ID3D12QueryHeapVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12QueryHeap * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12QueryHeap * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12QueryHeap * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12QueryHeap * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12QueryHeap * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12QueryHeap * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12QueryHeap * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12QueryHeap * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12QueryHeapVtbl; + + interface ID3D12QueryHeap + { + CONST_VTBL struct ID3D12QueryHeapVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12QueryHeap_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12QueryHeap_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12QueryHeap_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12QueryHeap_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12QueryHeap_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12QueryHeap_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12QueryHeap_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12QueryHeap_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12QueryHeap_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12CommandSignature_INTERFACE_DEFINED__ +#define __ID3D12CommandSignature_INTERFACE_DEFINED__ + +/* interface ID3D12CommandSignature */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12CommandSignature; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c36a797c-ec80-4f0a-8985-a7b2475082d1") + ID3D12CommandSignature : public ID3D12Pageable + { + public: + }; + + +#else /* C style interface */ + + typedef struct ID3D12CommandSignatureVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12CommandSignature * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12CommandSignature * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12CommandSignature * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12CommandSignature * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12CommandSignature * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12CommandSignature * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12CommandSignature * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12CommandSignature * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12CommandSignatureVtbl; + + interface ID3D12CommandSignature + { + CONST_VTBL struct ID3D12CommandSignatureVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12CommandSignature_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12CommandSignature_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12CommandSignature_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12CommandSignature_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12CommandSignature_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12CommandSignature_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12CommandSignature_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12CommandSignature_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12CommandSignature_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12CommandList_INTERFACE_DEFINED__ +#define __ID3D12CommandList_INTERFACE_DEFINED__ + +/* interface ID3D12CommandList */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12CommandList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7116d91c-e7e4-47ce-b8c6-ec8168f437e5") + ID3D12CommandList : public ID3D12DeviceChild + { + public: + virtual D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE GetType( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12CommandListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12CommandList * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12CommandList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12CommandList * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12CommandList * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12CommandList * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12CommandList * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12CommandList * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12CommandList * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12CommandList * This); + + END_INTERFACE + } ID3D12CommandListVtbl; + + interface ID3D12CommandList + { + CONST_VTBL struct ID3D12CommandListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12CommandList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12CommandList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12CommandList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12CommandList_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12CommandList_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12CommandList_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12CommandList_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12CommandList_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12CommandList_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12CommandList_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5b160d0f-ac1b-4185-8ba8-b3ae42a5a455") + ID3D12GraphicsCommandList : public ID3D12CommandList + { + public: + virtual HRESULT STDMETHODCALLTYPE Close( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState) = 0; + + virtual void STDMETHODCALLTYPE ClearState( + _In_opt_ ID3D12PipelineState *pPipelineState) = 0; + + virtual void STDMETHODCALLTYPE DrawInstanced( + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE DrawIndexedInstanced( + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation) = 0; + + virtual void STDMETHODCALLTYPE Dispatch( + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ) = 0; + + virtual void STDMETHODCALLTYPE CopyBufferRegion( + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes) = 0; + + virtual void STDMETHODCALLTYPE CopyTextureRegion( + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox) = 0; + + virtual void STDMETHODCALLTYPE CopyResource( + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource) = 0; + + virtual void STDMETHODCALLTYPE CopyTiles( + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags) = 0; + + virtual void STDMETHODCALLTYPE ResolveSubresource( + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format) = 0; + + virtual void STDMETHODCALLTYPE IASetPrimitiveTopology( + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology) = 0; + + virtual void STDMETHODCALLTYPE RSSetViewports( + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports) = 0; + + virtual void STDMETHODCALLTYPE RSSetScissorRects( + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE OMSetBlendFactor( + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]) = 0; + + virtual void STDMETHODCALLTYPE OMSetStencilRef( + _In_ UINT StencilRef) = 0; + + virtual void STDMETHODCALLTYPE SetPipelineState( + _In_ ID3D12PipelineState *pPipelineState) = 0; + + virtual void STDMETHODCALLTYPE ResourceBarrier( + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers) = 0; + + virtual void STDMETHODCALLTYPE ExecuteBundle( + _In_ ID3D12GraphicsCommandList *pCommandList) = 0; + + virtual void STDMETHODCALLTYPE SetDescriptorHeaps( + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRootSignature( + _In_opt_ ID3D12RootSignature *pRootSignature) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRootSignature( + _In_opt_ ID3D12RootSignature *pRootSignature) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRootDescriptorTable( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRootDescriptorTable( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRoot32BitConstant( + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRoot32BitConstant( + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRoot32BitConstants( + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRoot32BitConstants( + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRootConstantBufferView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRootConstantBufferView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRootShaderResourceView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRootShaderResourceView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE SetComputeRootUnorderedAccessView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE SetGraphicsRootUnorderedAccessView( + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0; + + virtual void STDMETHODCALLTYPE IASetIndexBuffer( + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView) = 0; + + virtual void STDMETHODCALLTYPE IASetVertexBuffers( + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews) = 0; + + virtual void STDMETHODCALLTYPE SOSetTargets( + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews) = 0; + + virtual void STDMETHODCALLTYPE OMSetRenderTargets( + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor) = 0; + + virtual void STDMETHODCALLTYPE ClearDepthStencilView( + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE ClearRenderTargetView( + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewUint( + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat( + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects) = 0; + + virtual void STDMETHODCALLTYPE DiscardResource( + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion) = 0; + + virtual void STDMETHODCALLTYPE BeginQuery( + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index) = 0; + + virtual void STDMETHODCALLTYPE EndQuery( + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index) = 0; + + virtual void STDMETHODCALLTYPE ResolveQueryData( + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset) = 0; + + virtual void STDMETHODCALLTYPE SetPredication( + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation) = 0; + + virtual void STDMETHODCALLTYPE SetMarker( + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size) = 0; + + virtual void STDMETHODCALLTYPE BeginEvent( + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size) = 0; + + virtual void STDMETHODCALLTYPE EndEvent( void) = 0; + + virtual void STDMETHODCALLTYPE ExecuteIndirect( + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + END_INTERFACE + } ID3D12GraphicsCommandListVtbl; + + interface ID3D12GraphicsCommandList + { + CONST_VTBL struct ID3D12GraphicsCommandListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList1_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList1_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("553103fb-1fe7-4557-bb38-946d7d0e7ca7") + ID3D12GraphicsCommandList1 : public ID3D12GraphicsCommandList + { + public: + virtual void STDMETHODCALLTYPE AtomicCopyBufferUINT( + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges) = 0; + + virtual void STDMETHODCALLTYPE AtomicCopyBufferUINT64( + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges) = 0; + + virtual void STDMETHODCALLTYPE OMSetDepthBounds( + _In_ FLOAT Min, + _In_ FLOAT Max) = 0; + + virtual void STDMETHODCALLTYPE SetSamplePositions( + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions) = 0; + + virtual void STDMETHODCALLTYPE ResolveSubresourceRegion( + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode) = 0; + + virtual void STDMETHODCALLTYPE SetViewInstanceMask( + _In_ UINT Mask) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandList1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList1 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList1 * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList1 * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList1 * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList1 * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList1 * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList1 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList1 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList1 * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList1 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList1 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList1 * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList1 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList1 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList1 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList1 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList1 * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList1 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList1 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList1 * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT64 )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *OMSetDepthBounds )( + ID3D12GraphicsCommandList1 * This, + _In_ FLOAT Min, + _In_ FLOAT Max); + + void ( STDMETHODCALLTYPE *SetSamplePositions )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions); + + void ( STDMETHODCALLTYPE *ResolveSubresourceRegion )( + ID3D12GraphicsCommandList1 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode); + + void ( STDMETHODCALLTYPE *SetViewInstanceMask )( + ID3D12GraphicsCommandList1 * This, + _In_ UINT Mask); + + END_INTERFACE + } ID3D12GraphicsCommandList1Vtbl; + + interface ID3D12GraphicsCommandList1 + { + CONST_VTBL struct ID3D12GraphicsCommandList1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList1_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList1_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList1_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList1_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList1_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList1_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList1_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList1_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList1_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList1_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList1_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList1_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList1_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList1_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList1_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList1_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList1_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList1_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList1_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList1_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList1_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList1_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList1_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList1_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList1_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList1_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList1_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList1_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList1_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList1_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList1_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList1_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList1_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList1_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList1_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList1_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList1_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList1_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList1_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList1_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList1_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList1_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList1_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList1_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + + +#define ID3D12GraphicsCommandList1_AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList1_AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList1_OMSetDepthBounds(This,Min,Max) \ + ( (This)->lpVtbl -> OMSetDepthBounds(This,Min,Max) ) + +#define ID3D12GraphicsCommandList1_SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) \ + ( (This)->lpVtbl -> SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) ) + +#define ID3D12GraphicsCommandList1_ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) \ + ( (This)->lpVtbl -> ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) ) + +#define ID3D12GraphicsCommandList1_SetViewInstanceMask(This,Mask) \ + ( (This)->lpVtbl -> SetViewInstanceMask(This,Mask) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0018 */ +/* [local] */ + +typedef struct D3D12_WRITEBUFFERIMMEDIATE_PARAMETER + { + D3D12_GPU_VIRTUAL_ADDRESS Dest; + UINT32 Value; + } D3D12_WRITEBUFFERIMMEDIATE_PARAMETER; + +typedef +enum D3D12_WRITEBUFFERIMMEDIATE_MODE + { + D3D12_WRITEBUFFERIMMEDIATE_MODE_DEFAULT = 0, + D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN = 0x1, + D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT = 0x2 + } D3D12_WRITEBUFFERIMMEDIATE_MODE; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0018_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0018_v0_0_s_ifspec; + +#ifndef __ID3D12GraphicsCommandList2_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList2_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList2 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("38C3E585-FF17-412C-9150-4FC6F9D72A28") + ID3D12GraphicsCommandList2 : public ID3D12GraphicsCommandList1 + { + public: + virtual void STDMETHODCALLTYPE WriteBufferImmediate( + UINT Count, + _In_reads_(Count) const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *pParams, + _In_reads_opt_(Count) const D3D12_WRITEBUFFERIMMEDIATE_MODE *pModes) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandList2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList2 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList2 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList2 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList2 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList2 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList2 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList2 * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList2 * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList2 * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList2 * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList2 * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList2 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList2 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList2 * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList2 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList2 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList2 * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList2 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList2 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList2 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList2 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList2 * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList2 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList2 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList2 * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT64 )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *OMSetDepthBounds )( + ID3D12GraphicsCommandList2 * This, + _In_ FLOAT Min, + _In_ FLOAT Max); + + void ( STDMETHODCALLTYPE *SetSamplePositions )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions); + + void ( STDMETHODCALLTYPE *ResolveSubresourceRegion )( + ID3D12GraphicsCommandList2 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode); + + void ( STDMETHODCALLTYPE *SetViewInstanceMask )( + ID3D12GraphicsCommandList2 * This, + _In_ UINT Mask); + + void ( STDMETHODCALLTYPE *WriteBufferImmediate )( + ID3D12GraphicsCommandList2 * This, + UINT Count, + _In_reads_(Count) const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *pParams, + _In_reads_opt_(Count) const D3D12_WRITEBUFFERIMMEDIATE_MODE *pModes); + + END_INTERFACE + } ID3D12GraphicsCommandList2Vtbl; + + interface ID3D12GraphicsCommandList2 + { + CONST_VTBL struct ID3D12GraphicsCommandList2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList2_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList2_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList2_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList2_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList2_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList2_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList2_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList2_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList2_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList2_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList2_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList2_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList2_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList2_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList2_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList2_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList2_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList2_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList2_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList2_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList2_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList2_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList2_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList2_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList2_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList2_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList2_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList2_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList2_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList2_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList2_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList2_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList2_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList2_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList2_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList2_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList2_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList2_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList2_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList2_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList2_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList2_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList2_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList2_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList2_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList2_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList2_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList2_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + + +#define ID3D12GraphicsCommandList2_AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList2_AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList2_OMSetDepthBounds(This,Min,Max) \ + ( (This)->lpVtbl -> OMSetDepthBounds(This,Min,Max) ) + +#define ID3D12GraphicsCommandList2_SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) \ + ( (This)->lpVtbl -> SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) ) + +#define ID3D12GraphicsCommandList2_ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) \ + ( (This)->lpVtbl -> ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) ) + +#define ID3D12GraphicsCommandList2_SetViewInstanceMask(This,Mask) \ + ( (This)->lpVtbl -> SetViewInstanceMask(This,Mask) ) + + +#define ID3D12GraphicsCommandList2_WriteBufferImmediate(This,Count,pParams,pModes) \ + ( (This)->lpVtbl -> WriteBufferImmediate(This,Count,pParams,pModes) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList2_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12CommandQueue_INTERFACE_DEFINED__ +#define __ID3D12CommandQueue_INTERFACE_DEFINED__ + +/* interface ID3D12CommandQueue */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12CommandQueue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0ec870a6-5d7e-4c22-8cfc-5baae07616ed") + ID3D12CommandQueue : public ID3D12Pageable + { + public: + virtual void STDMETHODCALLTYPE UpdateTileMappings( + _In_ ID3D12Resource *pResource, + UINT NumResourceRegions, + _In_reads_opt_(NumResourceRegions) const D3D12_TILED_RESOURCE_COORDINATE *pResourceRegionStartCoordinates, + _In_reads_opt_(NumResourceRegions) const D3D12_TILE_REGION_SIZE *pResourceRegionSizes, + _In_opt_ ID3D12Heap *pHeap, + UINT NumRanges, + _In_reads_opt_(NumRanges) const D3D12_TILE_RANGE_FLAGS *pRangeFlags, + _In_reads_opt_(NumRanges) const UINT *pHeapRangeStartOffsets, + _In_reads_opt_(NumRanges) const UINT *pRangeTileCounts, + D3D12_TILE_MAPPING_FLAGS Flags) = 0; + + virtual void STDMETHODCALLTYPE CopyTileMappings( + _In_ ID3D12Resource *pDstResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pDstRegionStartCoordinate, + _In_ ID3D12Resource *pSrcResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pSrcRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pRegionSize, + D3D12_TILE_MAPPING_FLAGS Flags) = 0; + + virtual void STDMETHODCALLTYPE ExecuteCommandLists( + _In_ UINT NumCommandLists, + _In_reads_(NumCommandLists) ID3D12CommandList *const *ppCommandLists) = 0; + + virtual void STDMETHODCALLTYPE SetMarker( + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size) = 0; + + virtual void STDMETHODCALLTYPE BeginEvent( + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size) = 0; + + virtual void STDMETHODCALLTYPE EndEvent( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Signal( + ID3D12Fence *pFence, + UINT64 Value) = 0; + + virtual HRESULT STDMETHODCALLTYPE Wait( + ID3D12Fence *pFence, + UINT64 Value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTimestampFrequency( + _Out_ UINT64 *pFrequency) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetClockCalibration( + _Out_ UINT64 *pGpuTimestamp, + _Out_ UINT64 *pCpuTimestamp) = 0; + + virtual D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE GetDesc( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12CommandQueueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12CommandQueue * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12CommandQueue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12CommandQueue * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12CommandQueue * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12CommandQueue * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12CommandQueue * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12CommandQueue * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12CommandQueue * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + void ( STDMETHODCALLTYPE *UpdateTileMappings )( + ID3D12CommandQueue * This, + _In_ ID3D12Resource *pResource, + UINT NumResourceRegions, + _In_reads_opt_(NumResourceRegions) const D3D12_TILED_RESOURCE_COORDINATE *pResourceRegionStartCoordinates, + _In_reads_opt_(NumResourceRegions) const D3D12_TILE_REGION_SIZE *pResourceRegionSizes, + _In_opt_ ID3D12Heap *pHeap, + UINT NumRanges, + _In_reads_opt_(NumRanges) const D3D12_TILE_RANGE_FLAGS *pRangeFlags, + _In_reads_opt_(NumRanges) const UINT *pHeapRangeStartOffsets, + _In_reads_opt_(NumRanges) const UINT *pRangeTileCounts, + D3D12_TILE_MAPPING_FLAGS Flags); + + void ( STDMETHODCALLTYPE *CopyTileMappings )( + ID3D12CommandQueue * This, + _In_ ID3D12Resource *pDstResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pDstRegionStartCoordinate, + _In_ ID3D12Resource *pSrcResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pSrcRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pRegionSize, + D3D12_TILE_MAPPING_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ExecuteCommandLists )( + ID3D12CommandQueue * This, + _In_ UINT NumCommandLists, + _In_reads_(NumCommandLists) ID3D12CommandList *const *ppCommandLists); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12CommandQueue * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12CommandQueue * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12CommandQueue * This); + + HRESULT ( STDMETHODCALLTYPE *Signal )( + ID3D12CommandQueue * This, + ID3D12Fence *pFence, + UINT64 Value); + + HRESULT ( STDMETHODCALLTYPE *Wait )( + ID3D12CommandQueue * This, + ID3D12Fence *pFence, + UINT64 Value); + + HRESULT ( STDMETHODCALLTYPE *GetTimestampFrequency )( + ID3D12CommandQueue * This, + _Out_ UINT64 *pFrequency); + + HRESULT ( STDMETHODCALLTYPE *GetClockCalibration )( + ID3D12CommandQueue * This, + _Out_ UINT64 *pGpuTimestamp, + _Out_ UINT64 *pCpuTimestamp); + + D3D12_COMMAND_QUEUE_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12CommandQueue * This); + + END_INTERFACE + } ID3D12CommandQueueVtbl; + + interface ID3D12CommandQueue + { + CONST_VTBL struct ID3D12CommandQueueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12CommandQueue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12CommandQueue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12CommandQueue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12CommandQueue_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12CommandQueue_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12CommandQueue_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12CommandQueue_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12CommandQueue_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12CommandQueue_UpdateTileMappings(This,pResource,NumResourceRegions,pResourceRegionStartCoordinates,pResourceRegionSizes,pHeap,NumRanges,pRangeFlags,pHeapRangeStartOffsets,pRangeTileCounts,Flags) \ + ( (This)->lpVtbl -> UpdateTileMappings(This,pResource,NumResourceRegions,pResourceRegionStartCoordinates,pResourceRegionSizes,pHeap,NumRanges,pRangeFlags,pHeapRangeStartOffsets,pRangeTileCounts,Flags) ) + +#define ID3D12CommandQueue_CopyTileMappings(This,pDstResource,pDstRegionStartCoordinate,pSrcResource,pSrcRegionStartCoordinate,pRegionSize,Flags) \ + ( (This)->lpVtbl -> CopyTileMappings(This,pDstResource,pDstRegionStartCoordinate,pSrcResource,pSrcRegionStartCoordinate,pRegionSize,Flags) ) + +#define ID3D12CommandQueue_ExecuteCommandLists(This,NumCommandLists,ppCommandLists) \ + ( (This)->lpVtbl -> ExecuteCommandLists(This,NumCommandLists,ppCommandLists) ) + +#define ID3D12CommandQueue_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12CommandQueue_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12CommandQueue_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12CommandQueue_Signal(This,pFence,Value) \ + ( (This)->lpVtbl -> Signal(This,pFence,Value) ) + +#define ID3D12CommandQueue_Wait(This,pFence,Value) \ + ( (This)->lpVtbl -> Wait(This,pFence,Value) ) + +#define ID3D12CommandQueue_GetTimestampFrequency(This,pFrequency) \ + ( (This)->lpVtbl -> GetTimestampFrequency(This,pFrequency) ) + +#define ID3D12CommandQueue_GetClockCalibration(This,pGpuTimestamp,pCpuTimestamp) \ + ( (This)->lpVtbl -> GetClockCalibration(This,pGpuTimestamp,pCpuTimestamp) ) + +#define ID3D12CommandQueue_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12CommandQueue_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0020 */ +/* [local] */ + +#ifdef __midl +#ifndef LUID_DEFINED +#define LUID_DEFINED 1 +typedef struct __LUID + { + DWORD LowPart; + LONG HighPart; + } LUID; + +typedef struct __LUID *PLUID; + +#endif +#endif + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0020_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0020_v0_0_s_ifspec; + +#ifndef __ID3D12Device_INTERFACE_DEFINED__ +#define __ID3D12Device_INTERFACE_DEFINED__ + +/* interface ID3D12Device */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("189819f1-1db6-4b57-be54-1821339b85f7") + ID3D12Device : public ID3D12Object + { + public: + virtual UINT STDMETHODCALLTYPE GetNodeCount( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommandQueue( + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommandAllocator( + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateGraphicsPipelineState( + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateComputePipelineState( + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommandList( + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport( + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateDescriptorHeap( + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap) = 0; + + virtual UINT STDMETHODCALLTYPE GetDescriptorHandleIncrementSize( + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateRootSignature( + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature) = 0; + + virtual void STDMETHODCALLTYPE CreateConstantBufferView( + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CreateShaderResourceView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CreateUnorderedAccessView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CreateRenderTargetView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CreateDepthStencilView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CreateSampler( + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) = 0; + + virtual void STDMETHODCALLTYPE CopyDescriptors( + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) = 0; + + virtual void STDMETHODCALLTYPE CopyDescriptorsSimple( + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) = 0; + + virtual D3D12_RESOURCE_ALLOCATION_INFO STDMETHODCALLTYPE GetResourceAllocationInfo( + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs) = 0; + + virtual D3D12_HEAP_PROPERTIES STDMETHODCALLTYPE GetCustomHeapProperties( + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommittedResource( + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateHeap( + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreatePlacedResource( + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateReservedResource( + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle( + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle) = 0; + + virtual HRESULT STDMETHODCALLTYPE OpenSharedHandle( + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj) = 0; + + virtual HRESULT STDMETHODCALLTYPE OpenSharedHandleByName( + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle) = 0; + + virtual HRESULT STDMETHODCALLTYPE MakeResident( + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects) = 0; + + virtual HRESULT STDMETHODCALLTYPE Evict( + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateFence( + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason( void) = 0; + + virtual void STDMETHODCALLTYPE GetCopyableFootprints( + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateQueryHeap( + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetStablePowerState( + BOOL Enable) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommandSignature( + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature) = 0; + + virtual void STDMETHODCALLTYPE GetResourceTiling( + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips) = 0; + + virtual LUID STDMETHODCALLTYPE GetAdapterLuid( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DeviceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device * This); + + END_INTERFACE + } ID3D12DeviceVtbl; + + interface ID3D12Device + { + CONST_VTBL struct ID3D12DeviceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + + + + + + + + + +#endif /* __ID3D12Device_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12PipelineLibrary_INTERFACE_DEFINED__ +#define __ID3D12PipelineLibrary_INTERFACE_DEFINED__ + +/* interface ID3D12PipelineLibrary */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12PipelineLibrary; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c64226a8-9201-46af-b4cc-53fb9ff7414f") + ID3D12PipelineLibrary : public ID3D12DeviceChild + { + public: + virtual HRESULT STDMETHODCALLTYPE StorePipeline( + _In_opt_ LPCWSTR pName, + _In_ ID3D12PipelineState *pPipeline) = 0; + + virtual HRESULT STDMETHODCALLTYPE LoadGraphicsPipeline( + _In_ LPCWSTR pName, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + virtual HRESULT STDMETHODCALLTYPE LoadComputePipeline( + _In_ LPCWSTR pName, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + virtual SIZE_T STDMETHODCALLTYPE GetSerializedSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Serialize( + _Out_writes_(DataSizeInBytes) void *pData, + SIZE_T DataSizeInBytes) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12PipelineLibraryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12PipelineLibrary * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12PipelineLibrary * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12PipelineLibrary * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12PipelineLibrary * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12PipelineLibrary * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12PipelineLibrary * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12PipelineLibrary * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12PipelineLibrary * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *StorePipeline )( + ID3D12PipelineLibrary * This, + _In_opt_ LPCWSTR pName, + _In_ ID3D12PipelineState *pPipeline); + + HRESULT ( STDMETHODCALLTYPE *LoadGraphicsPipeline )( + ID3D12PipelineLibrary * This, + _In_ LPCWSTR pName, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *LoadComputePipeline )( + ID3D12PipelineLibrary * This, + _In_ LPCWSTR pName, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + SIZE_T ( STDMETHODCALLTYPE *GetSerializedSize )( + ID3D12PipelineLibrary * This); + + HRESULT ( STDMETHODCALLTYPE *Serialize )( + ID3D12PipelineLibrary * This, + _Out_writes_(DataSizeInBytes) void *pData, + SIZE_T DataSizeInBytes); + + END_INTERFACE + } ID3D12PipelineLibraryVtbl; + + interface ID3D12PipelineLibrary + { + CONST_VTBL struct ID3D12PipelineLibraryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12PipelineLibrary_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12PipelineLibrary_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12PipelineLibrary_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12PipelineLibrary_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12PipelineLibrary_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12PipelineLibrary_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12PipelineLibrary_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12PipelineLibrary_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12PipelineLibrary_StorePipeline(This,pName,pPipeline) \ + ( (This)->lpVtbl -> StorePipeline(This,pName,pPipeline) ) + +#define ID3D12PipelineLibrary_LoadGraphicsPipeline(This,pName,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> LoadGraphicsPipeline(This,pName,pDesc,riid,ppPipelineState) ) + +#define ID3D12PipelineLibrary_LoadComputePipeline(This,pName,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> LoadComputePipeline(This,pName,pDesc,riid,ppPipelineState) ) + +#define ID3D12PipelineLibrary_GetSerializedSize(This) \ + ( (This)->lpVtbl -> GetSerializedSize(This) ) + +#define ID3D12PipelineLibrary_Serialize(This,pData,DataSizeInBytes) \ + ( (This)->lpVtbl -> Serialize(This,pData,DataSizeInBytes) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12PipelineLibrary_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12PipelineLibrary1_INTERFACE_DEFINED__ +#define __ID3D12PipelineLibrary1_INTERFACE_DEFINED__ + +/* interface ID3D12PipelineLibrary1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12PipelineLibrary1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("80eabf42-2568-4e5e-bd82-c37f86961dc3") + ID3D12PipelineLibrary1 : public ID3D12PipelineLibrary + { + public: + virtual HRESULT STDMETHODCALLTYPE LoadPipeline( + _In_ LPCWSTR pName, + _In_ const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12PipelineLibrary1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12PipelineLibrary1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12PipelineLibrary1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12PipelineLibrary1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12PipelineLibrary1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12PipelineLibrary1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12PipelineLibrary1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12PipelineLibrary1 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12PipelineLibrary1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *StorePipeline )( + ID3D12PipelineLibrary1 * This, + _In_opt_ LPCWSTR pName, + _In_ ID3D12PipelineState *pPipeline); + + HRESULT ( STDMETHODCALLTYPE *LoadGraphicsPipeline )( + ID3D12PipelineLibrary1 * This, + _In_ LPCWSTR pName, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *LoadComputePipeline )( + ID3D12PipelineLibrary1 * This, + _In_ LPCWSTR pName, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + SIZE_T ( STDMETHODCALLTYPE *GetSerializedSize )( + ID3D12PipelineLibrary1 * This); + + HRESULT ( STDMETHODCALLTYPE *Serialize )( + ID3D12PipelineLibrary1 * This, + _Out_writes_(DataSizeInBytes) void *pData, + SIZE_T DataSizeInBytes); + + HRESULT ( STDMETHODCALLTYPE *LoadPipeline )( + ID3D12PipelineLibrary1 * This, + _In_ LPCWSTR pName, + _In_ const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + END_INTERFACE + } ID3D12PipelineLibrary1Vtbl; + + interface ID3D12PipelineLibrary1 + { + CONST_VTBL struct ID3D12PipelineLibrary1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12PipelineLibrary1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12PipelineLibrary1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12PipelineLibrary1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12PipelineLibrary1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12PipelineLibrary1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12PipelineLibrary1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12PipelineLibrary1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12PipelineLibrary1_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12PipelineLibrary1_StorePipeline(This,pName,pPipeline) \ + ( (This)->lpVtbl -> StorePipeline(This,pName,pPipeline) ) + +#define ID3D12PipelineLibrary1_LoadGraphicsPipeline(This,pName,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> LoadGraphicsPipeline(This,pName,pDesc,riid,ppPipelineState) ) + +#define ID3D12PipelineLibrary1_LoadComputePipeline(This,pName,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> LoadComputePipeline(This,pName,pDesc,riid,ppPipelineState) ) + +#define ID3D12PipelineLibrary1_GetSerializedSize(This) \ + ( (This)->lpVtbl -> GetSerializedSize(This) ) + +#define ID3D12PipelineLibrary1_Serialize(This,pData,DataSizeInBytes) \ + ( (This)->lpVtbl -> Serialize(This,pData,DataSizeInBytes) ) + + +#define ID3D12PipelineLibrary1_LoadPipeline(This,pName,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> LoadPipeline(This,pName,pDesc,riid,ppPipelineState) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12PipelineLibrary1_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0023 */ +/* [local] */ + +typedef +enum D3D12_MULTIPLE_FENCE_WAIT_FLAGS + { + D3D12_MULTIPLE_FENCE_WAIT_FLAG_NONE = 0, + D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY = 0x1, + D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL = 0 + } D3D12_MULTIPLE_FENCE_WAIT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_MULTIPLE_FENCE_WAIT_FLAGS ); +typedef +enum D3D12_RESIDENCY_PRIORITY + { + D3D12_RESIDENCY_PRIORITY_MINIMUM = 0x28000000, + D3D12_RESIDENCY_PRIORITY_LOW = 0x50000000, + D3D12_RESIDENCY_PRIORITY_NORMAL = 0x78000000, + D3D12_RESIDENCY_PRIORITY_HIGH = 0xa0010000, + D3D12_RESIDENCY_PRIORITY_MAXIMUM = 0xc8000000 + } D3D12_RESIDENCY_PRIORITY; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0023_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0023_v0_0_s_ifspec; + +#ifndef __ID3D12Device1_INTERFACE_DEFINED__ +#define __ID3D12Device1_INTERFACE_DEFINED__ + +/* interface ID3D12Device1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("77acce80-638e-4e65-8895-c1f23386863e") + ID3D12Device1 : public ID3D12Device + { + public: + virtual HRESULT STDMETHODCALLTYPE CreatePipelineLibrary( + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetEventOnMultipleFenceCompletion( + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetResidencyPriority( + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device1 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device1 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device1 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device1 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device1 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device1 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device1 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device1 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device1 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device1 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device1 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device1 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device1 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device1 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device1 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device1 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device1 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device1 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device1 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device1 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device1 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device1 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device1 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device1 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device1 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device1 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device1 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device1 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device1 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device1 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device1 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device1 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device1 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device1 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device1 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device1 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device1 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device1 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device1 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device1 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + END_INTERFACE + } ID3D12Device1Vtbl; + + interface ID3D12Device1 + { + CONST_VTBL struct ID3D12Device1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device1_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device1_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device1_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device1_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device1_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device1_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device1_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device1_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device1_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device1_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device1_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device1_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device1_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device1_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device1_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device1_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device1_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device1_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device1_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device1_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device1_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device1_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device1_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device1_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device1_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device1_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device1_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device1_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device1_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device1_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device1_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device1_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device1_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device1_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device1_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Device1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Device2_INTERFACE_DEFINED__ +#define __ID3D12Device2_INTERFACE_DEFINED__ + +/* interface ID3D12Device2 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("30baa41e-b15b-475c-a0bb-1af5c5b64328") + ID3D12Device2 : public ID3D12Device1 + { + public: + virtual HRESULT STDMETHODCALLTYPE CreatePipelineState( + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device2 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device2 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device2 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device2 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device2 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device2 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device2 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device2 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device2 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device2 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device2 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device2 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device2 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device2 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device2 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device2 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device2 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device2 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device2 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device2 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device2 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device2 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device2 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device2 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device2 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device2 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device2 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device2 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device2 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device2 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device2 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device2 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device2 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device2 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device2 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device2 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device2 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device2 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device2 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device2 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device2 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device2 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device2 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device2 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device2 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineState )( + ID3D12Device2 * This, + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + END_INTERFACE + } ID3D12Device2Vtbl; + + interface ID3D12Device2 + { + CONST_VTBL struct ID3D12Device2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device2_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device2_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device2_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device2_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device2_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device2_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device2_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device2_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device2_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device2_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device2_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device2_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device2_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device2_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device2_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device2_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device2_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device2_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device2_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device2_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device2_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device2_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device2_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device2_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device2_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device2_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device2_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device2_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device2_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device2_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device2_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device2_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device2_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device2_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device2_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device2_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device2_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device2_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device2_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + + +#define ID3D12Device2_CreatePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreatePipelineState(This,pDesc,riid,ppPipelineState) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Device2_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0025 */ +/* [local] */ + +typedef +enum D3D12_RESIDENCY_FLAGS + { + D3D12_RESIDENCY_FLAG_NONE = 0, + D3D12_RESIDENCY_FLAG_DENY_OVERBUDGET = 0x1 + } D3D12_RESIDENCY_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RESIDENCY_FLAGS ); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0025_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0025_v0_0_s_ifspec; + +#ifndef __ID3D12Device3_INTERFACE_DEFINED__ +#define __ID3D12Device3_INTERFACE_DEFINED__ + +/* interface ID3D12Device3 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("81dadc15-2bad-4392-93c5-101345c4aa98") + ID3D12Device3 : public ID3D12Device2 + { + public: + virtual HRESULT STDMETHODCALLTYPE OpenExistingHeapFromAddress( + _In_ const void *pAddress, + REFIID riid, + _COM_Outptr_ void **ppvHeap) = 0; + + virtual HRESULT STDMETHODCALLTYPE OpenExistingHeapFromFileMapping( + _In_ HANDLE hFileMapping, + REFIID riid, + _COM_Outptr_ void **ppvHeap) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnqueueMakeResident( + D3D12_RESIDENCY_FLAGS Flags, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_ ID3D12Fence *pFenceToSignal, + UINT64 FenceValueToSignal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device3 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device3 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device3 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device3 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device3 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device3 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device3 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device3 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device3 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device3 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device3 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device3 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device3 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device3 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device3 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device3 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device3 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device3 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device3 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device3 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device3 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device3 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device3 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device3 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device3 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device3 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device3 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device3 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device3 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device3 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device3 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device3 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device3 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device3 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device3 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device3 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device3 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device3 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device3 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device3 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device3 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device3 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device3 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device3 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device3 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineState )( + ID3D12Device3 * This, + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromAddress )( + ID3D12Device3 * This, + _In_ const void *pAddress, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromFileMapping )( + ID3D12Device3 * This, + _In_ HANDLE hFileMapping, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *EnqueueMakeResident )( + ID3D12Device3 * This, + D3D12_RESIDENCY_FLAGS Flags, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_ ID3D12Fence *pFenceToSignal, + UINT64 FenceValueToSignal); + + END_INTERFACE + } ID3D12Device3Vtbl; + + interface ID3D12Device3 + { + CONST_VTBL struct ID3D12Device3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device3_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device3_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device3_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device3_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device3_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device3_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device3_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device3_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device3_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device3_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device3_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device3_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device3_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device3_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device3_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device3_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device3_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device3_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device3_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device3_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device3_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device3_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device3_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device3_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device3_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device3_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device3_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device3_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device3_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device3_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device3_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device3_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device3_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device3_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device3_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device3_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device3_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device3_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device3_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + + +#define ID3D12Device3_CreatePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreatePipelineState(This,pDesc,riid,ppPipelineState) ) + + +#define ID3D12Device3_OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) ) + +#define ID3D12Device3_OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) ) + +#define ID3D12Device3_EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) \ + ( (This)->lpVtbl -> EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Device3_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0026 */ +/* [local] */ + +typedef +enum D3D12_COMMAND_LIST_FLAGS + { + D3D12_COMMAND_LIST_FLAG_NONE = 0 + } D3D12_COMMAND_LIST_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMMAND_LIST_FLAGS ); +typedef +enum D3D12_COMMAND_POOL_FLAGS + { + D3D12_COMMAND_POOL_FLAG_NONE = 0 + } D3D12_COMMAND_POOL_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMMAND_POOL_FLAGS ); +typedef +enum D3D12_COMMAND_RECORDER_FLAGS + { + D3D12_COMMAND_RECORDER_FLAG_NONE = 0 + } D3D12_COMMAND_RECORDER_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMMAND_RECORDER_FLAGS ); +typedef +enum D3D12_PROTECTED_SESSION_STATUS + { + D3D12_PROTECTED_SESSION_STATUS_OK = 0, + D3D12_PROTECTED_SESSION_STATUS_INVALID = 1 + } D3D12_PROTECTED_SESSION_STATUS; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0026_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0026_v0_0_s_ifspec; + +#ifndef __ID3D12ProtectedSession_INTERFACE_DEFINED__ +#define __ID3D12ProtectedSession_INTERFACE_DEFINED__ + +/* interface ID3D12ProtectedSession */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12ProtectedSession; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A1533D18-0AC1-4084-85B9-89A96116806B") + ID3D12ProtectedSession : public ID3D12DeviceChild + { + public: + virtual HRESULT STDMETHODCALLTYPE GetStatusFence( + REFIID riid, + _COM_Outptr_opt_ void **ppFence) = 0; + + virtual D3D12_PROTECTED_SESSION_STATUS STDMETHODCALLTYPE GetSessionStatus( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12ProtectedSessionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12ProtectedSession * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12ProtectedSession * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12ProtectedSession * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12ProtectedSession * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12ProtectedSession * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12ProtectedSession * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12ProtectedSession * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12ProtectedSession * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *GetStatusFence )( + ID3D12ProtectedSession * This, + REFIID riid, + _COM_Outptr_opt_ void **ppFence); + + D3D12_PROTECTED_SESSION_STATUS ( STDMETHODCALLTYPE *GetSessionStatus )( + ID3D12ProtectedSession * This); + + END_INTERFACE + } ID3D12ProtectedSessionVtbl; + + interface ID3D12ProtectedSession + { + CONST_VTBL struct ID3D12ProtectedSessionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12ProtectedSession_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12ProtectedSession_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12ProtectedSession_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12ProtectedSession_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12ProtectedSession_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12ProtectedSession_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12ProtectedSession_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12ProtectedSession_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12ProtectedSession_GetStatusFence(This,riid,ppFence) \ + ( (This)->lpVtbl -> GetStatusFence(This,riid,ppFence) ) + +#define ID3D12ProtectedSession_GetSessionStatus(This) \ + ( (This)->lpVtbl -> GetSessionStatus(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12ProtectedSession_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0027 */ +/* [local] */ + +typedef +enum D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS + { + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE = 0, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED = 0x1 + } D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS ); +typedef struct D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT + { + UINT NodeIndex; + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS Support; + } D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT; + +typedef +enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS + { + D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0 + } D3D12_PROTECTED_RESOURCE_SESSION_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_PROTECTED_RESOURCE_SESSION_FLAGS ); +typedef struct D3D12_PROTECTED_RESOURCE_SESSION_DESC + { + UINT NodeMask; + D3D12_PROTECTED_RESOURCE_SESSION_FLAGS Flags; + } D3D12_PROTECTED_RESOURCE_SESSION_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0027_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0027_v0_0_s_ifspec; + +#ifndef __ID3D12ProtectedResourceSession_INTERFACE_DEFINED__ +#define __ID3D12ProtectedResourceSession_INTERFACE_DEFINED__ + +/* interface ID3D12ProtectedResourceSession */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12ProtectedResourceSession; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6CD696F4-F289-40CC-8091-5A6C0A099C3D") + ID3D12ProtectedResourceSession : public ID3D12ProtectedSession + { + public: + virtual D3D12_PROTECTED_RESOURCE_SESSION_DESC STDMETHODCALLTYPE GetDesc( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12ProtectedResourceSessionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12ProtectedResourceSession * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12ProtectedResourceSession * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12ProtectedResourceSession * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12ProtectedResourceSession * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12ProtectedResourceSession * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12ProtectedResourceSession * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12ProtectedResourceSession * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12ProtectedResourceSession * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *GetStatusFence )( + ID3D12ProtectedResourceSession * This, + REFIID riid, + _COM_Outptr_opt_ void **ppFence); + + D3D12_PROTECTED_SESSION_STATUS ( STDMETHODCALLTYPE *GetSessionStatus )( + ID3D12ProtectedResourceSession * This); + + D3D12_PROTECTED_RESOURCE_SESSION_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12ProtectedResourceSession * This); + + END_INTERFACE + } ID3D12ProtectedResourceSessionVtbl; + + interface ID3D12ProtectedResourceSession + { + CONST_VTBL struct ID3D12ProtectedResourceSessionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12ProtectedResourceSession_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12ProtectedResourceSession_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12ProtectedResourceSession_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12ProtectedResourceSession_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12ProtectedResourceSession_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12ProtectedResourceSession_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12ProtectedResourceSession_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12ProtectedResourceSession_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12ProtectedResourceSession_GetStatusFence(This,riid,ppFence) \ + ( (This)->lpVtbl -> GetStatusFence(This,riid,ppFence) ) + +#define ID3D12ProtectedResourceSession_GetSessionStatus(This) \ + ( (This)->lpVtbl -> GetSessionStatus(This) ) + + +#define ID3D12ProtectedResourceSession_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12ProtectedResourceSession_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Device4_INTERFACE_DEFINED__ +#define __ID3D12Device4_INTERFACE_DEFINED__ + +/* interface ID3D12Device4 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e865df17-a9ee-46f9-a463-3098315aa2e5") + ID3D12Device4 : public ID3D12Device3 + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateCommandList1( + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ D3D12_COMMAND_LIST_FLAGS flags, + REFIID riid, + _COM_Outptr_ void **ppCommandList) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateProtectedResourceSession( + _In_ const D3D12_PROTECTED_RESOURCE_SESSION_DESC *pDesc, + _In_ REFIID riid, + _COM_Outptr_ void **ppSession) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateCommittedResource1( + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateHeap1( + _In_ const D3D12_HEAP_DESC *pDesc, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateReservedResource1( + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource) = 0; + + virtual D3D12_RESOURCE_ALLOCATION_INFO STDMETHODCALLTYPE GetResourceAllocationInfo1( + UINT visibleMask, + UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs, + _Out_writes_opt_(numResourceDescs) D3D12_RESOURCE_ALLOCATION_INFO1 *pResourceAllocationInfo1) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device4 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device4 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device4 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device4 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device4 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device4 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device4 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device4 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device4 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device4 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device4 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device4 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device4 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device4 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device4 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device4 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device4 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device4 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device4 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device4 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device4 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device4 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device4 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device4 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device4 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device4 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device4 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device4 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device4 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device4 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device4 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device4 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device4 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device4 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device4 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device4 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device4 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device4 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device4 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device4 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device4 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device4 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device4 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device4 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device4 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineState )( + ID3D12Device4 * This, + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromAddress )( + ID3D12Device4 * This, + _In_ const void *pAddress, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromFileMapping )( + ID3D12Device4 * This, + _In_ HANDLE hFileMapping, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *EnqueueMakeResident )( + ID3D12Device4 * This, + D3D12_RESIDENCY_FLAGS Flags, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_ ID3D12Fence *pFenceToSignal, + UINT64 FenceValueToSignal); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList1 )( + ID3D12Device4 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ D3D12_COMMAND_LIST_FLAGS flags, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CreateProtectedResourceSession )( + ID3D12Device4 * This, + _In_ const D3D12_PROTECTED_RESOURCE_SESSION_DESC *pDesc, + _In_ REFIID riid, + _COM_Outptr_ void **ppSession); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource1 )( + ID3D12Device4 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap1 )( + ID3D12Device4 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource1 )( + ID3D12Device4 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo1 )( + ID3D12Device4 * This, + UINT visibleMask, + UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs, + _Out_writes_opt_(numResourceDescs) D3D12_RESOURCE_ALLOCATION_INFO1 *pResourceAllocationInfo1); + + END_INTERFACE + } ID3D12Device4Vtbl; + + interface ID3D12Device4 + { + CONST_VTBL struct ID3D12Device4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device4_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device4_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device4_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device4_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device4_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device4_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device4_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device4_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device4_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device4_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device4_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device4_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device4_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device4_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device4_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device4_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device4_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device4_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device4_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device4_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device4_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device4_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device4_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device4_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device4_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device4_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device4_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device4_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device4_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device4_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device4_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device4_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device4_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device4_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device4_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device4_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device4_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device4_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device4_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + + +#define ID3D12Device4_CreatePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreatePipelineState(This,pDesc,riid,ppPipelineState) ) + + +#define ID3D12Device4_OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) ) + +#define ID3D12Device4_OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) ) + +#define ID3D12Device4_EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) \ + ( (This)->lpVtbl -> EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) ) + + +#define ID3D12Device4_CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) ) + +#define ID3D12Device4_CreateProtectedResourceSession(This,pDesc,riid,ppSession) \ + ( (This)->lpVtbl -> CreateProtectedResourceSession(This,pDesc,riid,ppSession) ) + +#define ID3D12Device4_CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) ) + +#define ID3D12Device4_CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) ) + +#define ID3D12Device4_CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) ) + +#define ID3D12Device4_GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12Device4_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0029 */ +/* [local] */ + +typedef +enum D3D12_LIFETIME_STATE + { + D3D12_LIFETIME_STATE_IN_USE = 0, + D3D12_LIFETIME_STATE_NOT_IN_USE = ( D3D12_LIFETIME_STATE_IN_USE + 1 ) + } D3D12_LIFETIME_STATE; + + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0029_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0029_v0_0_s_ifspec; + +#ifndef __ID3D12LifetimeOwner_INTERFACE_DEFINED__ +#define __ID3D12LifetimeOwner_INTERFACE_DEFINED__ + +/* interface ID3D12LifetimeOwner */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12LifetimeOwner; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e667af9f-cd56-4f46-83ce-032e595d70a8") + ID3D12LifetimeOwner : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE LifetimeStateUpdated( + D3D12_LIFETIME_STATE NewState) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12LifetimeOwnerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12LifetimeOwner * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12LifetimeOwner * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12LifetimeOwner * This); + + void ( STDMETHODCALLTYPE *LifetimeStateUpdated )( + ID3D12LifetimeOwner * This, + D3D12_LIFETIME_STATE NewState); + + END_INTERFACE + } ID3D12LifetimeOwnerVtbl; + + interface ID3D12LifetimeOwner + { + CONST_VTBL struct ID3D12LifetimeOwnerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12LifetimeOwner_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12LifetimeOwner_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12LifetimeOwner_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12LifetimeOwner_LifetimeStateUpdated(This,NewState) \ + ( (This)->lpVtbl -> LifetimeStateUpdated(This,NewState) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12LifetimeOwner_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12SwapChainAssistant_INTERFACE_DEFINED__ +#define __ID3D12SwapChainAssistant_INTERFACE_DEFINED__ + +/* interface ID3D12SwapChainAssistant */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12SwapChainAssistant; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("f1df64b6-57fd-49cd-8807-c0eb88b45c8f") + ID3D12SwapChainAssistant : public IUnknown + { + public: + virtual LUID STDMETHODCALLTYPE GetLUID( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetSwapChainObject( + REFIID riid, + _COM_Outptr_ void **ppv) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetCurrentResourceAndCommandQueue( + REFIID riidResource, + _COM_Outptr_ void **ppvResource, + REFIID riidQueue, + _COM_Outptr_ void **ppvQueue) = 0; + + virtual HRESULT STDMETHODCALLTYPE InsertImplicitSync( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12SwapChainAssistantVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12SwapChainAssistant * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12SwapChainAssistant * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12SwapChainAssistant * This); + + LUID ( STDMETHODCALLTYPE *GetLUID )( + ID3D12SwapChainAssistant * This); + + HRESULT ( STDMETHODCALLTYPE *GetSwapChainObject )( + ID3D12SwapChainAssistant * This, + REFIID riid, + _COM_Outptr_ void **ppv); + + HRESULT ( STDMETHODCALLTYPE *GetCurrentResourceAndCommandQueue )( + ID3D12SwapChainAssistant * This, + REFIID riidResource, + _COM_Outptr_ void **ppvResource, + REFIID riidQueue, + _COM_Outptr_ void **ppvQueue); + + HRESULT ( STDMETHODCALLTYPE *InsertImplicitSync )( + ID3D12SwapChainAssistant * This); + + END_INTERFACE + } ID3D12SwapChainAssistantVtbl; + + interface ID3D12SwapChainAssistant + { + CONST_VTBL struct ID3D12SwapChainAssistantVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12SwapChainAssistant_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12SwapChainAssistant_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12SwapChainAssistant_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12SwapChainAssistant_GetLUID(This) \ + ( (This)->lpVtbl -> GetLUID(This) ) + +#define ID3D12SwapChainAssistant_GetSwapChainObject(This,riid,ppv) \ + ( (This)->lpVtbl -> GetSwapChainObject(This,riid,ppv) ) + +#define ID3D12SwapChainAssistant_GetCurrentResourceAndCommandQueue(This,riidResource,ppvResource,riidQueue,ppvQueue) \ + ( (This)->lpVtbl -> GetCurrentResourceAndCommandQueue(This,riidResource,ppvResource,riidQueue,ppvQueue) ) + +#define ID3D12SwapChainAssistant_InsertImplicitSync(This) \ + ( (This)->lpVtbl -> InsertImplicitSync(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + + + + + +#endif /* __ID3D12SwapChainAssistant_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12LifetimeTracker_INTERFACE_DEFINED__ +#define __ID3D12LifetimeTracker_INTERFACE_DEFINED__ + +/* interface ID3D12LifetimeTracker */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12LifetimeTracker; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3fd03d36-4eb1-424a-a582-494ecb8ba813") + ID3D12LifetimeTracker : public ID3D12DeviceChild + { + public: + virtual HRESULT STDMETHODCALLTYPE DestroyOwnedObject( + _In_ ID3D12DeviceChild *pObject) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12LifetimeTrackerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12LifetimeTracker * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12LifetimeTracker * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12LifetimeTracker * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12LifetimeTracker * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12LifetimeTracker * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12LifetimeTracker * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12LifetimeTracker * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12LifetimeTracker * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *DestroyOwnedObject )( + ID3D12LifetimeTracker * This, + _In_ ID3D12DeviceChild *pObject); + + END_INTERFACE + } ID3D12LifetimeTrackerVtbl; + + interface ID3D12LifetimeTracker + { + CONST_VTBL struct ID3D12LifetimeTrackerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12LifetimeTracker_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12LifetimeTracker_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12LifetimeTracker_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12LifetimeTracker_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12LifetimeTracker_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12LifetimeTracker_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12LifetimeTracker_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12LifetimeTracker_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12LifetimeTracker_DestroyOwnedObject(This,pObject) \ + ( (This)->lpVtbl -> DestroyOwnedObject(This,pObject) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12LifetimeTracker_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0032 */ +/* [local] */ + +typedef +enum D3D12_META_COMMAND_PARAMETER_TYPE + { + D3D12_META_COMMAND_PARAMETER_TYPE_FLOAT = 0, + D3D12_META_COMMAND_PARAMETER_TYPE_UINT64 = 1, + D3D12_META_COMMAND_PARAMETER_TYPE_GPU_VIRTUAL_ADDRESS = 2, + D3D12_META_COMMAND_PARAMETER_TYPE_CPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 3, + D3D12_META_COMMAND_PARAMETER_TYPE_GPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 4 + } D3D12_META_COMMAND_PARAMETER_TYPE; + +typedef +enum D3D12_META_COMMAND_PARAMETER_FLAGS + { + D3D12_META_COMMAND_PARAMETER_FLAG_INPUT = 0x1, + D3D12_META_COMMAND_PARAMETER_FLAG_OUTPUT = 0x2 + } D3D12_META_COMMAND_PARAMETER_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_META_COMMAND_PARAMETER_FLAGS ); +typedef +enum D3D12_META_COMMAND_PARAMETER_STAGE + { + D3D12_META_COMMAND_PARAMETER_STAGE_CREATION = 0, + D3D12_META_COMMAND_PARAMETER_STAGE_INITIALIZATION = 1, + D3D12_META_COMMAND_PARAMETER_STAGE_EXECUTION = 2 + } D3D12_META_COMMAND_PARAMETER_STAGE; + +typedef struct D3D12_META_COMMAND_PARAMETER_DESC + { + LPCWSTR Name; + D3D12_META_COMMAND_PARAMETER_TYPE Type; + D3D12_META_COMMAND_PARAMETER_FLAGS Flags; + D3D12_RESOURCE_STATES RequiredResourceState; + UINT StructureOffset; + } D3D12_META_COMMAND_PARAMETER_DESC; + +typedef +enum D3D12_GRAPHICS_STATES + { + D3D12_GRAPHICS_STATE_NONE = 0, + D3D12_GRAPHICS_STATE_IA_VERTEX_BUFFERS = ( 1 << 0 ) , + D3D12_GRAPHICS_STATE_IA_INDEX_BUFFER = ( 1 << 1 ) , + D3D12_GRAPHICS_STATE_IA_PRIMITIVE_TOPOLOGY = ( 1 << 2 ) , + D3D12_GRAPHICS_STATE_DESCRIPTOR_HEAP = ( 1 << 3 ) , + D3D12_GRAPHICS_STATE_GRAPHICS_ROOT_SIGNATURE = ( 1 << 4 ) , + D3D12_GRAPHICS_STATE_COMPUTE_ROOT_SIGNATURE = ( 1 << 5 ) , + D3D12_GRAPHICS_STATE_RS_VIEWPORTS = ( 1 << 6 ) , + D3D12_GRAPHICS_STATE_RS_SCISSOR_RECTS = ( 1 << 7 ) , + D3D12_GRAPHICS_STATE_PREDICATION = ( 1 << 8 ) , + D3D12_GRAPHICS_STATE_OM_RENDER_TARGETS = ( 1 << 9 ) , + D3D12_GRAPHICS_STATE_OM_STENCIL_REF = ( 1 << 10 ) , + D3D12_GRAPHICS_STATE_OM_BLEND_FACTOR = ( 1 << 11 ) , + D3D12_GRAPHICS_STATE_PIPELINE_STATE = ( 1 << 12 ) , + D3D12_GRAPHICS_STATE_SO_TARGETS = ( 1 << 13 ) , + D3D12_GRAPHICS_STATE_OM_DEPTH_BOUNDS = ( 1 << 14 ) , + D3D12_GRAPHICS_STATE_SAMPLE_POSITIONS = ( 1 << 15 ) , + D3D12_GRAPHICS_STATE_VIEW_INSTANCE_MASK = ( 1 << 16 ) + } D3D12_GRAPHICS_STATES; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_GRAPHICS_STATES ); +typedef struct D3D12_META_COMMAND_DESC + { + GUID Id; + LPCWSTR Name; + D3D12_GRAPHICS_STATES InitializationDirtyState; + D3D12_GRAPHICS_STATES ExecutionDirtyState; + } D3D12_META_COMMAND_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0032_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0032_v0_0_s_ifspec; + +#ifndef __ID3D12StateObject_INTERFACE_DEFINED__ +#define __ID3D12StateObject_INTERFACE_DEFINED__ + +/* interface ID3D12StateObject */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12StateObject; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("47016943-fca8-4594-93ea-af258b55346d") + ID3D12StateObject : public ID3D12Pageable + { + public: + }; + + +#else /* C style interface */ + + typedef struct ID3D12StateObjectVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12StateObject * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12StateObject * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12StateObject * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12StateObject * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12StateObject * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12StateObject * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12StateObject * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12StateObject * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + END_INTERFACE + } ID3D12StateObjectVtbl; + + interface ID3D12StateObject + { + CONST_VTBL struct ID3D12StateObjectVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12StateObject_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12StateObject_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12StateObject_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12StateObject_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12StateObject_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12StateObject_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12StateObject_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12StateObject_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12StateObject_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12StateObjectProperties_INTERFACE_DEFINED__ +#define __ID3D12StateObjectProperties_INTERFACE_DEFINED__ + +/* interface ID3D12StateObjectProperties */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12StateObjectProperties; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("de5fa827-9bf9-4f26-89ff-d7f56fde3860") + ID3D12StateObjectProperties : public IUnknown + { + public: + virtual void *STDMETHODCALLTYPE GetShaderIdentifier( + _In_ LPCWSTR pExportName) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetShaderStackSize( + _In_ LPCWSTR pExportName) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetPipelineStackSize( void) = 0; + + virtual void STDMETHODCALLTYPE SetPipelineStackSize( + UINT64 PipelineStackSizeInBytes) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12StateObjectPropertiesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12StateObjectProperties * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12StateObjectProperties * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12StateObjectProperties * This); + + void *( STDMETHODCALLTYPE *GetShaderIdentifier )( + ID3D12StateObjectProperties * This, + _In_ LPCWSTR pExportName); + + UINT64 ( STDMETHODCALLTYPE *GetShaderStackSize )( + ID3D12StateObjectProperties * This, + _In_ LPCWSTR pExportName); + + UINT64 ( STDMETHODCALLTYPE *GetPipelineStackSize )( + ID3D12StateObjectProperties * This); + + void ( STDMETHODCALLTYPE *SetPipelineStackSize )( + ID3D12StateObjectProperties * This, + UINT64 PipelineStackSizeInBytes); + + END_INTERFACE + } ID3D12StateObjectPropertiesVtbl; + + interface ID3D12StateObjectProperties + { + CONST_VTBL struct ID3D12StateObjectPropertiesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12StateObjectProperties_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12StateObjectProperties_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12StateObjectProperties_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12StateObjectProperties_GetShaderIdentifier(This,pExportName) \ + ( (This)->lpVtbl -> GetShaderIdentifier(This,pExportName) ) + +#define ID3D12StateObjectProperties_GetShaderStackSize(This,pExportName) \ + ( (This)->lpVtbl -> GetShaderStackSize(This,pExportName) ) + +#define ID3D12StateObjectProperties_GetPipelineStackSize(This) \ + ( (This)->lpVtbl -> GetPipelineStackSize(This) ) + +#define ID3D12StateObjectProperties_SetPipelineStackSize(This,PipelineStackSizeInBytes) \ + ( (This)->lpVtbl -> SetPipelineStackSize(This,PipelineStackSizeInBytes) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12StateObjectProperties_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0034 */ +/* [local] */ + +typedef +enum D3D12_STATE_SUBOBJECT_TYPE + { + D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG = 0, + D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE = 1, + D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE = 2, + D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK = 3, + D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY = 5, + D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION = 6, + D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION = 7, + D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION = 8, + D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG = 9, + D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG = 10, + D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP = 11, + D3D12_STATE_SUBOBJECT_TYPE_MAX_VALID = ( D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP + 1 ) + } D3D12_STATE_SUBOBJECT_TYPE; + +typedef struct D3D12_STATE_SUBOBJECT + { + D3D12_STATE_SUBOBJECT_TYPE Type; + const void *pDesc; + } D3D12_STATE_SUBOBJECT; + +typedef +enum D3D12_STATE_OBJECT_FLAGS + { + D3D12_STATE_OBJECT_FLAG_NONE = 0, + D3D12_STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0x1, + D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 0x2 + } D3D12_STATE_OBJECT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_STATE_OBJECT_FLAGS ); +typedef struct D3D12_STATE_OBJECT_CONFIG + { + D3D12_STATE_OBJECT_FLAGS Flags; + } D3D12_STATE_OBJECT_CONFIG; + +typedef struct D3D12_GLOBAL_ROOT_SIGNATURE + { + ID3D12RootSignature *pGlobalRootSignature; + } D3D12_GLOBAL_ROOT_SIGNATURE; + +typedef struct D3D12_LOCAL_ROOT_SIGNATURE + { + ID3D12RootSignature *pLocalRootSignature; + } D3D12_LOCAL_ROOT_SIGNATURE; + +typedef struct D3D12_NODE_MASK + { + UINT NodeMask; + } D3D12_NODE_MASK; + +typedef +enum D3D12_EXPORT_FLAGS + { + D3D12_EXPORT_FLAG_NONE = 0 + } D3D12_EXPORT_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_EXPORT_FLAGS ); +typedef struct D3D12_EXPORT_DESC + { + LPCWSTR Name; + _In_opt_ LPCWSTR ExportToRename; + D3D12_EXPORT_FLAGS Flags; + } D3D12_EXPORT_DESC; + +typedef struct D3D12_DXIL_LIBRARY_DESC + { + D3D12_SHADER_BYTECODE DXILLibrary; + UINT NumExports; + _In_reads_(NumExports) D3D12_EXPORT_DESC *pExports; + } D3D12_DXIL_LIBRARY_DESC; + +typedef struct D3D12_EXISTING_COLLECTION_DESC + { + ID3D12StateObject *pExistingCollection; + UINT NumExports; + _In_reads_(NumExports) D3D12_EXPORT_DESC *pExports; + } D3D12_EXISTING_COLLECTION_DESC; + +typedef struct D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION + { + const D3D12_STATE_SUBOBJECT *pSubobjectToAssociate; + UINT NumExports; + _In_reads_(NumExports) LPCWSTR *pExports; + } D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + +typedef struct D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION + { + LPCWSTR SubobjectToAssociate; + UINT NumExports; + _In_reads_(NumExports) LPCWSTR *pExports; + } D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + +typedef +enum D3D12_HIT_GROUP_TYPE + { + D3D12_HIT_GROUP_TYPE_TRIANGLES = 0, + D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE = 0x1 + } D3D12_HIT_GROUP_TYPE; + +typedef struct D3D12_HIT_GROUP_DESC + { + LPCWSTR HitGroupExport; + D3D12_HIT_GROUP_TYPE Type; + _In_opt_ LPCWSTR AnyHitShaderImport; + _In_opt_ LPCWSTR ClosestHitShaderImport; + _In_opt_ LPCWSTR IntersectionShaderImport; + } D3D12_HIT_GROUP_DESC; + +typedef struct D3D12_RAYTRACING_SHADER_CONFIG + { + UINT MaxPayloadSizeInBytes; + UINT MaxAttributeSizeInBytes; + } D3D12_RAYTRACING_SHADER_CONFIG; + +typedef struct D3D12_RAYTRACING_PIPELINE_CONFIG + { + UINT MaxTraceRecursionDepth; + } D3D12_RAYTRACING_PIPELINE_CONFIG; + +typedef +enum D3D12_STATE_OBJECT_TYPE + { + D3D12_STATE_OBJECT_TYPE_COLLECTION = 0, + D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE = 3 + } D3D12_STATE_OBJECT_TYPE; + +typedef struct D3D12_STATE_OBJECT_DESC + { + D3D12_STATE_OBJECT_TYPE Type; + UINT NumSubobjects; + _In_reads_(NumSubobjects) const D3D12_STATE_SUBOBJECT *pSubobjects; + } D3D12_STATE_OBJECT_DESC; + +typedef +enum D3D12_RAYTRACING_GEOMETRY_FLAGS + { + D3D12_RAYTRACING_GEOMETRY_FLAG_NONE = 0, + D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE = 0x1, + D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 0x2 + } D3D12_RAYTRACING_GEOMETRY_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RAYTRACING_GEOMETRY_FLAGS ); +typedef +enum D3D12_RAYTRACING_GEOMETRY_TYPE + { + D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES = 0, + D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS = ( D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES + 1 ) + } D3D12_RAYTRACING_GEOMETRY_TYPE; + +typedef +enum D3D12_RAYTRACING_INSTANCE_FLAGS + { + D3D12_RAYTRACING_INSTANCE_FLAG_NONE = 0, + D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE = 0x1, + D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2, + D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE = 0x4, + D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE = 0x8 + } D3D12_RAYTRACING_INSTANCE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RAYTRACING_INSTANCE_FLAGS ); +typedef struct D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE + { + D3D12_GPU_VIRTUAL_ADDRESS StartAddress; + UINT64 StrideInBytes; + } D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE; + +typedef struct D3D12_GPU_VIRTUAL_ADDRESS_RANGE + { + D3D12_GPU_VIRTUAL_ADDRESS StartAddress; + UINT64 SizeInBytes; + } D3D12_GPU_VIRTUAL_ADDRESS_RANGE; + +typedef struct D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE + { + D3D12_GPU_VIRTUAL_ADDRESS StartAddress; + UINT64 SizeInBytes; + UINT64 StrideInBytes; + } D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE; + +typedef struct D3D12_RAYTRACING_GEOMETRY_TRIANGLES_DESC + { + D3D12_GPU_VIRTUAL_ADDRESS Transform3x4; + DXGI_FORMAT IndexFormat; + DXGI_FORMAT VertexFormat; + UINT IndexCount; + UINT VertexCount; + D3D12_GPU_VIRTUAL_ADDRESS IndexBuffer; + D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE VertexBuffer; + } D3D12_RAYTRACING_GEOMETRY_TRIANGLES_DESC; + +typedef struct D3D12_RAYTRACING_AABB + { + FLOAT MinX; + FLOAT MinY; + FLOAT MinZ; + FLOAT MaxX; + FLOAT MaxY; + FLOAT MaxZ; + } D3D12_RAYTRACING_AABB; + +typedef struct D3D12_RAYTRACING_GEOMETRY_AABBS_DESC + { + UINT64 AABBCount; + D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE AABBs; + } D3D12_RAYTRACING_GEOMETRY_AABBS_DESC; + +typedef +enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE = 0, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE = 0x1, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION = 0x2, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE = 0x4, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD = 0x8, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY = 0x10, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE = 0x20 + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS ); +typedef +enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE = 0, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT = 0x1, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_VISUALIZATION_DECODE_FOR_TOOLS = 0x2, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_SERIALIZE = 0x3, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_DESERIALIZE = 0x4 + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE; + +typedef +enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL = 0, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL = 0x1 + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE; + +typedef +enum D3D12_ELEMENTS_LAYOUT + { + D3D12_ELEMENTS_LAYOUT_ARRAY = 0, + D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS = 0x1 + } D3D12_ELEMENTS_LAYOUT; + +typedef +enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TYPE + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE = 0, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TOOLS_VISUALIZATION = 0x1, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION = 0x2, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE = 0x3 + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TYPE; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC + { + D3D12_GPU_VIRTUAL_ADDRESS DestBuffer; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TYPE InfoType; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC + { + UINT64 CompactedSizeInBytes; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TOOLS_VISUALIZATION_DESC + { + UINT64 DecodedSizeInBytes; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TOOLS_VISUALIZATION_DESC; + +typedef struct D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_TOOLS_VISUALIZATION_HEADER + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE Type; + UINT NumDescs; + } D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_TOOLS_VISUALIZATION_HEADER; + +// Regarding D3D12_BUILD_RAY_TRACING_ACCELERATION_STRUCTURE_TOOLS_VISUALIZATION_HEADER above, +// depending on Type field, NumDescs above is followed by either: +// D3D12_RAY_TRACING_INSTANCE_DESC InstanceDescs[NumDescs] +// or D3D12_RAY_TRACING_GEOMETRY_DESC GeometryDescs[NumDescs]. +// There is 4 bytes of padding between GeometryDesc structs in the array so alignment is natural when viewed by CPU. + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC + { + UINT64 SerializedSizeInBytes; + UINT64 NumBottomLevelAccelerationStructurePointers; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC; + +typedef struct D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER + { + GUID DriverOpaqueGUID; + BYTE DriverOpaqueVersioningData[ 16 ]; + } D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER; + +typedef +enum D3D12_SERIALIZED_DATA_TYPE + { + D3D12_SERIALIZED_DATA_RAYTRACING_ACCELERATION_STRUCTURE = 0 + } D3D12_SERIALIZED_DATA_TYPE; + +typedef +enum D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS + { + D3D12_DRIVER_MATCHING_IDENTIFIER_COMPATIBLE_WITH_DEVICE = 0, + D3D12_DRIVER_MATCHING_IDENTIFIER_UNSUPPORTED_TYPE = 0x1, + D3D12_DRIVER_MATCHING_IDENTIFIER_UNRECOGNIZED = 0x2, + D3D12_DRIVER_MATCHING_IDENTIFIER_INCOMPATIBLE_VERSION = 0x3, + D3D12_DRIVER_MATCHING_IDENTIFIER_INCOMPATIBLE_TYPE = 0x4 + } D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS; + +typedef struct D3D12_SERIALIZED_RAYTRACING_ACCELERATION_STRUCTURE_HEADER + { + D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER DriverMatchingIdentifier; + UINT64 SerializedSizeInBytesIncludingHeader; + UINT64 DeserializedSizeInBytes; + UINT64 NumBottomLevelAccelerationStructurePointersAfterHeader; + } D3D12_SERIALIZED_RAYTRACING_ACCELERATION_STRUCTURE_HEADER; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC + { + UINT64 CurrentSizeInBytes; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC; + +typedef struct D3D12_RAYTRACING_INSTANCE_DESC + { + FLOAT Transform[ 3 ][ 4 ]; + UINT InstanceID : 24; + UINT InstanceMask : 8; + UINT InstanceContributionToHitGroupIndex : 24; + UINT Flags : 8; + D3D12_GPU_VIRTUAL_ADDRESS AccelerationStructure; + } D3D12_RAYTRACING_INSTANCE_DESC; + +typedef struct D3D12_RAYTRACING_GEOMETRY_DESC + { + D3D12_RAYTRACING_GEOMETRY_TYPE Type; + D3D12_RAYTRACING_GEOMETRY_FLAGS Flags; + union + { + D3D12_RAYTRACING_GEOMETRY_TRIANGLES_DESC Triangles; + D3D12_RAYTRACING_GEOMETRY_AABBS_DESC AABBs; + } ; + } D3D12_RAYTRACING_GEOMETRY_DESC; + +typedef struct D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE Type; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS Flags; + UINT NumDescs; + D3D12_ELEMENTS_LAYOUT DescsLayout; + union + { + D3D12_GPU_VIRTUAL_ADDRESS InstanceDescs; + const D3D12_RAYTRACING_GEOMETRY_DESC *pGeometryDescs; + const D3D12_RAYTRACING_GEOMETRY_DESC *const *ppGeometryDescs; + } ; + } D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS; + +typedef struct D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC + { + D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS Inputs; + _In_opt_ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData; + D3D12_GPU_VIRTUAL_ADDRESS ScratchAccelerationStructureData; + } D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC; + +typedef struct D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO + { + UINT64 ResultDataMaxSizeInBytes; + UINT64 ScratchDataSizeInBytes; + UINT64 UpdateScratchDataSizeInBytes; + } D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO; + +typedef +enum D3D12_RAY_FLAGS + { + D3D12_RAY_FLAG_NONE = 0, + D3D12_RAY_FLAG_FORCE_OPAQUE = 0x1, + D3D12_RAY_FLAG_FORCE_NON_OPAQUE = 0x2, + D3D12_RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH = 0x4, + D3D12_RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x8, + D3D12_RAY_FLAG_CULL_BACK_FACING_TRIANGLES = 0x10, + D3D12_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES = 0x20, + D3D12_RAY_FLAG_CULL_OPAQUE = 0x40, + D3D12_RAY_FLAG_CULL_NON_OPAQUE = 0x80 + } D3D12_RAY_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RAY_FLAGS ); +typedef +enum D3D12_HIT_KIND + { + D3D12_HIT_KIND_TRIANGLE_FRONT_FACE = 0xfe, + D3D12_HIT_KIND_TRIANGLE_BACK_FACE = 0xff + } D3D12_HIT_KIND; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0034_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0034_v0_0_s_ifspec; + +#ifndef __ID3D12Device5_INTERFACE_DEFINED__ +#define __ID3D12Device5_INTERFACE_DEFINED__ + +/* interface ID3D12Device5 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device5; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8b4f173b-2fea-4b80-8f58-4307191ab95d") + ID3D12Device5 : public ID3D12Device4 + { + public: + virtual HRESULT STDMETHODCALLTYPE CreateLifetimeTracker( + _In_ ID3D12LifetimeOwner *pOwner, + REFIID riid, + _COM_Outptr_ void **ppvTracker) = 0; + + virtual void STDMETHODCALLTYPE RemoveDevice( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumerateMetaCommands( + _Inout_ UINT *pNumMetaCommands, + _Out_writes_opt_(*pNumMetaCommands) D3D12_META_COMMAND_DESC *pDescs) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnumerateMetaCommandParameters( + _In_ REFGUID CommandId, + _In_ D3D12_META_COMMAND_PARAMETER_STAGE Stage, + _Out_opt_ UINT *pTotalStructureSizeInBytes, + _Inout_ UINT *pParameterCount, + _Out_writes_opt_(*pParameterCount) D3D12_META_COMMAND_PARAMETER_DESC *pParameterDescs) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateMetaCommand( + _In_ REFGUID CommandId, + _In_ UINT NodeMask, + _In_reads_bytes_opt_(CreationParametersDataSizeInBytes) const void *pCreationParametersData, + _In_ SIZE_T CreationParametersDataSizeInBytes, + REFIID riid, + _COM_Outptr_ void **ppMetaCommand) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateStateObject( + const D3D12_STATE_OBJECT_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppStateObject) = 0; + + virtual void STDMETHODCALLTYPE GetRaytracingAccelerationStructurePrebuildInfo( + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *pDesc, + _Out_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *pInfo) = 0; + + virtual D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE CheckDriverMatchingIdentifier( + _In_ D3D12_SERIALIZED_DATA_TYPE SerializedDataType, + _In_ const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *pIdentifierToCheck) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device5Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device5 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device5 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device5 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device5 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device5 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device5 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device5 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device5 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device5 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device5 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device5 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device5 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device5 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device5 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device5 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device5 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device5 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device5 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device5 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device5 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device5 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device5 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device5 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device5 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device5 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device5 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device5 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device5 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device5 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device5 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device5 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device5 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device5 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device5 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device5 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device5 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device5 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device5 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device5 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device5 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device5 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device5 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device5 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device5 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device5 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device5 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device5 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineState )( + ID3D12Device5 * This, + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromAddress )( + ID3D12Device5 * This, + _In_ const void *pAddress, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromFileMapping )( + ID3D12Device5 * This, + _In_ HANDLE hFileMapping, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *EnqueueMakeResident )( + ID3D12Device5 * This, + D3D12_RESIDENCY_FLAGS Flags, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_ ID3D12Fence *pFenceToSignal, + UINT64 FenceValueToSignal); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList1 )( + ID3D12Device5 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ D3D12_COMMAND_LIST_FLAGS flags, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CreateProtectedResourceSession )( + ID3D12Device5 * This, + _In_ const D3D12_PROTECTED_RESOURCE_SESSION_DESC *pDesc, + _In_ REFIID riid, + _COM_Outptr_ void **ppSession); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource1 )( + ID3D12Device5 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap1 )( + ID3D12Device5 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource1 )( + ID3D12Device5 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo1 )( + ID3D12Device5 * This, + UINT visibleMask, + UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs, + _Out_writes_opt_(numResourceDescs) D3D12_RESOURCE_ALLOCATION_INFO1 *pResourceAllocationInfo1); + + HRESULT ( STDMETHODCALLTYPE *CreateLifetimeTracker )( + ID3D12Device5 * This, + _In_ ID3D12LifetimeOwner *pOwner, + REFIID riid, + _COM_Outptr_ void **ppvTracker); + + void ( STDMETHODCALLTYPE *RemoveDevice )( + ID3D12Device5 * This); + + HRESULT ( STDMETHODCALLTYPE *EnumerateMetaCommands )( + ID3D12Device5 * This, + _Inout_ UINT *pNumMetaCommands, + _Out_writes_opt_(*pNumMetaCommands) D3D12_META_COMMAND_DESC *pDescs); + + HRESULT ( STDMETHODCALLTYPE *EnumerateMetaCommandParameters )( + ID3D12Device5 * This, + _In_ REFGUID CommandId, + _In_ D3D12_META_COMMAND_PARAMETER_STAGE Stage, + _Out_opt_ UINT *pTotalStructureSizeInBytes, + _Inout_ UINT *pParameterCount, + _Out_writes_opt_(*pParameterCount) D3D12_META_COMMAND_PARAMETER_DESC *pParameterDescs); + + HRESULT ( STDMETHODCALLTYPE *CreateMetaCommand )( + ID3D12Device5 * This, + _In_ REFGUID CommandId, + _In_ UINT NodeMask, + _In_reads_bytes_opt_(CreationParametersDataSizeInBytes) const void *pCreationParametersData, + _In_ SIZE_T CreationParametersDataSizeInBytes, + REFIID riid, + _COM_Outptr_ void **ppMetaCommand); + + HRESULT ( STDMETHODCALLTYPE *CreateStateObject )( + ID3D12Device5 * This, + const D3D12_STATE_OBJECT_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppStateObject); + + void ( STDMETHODCALLTYPE *GetRaytracingAccelerationStructurePrebuildInfo )( + ID3D12Device5 * This, + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *pDesc, + _Out_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *pInfo); + + D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS ( STDMETHODCALLTYPE *CheckDriverMatchingIdentifier )( + ID3D12Device5 * This, + _In_ D3D12_SERIALIZED_DATA_TYPE SerializedDataType, + _In_ const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *pIdentifierToCheck); + + END_INTERFACE + } ID3D12Device5Vtbl; + + interface ID3D12Device5 + { + CONST_VTBL struct ID3D12Device5Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device5_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device5_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device5_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device5_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device5_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device5_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device5_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device5_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device5_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device5_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device5_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device5_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device5_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device5_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device5_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device5_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device5_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device5_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device5_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device5_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device5_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device5_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device5_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device5_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device5_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device5_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device5_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device5_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device5_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device5_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device5_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device5_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device5_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device5_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device5_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device5_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device5_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device5_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device5_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device5_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device5_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device5_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + + +#define ID3D12Device5_CreatePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreatePipelineState(This,pDesc,riid,ppPipelineState) ) + + +#define ID3D12Device5_OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) ) + +#define ID3D12Device5_OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) ) + +#define ID3D12Device5_EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) \ + ( (This)->lpVtbl -> EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) ) + + +#define ID3D12Device5_CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) ) + +#define ID3D12Device5_CreateProtectedResourceSession(This,pDesc,riid,ppSession) \ + ( (This)->lpVtbl -> CreateProtectedResourceSession(This,pDesc,riid,ppSession) ) + +#define ID3D12Device5_CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) ) + +#define ID3D12Device5_CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) ) + +#define ID3D12Device5_CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) ) + +#define ID3D12Device5_GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) ) + + +#define ID3D12Device5_CreateLifetimeTracker(This,pOwner,riid,ppvTracker) \ + ( (This)->lpVtbl -> CreateLifetimeTracker(This,pOwner,riid,ppvTracker) ) + +#define ID3D12Device5_RemoveDevice(This) \ + ( (This)->lpVtbl -> RemoveDevice(This) ) + +#define ID3D12Device5_EnumerateMetaCommands(This,pNumMetaCommands,pDescs) \ + ( (This)->lpVtbl -> EnumerateMetaCommands(This,pNumMetaCommands,pDescs) ) + +#define ID3D12Device5_EnumerateMetaCommandParameters(This,CommandId,Stage,pTotalStructureSizeInBytes,pParameterCount,pParameterDescs) \ + ( (This)->lpVtbl -> EnumerateMetaCommandParameters(This,CommandId,Stage,pTotalStructureSizeInBytes,pParameterCount,pParameterDescs) ) + +#define ID3D12Device5_CreateMetaCommand(This,CommandId,NodeMask,pCreationParametersData,CreationParametersDataSizeInBytes,riid,ppMetaCommand) \ + ( (This)->lpVtbl -> CreateMetaCommand(This,CommandId,NodeMask,pCreationParametersData,CreationParametersDataSizeInBytes,riid,ppMetaCommand) ) + +#define ID3D12Device5_CreateStateObject(This,pDesc,riid,ppStateObject) \ + ( (This)->lpVtbl -> CreateStateObject(This,pDesc,riid,ppStateObject) ) + +#define ID3D12Device5_GetRaytracingAccelerationStructurePrebuildInfo(This,pDesc,pInfo) \ + ( (This)->lpVtbl -> GetRaytracingAccelerationStructurePrebuildInfo(This,pDesc,pInfo) ) + +#define ID3D12Device5_CheckDriverMatchingIdentifier(This,SerializedDataType,pIdentifierToCheck) \ + ( (This)->lpVtbl -> CheckDriverMatchingIdentifier(This,SerializedDataType,pIdentifierToCheck) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Device5_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0035 */ +/* [local] */ + +typedef +enum D3D12_AUTO_BREADCRUMB_OP + { + D3D12_AUTO_BREADCRUMB_OP_SETMARKER = 0, + D3D12_AUTO_BREADCRUMB_OP_BEGINEVENT = 1, + D3D12_AUTO_BREADCRUMB_OP_ENDEVENT = 2, + D3D12_AUTO_BREADCRUMB_OP_DRAWINSTANCED = 3, + D3D12_AUTO_BREADCRUMB_OP_DRAWINDEXEDINSTANCED = 4, + D3D12_AUTO_BREADCRUMB_OP_EXECUTEINDIRECT = 5, + D3D12_AUTO_BREADCRUMB_OP_DISPATCH = 6, + D3D12_AUTO_BREADCRUMB_OP_COPYBUFFERREGION = 7, + D3D12_AUTO_BREADCRUMB_OP_COPYTEXTUREREGION = 8, + D3D12_AUTO_BREADCRUMB_OP_COPYRESOURCE = 9, + D3D12_AUTO_BREADCRUMB_OP_COPYTILES = 10, + D3D12_AUTO_BREADCRUMB_OP_RESOLVESUBRESOURCE = 11, + D3D12_AUTO_BREADCRUMB_OP_CLEARRENDERTARGETVIEW = 12, + D3D12_AUTO_BREADCRUMB_OP_CLEARUNORDEREDACCESSVIEW = 13, + D3D12_AUTO_BREADCRUMB_OP_CLEARDEPTHSTENCILVIEW = 14, + D3D12_AUTO_BREADCRUMB_OP_RESOURCEBARRIER = 15, + D3D12_AUTO_BREADCRUMB_OP_EXECUTEBUNDLE = 16, + D3D12_AUTO_BREADCRUMB_OP_PRESENT = 17, + D3D12_AUTO_BREADCRUMB_OP_RESOLVEQUERYDATA = 18, + D3D12_AUTO_BREADCRUMB_OP_BEGINSUBMISSION = 19, + D3D12_AUTO_BREADCRUMB_OP_ENDSUBMISSION = 20, + D3D12_AUTO_BREADCRUMB_OP_DECODEFRAME = 21, + D3D12_AUTO_BREADCRUMB_OP_PROCESSFRAMES = 22, + D3D12_AUTO_BREADCRUMB_OP_ATOMICCOPYBUFFERUINT = 23, + D3D12_AUTO_BREADCRUMB_OP_ATOMICCOPYBUFFERUINT64 = 24, + D3D12_AUTO_BREADCRUMB_OP_RESOLVESUBRESOURCEREGION = 25, + D3D12_AUTO_BREADCRUMB_OP_WRITEBUFFERIMMEDIATE = 26, + D3D12_AUTO_BREADCRUMB_OP_DECODEFRAME1 = 27, + D3D12_AUTO_BREADCRUMB_OP_SETPROTECTEDRESOURCESESSION = 28, + D3D12_AUTO_BREADCRUMB_OP_DECODEFRAME2 = 29, + D3D12_AUTO_BREADCRUMB_OP_PROCESSFRAMES1 = 30, + D3D12_AUTO_BREADCRUMB_OP_BUILDRAYTRACINGACCELERATIONSTRUCTURE = 31, + D3D12_AUTO_BREADCRUMB_OP_EMITRAYTRACINGACCELERATIONSTRUCTUREPOSTBUILDINFO = 32, + D3D12_AUTO_BREADCRUMB_OP_COPYRAYTRACINGACCELERATIONSTRUCTURE = 33, + D3D12_AUTO_BREADCRUMB_OP_DISPATCHRAYS = 34, + D3D12_AUTO_BREADCRUMB_OP_INITIALIZEMETACOMMAND = 35, + D3D12_AUTO_BREADCRUMB_OP_EXECUTEMETACOMMAND = 36, + D3D12_AUTO_BREADCRUMB_OP_ESTIMATEMOTION = 37, + D3D12_AUTO_BREADCRUMB_OP_RESOLVEMOTIONVECTORHEAP = 38, + D3D12_AUTO_BREADCRUMB_OP_SETPIPELINESTATE1 = 39, + D3D12_AUTO_BREADCRUMB_OP_INITIALIZEEXTENSIONCOMMAND = 40, + D3D12_AUTO_BREADCRUMB_OP_EXECUTEEXTENSIONCOMMAND = 41 + } D3D12_AUTO_BREADCRUMB_OP; + +typedef struct D3D12_AUTO_BREADCRUMB_NODE + { + const char *pCommandListDebugNameA; + const wchar_t *pCommandListDebugNameW; + const char *pCommandQueueDebugNameA; + const wchar_t *pCommandQueueDebugNameW; + ID3D12GraphicsCommandList *pCommandList; + ID3D12CommandQueue *pCommandQueue; + UINT32 BreadcrumbCount; + const UINT32 *pLastBreadcrumbValue; + const D3D12_AUTO_BREADCRUMB_OP *pCommandHistory; + const struct D3D12_AUTO_BREADCRUMB_NODE *pNext; + } D3D12_AUTO_BREADCRUMB_NODE; + +typedef +enum D3D12_DRED_VERSION + { + D3D12_DRED_VERSION_1_0 = 0x1, + D3D12_DRED_VERSION_1_1 = 0x2 + } D3D12_DRED_VERSION; + +typedef +enum D3D12_DRED_FLAGS + { + D3D12_DRED_FLAG_NONE = 0, + D3D12_DRED_FLAG_FORCE_ENABLE = 1, + D3D12_DRED_FLAG_DISABLE_AUTOBREADCRUMBS = 2 + } D3D12_DRED_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_DRED_FLAGS ); +typedef +enum D3D12_DRED_ENABLEMENT + { + D3D12_DRED_ENABLEMENT_SYSTEM_CONTROLLED = 0, + D3D12_DRED_ENABLEMENT_FORCED_OFF = 1, + D3D12_DRED_ENABLEMENT_FORCED_ON = 2 + } D3D12_DRED_ENABLEMENT; + +typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA + { + _In_ D3D12_DRED_FLAGS Flags; + _Out_ D3D12_AUTO_BREADCRUMB_NODE *pHeadAutoBreadcrumbNode; + } D3D12_DEVICE_REMOVED_EXTENDED_DATA; + +typedef +enum D3D12_DRED_ALLOCATION_TYPE + { + D3D12_DRED_ALLOCATION_TYPE_COMMAND_QUEUE = 19, + D3D12_DRED_ALLOCATION_TYPE_COMMAND_ALLOCATOR = 20, + D3D12_DRED_ALLOCATION_TYPE_PIPELINE_STATE = 21, + D3D12_DRED_ALLOCATION_TYPE_COMMAND_LIST = 22, + D3D12_DRED_ALLOCATION_TYPE_FENCE = 23, + D3D12_DRED_ALLOCATION_TYPE_DESCRIPTOR_HEAP = 24, + D3D12_DRED_ALLOCATION_TYPE_HEAP = 25, + D3D12_DRED_ALLOCATION_TYPE_QUERY_HEAP = 27, + D3D12_DRED_ALLOCATION_TYPE_COMMAND_SIGNATURE = 28, + D3D12_DRED_ALLOCATION_TYPE_PIPELINE_LIBRARY = 29, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_DECODER = 30, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_PROCESSOR = 32, + D3D12_DRED_ALLOCATION_TYPE_RESOURCE = 34, + D3D12_DRED_ALLOCATION_TYPE_PASS = 35, + D3D12_DRED_ALLOCATION_TYPE_CRYPTOSESSION = 36, + D3D12_DRED_ALLOCATION_TYPE_CRYPTOSESSIONPOLICY = 37, + D3D12_DRED_ALLOCATION_TYPE_PROTECTEDRESOURCESESSION = 38, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_DECODER_HEAP = 39, + D3D12_DRED_ALLOCATION_TYPE_COMMAND_POOL = 40, + D3D12_DRED_ALLOCATION_TYPE_COMMAND_RECORDER = 41, + D3D12_DRED_ALLOCATION_TYPE_STATE_OBJECT = 42, + D3D12_DRED_ALLOCATION_TYPE_METACOMMAND = 43, + D3D12_DRED_ALLOCATION_TYPE_SCHEDULINGGROUP = 44, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_MOTION_ESTIMATOR = 45, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_MOTION_VECTOR_HEAP = 46, + D3D12_DRED_ALLOCATION_TYPE_VIDEO_EXTENSION_COMMAND = 47, + D3D12_DRED_ALLOCATION_TYPE_INVALID = 0xffffffff + } D3D12_DRED_ALLOCATION_TYPE; + +typedef struct D3D12_DRED_ALLOCATION_NODE + { + const char *ObjectNameA; + const wchar_t *ObjectNameW; + D3D12_DRED_ALLOCATION_TYPE AllocationType; + const struct D3D12_DRED_ALLOCATION_NODE *pNext; + } D3D12_DRED_ALLOCATION_NODE; + +typedef struct D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT + { + _Out_ const D3D12_AUTO_BREADCRUMB_NODE *pHeadAutoBreadcrumbNode; + } D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT; + +typedef struct D3D12_DRED_PAGE_FAULT_OUTPUT + { + D3D12_GPU_VIRTUAL_ADDRESS PageFaultVA; + _Out_ const D3D12_DRED_ALLOCATION_NODE *pHeadExistingAllocationNode; + _Out_ const D3D12_DRED_ALLOCATION_NODE *pHeadRecentFreedAllocationNode; + } D3D12_DRED_PAGE_FAULT_OUTPUT; + +typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA1 + { + HRESULT DeviceRemovedReason; + D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT AutoBreadcrumbsOutput; + D3D12_DRED_PAGE_FAULT_OUTPUT PageFaultOutput; + } D3D12_DEVICE_REMOVED_EXTENDED_DATA1; + +typedef struct D3D12_VERSIONED_DEVICE_REMOVED_EXTENDED_DATA + { + D3D12_DRED_VERSION Version; + union + { + D3D12_DEVICE_REMOVED_EXTENDED_DATA Dred_1_0; + D3D12_DEVICE_REMOVED_EXTENDED_DATA1 Dred_1_1; + } ; + } D3D12_VERSIONED_DEVICE_REMOVED_EXTENDED_DATA; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0035_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0035_v0_0_s_ifspec; + +#ifndef __ID3D12DeviceRemovedExtendedDataSettings_INTERFACE_DEFINED__ +#define __ID3D12DeviceRemovedExtendedDataSettings_INTERFACE_DEFINED__ + +/* interface ID3D12DeviceRemovedExtendedDataSettings */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DeviceRemovedExtendedDataSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63") + ID3D12DeviceRemovedExtendedDataSettings : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE SetAutoBreadcrumbsEnablement( + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0000) = 0; + + virtual void STDMETHODCALLTYPE SetPageFaultEnablement( + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0001) = 0; + + virtual void STDMETHODCALLTYPE SetWatsonDumpEnablement( + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0002) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DeviceRemovedExtendedDataSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DeviceRemovedExtendedDataSettings * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DeviceRemovedExtendedDataSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DeviceRemovedExtendedDataSettings * This); + + void ( STDMETHODCALLTYPE *SetAutoBreadcrumbsEnablement )( + ID3D12DeviceRemovedExtendedDataSettings * This, + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0000); + + void ( STDMETHODCALLTYPE *SetPageFaultEnablement )( + ID3D12DeviceRemovedExtendedDataSettings * This, + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0001); + + void ( STDMETHODCALLTYPE *SetWatsonDumpEnablement )( + ID3D12DeviceRemovedExtendedDataSettings * This, + D3D12_DRED_ENABLEMENT __MIDL__ID3D12DeviceRemovedExtendedDataSettings0002); + + END_INTERFACE + } ID3D12DeviceRemovedExtendedDataSettingsVtbl; + + interface ID3D12DeviceRemovedExtendedDataSettings + { + CONST_VTBL struct ID3D12DeviceRemovedExtendedDataSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DeviceRemovedExtendedDataSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DeviceRemovedExtendedDataSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DeviceRemovedExtendedDataSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DeviceRemovedExtendedDataSettings_SetAutoBreadcrumbsEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0000) \ + ( (This)->lpVtbl -> SetAutoBreadcrumbsEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0000) ) + +#define ID3D12DeviceRemovedExtendedDataSettings_SetPageFaultEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0001) \ + ( (This)->lpVtbl -> SetPageFaultEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0001) ) + +#define ID3D12DeviceRemovedExtendedDataSettings_SetWatsonDumpEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0002) \ + ( (This)->lpVtbl -> SetWatsonDumpEnablement(This,__MIDL__ID3D12DeviceRemovedExtendedDataSettings0002) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DeviceRemovedExtendedDataSettings_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DeviceRemovedExtendedData_INTERFACE_DEFINED__ +#define __ID3D12DeviceRemovedExtendedData_INTERFACE_DEFINED__ + +/* interface ID3D12DeviceRemovedExtendedData */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DeviceRemovedExtendedData; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("98931D33-5AE8-4791-AA3C-1A73A2934E71") + ID3D12DeviceRemovedExtendedData : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetAutoBreadcrumbsOutput( + D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT *pOutput) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPageFaultAllocationOutput( + D3D12_DRED_PAGE_FAULT_OUTPUT *pOutput) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DeviceRemovedExtendedDataVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DeviceRemovedExtendedData * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DeviceRemovedExtendedData * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DeviceRemovedExtendedData * This); + + HRESULT ( STDMETHODCALLTYPE *GetAutoBreadcrumbsOutput )( + ID3D12DeviceRemovedExtendedData * This, + D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT *pOutput); + + HRESULT ( STDMETHODCALLTYPE *GetPageFaultAllocationOutput )( + ID3D12DeviceRemovedExtendedData * This, + D3D12_DRED_PAGE_FAULT_OUTPUT *pOutput); + + END_INTERFACE + } ID3D12DeviceRemovedExtendedDataVtbl; + + interface ID3D12DeviceRemovedExtendedData + { + CONST_VTBL struct ID3D12DeviceRemovedExtendedDataVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DeviceRemovedExtendedData_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DeviceRemovedExtendedData_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DeviceRemovedExtendedData_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DeviceRemovedExtendedData_GetAutoBreadcrumbsOutput(This,pOutput) \ + ( (This)->lpVtbl -> GetAutoBreadcrumbsOutput(This,pOutput) ) + +#define ID3D12DeviceRemovedExtendedData_GetPageFaultAllocationOutput(This,pOutput) \ + ( (This)->lpVtbl -> GetPageFaultAllocationOutput(This,pOutput) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DeviceRemovedExtendedData_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0037 */ +/* [local] */ + +typedef +enum D3D12_BACKGROUND_PROCESSING_MODE + { + D3D12_BACKGROUND_PROCESSING_MODE_ALLOWED = 0, + D3D12_BACKGROUND_PROCESSING_MODE_ALLOW_INTRUSIVE_MEASUREMENTS = ( D3D12_BACKGROUND_PROCESSING_MODE_ALLOWED + 1 ) , + D3D12_BACKGROUND_PROCESSING_MODE_DISABLE_BACKGROUND_WORK = ( D3D12_BACKGROUND_PROCESSING_MODE_ALLOW_INTRUSIVE_MEASUREMENTS + 1 ) , + D3D12_BACKGROUND_PROCESSING_MODE_DISABLE_PROFILING_BY_SYSTEM = ( D3D12_BACKGROUND_PROCESSING_MODE_DISABLE_BACKGROUND_WORK + 1 ) + } D3D12_BACKGROUND_PROCESSING_MODE; + +typedef +enum D3D12_MEASUREMENTS_ACTION + { + D3D12_MEASUREMENTS_ACTION_KEEP_ALL = 0, + D3D12_MEASUREMENTS_ACTION_COMMIT_RESULTS = ( D3D12_MEASUREMENTS_ACTION_KEEP_ALL + 1 ) , + D3D12_MEASUREMENTS_ACTION_COMMIT_RESULTS_HIGH_PRIORITY = ( D3D12_MEASUREMENTS_ACTION_COMMIT_RESULTS + 1 ) , + D3D12_MEASUREMENTS_ACTION_DISCARD_PREVIOUS = ( D3D12_MEASUREMENTS_ACTION_COMMIT_RESULTS_HIGH_PRIORITY + 1 ) + } D3D12_MEASUREMENTS_ACTION; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0037_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0037_v0_0_s_ifspec; + +#ifndef __ID3D12Device6_INTERFACE_DEFINED__ +#define __ID3D12Device6_INTERFACE_DEFINED__ + +/* interface ID3D12Device6 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Device6; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("c70b221b-40e4-4a17-89af-025a0727a6dc") + ID3D12Device6 : public ID3D12Device5 + { + public: + virtual HRESULT STDMETHODCALLTYPE SetBackgroundProcessingMode( + D3D12_BACKGROUND_PROCESSING_MODE Mode, + D3D12_MEASUREMENTS_ACTION MeasurementsAction, + _In_opt_ HANDLE hEventToSignalUponCompletion, + _Out_opt_ BOOL *pbFurtherMeasurementsDesired) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Device6Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Device6 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Device6 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Device6 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Device6 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Device6 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Device6 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Device6 * This, + _In_z_ LPCWSTR Name); + + UINT ( STDMETHODCALLTYPE *GetNodeCount )( + ID3D12Device6 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandQueue )( + ID3D12Device6 * This, + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandAllocator )( + ID3D12Device6 * This, + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateGraphicsPipelineState )( + ID3D12Device6 * This, + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateComputePipelineState )( + ID3D12Device6 * This, + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList )( + ID3D12Device6 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CheckFeatureSupport )( + ID3D12Device6 * This, + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize); + + HRESULT ( STDMETHODCALLTYPE *CreateDescriptorHeap )( + ID3D12Device6 * This, + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + UINT ( STDMETHODCALLTYPE *GetDescriptorHandleIncrementSize )( + ID3D12Device6 * This, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType); + + HRESULT ( STDMETHODCALLTYPE *CreateRootSignature )( + ID3D12Device6 * This, + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature); + + void ( STDMETHODCALLTYPE *CreateConstantBufferView )( + ID3D12Device6 * This, + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateShaderResourceView )( + ID3D12Device6 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateUnorderedAccessView )( + ID3D12Device6 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateRenderTargetView )( + ID3D12Device6 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateDepthStencilView )( + ID3D12Device6 * This, + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CreateSampler )( + ID3D12Device6 * This, + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + + void ( STDMETHODCALLTYPE *CopyDescriptors )( + ID3D12Device6 * This, + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + void ( STDMETHODCALLTYPE *CopyDescriptorsSimple )( + ID3D12Device6 * This, + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo )( + ID3D12Device6 * This, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs); + + D3D12_HEAP_PROPERTIES ( STDMETHODCALLTYPE *GetCustomHeapProperties )( + ID3D12Device6 * This, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource )( + ID3D12Device6 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap )( + ID3D12Device6 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreatePlacedResource )( + ID3D12Device6 * This, + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource )( + ID3D12Device6 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateSharedHandle )( + ID3D12Device6 * This, + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandle )( + ID3D12Device6 * This, + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj); + + HRESULT ( STDMETHODCALLTYPE *OpenSharedHandleByName )( + ID3D12Device6 * This, + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle); + + HRESULT ( STDMETHODCALLTYPE *MakeResident )( + ID3D12Device6 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *Evict )( + ID3D12Device6 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects); + + HRESULT ( STDMETHODCALLTYPE *CreateFence )( + ID3D12Device6 * This, + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence); + + HRESULT ( STDMETHODCALLTYPE *GetDeviceRemovedReason )( + ID3D12Device6 * This); + + void ( STDMETHODCALLTYPE *GetCopyableFootprints )( + ID3D12Device6 * This, + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes); + + HRESULT ( STDMETHODCALLTYPE *CreateQueryHeap )( + ID3D12Device6 * This, + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *SetStablePowerState )( + ID3D12Device6 * This, + BOOL Enable); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandSignature )( + ID3D12Device6 * This, + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature); + + void ( STDMETHODCALLTYPE *GetResourceTiling )( + ID3D12Device6 * This, + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + LUID ( STDMETHODCALLTYPE *GetAdapterLuid )( + ID3D12Device6 * This); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineLibrary )( + ID3D12Device6 * This, + _In_reads_(BlobLength) const void *pLibraryBlob, + SIZE_T BlobLength, + REFIID riid, + _COM_Outptr_ void **ppPipelineLibrary); + + HRESULT ( STDMETHODCALLTYPE *SetEventOnMultipleFenceCompletion )( + ID3D12Device6 * This, + _In_reads_(NumFences) ID3D12Fence *const *ppFences, + _In_reads_(NumFences) const UINT64 *pFenceValues, + UINT NumFences, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, + HANDLE hEvent); + + HRESULT ( STDMETHODCALLTYPE *SetResidencyPriority )( + ID3D12Device6 * This, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_reads_(NumObjects) const D3D12_RESIDENCY_PRIORITY *pPriorities); + + HRESULT ( STDMETHODCALLTYPE *CreatePipelineState )( + ID3D12Device6 * This, + const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromAddress )( + ID3D12Device6 * This, + _In_ const void *pAddress, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *OpenExistingHeapFromFileMapping )( + ID3D12Device6 * This, + _In_ HANDLE hFileMapping, + REFIID riid, + _COM_Outptr_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *EnqueueMakeResident )( + ID3D12Device6 * This, + D3D12_RESIDENCY_FLAGS Flags, + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects, + _In_ ID3D12Fence *pFenceToSignal, + UINT64 FenceValueToSignal); + + HRESULT ( STDMETHODCALLTYPE *CreateCommandList1 )( + ID3D12Device6 * This, + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ D3D12_COMMAND_LIST_FLAGS flags, + REFIID riid, + _COM_Outptr_ void **ppCommandList); + + HRESULT ( STDMETHODCALLTYPE *CreateProtectedResourceSession )( + ID3D12Device6 * This, + _In_ const D3D12_PROTECTED_RESOURCE_SESSION_DESC *pDesc, + _In_ REFIID riid, + _COM_Outptr_ void **ppSession); + + HRESULT ( STDMETHODCALLTYPE *CreateCommittedResource1 )( + ID3D12Device6 * This, + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource); + + HRESULT ( STDMETHODCALLTYPE *CreateHeap1 )( + ID3D12Device6 * This, + _In_ const D3D12_HEAP_DESC *pDesc, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap); + + HRESULT ( STDMETHODCALLTYPE *CreateReservedResource1 )( + ID3D12Device6 * This, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource); + + D3D12_RESOURCE_ALLOCATION_INFO ( STDMETHODCALLTYPE *GetResourceAllocationInfo1 )( + ID3D12Device6 * This, + UINT visibleMask, + UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs, + _Out_writes_opt_(numResourceDescs) D3D12_RESOURCE_ALLOCATION_INFO1 *pResourceAllocationInfo1); + + HRESULT ( STDMETHODCALLTYPE *CreateLifetimeTracker )( + ID3D12Device6 * This, + _In_ ID3D12LifetimeOwner *pOwner, + REFIID riid, + _COM_Outptr_ void **ppvTracker); + + void ( STDMETHODCALLTYPE *RemoveDevice )( + ID3D12Device6 * This); + + HRESULT ( STDMETHODCALLTYPE *EnumerateMetaCommands )( + ID3D12Device6 * This, + _Inout_ UINT *pNumMetaCommands, + _Out_writes_opt_(*pNumMetaCommands) D3D12_META_COMMAND_DESC *pDescs); + + HRESULT ( STDMETHODCALLTYPE *EnumerateMetaCommandParameters )( + ID3D12Device6 * This, + _In_ REFGUID CommandId, + _In_ D3D12_META_COMMAND_PARAMETER_STAGE Stage, + _Out_opt_ UINT *pTotalStructureSizeInBytes, + _Inout_ UINT *pParameterCount, + _Out_writes_opt_(*pParameterCount) D3D12_META_COMMAND_PARAMETER_DESC *pParameterDescs); + + HRESULT ( STDMETHODCALLTYPE *CreateMetaCommand )( + ID3D12Device6 * This, + _In_ REFGUID CommandId, + _In_ UINT NodeMask, + _In_reads_bytes_opt_(CreationParametersDataSizeInBytes) const void *pCreationParametersData, + _In_ SIZE_T CreationParametersDataSizeInBytes, + REFIID riid, + _COM_Outptr_ void **ppMetaCommand); + + HRESULT ( STDMETHODCALLTYPE *CreateStateObject )( + ID3D12Device6 * This, + const D3D12_STATE_OBJECT_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppStateObject); + + void ( STDMETHODCALLTYPE *GetRaytracingAccelerationStructurePrebuildInfo )( + ID3D12Device6 * This, + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *pDesc, + _Out_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *pInfo); + + D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS ( STDMETHODCALLTYPE *CheckDriverMatchingIdentifier )( + ID3D12Device6 * This, + _In_ D3D12_SERIALIZED_DATA_TYPE SerializedDataType, + _In_ const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *pIdentifierToCheck); + + HRESULT ( STDMETHODCALLTYPE *SetBackgroundProcessingMode )( + ID3D12Device6 * This, + D3D12_BACKGROUND_PROCESSING_MODE Mode, + D3D12_MEASUREMENTS_ACTION MeasurementsAction, + _In_opt_ HANDLE hEventToSignalUponCompletion, + _Out_opt_ BOOL *pbFurtherMeasurementsDesired); + + END_INTERFACE + } ID3D12Device6Vtbl; + + interface ID3D12Device6 + { + CONST_VTBL struct ID3D12Device6Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Device6_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Device6_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Device6_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Device6_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Device6_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Device6_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Device6_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Device6_GetNodeCount(This) \ + ( (This)->lpVtbl -> GetNodeCount(This) ) + +#define ID3D12Device6_CreateCommandQueue(This,pDesc,riid,ppCommandQueue) \ + ( (This)->lpVtbl -> CreateCommandQueue(This,pDesc,riid,ppCommandQueue) ) + +#define ID3D12Device6_CreateCommandAllocator(This,type,riid,ppCommandAllocator) \ + ( (This)->lpVtbl -> CreateCommandAllocator(This,type,riid,ppCommandAllocator) ) + +#define ID3D12Device6_CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateGraphicsPipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device6_CreateComputePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreateComputePipelineState(This,pDesc,riid,ppPipelineState) ) + +#define ID3D12Device6_CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList(This,nodeMask,type,pCommandAllocator,pInitialState,riid,ppCommandList) ) + +#define ID3D12Device6_CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) \ + ( (This)->lpVtbl -> CheckFeatureSupport(This,Feature,pFeatureSupportData,FeatureSupportDataSize) ) + +#define ID3D12Device6_CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateDescriptorHeap(This,pDescriptorHeapDesc,riid,ppvHeap) ) + +#define ID3D12Device6_GetDescriptorHandleIncrementSize(This,DescriptorHeapType) \ + ( (This)->lpVtbl -> GetDescriptorHandleIncrementSize(This,DescriptorHeapType) ) + +#define ID3D12Device6_CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) \ + ( (This)->lpVtbl -> CreateRootSignature(This,nodeMask,pBlobWithRootSignature,blobLengthInBytes,riid,ppvRootSignature) ) + +#define ID3D12Device6_CreateConstantBufferView(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateConstantBufferView(This,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateShaderResourceView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateUnorderedAccessView(This,pResource,pCounterResource,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateRenderTargetView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateDepthStencilView(This,pResource,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CreateSampler(This,pDesc,DestDescriptor) \ + ( (This)->lpVtbl -> CreateSampler(This,pDesc,DestDescriptor) ) + +#define ID3D12Device6_CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptors(This,NumDestDescriptorRanges,pDestDescriptorRangeStarts,pDestDescriptorRangeSizes,NumSrcDescriptorRanges,pSrcDescriptorRangeStarts,pSrcDescriptorRangeSizes,DescriptorHeapsType) ) + +#define ID3D12Device6_CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) \ + ( (This)->lpVtbl -> CopyDescriptorsSimple(This,NumDescriptors,DestDescriptorRangeStart,SrcDescriptorRangeStart,DescriptorHeapsType) ) + +#define ID3D12Device6_GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo(This,visibleMask,numResourceDescs,pResourceDescs) ) + +#define ID3D12Device6_GetCustomHeapProperties(This,nodeMask,heapType) \ + ( (This)->lpVtbl -> GetCustomHeapProperties(This,nodeMask,heapType) ) + +#define ID3D12Device6_CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,riidResource,ppvResource) ) + +#define ID3D12Device6_CreateHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device6_CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreatePlacedResource(This,pHeap,HeapOffset,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device6_CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource(This,pDesc,InitialState,pOptimizedClearValue,riid,ppvResource) ) + +#define ID3D12Device6_CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) \ + ( (This)->lpVtbl -> CreateSharedHandle(This,pObject,pAttributes,Access,Name,pHandle) ) + +#define ID3D12Device6_OpenSharedHandle(This,NTHandle,riid,ppvObj) \ + ( (This)->lpVtbl -> OpenSharedHandle(This,NTHandle,riid,ppvObj) ) + +#define ID3D12Device6_OpenSharedHandleByName(This,Name,Access,pNTHandle) \ + ( (This)->lpVtbl -> OpenSharedHandleByName(This,Name,Access,pNTHandle) ) + +#define ID3D12Device6_MakeResident(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> MakeResident(This,NumObjects,ppObjects) ) + +#define ID3D12Device6_Evict(This,NumObjects,ppObjects) \ + ( (This)->lpVtbl -> Evict(This,NumObjects,ppObjects) ) + +#define ID3D12Device6_CreateFence(This,InitialValue,Flags,riid,ppFence) \ + ( (This)->lpVtbl -> CreateFence(This,InitialValue,Flags,riid,ppFence) ) + +#define ID3D12Device6_GetDeviceRemovedReason(This) \ + ( (This)->lpVtbl -> GetDeviceRemovedReason(This) ) + +#define ID3D12Device6_GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) \ + ( (This)->lpVtbl -> GetCopyableFootprints(This,pResourceDesc,FirstSubresource,NumSubresources,BaseOffset,pLayouts,pNumRows,pRowSizeInBytes,pTotalBytes) ) + +#define ID3D12Device6_CreateQueryHeap(This,pDesc,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateQueryHeap(This,pDesc,riid,ppvHeap) ) + +#define ID3D12Device6_SetStablePowerState(This,Enable) \ + ( (This)->lpVtbl -> SetStablePowerState(This,Enable) ) + +#define ID3D12Device6_CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) \ + ( (This)->lpVtbl -> CreateCommandSignature(This,pDesc,pRootSignature,riid,ppvCommandSignature) ) + +#define ID3D12Device6_GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) \ + ( (This)->lpVtbl -> GetResourceTiling(This,pTiledResource,pNumTilesForEntireResource,pPackedMipDesc,pStandardTileShapeForNonPackedMips,pNumSubresourceTilings,FirstSubresourceTilingToGet,pSubresourceTilingsForNonPackedMips) ) + +#define ID3D12Device6_GetAdapterLuid(This) \ + ( (This)->lpVtbl -> GetAdapterLuid(This) ) + + +#define ID3D12Device6_CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) \ + ( (This)->lpVtbl -> CreatePipelineLibrary(This,pLibraryBlob,BlobLength,riid,ppPipelineLibrary) ) + +#define ID3D12Device6_SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) \ + ( (This)->lpVtbl -> SetEventOnMultipleFenceCompletion(This,ppFences,pFenceValues,NumFences,Flags,hEvent) ) + +#define ID3D12Device6_SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) \ + ( (This)->lpVtbl -> SetResidencyPriority(This,NumObjects,ppObjects,pPriorities) ) + + +#define ID3D12Device6_CreatePipelineState(This,pDesc,riid,ppPipelineState) \ + ( (This)->lpVtbl -> CreatePipelineState(This,pDesc,riid,ppPipelineState) ) + + +#define ID3D12Device6_OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromAddress(This,pAddress,riid,ppvHeap) ) + +#define ID3D12Device6_OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) \ + ( (This)->lpVtbl -> OpenExistingHeapFromFileMapping(This,hFileMapping,riid,ppvHeap) ) + +#define ID3D12Device6_EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) \ + ( (This)->lpVtbl -> EnqueueMakeResident(This,Flags,NumObjects,ppObjects,pFenceToSignal,FenceValueToSignal) ) + + +#define ID3D12Device6_CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) \ + ( (This)->lpVtbl -> CreateCommandList1(This,nodeMask,type,flags,riid,ppCommandList) ) + +#define ID3D12Device6_CreateProtectedResourceSession(This,pDesc,riid,ppSession) \ + ( (This)->lpVtbl -> CreateProtectedResourceSession(This,pDesc,riid,ppSession) ) + +#define ID3D12Device6_CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) \ + ( (This)->lpVtbl -> CreateCommittedResource1(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pProtectedSession,riidResource,ppvResource) ) + +#define ID3D12Device6_CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) \ + ( (This)->lpVtbl -> CreateHeap1(This,pDesc,pProtectedSession,riid,ppvHeap) ) + +#define ID3D12Device6_CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) \ + ( (This)->lpVtbl -> CreateReservedResource1(This,pDesc,InitialState,pOptimizedClearValue,pProtectedSession,riid,ppvResource) ) + +#define ID3D12Device6_GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) \ + ( (This)->lpVtbl -> GetResourceAllocationInfo1(This,visibleMask,numResourceDescs,pResourceDescs,pResourceAllocationInfo1) ) + + +#define ID3D12Device6_CreateLifetimeTracker(This,pOwner,riid,ppvTracker) \ + ( (This)->lpVtbl -> CreateLifetimeTracker(This,pOwner,riid,ppvTracker) ) + +#define ID3D12Device6_RemoveDevice(This) \ + ( (This)->lpVtbl -> RemoveDevice(This) ) + +#define ID3D12Device6_EnumerateMetaCommands(This,pNumMetaCommands,pDescs) \ + ( (This)->lpVtbl -> EnumerateMetaCommands(This,pNumMetaCommands,pDescs) ) + +#define ID3D12Device6_EnumerateMetaCommandParameters(This,CommandId,Stage,pTotalStructureSizeInBytes,pParameterCount,pParameterDescs) \ + ( (This)->lpVtbl -> EnumerateMetaCommandParameters(This,CommandId,Stage,pTotalStructureSizeInBytes,pParameterCount,pParameterDescs) ) + +#define ID3D12Device6_CreateMetaCommand(This,CommandId,NodeMask,pCreationParametersData,CreationParametersDataSizeInBytes,riid,ppMetaCommand) \ + ( (This)->lpVtbl -> CreateMetaCommand(This,CommandId,NodeMask,pCreationParametersData,CreationParametersDataSizeInBytes,riid,ppMetaCommand) ) + +#define ID3D12Device6_CreateStateObject(This,pDesc,riid,ppStateObject) \ + ( (This)->lpVtbl -> CreateStateObject(This,pDesc,riid,ppStateObject) ) + +#define ID3D12Device6_GetRaytracingAccelerationStructurePrebuildInfo(This,pDesc,pInfo) \ + ( (This)->lpVtbl -> GetRaytracingAccelerationStructurePrebuildInfo(This,pDesc,pInfo) ) + +#define ID3D12Device6_CheckDriverMatchingIdentifier(This,SerializedDataType,pIdentifierToCheck) \ + ( (This)->lpVtbl -> CheckDriverMatchingIdentifier(This,SerializedDataType,pIdentifierToCheck) ) + + +#define ID3D12Device6_SetBackgroundProcessingMode(This,Mode,MeasurementsAction,hEventToSignalUponCompletion,pbFurtherMeasurementsDesired) \ + ( (This)->lpVtbl -> SetBackgroundProcessingMode(This,Mode,MeasurementsAction,hEventToSignalUponCompletion,pbFurtherMeasurementsDesired) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Device6_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Resource1_INTERFACE_DEFINED__ +#define __ID3D12Resource1_INTERFACE_DEFINED__ + +/* interface ID3D12Resource1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Resource1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9D5E227A-4430-4161-88B3-3ECA6BB16E19") + ID3D12Resource1 : public ID3D12Resource + { + public: + virtual HRESULT STDMETHODCALLTYPE GetProtectedResourceSession( + REFIID riid, + _COM_Outptr_opt_ void **ppProtectedSession) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Resource1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Resource1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Resource1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Resource1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Resource1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Resource1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Resource1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Resource1 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Resource1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + HRESULT ( STDMETHODCALLTYPE *Map )( + ID3D12Resource1 * This, + UINT Subresource, + _In_opt_ const D3D12_RANGE *pReadRange, + _Outptr_opt_result_bytebuffer_(_Inexpressible_("Dependent on resource")) void **ppData); + + void ( STDMETHODCALLTYPE *Unmap )( + ID3D12Resource1 * This, + UINT Subresource, + _In_opt_ const D3D12_RANGE *pWrittenRange); + + D3D12_RESOURCE_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12Resource1 * This); + + D3D12_GPU_VIRTUAL_ADDRESS ( STDMETHODCALLTYPE *GetGPUVirtualAddress )( + ID3D12Resource1 * This); + + HRESULT ( STDMETHODCALLTYPE *WriteToSubresource )( + ID3D12Resource1 * This, + UINT DstSubresource, + _In_opt_ const D3D12_BOX *pDstBox, + _In_ const void *pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch); + + HRESULT ( STDMETHODCALLTYPE *ReadFromSubresource )( + ID3D12Resource1 * This, + _Out_ void *pDstData, + UINT DstRowPitch, + UINT DstDepthPitch, + UINT SrcSubresource, + _In_opt_ const D3D12_BOX *pSrcBox); + + HRESULT ( STDMETHODCALLTYPE *GetHeapProperties )( + ID3D12Resource1 * This, + _Out_opt_ D3D12_HEAP_PROPERTIES *pHeapProperties, + _Out_opt_ D3D12_HEAP_FLAGS *pHeapFlags); + + HRESULT ( STDMETHODCALLTYPE *GetProtectedResourceSession )( + ID3D12Resource1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppProtectedSession); + + END_INTERFACE + } ID3D12Resource1Vtbl; + + interface ID3D12Resource1 + { + CONST_VTBL struct ID3D12Resource1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Resource1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Resource1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Resource1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Resource1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Resource1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Resource1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Resource1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Resource1_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Resource1_Map(This,Subresource,pReadRange,ppData) \ + ( (This)->lpVtbl -> Map(This,Subresource,pReadRange,ppData) ) + +#define ID3D12Resource1_Unmap(This,Subresource,pWrittenRange) \ + ( (This)->lpVtbl -> Unmap(This,Subresource,pWrittenRange) ) + +#define ID3D12Resource1_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + +#define ID3D12Resource1_GetGPUVirtualAddress(This) \ + ( (This)->lpVtbl -> GetGPUVirtualAddress(This) ) + +#define ID3D12Resource1_WriteToSubresource(This,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) \ + ( (This)->lpVtbl -> WriteToSubresource(This,DstSubresource,pDstBox,pSrcData,SrcRowPitch,SrcDepthPitch) ) + +#define ID3D12Resource1_ReadFromSubresource(This,pDstData,DstRowPitch,DstDepthPitch,SrcSubresource,pSrcBox) \ + ( (This)->lpVtbl -> ReadFromSubresource(This,pDstData,DstRowPitch,DstDepthPitch,SrcSubresource,pSrcBox) ) + +#define ID3D12Resource1_GetHeapProperties(This,pHeapProperties,pHeapFlags) \ + ( (This)->lpVtbl -> GetHeapProperties(This,pHeapProperties,pHeapFlags) ) + + +#define ID3D12Resource1_GetProtectedResourceSession(This,riid,ppProtectedSession) \ + ( (This)->lpVtbl -> GetProtectedResourceSession(This,riid,ppProtectedSession) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Resource1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Heap1_INTERFACE_DEFINED__ +#define __ID3D12Heap1_INTERFACE_DEFINED__ + +/* interface ID3D12Heap1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Heap1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("572F7389-2168-49E3-9693-D6DF5871BF6D") + ID3D12Heap1 : public ID3D12Heap + { + public: + virtual HRESULT STDMETHODCALLTYPE GetProtectedResourceSession( + REFIID riid, + _COM_Outptr_opt_ void **ppProtectedSession) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Heap1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Heap1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Heap1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Heap1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12Heap1 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12Heap1 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12Heap1 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12Heap1 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12Heap1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_HEAP_DESC ( STDMETHODCALLTYPE *GetDesc )( + ID3D12Heap1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetProtectedResourceSession )( + ID3D12Heap1 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppProtectedSession); + + END_INTERFACE + } ID3D12Heap1Vtbl; + + interface ID3D12Heap1 + { + CONST_VTBL struct ID3D12Heap1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Heap1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Heap1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Heap1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Heap1_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12Heap1_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12Heap1_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12Heap1_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12Heap1_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12Heap1_GetDesc(This) \ + ( (This)->lpVtbl -> GetDesc(This) ) + + +#define ID3D12Heap1_GetProtectedResourceSession(This,riid,ppProtectedSession) \ + ( (This)->lpVtbl -> GetProtectedResourceSession(This,riid,ppProtectedSession) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Heap1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12GraphicsCommandList3_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList3_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList3 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6FDA83A7-B84C-4E38-9AC8-C7BD22016B3D") + ID3D12GraphicsCommandList3 : public ID3D12GraphicsCommandList2 + { + public: + virtual void STDMETHODCALLTYPE SetProtectedResourceSession( + _In_opt_ ID3D12ProtectedResourceSession *pProtectedResourceSession) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandList3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList3 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList3 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList3 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList3 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList3 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList3 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList3 * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList3 * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList3 * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList3 * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList3 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList3 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList3 * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList3 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList3 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList3 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList3 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList3 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList3 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList3 * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT64 )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *OMSetDepthBounds )( + ID3D12GraphicsCommandList3 * This, + _In_ FLOAT Min, + _In_ FLOAT Max); + + void ( STDMETHODCALLTYPE *SetSamplePositions )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions); + + void ( STDMETHODCALLTYPE *ResolveSubresourceRegion )( + ID3D12GraphicsCommandList3 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode); + + void ( STDMETHODCALLTYPE *SetViewInstanceMask )( + ID3D12GraphicsCommandList3 * This, + _In_ UINT Mask); + + void ( STDMETHODCALLTYPE *WriteBufferImmediate )( + ID3D12GraphicsCommandList3 * This, + UINT Count, + _In_reads_(Count) const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *pParams, + _In_reads_opt_(Count) const D3D12_WRITEBUFFERIMMEDIATE_MODE *pModes); + + void ( STDMETHODCALLTYPE *SetProtectedResourceSession )( + ID3D12GraphicsCommandList3 * This, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedResourceSession); + + END_INTERFACE + } ID3D12GraphicsCommandList3Vtbl; + + interface ID3D12GraphicsCommandList3 + { + CONST_VTBL struct ID3D12GraphicsCommandList3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList3_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList3_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList3_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList3_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList3_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList3_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList3_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList3_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList3_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList3_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList3_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList3_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList3_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList3_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList3_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList3_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList3_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList3_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList3_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList3_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList3_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList3_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList3_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList3_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList3_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList3_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList3_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList3_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList3_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList3_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList3_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList3_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList3_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList3_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList3_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList3_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList3_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList3_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList3_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList3_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList3_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList3_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList3_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList3_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList3_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList3_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList3_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList3_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + + +#define ID3D12GraphicsCommandList3_AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList3_AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList3_OMSetDepthBounds(This,Min,Max) \ + ( (This)->lpVtbl -> OMSetDepthBounds(This,Min,Max) ) + +#define ID3D12GraphicsCommandList3_SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) \ + ( (This)->lpVtbl -> SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) ) + +#define ID3D12GraphicsCommandList3_ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) \ + ( (This)->lpVtbl -> ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) ) + +#define ID3D12GraphicsCommandList3_SetViewInstanceMask(This,Mask) \ + ( (This)->lpVtbl -> SetViewInstanceMask(This,Mask) ) + + +#define ID3D12GraphicsCommandList3_WriteBufferImmediate(This,Count,pParams,pModes) \ + ( (This)->lpVtbl -> WriteBufferImmediate(This,Count,pParams,pModes) ) + + +#define ID3D12GraphicsCommandList3_SetProtectedResourceSession(This,pProtectedResourceSession) \ + ( (This)->lpVtbl -> SetProtectedResourceSession(This,pProtectedResourceSession) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList3_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0041 */ +/* [local] */ + +typedef +enum D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE + { + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD = 0, + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE = ( D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD + 1 ) , + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR = ( D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE + 1 ) , + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS = ( D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR + 1 ) + } D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE; + +typedef struct D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS + { + D3D12_CLEAR_VALUE ClearValue; + } D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS; + +typedef struct D3D12_RENDER_PASS_BEGINNING_ACCESS + { + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE Type; + union + { + D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS Clear; + } ; + } D3D12_RENDER_PASS_BEGINNING_ACCESS; + +typedef +enum D3D12_RENDER_PASS_ENDING_ACCESS_TYPE + { + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD = 0, + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE = ( D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD + 1 ) , + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE = ( D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE + 1 ) , + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS = ( D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE + 1 ) + } D3D12_RENDER_PASS_ENDING_ACCESS_TYPE; + +typedef struct D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS + { + UINT SrcSubresource; + UINT DstSubresource; + UINT DstX; + UINT DstY; + D3D12_RECT SrcRect; + } D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS; + +typedef struct D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS + { + ID3D12Resource *pSrcResource; + ID3D12Resource *pDstResource; + UINT SubresourceCount; + _Field_size_full_(SubresourceCount) const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS *pSubresourceParameters; + DXGI_FORMAT Format; + D3D12_RESOLVE_MODE ResolveMode; + BOOL PreserveResolveSource; + } D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS; + +typedef struct D3D12_RENDER_PASS_ENDING_ACCESS + { + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE Type; + union + { + D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS Resolve; + } ; + } D3D12_RENDER_PASS_ENDING_ACCESS; + +typedef struct D3D12_RENDER_PASS_RENDER_TARGET_DESC + { + D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptor; + D3D12_RENDER_PASS_BEGINNING_ACCESS BeginningAccess; + D3D12_RENDER_PASS_ENDING_ACCESS EndingAccess; + } D3D12_RENDER_PASS_RENDER_TARGET_DESC; + +typedef struct D3D12_RENDER_PASS_DEPTH_STENCIL_DESC + { + D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptor; + D3D12_RENDER_PASS_BEGINNING_ACCESS DepthBeginningAccess; + D3D12_RENDER_PASS_BEGINNING_ACCESS StencilBeginningAccess; + D3D12_RENDER_PASS_ENDING_ACCESS DepthEndingAccess; + D3D12_RENDER_PASS_ENDING_ACCESS StencilEndingAccess; + } D3D12_RENDER_PASS_DEPTH_STENCIL_DESC; + +typedef +enum D3D12_RENDER_PASS_FLAGS + { + D3D12_RENDER_PASS_FLAG_NONE = 0, + D3D12_RENDER_PASS_FLAG_ALLOW_UAV_WRITES = 0x1, + D3D12_RENDER_PASS_FLAG_SUSPENDING_PASS = 0x2, + D3D12_RENDER_PASS_FLAG_RESUMING_PASS = 0x4 + } D3D12_RENDER_PASS_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS( D3D12_RENDER_PASS_FLAGS ); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0041_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0041_v0_0_s_ifspec; + +#ifndef __ID3D12MetaCommand_INTERFACE_DEFINED__ +#define __ID3D12MetaCommand_INTERFACE_DEFINED__ + +/* interface ID3D12MetaCommand */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12MetaCommand; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("DBB84C27-36CE-4FC9-B801-F048C46AC570") + ID3D12MetaCommand : public ID3D12Pageable + { + public: + virtual UINT64 STDMETHODCALLTYPE GetRequiredParameterResourceSize( + _In_ D3D12_META_COMMAND_PARAMETER_STAGE Stage, + _In_ UINT ParameterIndex) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12MetaCommandVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12MetaCommand * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12MetaCommand * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12MetaCommand * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12MetaCommand * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12MetaCommand * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12MetaCommand * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12MetaCommand * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12MetaCommand * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + UINT64 ( STDMETHODCALLTYPE *GetRequiredParameterResourceSize )( + ID3D12MetaCommand * This, + _In_ D3D12_META_COMMAND_PARAMETER_STAGE Stage, + _In_ UINT ParameterIndex); + + END_INTERFACE + } ID3D12MetaCommandVtbl; + + interface ID3D12MetaCommand + { + CONST_VTBL struct ID3D12MetaCommandVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12MetaCommand_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12MetaCommand_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12MetaCommand_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12MetaCommand_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12MetaCommand_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12MetaCommand_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12MetaCommand_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12MetaCommand_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + + +#define ID3D12MetaCommand_GetRequiredParameterResourceSize(This,Stage,ParameterIndex) \ + ( (This)->lpVtbl -> GetRequiredParameterResourceSize(This,Stage,ParameterIndex) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12MetaCommand_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0042 */ +/* [local] */ + +typedef struct D3D12_DISPATCH_RAYS_DESC + { + D3D12_GPU_VIRTUAL_ADDRESS_RANGE RayGenerationShaderRecord; + D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE MissShaderTable; + D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE HitGroupTable; + D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE CallableShaderTable; + UINT Width; + UINT Height; + UINT Depth; + } D3D12_DISPATCH_RAYS_DESC; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0042_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0042_v0_0_s_ifspec; + +#ifndef __ID3D12GraphicsCommandList4_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList4_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList4 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8754318e-d3a9-4541-98cf-645b50dc4874") + ID3D12GraphicsCommandList4 : public ID3D12GraphicsCommandList3 + { + public: + virtual void STDMETHODCALLTYPE BeginRenderPass( + _In_ UINT NumRenderTargets, + _In_reads_opt_(NumRenderTargets) const D3D12_RENDER_PASS_RENDER_TARGET_DESC *pRenderTargets, + _In_opt_ const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags) = 0; + + virtual void STDMETHODCALLTYPE EndRenderPass( void) = 0; + + virtual void STDMETHODCALLTYPE InitializeMetaCommand( + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(InitializationParametersDataSizeInBytes) const void *pInitializationParametersData, + _In_ SIZE_T InitializationParametersDataSizeInBytes) = 0; + + virtual void STDMETHODCALLTYPE ExecuteMetaCommand( + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(ExecutionParametersDataSizeInBytes) const void *pExecutionParametersData, + _In_ SIZE_T ExecutionParametersDataSizeInBytes) = 0; + + virtual void STDMETHODCALLTYPE BuildRaytracingAccelerationStructure( + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *pDesc, + _In_ UINT NumPostbuildInfoDescs, + _In_reads_opt_(NumPostbuildInfoDescs) const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pPostbuildInfoDescs) = 0; + + virtual void STDMETHODCALLTYPE EmitRaytracingAccelerationStructurePostbuildInfo( + _In_ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pDesc, + _In_ UINT NumSourceAccelerationStructures, + _In_reads_( NumSourceAccelerationStructures ) const D3D12_GPU_VIRTUAL_ADDRESS *pSourceAccelerationStructureData) = 0; + + virtual void STDMETHODCALLTYPE CopyRaytracingAccelerationStructure( + _In_ D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData, + _In_ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData, + _In_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE Mode) = 0; + + virtual void STDMETHODCALLTYPE SetPipelineState1( + _In_ ID3D12StateObject *pStateObject) = 0; + + virtual void STDMETHODCALLTYPE DispatchRays( + _In_ const D3D12_DISPATCH_RAYS_DESC *pDesc) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandList4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList4 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList4 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList4 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList4 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList4 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList4 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList4 * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList4 * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList4 * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList4 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList4 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList4 * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList4 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList4 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList4 * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT64 )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *OMSetDepthBounds )( + ID3D12GraphicsCommandList4 * This, + _In_ FLOAT Min, + _In_ FLOAT Max); + + void ( STDMETHODCALLTYPE *SetSamplePositions )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions); + + void ( STDMETHODCALLTYPE *ResolveSubresourceRegion )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode); + + void ( STDMETHODCALLTYPE *SetViewInstanceMask )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT Mask); + + void ( STDMETHODCALLTYPE *WriteBufferImmediate )( + ID3D12GraphicsCommandList4 * This, + UINT Count, + _In_reads_(Count) const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *pParams, + _In_reads_opt_(Count) const D3D12_WRITEBUFFERIMMEDIATE_MODE *pModes); + + void ( STDMETHODCALLTYPE *SetProtectedResourceSession )( + ID3D12GraphicsCommandList4 * This, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedResourceSession); + + void ( STDMETHODCALLTYPE *BeginRenderPass )( + ID3D12GraphicsCommandList4 * This, + _In_ UINT NumRenderTargets, + _In_reads_opt_(NumRenderTargets) const D3D12_RENDER_PASS_RENDER_TARGET_DESC *pRenderTargets, + _In_opt_ const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags); + + void ( STDMETHODCALLTYPE *EndRenderPass )( + ID3D12GraphicsCommandList4 * This); + + void ( STDMETHODCALLTYPE *InitializeMetaCommand )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(InitializationParametersDataSizeInBytes) const void *pInitializationParametersData, + _In_ SIZE_T InitializationParametersDataSizeInBytes); + + void ( STDMETHODCALLTYPE *ExecuteMetaCommand )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(ExecutionParametersDataSizeInBytes) const void *pExecutionParametersData, + _In_ SIZE_T ExecutionParametersDataSizeInBytes); + + void ( STDMETHODCALLTYPE *BuildRaytracingAccelerationStructure )( + ID3D12GraphicsCommandList4 * This, + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *pDesc, + _In_ UINT NumPostbuildInfoDescs, + _In_reads_opt_(NumPostbuildInfoDescs) const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pPostbuildInfoDescs); + + void ( STDMETHODCALLTYPE *EmitRaytracingAccelerationStructurePostbuildInfo )( + ID3D12GraphicsCommandList4 * This, + _In_ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pDesc, + _In_ UINT NumSourceAccelerationStructures, + _In_reads_( NumSourceAccelerationStructures ) const D3D12_GPU_VIRTUAL_ADDRESS *pSourceAccelerationStructureData); + + void ( STDMETHODCALLTYPE *CopyRaytracingAccelerationStructure )( + ID3D12GraphicsCommandList4 * This, + _In_ D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData, + _In_ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData, + _In_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE Mode); + + void ( STDMETHODCALLTYPE *SetPipelineState1 )( + ID3D12GraphicsCommandList4 * This, + _In_ ID3D12StateObject *pStateObject); + + void ( STDMETHODCALLTYPE *DispatchRays )( + ID3D12GraphicsCommandList4 * This, + _In_ const D3D12_DISPATCH_RAYS_DESC *pDesc); + + END_INTERFACE + } ID3D12GraphicsCommandList4Vtbl; + + interface ID3D12GraphicsCommandList4 + { + CONST_VTBL struct ID3D12GraphicsCommandList4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList4_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList4_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList4_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList4_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList4_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList4_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList4_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList4_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList4_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList4_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList4_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList4_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList4_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList4_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList4_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList4_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList4_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList4_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList4_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList4_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList4_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList4_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList4_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList4_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList4_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList4_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList4_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList4_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList4_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList4_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList4_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList4_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList4_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList4_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList4_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList4_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList4_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList4_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList4_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList4_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList4_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList4_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList4_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList4_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList4_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList4_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList4_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList4_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + + +#define ID3D12GraphicsCommandList4_AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList4_AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList4_OMSetDepthBounds(This,Min,Max) \ + ( (This)->lpVtbl -> OMSetDepthBounds(This,Min,Max) ) + +#define ID3D12GraphicsCommandList4_SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) \ + ( (This)->lpVtbl -> SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) ) + +#define ID3D12GraphicsCommandList4_ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) \ + ( (This)->lpVtbl -> ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) ) + +#define ID3D12GraphicsCommandList4_SetViewInstanceMask(This,Mask) \ + ( (This)->lpVtbl -> SetViewInstanceMask(This,Mask) ) + + +#define ID3D12GraphicsCommandList4_WriteBufferImmediate(This,Count,pParams,pModes) \ + ( (This)->lpVtbl -> WriteBufferImmediate(This,Count,pParams,pModes) ) + + +#define ID3D12GraphicsCommandList4_SetProtectedResourceSession(This,pProtectedResourceSession) \ + ( (This)->lpVtbl -> SetProtectedResourceSession(This,pProtectedResourceSession) ) + + +#define ID3D12GraphicsCommandList4_BeginRenderPass(This,NumRenderTargets,pRenderTargets,pDepthStencil,Flags) \ + ( (This)->lpVtbl -> BeginRenderPass(This,NumRenderTargets,pRenderTargets,pDepthStencil,Flags) ) + +#define ID3D12GraphicsCommandList4_EndRenderPass(This) \ + ( (This)->lpVtbl -> EndRenderPass(This) ) + +#define ID3D12GraphicsCommandList4_InitializeMetaCommand(This,pMetaCommand,pInitializationParametersData,InitializationParametersDataSizeInBytes) \ + ( (This)->lpVtbl -> InitializeMetaCommand(This,pMetaCommand,pInitializationParametersData,InitializationParametersDataSizeInBytes) ) + +#define ID3D12GraphicsCommandList4_ExecuteMetaCommand(This,pMetaCommand,pExecutionParametersData,ExecutionParametersDataSizeInBytes) \ + ( (This)->lpVtbl -> ExecuteMetaCommand(This,pMetaCommand,pExecutionParametersData,ExecutionParametersDataSizeInBytes) ) + +#define ID3D12GraphicsCommandList4_BuildRaytracingAccelerationStructure(This,pDesc,NumPostbuildInfoDescs,pPostbuildInfoDescs) \ + ( (This)->lpVtbl -> BuildRaytracingAccelerationStructure(This,pDesc,NumPostbuildInfoDescs,pPostbuildInfoDescs) ) + +#define ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo(This,pDesc,NumSourceAccelerationStructures,pSourceAccelerationStructureData) \ + ( (This)->lpVtbl -> EmitRaytracingAccelerationStructurePostbuildInfo(This,pDesc,NumSourceAccelerationStructures,pSourceAccelerationStructureData) ) + +#define ID3D12GraphicsCommandList4_CopyRaytracingAccelerationStructure(This,DestAccelerationStructureData,SourceAccelerationStructureData,Mode) \ + ( (This)->lpVtbl -> CopyRaytracingAccelerationStructure(This,DestAccelerationStructureData,SourceAccelerationStructureData,Mode) ) + +#define ID3D12GraphicsCommandList4_SetPipelineState1(This,pStateObject) \ + ( (This)->lpVtbl -> SetPipelineState1(This,pStateObject) ) + +#define ID3D12GraphicsCommandList4_DispatchRays(This,pDesc) \ + ( (This)->lpVtbl -> DispatchRays(This,pDesc) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList4_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Tools_INTERFACE_DEFINED__ +#define __ID3D12Tools_INTERFACE_DEFINED__ + +/* interface ID3D12Tools */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Tools; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7071e1f0-e84b-4b33-974f-12fa49de65c5") + ID3D12Tools : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE EnableShaderInstrumentation( + BOOL bEnable) = 0; + + virtual BOOL STDMETHODCALLTYPE ShaderInstrumentationEnabled( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12ToolsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Tools * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Tools * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Tools * This); + + void ( STDMETHODCALLTYPE *EnableShaderInstrumentation )( + ID3D12Tools * This, + BOOL bEnable); + + BOOL ( STDMETHODCALLTYPE *ShaderInstrumentationEnabled )( + ID3D12Tools * This); + + END_INTERFACE + } ID3D12ToolsVtbl; + + interface ID3D12Tools + { + CONST_VTBL struct ID3D12ToolsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Tools_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Tools_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Tools_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Tools_EnableShaderInstrumentation(This,bEnable) \ + ( (This)->lpVtbl -> EnableShaderInstrumentation(This,bEnable) ) + +#define ID3D12Tools_ShaderInstrumentationEnabled(This) \ + ( (This)->lpVtbl -> ShaderInstrumentationEnabled(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Tools_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0044 */ +/* [local] */ + +typedef struct D3D12_SUBRESOURCE_DATA + { + const void *pData; + LONG_PTR RowPitch; + LONG_PTR SlicePitch; + } D3D12_SUBRESOURCE_DATA; + +typedef struct D3D12_MEMCPY_DEST + { + void *pData; + SIZE_T RowPitch; + SIZE_T SlicePitch; + } D3D12_MEMCPY_DEST; + +#if !defined( D3D12_IGNORE_SDK_LAYERS ) +#include "d3d12sdklayers.h" +#endif + +/////////////////////////////////////////////////////////////////////////// +// D3D12CreateDevice +// ------------------ +// +// pAdapter +// If NULL, D3D12CreateDevice will choose the primary adapter. +// If non-NULL, D3D12CreateDevice will use the provided adapter. +// MinimumFeatureLevel +// The minimum feature level required for successful device creation. +// riid +// The interface IID of the device to be returned. Expected: ID3D12Device. +// ppDevice +// Pointer to returned interface. May be NULL. +// +// Return Values +// Any of those documented for +// CreateDXGIFactory1 +// IDXGIFactory::EnumAdapters +// D3D12CreateDevice +// +/////////////////////////////////////////////////////////////////////////// +typedef HRESULT (WINAPI* PFN_D3D12_CREATE_DEVICE)( _In_opt_ IUnknown*, + D3D_FEATURE_LEVEL, + _In_ REFIID, _COM_Outptr_opt_ void** ); + +HRESULT WINAPI D3D12CreateDevice( + _In_opt_ IUnknown* pAdapter, + D3D_FEATURE_LEVEL MinimumFeatureLevel, + _In_ REFIID riid, // Expected: ID3D12Device + _COM_Outptr_opt_ void** ppDevice ); + + +typedef HRESULT (WINAPI* PFN_D3D12_GET_DEBUG_INTERFACE)( _In_ REFIID, _COM_Outptr_opt_ void** ); + +HRESULT WINAPI D3D12GetDebugInterface( _In_ REFIID riid, _COM_Outptr_opt_ void** ppvDebug ); + +// -------------------------------------------------------------------------------------------------------------------------------- +// D3D12EnableExperimentalFeatures +// +// Pass in a list of feature GUIDs to be enabled together. +// +// If a particular feature requires some configuration information on enablement, it will have +// a configuration struct that can be passed alongside the GUID. +// +// Some features might use an interface IID as the GUID. For these, once the feature is enabled via +// D3D12EnableExperimentalFeatures, D3D12GetDebugInterface can then be called with the IID to retrieve the interface +// for manipulating the feature. This allows for control that might not cleanly be expressed by just +// the configuration struct that D3D12EnableExperimentalFeatures provides. +// +// If this method is called and a change to existing feature enablement is made, +// all current D3D12 devices are set to DEVICE_REMOVED state, since under the covers there is really only one +// singleton device for a process. Removing the devices when configuration changes prevents +// mismatched expectations of how a device is supposed to work after it has been created from the app's point of view. +// +// The call returns E_NOINTERFACE if an unrecognized feature is passed in or Windows Developer mode is not on. +// The call returns E_INVALIDARG if the configuration of a feature is incorrect, the set of features passed +// in are known to be incompatible with each other, or other errors. +// Returns S_OK otherwise. +// +// -------------------------------------------------------------------------------------------------------------------------------- +HRESULT WINAPI D3D12EnableExperimentalFeatures( + UINT NumFeatures, + __in_ecount(NumFeatures) const IID* pIIDs, + __in_ecount_opt(NumFeatures) void* pConfigurationStructs, + __in_ecount_opt(NumFeatures) UINT* pConfigurationStructSizes); + +// -------------------------------------------------------------------------------------------------------------------------------- +// Experimental Feature: D3D12ExperimentalShaderModels +// +// Use with D3D12EnableExperimentalFeatures to enable experimental shader model support, +// meaning shader models that haven't been finalized for use in retail. +// +// Enabling D3D12ExperimentalShaderModels needs no configuration struct, pass NULL in the pConfigurationStructs array. +// +// -------------------------------------------------------------------------------------------------------------------------------- +static const UUID D3D12ExperimentalShaderModels = { /* 76f5573e-f13a-40f5-b297-81ce9e18933f */ + 0x76f5573e, + 0xf13a, + 0x40f5, + { 0xb2, 0x97, 0x81, 0xce, 0x9e, 0x18, 0x93, 0x3f } +}; +// -------------------------------------------------------------------------------------------------------------------------------- +// Experimental Feature: D3D12TiledResourceTier4 +// +// Use with D3D12EnableExperimentalFeatures to enable tiled resource tier 4 support, +// meaning texture tile data-inheritance is allowed. +// +// Enabling D3D12TiledResourceTier4 needs no configuration struct, pass NULL in the pConfigurationStructs array. +// +// -------------------------------------------------------------------------------------------------------------------------------- +static const UUID D3D12TiledResourceTier4 = { /* c9c4725f-a81a-4f56-8c5b-c51039d694fb */ + 0xc9c4725f, + 0xa81a, + 0x4f56, + { 0x8c, 0x5b, 0xc5, 0x10, 0x39, 0xd6, 0x94, 0xfb } +}; +// -------------------------------------------------------------------------------------------------------------------------------- +// Experimental Feature: D3D12MetaCommand +// +// Use with D3D12EnableExperimentalFeatures to enable the D3D12 Meta Command. +// +// Enabling D3D12MetaCommand needs no configuration struct, pass NULL in the pConfigurationStructs array. +// +// -------------------------------------------------------------------------------------------------------------------------------- +static const UUID D3D12MetaCommand = { /* C734C97E-8077-48C8-9FDC-D9D1DD31DD77 */ + 0xc734c97e, + 0x8077, + 0x48c8, + { 0x9f, 0xdc, 0xd9, 0xd1, 0xdd, 0x31, 0xdd, 0x77 } +}; +// -------------------------------------------------------------------------------------------------------------------------------- +// Experimental Feature: D3D12ComputeOnlyDevices +// +// Use with D3D12EnableExperimentalFeatures to enable compute only devices (D3D_FEATURE_LEVEL_1_0_CORE). +// +// Enabling D3D12ComputeOnlyDevices needs no configuration struct, pass NULL in the pConfigurationStructs array. +// +// -------------------------------------------------------------------------------------------------------------------------------- +static const UUID D3D12ComputeOnlyDevices = { /* 50f7ab08-4b6d-4e14-89a5-5d16cd272594 */ + 0x50f7ab08, + 0x4b6d, + 0x4e14, + {0x89, 0xa5, 0x5d, 0x16, 0xcd, 0x27, 0x25, 0x94} +}; +typedef +enum D3D12_AXIS_SHADING_RATE + { + D3D12_AXIS_SHADING_RATE_1X = 0, + D3D12_AXIS_SHADING_RATE_2X = 0x1, + D3D12_AXIS_SHADING_RATE_4X = 0x2 + } D3D12_AXIS_SHADING_RATE; + +#define D3D12_SHADING_RATE_X_AXIS_SHIFT 2 +#define D3D12_SHADING_RATE_VALID_MASK 3 +#define D3D12_MAKE_COARSE_SHADING_RATE(x,y) ((x) << D3D12_SHADING_RATE_X_AXIS_SHIFT | (y)) +#define D3D12_GET_COARSE_SHADING_RATE_X_AXIS(x) (((x) >> D3D12_SHADING_RATE_X_AXIS_SHIFT) & D3D12_SHADING_RATE_VALID_MASK) +#define D3D12_GET_COARSE_SHADING_RATE_Y_AXIS(y) ((y) & D3D12_SHADING_RATE_VALID_MASK) +typedef +enum D3D12_SHADING_RATE + { + D3D12_SHADING_RATE_1X1 = 0, + D3D12_SHADING_RATE_1X2 = 0x1, + D3D12_SHADING_RATE_2X1 = 0x4, + D3D12_SHADING_RATE_2X2 = 0x5, + D3D12_SHADING_RATE_2X4 = 0x6, + D3D12_SHADING_RATE_4X2 = 0x9, + D3D12_SHADING_RATE_4X4 = 0xa + } D3D12_SHADING_RATE; + +typedef +enum D3D12_SHADING_RATE_COMBINER + { + D3D12_SHADING_RATE_COMBINER_PASSTHROUGH = 0, + D3D12_SHADING_RATE_COMBINER_OVERRIDE = 1, + D3D12_SHADING_RATE_COMBINER_MIN = 2, + D3D12_SHADING_RATE_COMBINER_MAX = 3, + D3D12_SHADING_RATE_COMBINER_SUM = 4 + } D3D12_SHADING_RATE_COMBINER; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0044_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0044_v0_0_s_ifspec; + +#ifndef __ID3D12GraphicsCommandList5_INTERFACE_DEFINED__ +#define __ID3D12GraphicsCommandList5_INTERFACE_DEFINED__ + +/* interface ID3D12GraphicsCommandList5 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12GraphicsCommandList5; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("55050859-4024-474c-87f5-6472eaee44ea") + ID3D12GraphicsCommandList5 : public ID3D12GraphicsCommandList4 + { + public: + virtual void STDMETHODCALLTYPE RSSetShadingRate( + _In_ D3D12_SHADING_RATE baseShadingRate, + _In_reads_opt_(D3D12_RS_SET_SHADING_RATE_COMBINER_COUNT) const D3D12_SHADING_RATE_COMBINER *combiners) = 0; + + virtual void STDMETHODCALLTYPE RSSetShadingRateImage( + _In_opt_ ID3D12Resource *shadingRateImage) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12GraphicsCommandList5Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12GraphicsCommandList5 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12GraphicsCommandList5 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12GraphicsCommandList5 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + ID3D12GraphicsCommandList5 * This, + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + ID3D12GraphicsCommandList5 * This, + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + ID3D12GraphicsCommandList5 * This, + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData); + + HRESULT ( STDMETHODCALLTYPE *SetName )( + ID3D12GraphicsCommandList5 * This, + _In_z_ LPCWSTR Name); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + ID3D12GraphicsCommandList5 * This, + REFIID riid, + _COM_Outptr_opt_ void **ppvDevice); + + D3D12_COMMAND_LIST_TYPE ( STDMETHODCALLTYPE *GetType )( + ID3D12GraphicsCommandList5 * This); + + HRESULT ( STDMETHODCALLTYPE *Close )( + ID3D12GraphicsCommandList5 * This); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12CommandAllocator *pAllocator, + _In_opt_ ID3D12PipelineState *pInitialState); + + void ( STDMETHODCALLTYPE *ClearState )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *DrawInstanced )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT VertexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *DrawIndexedInstanced )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT IndexCountPerInstance, + _In_ UINT InstanceCount, + _In_ UINT StartIndexLocation, + _In_ INT BaseVertexLocation, + _In_ UINT StartInstanceLocation); + + void ( STDMETHODCALLTYPE *Dispatch )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT ThreadGroupCountX, + _In_ UINT ThreadGroupCountY, + _In_ UINT ThreadGroupCountZ); + + void ( STDMETHODCALLTYPE *CopyBufferRegion )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT64 NumBytes); + + void ( STDMETHODCALLTYPE *CopyTextureRegion )( + ID3D12GraphicsCommandList5 * This, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pDst, + UINT DstX, + UINT DstY, + UINT DstZ, + _In_ const D3D12_TEXTURE_COPY_LOCATION *pSrc, + _In_opt_ const D3D12_BOX *pSrcBox); + + void ( STDMETHODCALLTYPE *CopyResource )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstResource, + _In_ ID3D12Resource *pSrcResource); + + void ( STDMETHODCALLTYPE *CopyTiles )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pTiledResource, + _In_ const D3D12_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + _In_ const D3D12_TILE_REGION_SIZE *pTileRegionSize, + _In_ ID3D12Resource *pBuffer, + UINT64 BufferStartOffsetInBytes, + D3D12_TILE_COPY_FLAGS Flags); + + void ( STDMETHODCALLTYPE *ResolveSubresource )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_ DXGI_FORMAT Format); + + void ( STDMETHODCALLTYPE *IASetPrimitiveTopology )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_PRIMITIVE_TOPOLOGY PrimitiveTopology); + + void ( STDMETHODCALLTYPE *RSSetViewports )( + ID3D12GraphicsCommandList5 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, + _In_reads_( NumViewports) const D3D12_VIEWPORT *pViewports); + + void ( STDMETHODCALLTYPE *RSSetScissorRects )( + ID3D12GraphicsCommandList5 * This, + _In_range_(0, D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, + _In_reads_( NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *OMSetBlendFactor )( + ID3D12GraphicsCommandList5 * This, + _In_reads_opt_(4) const FLOAT BlendFactor[ 4 ]); + + void ( STDMETHODCALLTYPE *OMSetStencilRef )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT StencilRef); + + void ( STDMETHODCALLTYPE *SetPipelineState )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12PipelineState *pPipelineState); + + void ( STDMETHODCALLTYPE *ResourceBarrier )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT NumBarriers, + _In_reads_(NumBarriers) const D3D12_RESOURCE_BARRIER *pBarriers); + + void ( STDMETHODCALLTYPE *ExecuteBundle )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12GraphicsCommandList *pCommandList); + + void ( STDMETHODCALLTYPE *SetDescriptorHeaps )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT NumDescriptorHeaps, + _In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps); + + void ( STDMETHODCALLTYPE *SetComputeRootSignature )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetGraphicsRootSignature )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12RootSignature *pRootSignature); + + void ( STDMETHODCALLTYPE *SetComputeRootDescriptorTable )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetGraphicsRootDescriptorTable )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstant )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstant )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ UINT SrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRoot32BitConstants )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetGraphicsRoot32BitConstants )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ UINT Num32BitValuesToSet, + _In_reads_(Num32BitValuesToSet*sizeof(UINT)) const void *pSrcData, + _In_ UINT DestOffsetIn32BitValues); + + void ( STDMETHODCALLTYPE *SetComputeRootConstantBufferView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootConstantBufferView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootShaderResourceView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootShaderResourceView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetComputeRootUnorderedAccessView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *SetGraphicsRootUnorderedAccessView )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT RootParameterIndex, + _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); + + void ( STDMETHODCALLTYPE *IASetIndexBuffer )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ const D3D12_INDEX_BUFFER_VIEW *pView); + + void ( STDMETHODCALLTYPE *IASetVertexBuffers )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_VERTEX_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *SOSetTargets )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT StartSlot, + _In_ UINT NumViews, + _In_reads_opt_(NumViews) const D3D12_STREAM_OUTPUT_BUFFER_VIEW *pViews); + + void ( STDMETHODCALLTYPE *OMSetRenderTargets )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT NumRenderTargetDescriptors, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors, + _In_ BOOL RTsSingleHandleToDescriptorRange, + _In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor); + + void ( STDMETHODCALLTYPE *ClearDepthStencilView )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView, + _In_ D3D12_CLEAR_FLAGS ClearFlags, + _In_ FLOAT Depth, + _In_ UINT8 Stencil, + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearRenderTargetView )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView, + _In_ const FLOAT ColorRGBA[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewUint )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const UINT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *ClearUnorderedAccessViewFloat )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_GPU_DESCRIPTOR_HANDLE ViewGPUHandleInCurrentHeap, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE ViewCPUHandle, + _In_ ID3D12Resource *pResource, + _In_ const FLOAT Values[ 4 ], + _In_ UINT NumRects, + _In_reads_(NumRects) const D3D12_RECT *pRects); + + void ( STDMETHODCALLTYPE *DiscardResource )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DISCARD_REGION *pRegion); + + void ( STDMETHODCALLTYPE *BeginQuery )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *EndQuery )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT Index); + + void ( STDMETHODCALLTYPE *ResolveQueryData )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12QueryHeap *pQueryHeap, + _In_ D3D12_QUERY_TYPE Type, + _In_ UINT StartIndex, + _In_ UINT NumQueries, + _In_ ID3D12Resource *pDestinationBuffer, + _In_ UINT64 AlignedDestinationBufferOffset); + + void ( STDMETHODCALLTYPE *SetPredication )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12Resource *pBuffer, + _In_ UINT64 AlignedBufferOffset, + _In_ D3D12_PREDICATION_OP Operation); + + void ( STDMETHODCALLTYPE *SetMarker )( + ID3D12GraphicsCommandList5 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *BeginEvent )( + ID3D12GraphicsCommandList5 * This, + UINT Metadata, + _In_reads_bytes_opt_(Size) const void *pData, + UINT Size); + + void ( STDMETHODCALLTYPE *EndEvent )( + ID3D12GraphicsCommandList5 * This); + + void ( STDMETHODCALLTYPE *ExecuteIndirect )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12CommandSignature *pCommandSignature, + _In_ UINT MaxCommandCount, + _In_ ID3D12Resource *pArgumentBuffer, + _In_ UINT64 ArgumentBufferOffset, + _In_opt_ ID3D12Resource *pCountBuffer, + _In_ UINT64 CountBufferOffset); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *AtomicCopyBufferUINT64 )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstBuffer, + UINT64 DstOffset, + _In_ ID3D12Resource *pSrcBuffer, + UINT64 SrcOffset, + UINT Dependencies, + _In_reads_(Dependencies) ID3D12Resource *const *ppDependentResources, + _In_reads_(Dependencies) const D3D12_SUBRESOURCE_RANGE_UINT64 *pDependentSubresourceRanges); + + void ( STDMETHODCALLTYPE *OMSetDepthBounds )( + ID3D12GraphicsCommandList5 * This, + _In_ FLOAT Min, + _In_ FLOAT Max); + + void ( STDMETHODCALLTYPE *SetSamplePositions )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT NumSamplesPerPixel, + _In_ UINT NumPixels, + _In_reads_(NumSamplesPerPixel*NumPixels) D3D12_SAMPLE_POSITION *pSamplePositions); + + void ( STDMETHODCALLTYPE *ResolveSubresourceRegion )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12Resource *pDstResource, + _In_ UINT DstSubresource, + _In_ UINT DstX, + _In_ UINT DstY, + _In_ ID3D12Resource *pSrcResource, + _In_ UINT SrcSubresource, + _In_opt_ D3D12_RECT *pSrcRect, + _In_ DXGI_FORMAT Format, + _In_ D3D12_RESOLVE_MODE ResolveMode); + + void ( STDMETHODCALLTYPE *SetViewInstanceMask )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT Mask); + + void ( STDMETHODCALLTYPE *WriteBufferImmediate )( + ID3D12GraphicsCommandList5 * This, + UINT Count, + _In_reads_(Count) const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *pParams, + _In_reads_opt_(Count) const D3D12_WRITEBUFFERIMMEDIATE_MODE *pModes); + + void ( STDMETHODCALLTYPE *SetProtectedResourceSession )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedResourceSession); + + void ( STDMETHODCALLTYPE *BeginRenderPass )( + ID3D12GraphicsCommandList5 * This, + _In_ UINT NumRenderTargets, + _In_reads_opt_(NumRenderTargets) const D3D12_RENDER_PASS_RENDER_TARGET_DESC *pRenderTargets, + _In_opt_ const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags); + + void ( STDMETHODCALLTYPE *EndRenderPass )( + ID3D12GraphicsCommandList5 * This); + + void ( STDMETHODCALLTYPE *InitializeMetaCommand )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(InitializationParametersDataSizeInBytes) const void *pInitializationParametersData, + _In_ SIZE_T InitializationParametersDataSizeInBytes); + + void ( STDMETHODCALLTYPE *ExecuteMetaCommand )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12MetaCommand *pMetaCommand, + _In_reads_bytes_opt_(ExecutionParametersDataSizeInBytes) const void *pExecutionParametersData, + _In_ SIZE_T ExecutionParametersDataSizeInBytes); + + void ( STDMETHODCALLTYPE *BuildRaytracingAccelerationStructure )( + ID3D12GraphicsCommandList5 * This, + _In_ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *pDesc, + _In_ UINT NumPostbuildInfoDescs, + _In_reads_opt_(NumPostbuildInfoDescs) const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pPostbuildInfoDescs); + + void ( STDMETHODCALLTYPE *EmitRaytracingAccelerationStructurePostbuildInfo )( + ID3D12GraphicsCommandList5 * This, + _In_ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *pDesc, + _In_ UINT NumSourceAccelerationStructures, + _In_reads_( NumSourceAccelerationStructures ) const D3D12_GPU_VIRTUAL_ADDRESS *pSourceAccelerationStructureData); + + void ( STDMETHODCALLTYPE *CopyRaytracingAccelerationStructure )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData, + _In_ D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData, + _In_ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE Mode); + + void ( STDMETHODCALLTYPE *SetPipelineState1 )( + ID3D12GraphicsCommandList5 * This, + _In_ ID3D12StateObject *pStateObject); + + void ( STDMETHODCALLTYPE *DispatchRays )( + ID3D12GraphicsCommandList5 * This, + _In_ const D3D12_DISPATCH_RAYS_DESC *pDesc); + + void ( STDMETHODCALLTYPE *RSSetShadingRate )( + ID3D12GraphicsCommandList5 * This, + _In_ D3D12_SHADING_RATE baseShadingRate, + _In_reads_opt_(D3D12_RS_SET_SHADING_RATE_COMBINER_COUNT) const D3D12_SHADING_RATE_COMBINER *combiners); + + void ( STDMETHODCALLTYPE *RSSetShadingRateImage )( + ID3D12GraphicsCommandList5 * This, + _In_opt_ ID3D12Resource *shadingRateImage); + + END_INTERFACE + } ID3D12GraphicsCommandList5Vtbl; + + interface ID3D12GraphicsCommandList5 + { + CONST_VTBL struct ID3D12GraphicsCommandList5Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12GraphicsCommandList5_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12GraphicsCommandList5_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12GraphicsCommandList5_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12GraphicsCommandList5_GetPrivateData(This,guid,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,guid,pDataSize,pData) ) + +#define ID3D12GraphicsCommandList5_SetPrivateData(This,guid,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,guid,DataSize,pData) ) + +#define ID3D12GraphicsCommandList5_SetPrivateDataInterface(This,guid,pData) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,guid,pData) ) + +#define ID3D12GraphicsCommandList5_SetName(This,Name) \ + ( (This)->lpVtbl -> SetName(This,Name) ) + + +#define ID3D12GraphicsCommandList5_GetDevice(This,riid,ppvDevice) \ + ( (This)->lpVtbl -> GetDevice(This,riid,ppvDevice) ) + + +#define ID3D12GraphicsCommandList5_GetType(This) \ + ( (This)->lpVtbl -> GetType(This) ) + + +#define ID3D12GraphicsCommandList5_Close(This) \ + ( (This)->lpVtbl -> Close(This) ) + +#define ID3D12GraphicsCommandList5_Reset(This,pAllocator,pInitialState) \ + ( (This)->lpVtbl -> Reset(This,pAllocator,pInitialState) ) + +#define ID3D12GraphicsCommandList5_ClearState(This,pPipelineState) \ + ( (This)->lpVtbl -> ClearState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList5_DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawInstanced(This,VertexCountPerInstance,InstanceCount,StartVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList5_DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) \ + ( (This)->lpVtbl -> DrawIndexedInstanced(This,IndexCountPerInstance,InstanceCount,StartIndexLocation,BaseVertexLocation,StartInstanceLocation) ) + +#define ID3D12GraphicsCommandList5_Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) \ + ( (This)->lpVtbl -> Dispatch(This,ThreadGroupCountX,ThreadGroupCountY,ThreadGroupCountZ) ) + +#define ID3D12GraphicsCommandList5_CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) \ + ( (This)->lpVtbl -> CopyBufferRegion(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,NumBytes) ) + +#define ID3D12GraphicsCommandList5_CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) \ + ( (This)->lpVtbl -> CopyTextureRegion(This,pDst,DstX,DstY,DstZ,pSrc,pSrcBox) ) + +#define ID3D12GraphicsCommandList5_CopyResource(This,pDstResource,pSrcResource) \ + ( (This)->lpVtbl -> CopyResource(This,pDstResource,pSrcResource) ) + +#define ID3D12GraphicsCommandList5_CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) \ + ( (This)->lpVtbl -> CopyTiles(This,pTiledResource,pTileRegionStartCoordinate,pTileRegionSize,pBuffer,BufferStartOffsetInBytes,Flags) ) + +#define ID3D12GraphicsCommandList5_ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) \ + ( (This)->lpVtbl -> ResolveSubresource(This,pDstResource,DstSubresource,pSrcResource,SrcSubresource,Format) ) + +#define ID3D12GraphicsCommandList5_IASetPrimitiveTopology(This,PrimitiveTopology) \ + ( (This)->lpVtbl -> IASetPrimitiveTopology(This,PrimitiveTopology) ) + +#define ID3D12GraphicsCommandList5_RSSetViewports(This,NumViewports,pViewports) \ + ( (This)->lpVtbl -> RSSetViewports(This,NumViewports,pViewports) ) + +#define ID3D12GraphicsCommandList5_RSSetScissorRects(This,NumRects,pRects) \ + ( (This)->lpVtbl -> RSSetScissorRects(This,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList5_OMSetBlendFactor(This,BlendFactor) \ + ( (This)->lpVtbl -> OMSetBlendFactor(This,BlendFactor) ) + +#define ID3D12GraphicsCommandList5_OMSetStencilRef(This,StencilRef) \ + ( (This)->lpVtbl -> OMSetStencilRef(This,StencilRef) ) + +#define ID3D12GraphicsCommandList5_SetPipelineState(This,pPipelineState) \ + ( (This)->lpVtbl -> SetPipelineState(This,pPipelineState) ) + +#define ID3D12GraphicsCommandList5_ResourceBarrier(This,NumBarriers,pBarriers) \ + ( (This)->lpVtbl -> ResourceBarrier(This,NumBarriers,pBarriers) ) + +#define ID3D12GraphicsCommandList5_ExecuteBundle(This,pCommandList) \ + ( (This)->lpVtbl -> ExecuteBundle(This,pCommandList) ) + +#define ID3D12GraphicsCommandList5_SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) \ + ( (This)->lpVtbl -> SetDescriptorHeaps(This,NumDescriptorHeaps,ppDescriptorHeaps) ) + +#define ID3D12GraphicsCommandList5_SetComputeRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetComputeRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRootSignature(This,pRootSignature) \ + ( (This)->lpVtbl -> SetGraphicsRootSignature(This,pRootSignature) ) + +#define ID3D12GraphicsCommandList5_SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetComputeRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) \ + ( (This)->lpVtbl -> SetGraphicsRootDescriptorTable(This,RootParameterIndex,BaseDescriptor) ) + +#define ID3D12GraphicsCommandList5_SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstant(This,RootParameterIndex,SrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList5_SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetComputeRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) \ + ( (This)->lpVtbl -> SetGraphicsRoot32BitConstants(This,RootParameterIndex,Num32BitValuesToSet,pSrcData,DestOffsetIn32BitValues) ) + +#define ID3D12GraphicsCommandList5_SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootConstantBufferView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootShaderResourceView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetComputeRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) \ + ( (This)->lpVtbl -> SetGraphicsRootUnorderedAccessView(This,RootParameterIndex,BufferLocation) ) + +#define ID3D12GraphicsCommandList5_IASetIndexBuffer(This,pView) \ + ( (This)->lpVtbl -> IASetIndexBuffer(This,pView) ) + +#define ID3D12GraphicsCommandList5_IASetVertexBuffers(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> IASetVertexBuffers(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList5_SOSetTargets(This,StartSlot,NumViews,pViews) \ + ( (This)->lpVtbl -> SOSetTargets(This,StartSlot,NumViews,pViews) ) + +#define ID3D12GraphicsCommandList5_OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) \ + ( (This)->lpVtbl -> OMSetRenderTargets(This,NumRenderTargetDescriptors,pRenderTargetDescriptors,RTsSingleHandleToDescriptorRange,pDepthStencilDescriptor) ) + +#define ID3D12GraphicsCommandList5_ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearDepthStencilView(This,DepthStencilView,ClearFlags,Depth,Stencil,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList5_ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearRenderTargetView(This,RenderTargetView,ColorRGBA,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList5_ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewUint(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList5_ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) \ + ( (This)->lpVtbl -> ClearUnorderedAccessViewFloat(This,ViewGPUHandleInCurrentHeap,ViewCPUHandle,pResource,Values,NumRects,pRects) ) + +#define ID3D12GraphicsCommandList5_DiscardResource(This,pResource,pRegion) \ + ( (This)->lpVtbl -> DiscardResource(This,pResource,pRegion) ) + +#define ID3D12GraphicsCommandList5_BeginQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> BeginQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList5_EndQuery(This,pQueryHeap,Type,Index) \ + ( (This)->lpVtbl -> EndQuery(This,pQueryHeap,Type,Index) ) + +#define ID3D12GraphicsCommandList5_ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) \ + ( (This)->lpVtbl -> ResolveQueryData(This,pQueryHeap,Type,StartIndex,NumQueries,pDestinationBuffer,AlignedDestinationBufferOffset) ) + +#define ID3D12GraphicsCommandList5_SetPredication(This,pBuffer,AlignedBufferOffset,Operation) \ + ( (This)->lpVtbl -> SetPredication(This,pBuffer,AlignedBufferOffset,Operation) ) + +#define ID3D12GraphicsCommandList5_SetMarker(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> SetMarker(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList5_BeginEvent(This,Metadata,pData,Size) \ + ( (This)->lpVtbl -> BeginEvent(This,Metadata,pData,Size) ) + +#define ID3D12GraphicsCommandList5_EndEvent(This) \ + ( (This)->lpVtbl -> EndEvent(This) ) + +#define ID3D12GraphicsCommandList5_ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) \ + ( (This)->lpVtbl -> ExecuteIndirect(This,pCommandSignature,MaxCommandCount,pArgumentBuffer,ArgumentBufferOffset,pCountBuffer,CountBufferOffset) ) + + +#define ID3D12GraphicsCommandList5_AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList5_AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) \ + ( (This)->lpVtbl -> AtomicCopyBufferUINT64(This,pDstBuffer,DstOffset,pSrcBuffer,SrcOffset,Dependencies,ppDependentResources,pDependentSubresourceRanges) ) + +#define ID3D12GraphicsCommandList5_OMSetDepthBounds(This,Min,Max) \ + ( (This)->lpVtbl -> OMSetDepthBounds(This,Min,Max) ) + +#define ID3D12GraphicsCommandList5_SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) \ + ( (This)->lpVtbl -> SetSamplePositions(This,NumSamplesPerPixel,NumPixels,pSamplePositions) ) + +#define ID3D12GraphicsCommandList5_ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) \ + ( (This)->lpVtbl -> ResolveSubresourceRegion(This,pDstResource,DstSubresource,DstX,DstY,pSrcResource,SrcSubresource,pSrcRect,Format,ResolveMode) ) + +#define ID3D12GraphicsCommandList5_SetViewInstanceMask(This,Mask) \ + ( (This)->lpVtbl -> SetViewInstanceMask(This,Mask) ) + + +#define ID3D12GraphicsCommandList5_WriteBufferImmediate(This,Count,pParams,pModes) \ + ( (This)->lpVtbl -> WriteBufferImmediate(This,Count,pParams,pModes) ) + + +#define ID3D12GraphicsCommandList5_SetProtectedResourceSession(This,pProtectedResourceSession) \ + ( (This)->lpVtbl -> SetProtectedResourceSession(This,pProtectedResourceSession) ) + + +#define ID3D12GraphicsCommandList5_BeginRenderPass(This,NumRenderTargets,pRenderTargets,pDepthStencil,Flags) \ + ( (This)->lpVtbl -> BeginRenderPass(This,NumRenderTargets,pRenderTargets,pDepthStencil,Flags) ) + +#define ID3D12GraphicsCommandList5_EndRenderPass(This) \ + ( (This)->lpVtbl -> EndRenderPass(This) ) + +#define ID3D12GraphicsCommandList5_InitializeMetaCommand(This,pMetaCommand,pInitializationParametersData,InitializationParametersDataSizeInBytes) \ + ( (This)->lpVtbl -> InitializeMetaCommand(This,pMetaCommand,pInitializationParametersData,InitializationParametersDataSizeInBytes) ) + +#define ID3D12GraphicsCommandList5_ExecuteMetaCommand(This,pMetaCommand,pExecutionParametersData,ExecutionParametersDataSizeInBytes) \ + ( (This)->lpVtbl -> ExecuteMetaCommand(This,pMetaCommand,pExecutionParametersData,ExecutionParametersDataSizeInBytes) ) + +#define ID3D12GraphicsCommandList5_BuildRaytracingAccelerationStructure(This,pDesc,NumPostbuildInfoDescs,pPostbuildInfoDescs) \ + ( (This)->lpVtbl -> BuildRaytracingAccelerationStructure(This,pDesc,NumPostbuildInfoDescs,pPostbuildInfoDescs) ) + +#define ID3D12GraphicsCommandList5_EmitRaytracingAccelerationStructurePostbuildInfo(This,pDesc,NumSourceAccelerationStructures,pSourceAccelerationStructureData) \ + ( (This)->lpVtbl -> EmitRaytracingAccelerationStructurePostbuildInfo(This,pDesc,NumSourceAccelerationStructures,pSourceAccelerationStructureData) ) + +#define ID3D12GraphicsCommandList5_CopyRaytracingAccelerationStructure(This,DestAccelerationStructureData,SourceAccelerationStructureData,Mode) \ + ( (This)->lpVtbl -> CopyRaytracingAccelerationStructure(This,DestAccelerationStructureData,SourceAccelerationStructureData,Mode) ) + +#define ID3D12GraphicsCommandList5_SetPipelineState1(This,pStateObject) \ + ( (This)->lpVtbl -> SetPipelineState1(This,pStateObject) ) + +#define ID3D12GraphicsCommandList5_DispatchRays(This,pDesc) \ + ( (This)->lpVtbl -> DispatchRays(This,pDesc) ) + + +#define ID3D12GraphicsCommandList5_RSSetShadingRate(This,baseShadingRate,combiners) \ + ( (This)->lpVtbl -> RSSetShadingRate(This,baseShadingRate,combiners) ) + +#define ID3D12GraphicsCommandList5_RSSetShadingRateImage(This,shadingRateImage) \ + ( (This)->lpVtbl -> RSSetShadingRateImage(This,shadingRateImage) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12GraphicsCommandList5_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12_0000_0045 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */ +#pragma endregion +DEFINE_GUID(IID_ID3D12Object,0xc4fec28f,0x7966,0x4e95,0x9f,0x94,0xf4,0x31,0xcb,0x56,0xc3,0xb8); +DEFINE_GUID(IID_ID3D12DeviceChild,0x905db94b,0xa00c,0x4140,0x9d,0xf5,0x2b,0x64,0xca,0x9e,0xa3,0x57); +DEFINE_GUID(IID_ID3D12RootSignature,0xc54a6b66,0x72df,0x4ee8,0x8b,0xe5,0xa9,0x46,0xa1,0x42,0x92,0x14); +DEFINE_GUID(IID_ID3D12RootSignatureDeserializer,0x34AB647B,0x3CC8,0x46AC,0x84,0x1B,0xC0,0x96,0x56,0x45,0xC0,0x46); +DEFINE_GUID(IID_ID3D12VersionedRootSignatureDeserializer,0x7F91CE67,0x090C,0x4BB7,0xB7,0x8E,0xED,0x8F,0xF2,0xE3,0x1D,0xA0); +DEFINE_GUID(IID_ID3D12Pageable,0x63ee58fb,0x1268,0x4835,0x86,0xda,0xf0,0x08,0xce,0x62,0xf0,0xd6); +DEFINE_GUID(IID_ID3D12Heap,0x6b3b2502,0x6e51,0x45b3,0x90,0xee,0x98,0x84,0x26,0x5e,0x8d,0xf3); +DEFINE_GUID(IID_ID3D12Resource,0x696442be,0xa72e,0x4059,0xbc,0x79,0x5b,0x5c,0x98,0x04,0x0f,0xad); +DEFINE_GUID(IID_ID3D12CommandAllocator,0x6102dee4,0xaf59,0x4b09,0xb9,0x99,0xb4,0x4d,0x73,0xf0,0x9b,0x24); +DEFINE_GUID(IID_ID3D12Fence,0x0a753dcf,0xc4d8,0x4b91,0xad,0xf6,0xbe,0x5a,0x60,0xd9,0x5a,0x76); +DEFINE_GUID(IID_ID3D12Fence1,0x433685fe,0xe22b,0x4ca0,0xa8,0xdb,0xb5,0xb4,0xf4,0xdd,0x0e,0x4a); +DEFINE_GUID(IID_ID3D12PipelineState,0x765a30f3,0xf624,0x4c6f,0xa8,0x28,0xac,0xe9,0x48,0x62,0x24,0x45); +DEFINE_GUID(IID_ID3D12DescriptorHeap,0x8efb471d,0x616c,0x4f49,0x90,0xf7,0x12,0x7b,0xb7,0x63,0xfa,0x51); +DEFINE_GUID(IID_ID3D12QueryHeap,0x0d9658ae,0xed45,0x469e,0xa6,0x1d,0x97,0x0e,0xc5,0x83,0xca,0xb4); +DEFINE_GUID(IID_ID3D12CommandSignature,0xc36a797c,0xec80,0x4f0a,0x89,0x85,0xa7,0xb2,0x47,0x50,0x82,0xd1); +DEFINE_GUID(IID_ID3D12CommandList,0x7116d91c,0xe7e4,0x47ce,0xb8,0xc6,0xec,0x81,0x68,0xf4,0x37,0xe5); +DEFINE_GUID(IID_ID3D12GraphicsCommandList,0x5b160d0f,0xac1b,0x4185,0x8b,0xa8,0xb3,0xae,0x42,0xa5,0xa4,0x55); +DEFINE_GUID(IID_ID3D12GraphicsCommandList1,0x553103fb,0x1fe7,0x4557,0xbb,0x38,0x94,0x6d,0x7d,0x0e,0x7c,0xa7); +DEFINE_GUID(IID_ID3D12GraphicsCommandList2,0x38C3E585,0xFF17,0x412C,0x91,0x50,0x4F,0xC6,0xF9,0xD7,0x2A,0x28); +DEFINE_GUID(IID_ID3D12CommandQueue,0x0ec870a6,0x5d7e,0x4c22,0x8c,0xfc,0x5b,0xaa,0xe0,0x76,0x16,0xed); +DEFINE_GUID(IID_ID3D12Device,0x189819f1,0x1db6,0x4b57,0xbe,0x54,0x18,0x21,0x33,0x9b,0x85,0xf7); +DEFINE_GUID(IID_ID3D12PipelineLibrary,0xc64226a8,0x9201,0x46af,0xb4,0xcc,0x53,0xfb,0x9f,0xf7,0x41,0x4f); +DEFINE_GUID(IID_ID3D12PipelineLibrary1,0x80eabf42,0x2568,0x4e5e,0xbd,0x82,0xc3,0x7f,0x86,0x96,0x1d,0xc3); +DEFINE_GUID(IID_ID3D12Device1,0x77acce80,0x638e,0x4e65,0x88,0x95,0xc1,0xf2,0x33,0x86,0x86,0x3e); +DEFINE_GUID(IID_ID3D12Device2,0x30baa41e,0xb15b,0x475c,0xa0,0xbb,0x1a,0xf5,0xc5,0xb6,0x43,0x28); +DEFINE_GUID(IID_ID3D12Device3,0x81dadc15,0x2bad,0x4392,0x93,0xc5,0x10,0x13,0x45,0xc4,0xaa,0x98); +DEFINE_GUID(IID_ID3D12ProtectedSession,0xA1533D18,0x0AC1,0x4084,0x85,0xB9,0x89,0xA9,0x61,0x16,0x80,0x6B); +DEFINE_GUID(IID_ID3D12ProtectedResourceSession,0x6CD696F4,0xF289,0x40CC,0x80,0x91,0x5A,0x6C,0x0A,0x09,0x9C,0x3D); +DEFINE_GUID(IID_ID3D12Device4,0xe865df17,0xa9ee,0x46f9,0xa4,0x63,0x30,0x98,0x31,0x5a,0xa2,0xe5); +DEFINE_GUID(IID_ID3D12LifetimeOwner,0xe667af9f,0xcd56,0x4f46,0x83,0xce,0x03,0x2e,0x59,0x5d,0x70,0xa8); +DEFINE_GUID(IID_ID3D12SwapChainAssistant,0xf1df64b6,0x57fd,0x49cd,0x88,0x07,0xc0,0xeb,0x88,0xb4,0x5c,0x8f); +DEFINE_GUID(IID_ID3D12LifetimeTracker,0x3fd03d36,0x4eb1,0x424a,0xa5,0x82,0x49,0x4e,0xcb,0x8b,0xa8,0x13); +DEFINE_GUID(IID_ID3D12StateObject,0x47016943,0xfca8,0x4594,0x93,0xea,0xaf,0x25,0x8b,0x55,0x34,0x6d); +DEFINE_GUID(IID_ID3D12StateObjectProperties,0xde5fa827,0x9bf9,0x4f26,0x89,0xff,0xd7,0xf5,0x6f,0xde,0x38,0x60); +DEFINE_GUID(IID_ID3D12Device5,0x8b4f173b,0x2fea,0x4b80,0x8f,0x58,0x43,0x07,0x19,0x1a,0xb9,0x5d); +DEFINE_GUID(IID_ID3D12DeviceRemovedExtendedDataSettings,0x82BC481C,0x6B9B,0x4030,0xAE,0xDB,0x7E,0xE3,0xD1,0xDF,0x1E,0x63); +DEFINE_GUID(IID_ID3D12DeviceRemovedExtendedData,0x98931D33,0x5AE8,0x4791,0xAA,0x3C,0x1A,0x73,0xA2,0x93,0x4E,0x71); +DEFINE_GUID(IID_ID3D12Device6,0xc70b221b,0x40e4,0x4a17,0x89,0xaf,0x02,0x5a,0x07,0x27,0xa6,0xdc); +DEFINE_GUID(IID_ID3D12Resource1,0x9D5E227A,0x4430,0x4161,0x88,0xB3,0x3E,0xCA,0x6B,0xB1,0x6E,0x19); +DEFINE_GUID(IID_ID3D12Heap1,0x572F7389,0x2168,0x49E3,0x96,0x93,0xD6,0xDF,0x58,0x71,0xBF,0x6D); +DEFINE_GUID(IID_ID3D12GraphicsCommandList3,0x6FDA83A7,0xB84C,0x4E38,0x9A,0xC8,0xC7,0xBD,0x22,0x01,0x6B,0x3D); +DEFINE_GUID(IID_ID3D12MetaCommand,0xDBB84C27,0x36CE,0x4FC9,0xB8,0x01,0xF0,0x48,0xC4,0x6A,0xC5,0x70); +DEFINE_GUID(IID_ID3D12GraphicsCommandList4,0x8754318e,0xd3a9,0x4541,0x98,0xcf,0x64,0x5b,0x50,0xdc,0x48,0x74); +DEFINE_GUID(IID_ID3D12Tools,0x7071e1f0,0xe84b,0x4b33,0x97,0x4f,0x12,0xfa,0x49,0xde,0x65,0xc5); +DEFINE_GUID(IID_ID3D12GraphicsCommandList5,0x55050859,0x4024,0x474c,0x87,0xf5,0x64,0x72,0xea,0xee,0x44,0xea); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0045_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12_0000_0045_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12sdklayers.h b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12sdklayers.h new file mode 100644 index 000000000..cb4f9cd03 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3d12sdklayers.h @@ -0,0 +1,3230 @@ +/*------------------------------------------------------------------------------------- + * + * Copyright (c) Microsoft Corporation + * + *-------------------------------------------------------------------------------------*/ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0622 */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3d12sdklayers_h__ +#define __d3d12sdklayers_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D12Debug_FWD_DEFINED__ +#define __ID3D12Debug_FWD_DEFINED__ +typedef interface ID3D12Debug ID3D12Debug; + +#endif /* __ID3D12Debug_FWD_DEFINED__ */ + + +#ifndef __ID3D12Debug1_FWD_DEFINED__ +#define __ID3D12Debug1_FWD_DEFINED__ +typedef interface ID3D12Debug1 ID3D12Debug1; + +#endif /* __ID3D12Debug1_FWD_DEFINED__ */ + + +#ifndef __ID3D12Debug2_FWD_DEFINED__ +#define __ID3D12Debug2_FWD_DEFINED__ +typedef interface ID3D12Debug2 ID3D12Debug2; + +#endif /* __ID3D12Debug2_FWD_DEFINED__ */ + + +#ifndef __ID3D12Debug3_FWD_DEFINED__ +#define __ID3D12Debug3_FWD_DEFINED__ +typedef interface ID3D12Debug3 ID3D12Debug3; + +#endif /* __ID3D12Debug3_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugDevice1_FWD_DEFINED__ +#define __ID3D12DebugDevice1_FWD_DEFINED__ +typedef interface ID3D12DebugDevice1 ID3D12DebugDevice1; + +#endif /* __ID3D12DebugDevice1_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugDevice_FWD_DEFINED__ +#define __ID3D12DebugDevice_FWD_DEFINED__ +typedef interface ID3D12DebugDevice ID3D12DebugDevice; + +#endif /* __ID3D12DebugDevice_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugDevice2_FWD_DEFINED__ +#define __ID3D12DebugDevice2_FWD_DEFINED__ +typedef interface ID3D12DebugDevice2 ID3D12DebugDevice2; + +#endif /* __ID3D12DebugDevice2_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandQueue_FWD_DEFINED__ +#define __ID3D12DebugCommandQueue_FWD_DEFINED__ +typedef interface ID3D12DebugCommandQueue ID3D12DebugCommandQueue; + +#endif /* __ID3D12DebugCommandQueue_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandList1_FWD_DEFINED__ +#define __ID3D12DebugCommandList1_FWD_DEFINED__ +typedef interface ID3D12DebugCommandList1 ID3D12DebugCommandList1; + +#endif /* __ID3D12DebugCommandList1_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandList_FWD_DEFINED__ +#define __ID3D12DebugCommandList_FWD_DEFINED__ +typedef interface ID3D12DebugCommandList ID3D12DebugCommandList; + +#endif /* __ID3D12DebugCommandList_FWD_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandList2_FWD_DEFINED__ +#define __ID3D12DebugCommandList2_FWD_DEFINED__ +typedef interface ID3D12DebugCommandList2 ID3D12DebugCommandList2; + +#endif /* __ID3D12DebugCommandList2_FWD_DEFINED__ */ + + +#ifndef __ID3D12SharingContract_FWD_DEFINED__ +#define __ID3D12SharingContract_FWD_DEFINED__ +typedef interface ID3D12SharingContract ID3D12SharingContract; + +#endif /* __ID3D12SharingContract_FWD_DEFINED__ */ + + +#ifndef __ID3D12InfoQueue_FWD_DEFINED__ +#define __ID3D12InfoQueue_FWD_DEFINED__ +typedef interface ID3D12InfoQueue ID3D12InfoQueue; + +#endif /* __ID3D12InfoQueue_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" +#include "d3d12.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0000 */ +/* [local] */ + +#include +#pragma region App Family +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D12Debug_INTERFACE_DEFINED__ +#define __ID3D12Debug_INTERFACE_DEFINED__ + +/* interface ID3D12Debug */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Debug; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("344488b7-6846-474b-b989-f027448245e0") + ID3D12Debug : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE EnableDebugLayer( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Debug * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Debug * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Debug * This); + + void ( STDMETHODCALLTYPE *EnableDebugLayer )( + ID3D12Debug * This); + + END_INTERFACE + } ID3D12DebugVtbl; + + interface ID3D12Debug + { + CONST_VTBL struct ID3D12DebugVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Debug_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Debug_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Debug_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Debug_EnableDebugLayer(This) \ + ( (This)->lpVtbl -> EnableDebugLayer(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Debug_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0001 */ +/* [local] */ + +typedef +enum D3D12_GPU_BASED_VALIDATION_FLAGS + { + D3D12_GPU_BASED_VALIDATION_FLAGS_NONE = 0, + D3D12_GPU_BASED_VALIDATION_FLAGS_DISABLE_STATE_TRACKING = 0x1 + } D3D12_GPU_BASED_VALIDATION_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS(D3D12_GPU_BASED_VALIDATION_FLAGS) + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3D12Debug1_INTERFACE_DEFINED__ +#define __ID3D12Debug1_INTERFACE_DEFINED__ + +/* interface ID3D12Debug1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Debug1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("affaa4ca-63fe-4d8e-b8ad-159000af4304") + ID3D12Debug1 : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE EnableDebugLayer( void) = 0; + + virtual void STDMETHODCALLTYPE SetEnableGPUBasedValidation( + BOOL Enable) = 0; + + virtual void STDMETHODCALLTYPE SetEnableSynchronizedCommandQueueValidation( + BOOL Enable) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Debug1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Debug1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Debug1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Debug1 * This); + + void ( STDMETHODCALLTYPE *EnableDebugLayer )( + ID3D12Debug1 * This); + + void ( STDMETHODCALLTYPE *SetEnableGPUBasedValidation )( + ID3D12Debug1 * This, + BOOL Enable); + + void ( STDMETHODCALLTYPE *SetEnableSynchronizedCommandQueueValidation )( + ID3D12Debug1 * This, + BOOL Enable); + + END_INTERFACE + } ID3D12Debug1Vtbl; + + interface ID3D12Debug1 + { + CONST_VTBL struct ID3D12Debug1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Debug1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Debug1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Debug1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Debug1_EnableDebugLayer(This) \ + ( (This)->lpVtbl -> EnableDebugLayer(This) ) + +#define ID3D12Debug1_SetEnableGPUBasedValidation(This,Enable) \ + ( (This)->lpVtbl -> SetEnableGPUBasedValidation(This,Enable) ) + +#define ID3D12Debug1_SetEnableSynchronizedCommandQueueValidation(This,Enable) \ + ( (This)->lpVtbl -> SetEnableSynchronizedCommandQueueValidation(This,Enable) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Debug1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Debug2_INTERFACE_DEFINED__ +#define __ID3D12Debug2_INTERFACE_DEFINED__ + +/* interface ID3D12Debug2 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Debug2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("93a665c4-a3b2-4e5d-b692-a26ae14e3374") + ID3D12Debug2 : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE SetGPUBasedValidationFlags( + D3D12_GPU_BASED_VALIDATION_FLAGS Flags) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Debug2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Debug2 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Debug2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Debug2 * This); + + void ( STDMETHODCALLTYPE *SetGPUBasedValidationFlags )( + ID3D12Debug2 * This, + D3D12_GPU_BASED_VALIDATION_FLAGS Flags); + + END_INTERFACE + } ID3D12Debug2Vtbl; + + interface ID3D12Debug2 + { + CONST_VTBL struct ID3D12Debug2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Debug2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Debug2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Debug2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Debug2_SetGPUBasedValidationFlags(This,Flags) \ + ( (This)->lpVtbl -> SetGPUBasedValidationFlags(This,Flags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Debug2_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12Debug3_INTERFACE_DEFINED__ +#define __ID3D12Debug3_INTERFACE_DEFINED__ + +/* interface ID3D12Debug3 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12Debug3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5cf4e58f-f671-4ff1-a542-3686e3d153d1") + ID3D12Debug3 : public ID3D12Debug + { + public: + virtual void STDMETHODCALLTYPE SetEnableGPUBasedValidation( + BOOL Enable) = 0; + + virtual void STDMETHODCALLTYPE SetEnableSynchronizedCommandQueueValidation( + BOOL Enable) = 0; + + virtual void STDMETHODCALLTYPE SetGPUBasedValidationFlags( + D3D12_GPU_BASED_VALIDATION_FLAGS Flags) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12Debug3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12Debug3 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12Debug3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12Debug3 * This); + + void ( STDMETHODCALLTYPE *EnableDebugLayer )( + ID3D12Debug3 * This); + + void ( STDMETHODCALLTYPE *SetEnableGPUBasedValidation )( + ID3D12Debug3 * This, + BOOL Enable); + + void ( STDMETHODCALLTYPE *SetEnableSynchronizedCommandQueueValidation )( + ID3D12Debug3 * This, + BOOL Enable); + + void ( STDMETHODCALLTYPE *SetGPUBasedValidationFlags )( + ID3D12Debug3 * This, + D3D12_GPU_BASED_VALIDATION_FLAGS Flags); + + END_INTERFACE + } ID3D12Debug3Vtbl; + + interface ID3D12Debug3 + { + CONST_VTBL struct ID3D12Debug3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12Debug3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12Debug3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12Debug3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12Debug3_EnableDebugLayer(This) \ + ( (This)->lpVtbl -> EnableDebugLayer(This) ) + + +#define ID3D12Debug3_SetEnableGPUBasedValidation(This,Enable) \ + ( (This)->lpVtbl -> SetEnableGPUBasedValidation(This,Enable) ) + +#define ID3D12Debug3_SetEnableSynchronizedCommandQueueValidation(This,Enable) \ + ( (This)->lpVtbl -> SetEnableSynchronizedCommandQueueValidation(This,Enable) ) + +#define ID3D12Debug3_SetGPUBasedValidationFlags(This,Flags) \ + ( (This)->lpVtbl -> SetGPUBasedValidationFlags(This,Flags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12Debug3_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0004 */ +/* [local] */ + +typedef +enum D3D12_RLDO_FLAGS + { + D3D12_RLDO_NONE = 0, + D3D12_RLDO_SUMMARY = 0x1, + D3D12_RLDO_DETAIL = 0x2, + D3D12_RLDO_IGNORE_INTERNAL = 0x4 + } D3D12_RLDO_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS(D3D12_RLDO_FLAGS) +typedef +enum D3D12_DEBUG_DEVICE_PARAMETER_TYPE + { + D3D12_DEBUG_DEVICE_PARAMETER_FEATURE_FLAGS = 0, + D3D12_DEBUG_DEVICE_PARAMETER_GPU_BASED_VALIDATION_SETTINGS = ( D3D12_DEBUG_DEVICE_PARAMETER_FEATURE_FLAGS + 1 ) , + D3D12_DEBUG_DEVICE_PARAMETER_GPU_SLOWDOWN_PERFORMANCE_FACTOR = ( D3D12_DEBUG_DEVICE_PARAMETER_GPU_BASED_VALIDATION_SETTINGS + 1 ) + } D3D12_DEBUG_DEVICE_PARAMETER_TYPE; + +typedef +enum D3D12_DEBUG_FEATURE + { + D3D12_DEBUG_FEATURE_NONE = 0, + D3D12_DEBUG_FEATURE_ALLOW_BEHAVIOR_CHANGING_DEBUG_AIDS = 0x1, + D3D12_DEBUG_FEATURE_CONSERVATIVE_RESOURCE_STATE_TRACKING = 0x2, + D3D12_DEBUG_FEATURE_DISABLE_VIRTUALIZED_BUNDLES_VALIDATION = 0x4, + D3D12_DEBUG_FEATURE_EMULATE_WINDOWS7 = 0x8 + } D3D12_DEBUG_FEATURE; + +DEFINE_ENUM_FLAG_OPERATORS(D3D12_DEBUG_FEATURE) +typedef +enum D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE + { + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_NONE = 0, + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_STATE_TRACKING_ONLY = ( D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_NONE + 1 ) , + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_UNGUARDED_VALIDATION = ( D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_STATE_TRACKING_ONLY + 1 ) , + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_GUARDED_VALIDATION = ( D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_UNGUARDED_VALIDATION + 1 ) , + NUM_D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODES = ( D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_GUARDED_VALIDATION + 1 ) + } D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE; + +typedef +enum D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS + { + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_NONE = 0, + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_TRACKING_ONLY_SHADERS = 0x1, + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_UNGUARDED_VALIDATION_SHADERS = 0x2, + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_GUARDED_VALIDATION_SHADERS = 0x4, + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS_VALID_MASK = 0x7 + } D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS; + +DEFINE_ENUM_FLAG_OPERATORS(D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS) +typedef struct D3D12_DEBUG_DEVICE_GPU_BASED_VALIDATION_SETTINGS + { + UINT MaxMessagesPerCommandList; + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE DefaultShaderPatchMode; + D3D12_GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS PipelineStateCreateFlags; + } D3D12_DEBUG_DEVICE_GPU_BASED_VALIDATION_SETTINGS; + +typedef struct D3D12_DEBUG_DEVICE_GPU_SLOWDOWN_PERFORMANCE_FACTOR + { + FLOAT SlowdownFactor; + } D3D12_DEBUG_DEVICE_GPU_SLOWDOWN_PERFORMANCE_FACTOR; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0004_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0004_v0_0_s_ifspec; + +#ifndef __ID3D12DebugDevice1_INTERFACE_DEFINED__ +#define __ID3D12DebugDevice1_INTERFACE_DEFINED__ + +/* interface ID3D12DebugDevice1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugDevice1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a9b71770-d099-4a65-a698-3dee10020f88") + ID3D12DebugDevice1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter( + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter( + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects( + D3D12_RLDO_FLAGS Flags) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugDevice1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugDevice1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugDevice1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugDevice1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetDebugParameter )( + ID3D12DebugDevice1 * This, + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize); + + HRESULT ( STDMETHODCALLTYPE *GetDebugParameter )( + ID3D12DebugDevice1 * This, + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize); + + HRESULT ( STDMETHODCALLTYPE *ReportLiveDeviceObjects )( + ID3D12DebugDevice1 * This, + D3D12_RLDO_FLAGS Flags); + + END_INTERFACE + } ID3D12DebugDevice1Vtbl; + + interface ID3D12DebugDevice1 + { + CONST_VTBL struct ID3D12DebugDevice1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugDevice1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugDevice1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugDevice1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugDevice1_SetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> SetDebugParameter(This,Type,pData,DataSize) ) + +#define ID3D12DebugDevice1_GetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> GetDebugParameter(This,Type,pData,DataSize) ) + +#define ID3D12DebugDevice1_ReportLiveDeviceObjects(This,Flags) \ + ( (This)->lpVtbl -> ReportLiveDeviceObjects(This,Flags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugDevice1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DebugDevice_INTERFACE_DEFINED__ +#define __ID3D12DebugDevice_INTERFACE_DEFINED__ + +/* interface ID3D12DebugDevice */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugDevice; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3febd6dd-4973-4787-8194-e45f9e28923e") + ID3D12DebugDevice : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask( + D3D12_DEBUG_FEATURE Mask) = 0; + + virtual D3D12_DEBUG_FEATURE STDMETHODCALLTYPE GetFeatureMask( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects( + D3D12_RLDO_FLAGS Flags) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugDeviceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugDevice * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugDevice * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugDevice * This); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D12DebugDevice * This, + D3D12_DEBUG_FEATURE Mask); + + D3D12_DEBUG_FEATURE ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D12DebugDevice * This); + + HRESULT ( STDMETHODCALLTYPE *ReportLiveDeviceObjects )( + ID3D12DebugDevice * This, + D3D12_RLDO_FLAGS Flags); + + END_INTERFACE + } ID3D12DebugDeviceVtbl; + + interface ID3D12DebugDevice + { + CONST_VTBL struct ID3D12DebugDeviceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugDevice_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugDevice_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugDevice_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugDevice_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D12DebugDevice_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + +#define ID3D12DebugDevice_ReportLiveDeviceObjects(This,Flags) \ + ( (This)->lpVtbl -> ReportLiveDeviceObjects(This,Flags) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugDevice_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DebugDevice2_INTERFACE_DEFINED__ +#define __ID3D12DebugDevice2_INTERFACE_DEFINED__ + +/* interface ID3D12DebugDevice2 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugDevice2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("60eccbc1-378d-4df1-894c-f8ac5ce4d7dd") + ID3D12DebugDevice2 : public ID3D12DebugDevice + { + public: + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter( + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter( + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugDevice2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugDevice2 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugDevice2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugDevice2 * This); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D12DebugDevice2 * This, + D3D12_DEBUG_FEATURE Mask); + + D3D12_DEBUG_FEATURE ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D12DebugDevice2 * This); + + HRESULT ( STDMETHODCALLTYPE *ReportLiveDeviceObjects )( + ID3D12DebugDevice2 * This, + D3D12_RLDO_FLAGS Flags); + + HRESULT ( STDMETHODCALLTYPE *SetDebugParameter )( + ID3D12DebugDevice2 * This, + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize); + + HRESULT ( STDMETHODCALLTYPE *GetDebugParameter )( + ID3D12DebugDevice2 * This, + D3D12_DEBUG_DEVICE_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize); + + END_INTERFACE + } ID3D12DebugDevice2Vtbl; + + interface ID3D12DebugDevice2 + { + CONST_VTBL struct ID3D12DebugDevice2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugDevice2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugDevice2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugDevice2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugDevice2_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D12DebugDevice2_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + +#define ID3D12DebugDevice2_ReportLiveDeviceObjects(This,Flags) \ + ( (This)->lpVtbl -> ReportLiveDeviceObjects(This,Flags) ) + + +#define ID3D12DebugDevice2_SetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> SetDebugParameter(This,Type,pData,DataSize) ) + +#define ID3D12DebugDevice2_GetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> GetDebugParameter(This,Type,pData,DataSize) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugDevice2_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0007 */ +/* [local] */ + +DEFINE_GUID(DXGI_DEBUG_D3D12, 0xcf59a98c, 0xa950, 0x4326, 0x91, 0xef, 0x9b, 0xba, 0xa1, 0x7b, 0xfd, 0x95); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0007_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0007_v0_0_s_ifspec; + +#ifndef __ID3D12DebugCommandQueue_INTERFACE_DEFINED__ +#define __ID3D12DebugCommandQueue_INTERFACE_DEFINED__ + +/* interface ID3D12DebugCommandQueue */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugCommandQueue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("09e0bf36-54ac-484f-8847-4baeeab6053a") + ID3D12DebugCommandQueue : public IUnknown + { + public: + virtual BOOL STDMETHODCALLTYPE AssertResourceState( + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugCommandQueueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugCommandQueue * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugCommandQueue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugCommandQueue * This); + + BOOL ( STDMETHODCALLTYPE *AssertResourceState )( + ID3D12DebugCommandQueue * This, + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State); + + END_INTERFACE + } ID3D12DebugCommandQueueVtbl; + + interface ID3D12DebugCommandQueue + { + CONST_VTBL struct ID3D12DebugCommandQueueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugCommandQueue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugCommandQueue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugCommandQueue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugCommandQueue_AssertResourceState(This,pResource,Subresource,State) \ + ( (This)->lpVtbl -> AssertResourceState(This,pResource,Subresource,State) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugCommandQueue_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0008 */ +/* [local] */ + +typedef +enum D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE + { + D3D12_DEBUG_COMMAND_LIST_PARAMETER_GPU_BASED_VALIDATION_SETTINGS = 0 + } D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE; + +typedef struct D3D12_DEBUG_COMMAND_LIST_GPU_BASED_VALIDATION_SETTINGS + { + D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE ShaderPatchMode; + } D3D12_DEBUG_COMMAND_LIST_GPU_BASED_VALIDATION_SETTINGS; + + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0008_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0008_v0_0_s_ifspec; + +#ifndef __ID3D12DebugCommandList1_INTERFACE_DEFINED__ +#define __ID3D12DebugCommandList1_INTERFACE_DEFINED__ + +/* interface ID3D12DebugCommandList1 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugCommandList1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("102ca951-311b-4b01-b11f-ecb83e061b37") + ID3D12DebugCommandList1 : public IUnknown + { + public: + virtual BOOL STDMETHODCALLTYPE AssertResourceState( + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter( + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter( + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugCommandList1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugCommandList1 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugCommandList1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugCommandList1 * This); + + BOOL ( STDMETHODCALLTYPE *AssertResourceState )( + ID3D12DebugCommandList1 * This, + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State); + + HRESULT ( STDMETHODCALLTYPE *SetDebugParameter )( + ID3D12DebugCommandList1 * This, + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize); + + HRESULT ( STDMETHODCALLTYPE *GetDebugParameter )( + ID3D12DebugCommandList1 * This, + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize); + + END_INTERFACE + } ID3D12DebugCommandList1Vtbl; + + interface ID3D12DebugCommandList1 + { + CONST_VTBL struct ID3D12DebugCommandList1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugCommandList1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugCommandList1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugCommandList1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugCommandList1_AssertResourceState(This,pResource,Subresource,State) \ + ( (This)->lpVtbl -> AssertResourceState(This,pResource,Subresource,State) ) + +#define ID3D12DebugCommandList1_SetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> SetDebugParameter(This,Type,pData,DataSize) ) + +#define ID3D12DebugCommandList1_GetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> GetDebugParameter(This,Type,pData,DataSize) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugCommandList1_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandList_INTERFACE_DEFINED__ +#define __ID3D12DebugCommandList_INTERFACE_DEFINED__ + +/* interface ID3D12DebugCommandList */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugCommandList; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("09e0bf36-54ac-484f-8847-4baeeab6053f") + ID3D12DebugCommandList : public IUnknown + { + public: + virtual BOOL STDMETHODCALLTYPE AssertResourceState( + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask( + D3D12_DEBUG_FEATURE Mask) = 0; + + virtual D3D12_DEBUG_FEATURE STDMETHODCALLTYPE GetFeatureMask( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugCommandListVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugCommandList * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugCommandList * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugCommandList * This); + + BOOL ( STDMETHODCALLTYPE *AssertResourceState )( + ID3D12DebugCommandList * This, + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D12DebugCommandList * This, + D3D12_DEBUG_FEATURE Mask); + + D3D12_DEBUG_FEATURE ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D12DebugCommandList * This); + + END_INTERFACE + } ID3D12DebugCommandListVtbl; + + interface ID3D12DebugCommandList + { + CONST_VTBL struct ID3D12DebugCommandListVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugCommandList_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugCommandList_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugCommandList_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugCommandList_AssertResourceState(This,pResource,Subresource,State) \ + ( (This)->lpVtbl -> AssertResourceState(This,pResource,Subresource,State) ) + +#define ID3D12DebugCommandList_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D12DebugCommandList_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugCommandList_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12DebugCommandList2_INTERFACE_DEFINED__ +#define __ID3D12DebugCommandList2_INTERFACE_DEFINED__ + +/* interface ID3D12DebugCommandList2 */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12DebugCommandList2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("aeb575cf-4e06-48be-ba3b-c450fc96652e") + ID3D12DebugCommandList2 : public ID3D12DebugCommandList + { + public: + virtual HRESULT STDMETHODCALLTYPE SetDebugParameter( + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDebugParameter( + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12DebugCommandList2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12DebugCommandList2 * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12DebugCommandList2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12DebugCommandList2 * This); + + BOOL ( STDMETHODCALLTYPE *AssertResourceState )( + ID3D12DebugCommandList2 * This, + _In_ ID3D12Resource *pResource, + UINT Subresource, + UINT State); + + HRESULT ( STDMETHODCALLTYPE *SetFeatureMask )( + ID3D12DebugCommandList2 * This, + D3D12_DEBUG_FEATURE Mask); + + D3D12_DEBUG_FEATURE ( STDMETHODCALLTYPE *GetFeatureMask )( + ID3D12DebugCommandList2 * This); + + HRESULT ( STDMETHODCALLTYPE *SetDebugParameter )( + ID3D12DebugCommandList2 * This, + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _In_reads_bytes_(DataSize) const void *pData, + UINT DataSize); + + HRESULT ( STDMETHODCALLTYPE *GetDebugParameter )( + ID3D12DebugCommandList2 * This, + D3D12_DEBUG_COMMAND_LIST_PARAMETER_TYPE Type, + _Out_writes_bytes_(DataSize) void *pData, + UINT DataSize); + + END_INTERFACE + } ID3D12DebugCommandList2Vtbl; + + interface ID3D12DebugCommandList2 + { + CONST_VTBL struct ID3D12DebugCommandList2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12DebugCommandList2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12DebugCommandList2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12DebugCommandList2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12DebugCommandList2_AssertResourceState(This,pResource,Subresource,State) \ + ( (This)->lpVtbl -> AssertResourceState(This,pResource,Subresource,State) ) + +#define ID3D12DebugCommandList2_SetFeatureMask(This,Mask) \ + ( (This)->lpVtbl -> SetFeatureMask(This,Mask) ) + +#define ID3D12DebugCommandList2_GetFeatureMask(This) \ + ( (This)->lpVtbl -> GetFeatureMask(This) ) + + +#define ID3D12DebugCommandList2_SetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> SetDebugParameter(This,Type,pData,DataSize) ) + +#define ID3D12DebugCommandList2_GetDebugParameter(This,Type,pData,DataSize) \ + ( (This)->lpVtbl -> GetDebugParameter(This,Type,pData,DataSize) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12DebugCommandList2_INTERFACE_DEFINED__ */ + + +#ifndef __ID3D12SharingContract_INTERFACE_DEFINED__ +#define __ID3D12SharingContract_INTERFACE_DEFINED__ + +/* interface ID3D12SharingContract */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12SharingContract; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0adf7d52-929c-4e61-addb-ffed30de66ef") + ID3D12SharingContract : public IUnknown + { + public: + virtual void STDMETHODCALLTYPE Present( + _In_ ID3D12Resource *pResource, + UINT Subresource, + _In_ HWND window) = 0; + + virtual void STDMETHODCALLTYPE SharedFenceSignal( + _In_ ID3D12Fence *pFence, + UINT64 FenceValue) = 0; + + virtual void STDMETHODCALLTYPE BeginCapturableWork( + _In_ REFGUID guid) = 0; + + virtual void STDMETHODCALLTYPE EndCapturableWork( + _In_ REFGUID guid) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12SharingContractVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12SharingContract * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12SharingContract * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12SharingContract * This); + + void ( STDMETHODCALLTYPE *Present )( + ID3D12SharingContract * This, + _In_ ID3D12Resource *pResource, + UINT Subresource, + _In_ HWND window); + + void ( STDMETHODCALLTYPE *SharedFenceSignal )( + ID3D12SharingContract * This, + _In_ ID3D12Fence *pFence, + UINT64 FenceValue); + + void ( STDMETHODCALLTYPE *BeginCapturableWork )( + ID3D12SharingContract * This, + _In_ REFGUID guid); + + void ( STDMETHODCALLTYPE *EndCapturableWork )( + ID3D12SharingContract * This, + _In_ REFGUID guid); + + END_INTERFACE + } ID3D12SharingContractVtbl; + + interface ID3D12SharingContract + { + CONST_VTBL struct ID3D12SharingContractVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12SharingContract_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12SharingContract_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12SharingContract_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12SharingContract_Present(This,pResource,Subresource,window) \ + ( (This)->lpVtbl -> Present(This,pResource,Subresource,window) ) + +#define ID3D12SharingContract_SharedFenceSignal(This,pFence,FenceValue) \ + ( (This)->lpVtbl -> SharedFenceSignal(This,pFence,FenceValue) ) + +#define ID3D12SharingContract_BeginCapturableWork(This,guid) \ + ( (This)->lpVtbl -> BeginCapturableWork(This,guid) ) + +#define ID3D12SharingContract_EndCapturableWork(This,guid) \ + ( (This)->lpVtbl -> EndCapturableWork(This,guid) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12SharingContract_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0012 */ +/* [local] */ + +typedef +enum D3D12_MESSAGE_CATEGORY + { + D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED = 0, + D3D12_MESSAGE_CATEGORY_MISCELLANEOUS = ( D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED + 1 ) , + D3D12_MESSAGE_CATEGORY_INITIALIZATION = ( D3D12_MESSAGE_CATEGORY_MISCELLANEOUS + 1 ) , + D3D12_MESSAGE_CATEGORY_CLEANUP = ( D3D12_MESSAGE_CATEGORY_INITIALIZATION + 1 ) , + D3D12_MESSAGE_CATEGORY_COMPILATION = ( D3D12_MESSAGE_CATEGORY_CLEANUP + 1 ) , + D3D12_MESSAGE_CATEGORY_STATE_CREATION = ( D3D12_MESSAGE_CATEGORY_COMPILATION + 1 ) , + D3D12_MESSAGE_CATEGORY_STATE_SETTING = ( D3D12_MESSAGE_CATEGORY_STATE_CREATION + 1 ) , + D3D12_MESSAGE_CATEGORY_STATE_GETTING = ( D3D12_MESSAGE_CATEGORY_STATE_SETTING + 1 ) , + D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION = ( D3D12_MESSAGE_CATEGORY_STATE_GETTING + 1 ) , + D3D12_MESSAGE_CATEGORY_EXECUTION = ( D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION + 1 ) , + D3D12_MESSAGE_CATEGORY_SHADER = ( D3D12_MESSAGE_CATEGORY_EXECUTION + 1 ) + } D3D12_MESSAGE_CATEGORY; + +typedef +enum D3D12_MESSAGE_SEVERITY + { + D3D12_MESSAGE_SEVERITY_CORRUPTION = 0, + D3D12_MESSAGE_SEVERITY_ERROR = ( D3D12_MESSAGE_SEVERITY_CORRUPTION + 1 ) , + D3D12_MESSAGE_SEVERITY_WARNING = ( D3D12_MESSAGE_SEVERITY_ERROR + 1 ) , + D3D12_MESSAGE_SEVERITY_INFO = ( D3D12_MESSAGE_SEVERITY_WARNING + 1 ) , + D3D12_MESSAGE_SEVERITY_MESSAGE = ( D3D12_MESSAGE_SEVERITY_INFO + 1 ) + } D3D12_MESSAGE_SEVERITY; + +typedef +enum D3D12_MESSAGE_ID + { + D3D12_MESSAGE_ID_UNKNOWN = 0, + D3D12_MESSAGE_ID_STRING_FROM_APPLICATION = ( D3D12_MESSAGE_ID_UNKNOWN + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_THIS = ( D3D12_MESSAGE_ID_STRING_FROM_APPLICATION + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER1 = ( D3D12_MESSAGE_ID_CORRUPTED_THIS + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER2 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER1 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER3 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER2 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER4 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER3 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER5 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER4 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER6 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER5 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER7 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER6 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER8 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER7 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER9 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER8 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER10 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER9 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER11 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER10 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER12 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER11 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER13 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER12 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER14 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER13 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_PARAMETER15 = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER14 + 1 ) , + D3D12_MESSAGE_ID_CORRUPTED_MULTITHREADING = ( D3D12_MESSAGE_ID_CORRUPTED_PARAMETER15 + 1 ) , + D3D12_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CORRUPTED_MULTITHREADING + 1 ) , + D3D12_MESSAGE_ID_GETPRIVATEDATA_MOREDATA = ( D3D12_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA = ( D3D12_MESSAGE_ID_GETPRIVATEDATA_MOREDATA + 1 ) , + D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN = ( D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA + 1 ) , + D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS = ( D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDIUNKNOWN + 1 ) , + D3D12_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS = ( D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY = ( D3D12_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT = ( D3D12_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANESLICE = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDPLANESLICE = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDVIDEOPLANESLICE = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDPLANESLICE = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDVIDEOPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC + 1 ) , + D3D12_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT + 1 ) , + D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDDECL + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_EXPECTEDDECL + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX + 1 ) , + D3D12_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE = ( D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_NULLDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_NULLDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_NULLDESC + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDFILTER + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSU + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSV + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDADDRESSW + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMIPLODBIAS + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXANISOTROPY + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDCOMPARISONFUNC + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMINLOD + 1 ) , + D3D12_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_INVALIDMAXLOD + 1 ) , + D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED = ( D3D12_MESSAGE_ID_CREATESAMPLERSTATE_NULLDESC + 1 ) , + D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED = ( D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNRECOGNIZED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT = ( D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNDEFINED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR = ( D3D12_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_INVALIDVIEWPORT + 1 ) , + D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH = ( D3D12_MESSAGE_ID_DEVICE_RSSETSCISSORRECTS_INVALIDSCISSOR + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH = ( D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_DENORMFLUSH + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DENORMFLUSH + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSOURCESTATE + 1 ) , + D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX = ( D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE = ( D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONBOX + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID = ( D3D12_MESSAGE_ID_UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID = ( D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID = ( D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_DESTINATION_SUBRESOURCE_INVALID + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID = ( D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID = ( D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_SOURCE_SUBRESOURCE_INVALID + 1 ) , + D3D12_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE = ( D3D12_MESSAGE_ID_DEVICE_RESOLVESUBRESOURCE_FORMAT_INVALID + 1 ) , + D3D12_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_BUFFER_MAP_INVALIDMAPTYPE + 1 ) , + D3D12_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED = ( D3D12_MESSAGE_ID_BUFFER_MAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_BUFFER_MAP_ALREADYMAPPED + 1 ) , + D3D12_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED = ( D3D12_MESSAGE_ID_BUFFER_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE = ( D3D12_MESSAGE_ID_BUFFER_UNMAP_NOTMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDMAPTYPE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED = ( D3D12_MESSAGE_ID_TEXTURE1D_MAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_TEXTURE1D_MAP_ALREADYMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE1D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED = ( D3D12_MESSAGE_ID_TEXTURE1D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE = ( D3D12_MESSAGE_ID_TEXTURE1D_UNMAP_NOTMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDMAPTYPE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED = ( D3D12_MESSAGE_ID_TEXTURE2D_MAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_TEXTURE2D_MAP_ALREADYMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE2D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED = ( D3D12_MESSAGE_ID_TEXTURE2D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE = ( D3D12_MESSAGE_ID_TEXTURE2D_UNMAP_NOTMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDMAPTYPE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED = ( D3D12_MESSAGE_ID_TEXTURE3D_MAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_TEXTURE3D_MAP_ALREADYMAPPED + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_TEXTURE3D_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED = ( D3D12_MESSAGE_ID_TEXTURE3D_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED = ( D3D12_MESSAGE_ID_TEXTURE3D_UNMAP_NOTMAPPED + 1 ) , + D3D12_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED = ( D3D12_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_DEPRECATED + 1 ) , + D3D12_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS = ( D3D12_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_FORMAT_DEPRECATED + 1 ) , + D3D12_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_SETEXCEPTIONMODE_UNRECOGNIZEDFLAGS + 1 ) , + D3D12_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_SETEXCEPTIONMODE_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE = ( D3D12_MESSAGE_ID_SETEXCEPTIONMODE_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_REF_THREADING_MODE = ( D3D12_MESSAGE_ID_REF_SIMULATING_INFINITELY_FAST_HARDWARE + 1 ) , + D3D12_MESSAGE_ID_REF_UMDRIVER_EXCEPTION = ( D3D12_MESSAGE_ID_REF_THREADING_MODE + 1 ) , + D3D12_MESSAGE_ID_REF_KMDRIVER_EXCEPTION = ( D3D12_MESSAGE_ID_REF_UMDRIVER_EXCEPTION + 1 ) , + D3D12_MESSAGE_ID_REF_HARDWARE_EXCEPTION = ( D3D12_MESSAGE_ID_REF_KMDRIVER_EXCEPTION + 1 ) , + D3D12_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE = ( D3D12_MESSAGE_ID_REF_HARDWARE_EXCEPTION + 1 ) , + D3D12_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER = ( D3D12_MESSAGE_ID_REF_ACCESSING_INDEXABLE_TEMP_OUT_OF_RANGE + 1 ) , + D3D12_MESSAGE_ID_REF_OUT_OF_MEMORY = ( D3D12_MESSAGE_ID_REF_PROBLEM_PARSING_SHADER + 1 ) , + D3D12_MESSAGE_ID_REF_INFO = ( D3D12_MESSAGE_ID_REF_OUT_OF_MEMORY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW = ( D3D12_MESSAGE_ID_REF_INFO + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAW_VERTEXPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDEXED_INDEXPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAWINSTANCED_VERTEXPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAWINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INSTANCEPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDEXEDINSTANCED_INDEXPOS_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = ( D3D12_MESSAGE_ID_DEVICE_DRAW_VERTEX_SHADER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERINDEX + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_COMPONENTTYPE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_SYSTEMVALUE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INPUTLAYOUT_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_CONSTANT_BUFFER_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INPUTLAYOUT_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_CONSTANT_BUFFER_TOO_SMALL = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_CONSTANT_BUFFER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SAMPLER_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_CONSTANT_BUFFER_TOO_SMALL + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SHADERRESOURCEVIEW_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SAMPLER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VIEW_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SHADERRESOURCEVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VIEW_DIMENSION_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_TOO_SMALL = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_TOO_SMALL + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_FORMAT_INVALID = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_TOO_SMALL = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_FORMAT_INVALID + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_GS_INPUT_PRIMITIVE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_TOO_SMALL + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_RETURN_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_GS_INPUT_PRIMITIVE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_POSITION_NOT_PRESENT = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_RETURN_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OUTPUT_STREAM_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_POSITION_NOT_PRESENT + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_BOUND_RESOURCE_MAPPED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OUTPUT_STREAM_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INVALID_PRIMITIVETOPOLOGY = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_BOUND_RESOURCE_MAPPED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_OFFSET_UNALIGNED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INVALID_PRIMITIVETOPOLOGY + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_STRIDE_UNALIGNED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_OFFSET_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_OFFSET_UNALIGNED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_STRIDE_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_OFFSET_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OUTPUT_STREAM_OFFSET_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_LD_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_SAMPLE_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_FORMAT_SAMPLE_C_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RESOURCE_MULTISAMPLE_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SO_STRIDE_LARGER_THAN_BUFFER = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SO_TARGETS_BOUND_WITHOUT_SOURCE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_SO_STRIDE_LARGER_THAN_BUFFER + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING + 1 ) , + D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 + 1 ) , + D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT = ( D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT = ( D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN = ( D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BADINTERFACE_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D12_MESSAGE_ID_DEVICE_DRAW_VIEWPORT_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D12_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC + 1 ) , + D3D12_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW = ( D3D12_MESSAGE_ID_DEVICE_RSSETVIEWPORTS_DENORMFLUSH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_OMSETRENDERTARGETS_INVALIDVIEW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_SETTEXTFILTERSIZE_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY = ( D3D12_MESSAGE_ID_BLENDSTATE_GETDESC_LEGACY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_SHADERRESOURCEVIEW_GETDESC_LEGACY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_DRAW_PS_OUTPUT_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = ( D3D12_MESSAGE_ID_DEVICE_DRAW_RESOURCE_FORMAT_GATHER_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE = ( D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN + 1 ) , + D3D12_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE = ( D3D12_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_STRIDE_TOO_LARGE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT = ( D3D12_MESSAGE_ID_DEVICE_IASETVERTEXBUFFERS_INVALIDRANGE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT + 1 ) , + D3D12_MESSAGE_ID_LIVE_OBJECT_SUMMARY = ( D3D12_MESSAGE_ID_DEVICE_DRAW_RESOURCE_SAMPLE_COUNT_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_LIVE_BUFFER = ( D3D12_MESSAGE_ID_LIVE_OBJECT_SUMMARY + 1 ) , + D3D12_MESSAGE_ID_LIVE_TEXTURE1D = ( D3D12_MESSAGE_ID_LIVE_BUFFER + 1 ) , + D3D12_MESSAGE_ID_LIVE_TEXTURE2D = ( D3D12_MESSAGE_ID_LIVE_TEXTURE1D + 1 ) , + D3D12_MESSAGE_ID_LIVE_TEXTURE3D = ( D3D12_MESSAGE_ID_LIVE_TEXTURE2D + 1 ) , + D3D12_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW = ( D3D12_MESSAGE_ID_LIVE_TEXTURE3D + 1 ) , + D3D12_MESSAGE_ID_LIVE_RENDERTARGETVIEW = ( D3D12_MESSAGE_ID_LIVE_SHADERRESOURCEVIEW + 1 ) , + D3D12_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW = ( D3D12_MESSAGE_ID_LIVE_RENDERTARGETVIEW + 1 ) , + D3D12_MESSAGE_ID_LIVE_VERTEXSHADER = ( D3D12_MESSAGE_ID_LIVE_DEPTHSTENCILVIEW + 1 ) , + D3D12_MESSAGE_ID_LIVE_GEOMETRYSHADER = ( D3D12_MESSAGE_ID_LIVE_VERTEXSHADER + 1 ) , + D3D12_MESSAGE_ID_LIVE_PIXELSHADER = ( D3D12_MESSAGE_ID_LIVE_GEOMETRYSHADER + 1 ) , + D3D12_MESSAGE_ID_LIVE_INPUTLAYOUT = ( D3D12_MESSAGE_ID_LIVE_PIXELSHADER + 1 ) , + D3D12_MESSAGE_ID_LIVE_SAMPLER = ( D3D12_MESSAGE_ID_LIVE_INPUTLAYOUT + 1 ) , + D3D12_MESSAGE_ID_LIVE_BLENDSTATE = ( D3D12_MESSAGE_ID_LIVE_SAMPLER + 1 ) , + D3D12_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE = ( D3D12_MESSAGE_ID_LIVE_BLENDSTATE + 1 ) , + D3D12_MESSAGE_ID_LIVE_RASTERIZERSTATE = ( D3D12_MESSAGE_ID_LIVE_DEPTHSTENCILSTATE + 1 ) , + D3D12_MESSAGE_ID_LIVE_QUERY = ( D3D12_MESSAGE_ID_LIVE_RASTERIZERSTATE + 1 ) , + D3D12_MESSAGE_ID_LIVE_PREDICATE = ( D3D12_MESSAGE_ID_LIVE_QUERY + 1 ) , + D3D12_MESSAGE_ID_LIVE_COUNTER = ( D3D12_MESSAGE_ID_LIVE_PREDICATE + 1 ) , + D3D12_MESSAGE_ID_LIVE_DEVICE = ( D3D12_MESSAGE_ID_LIVE_COUNTER + 1 ) , + D3D12_MESSAGE_ID_LIVE_SWAPCHAIN = ( D3D12_MESSAGE_ID_LIVE_DEVICE + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS = ( D3D12_MESSAGE_ID_LIVE_SWAPCHAIN + 1 ) , + D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTREAMS = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTREAMS + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTREAMS = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTREAMS + 1 ) , + D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM = ( D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES + 1 ) , + D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES + 1 ) , + D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDCALL = ( D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES + 1 ) , + D3D12_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDCALL + 1 ) , + D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCALL = ( D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCALL + 1 ) , + D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE = ( D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_HS_XOR_DS_MISMATCH = ( D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_INVALID_ARG_BUFFER = ( D3D12_MESSAGE_ID_DEVICE_DRAW_HS_XOR_DS_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_UNALIGNED = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_INVALID_ARG_BUFFER + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDMAPTYPE = ( D3D12_MESSAGE_ID_DEVICE_DRAWINDIRECT_OFFSET_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDMAPTYPE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_ALREADYMAPPED = ( D3D12_MESSAGE_ID_RESOURCE_MAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_DEVICEREMOVED_RETURN = ( D3D12_MESSAGE_ID_RESOURCE_MAP_ALREADYMAPPED + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_RESOURCE_MAP_DEVICEREMOVED_RETURN + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_MAP_WITHOUT_INITIAL_DISCARD = ( D3D12_MESSAGE_ID_RESOURCE_MAP_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_UNMAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_RESOURCE_MAP_WITHOUT_INITIAL_DISCARD + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED = ( D3D12_MESSAGE_ID_RESOURCE_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_RASTERIZING_CONTROL_POINTS = ( D3D12_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_DRAW_RASTERIZING_CONTROL_POINTS + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_IASETPRIMITIVETOPOLOGY_TOPOLOGY_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_CONTROL_POINT_COUNT_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_TESSELLATOR_DOMAIN_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_CONTROL_POINT_COUNT_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_UNRECOGNIZED_FEATURE = ( D3D12_MESSAGE_ID_DEVICE_DRAW_HS_DS_TESSELLATOR_DOMAIN_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE = ( D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_UNRECOGNIZED_FEATURE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCALL = ( D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY = ( D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCALL + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE = ( D3D12_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE = ( D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_VIEWS_EMPTY = ( D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE + 1 ) , + D3D12_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFER = ( D3D12_MESSAGE_ID_DEVICE_CSSETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D12_MESSAGE_ID_CSSETCONSTANTBUFFERS_INVALIDBUFFER + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSSETSAMPLERS_SAMPLERS_EMPTY = ( D3D12_MESSAGE_ID_DEVICE_CSSETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSGETSHADERRESOURCES_VIEWS_EMPTY = ( D3D12_MESSAGE_ID_DEVICE_CSSETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSGETCONSTANTBUFFERS_BUFFERS_EMPTY = ( D3D12_MESSAGE_ID_DEVICE_CSGETSHADERRESOURCES_VIEWS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSGETSAMPLERS_SAMPLERS_EMPTY = ( D3D12_MESSAGE_ID_DEVICE_CSGETCONSTANTBUFFERS_BUFFERS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CSGETSAMPLERS_SAMPLERS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATEBUFFER_INVALIDSTRUCTURESTRIDE = ( D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFLAGS = ( D3D12_MESSAGE_ID_CREATEBUFFER_INVALIDSTRUCTURESTRIDE + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANESLICE = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDPLANESLICE = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDPLANESLICE + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_OVERLAPPING_OLD_SLOTS = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NO_OP = ( D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_OVERLAPPING_OLD_SLOTS + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_NO_OP + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_DENORMFLUSH = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSS_VIEWS_EMPTY = ( D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_DENORMFLUSH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CSGETUNORDEREDACCESSS_VIEWS_EMPTY = ( D3D12_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSS_VIEWS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS = ( D3D12_MESSAGE_ID_DEVICE_CSGETUNORDEREDACCESSS_VIEWS_EMPTY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_INVALID_ARG_BUFFER = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_UNALIGNED = ( D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_INVALID_ARG_BUFFER + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_UNALIGNED + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DEPTH_READONLY = ( D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_OFFSET_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_STENCIL_READONLY = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_DEPTH_READONLY + 1 ) , + D3D12_MESSAGE_ID_CHECKFEATURESUPPORT_FORMAT_DEPRECATED = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_STENCIL_READONLY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_CHECKFEATURESUPPORT_FORMAT_DEPRECATED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_UNORDEREDACCESSVIEW_RENDERTARGETVIEW_OVERLAP = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DRAW_UNORDEREDACCESSVIEW_RENDERTARGETVIEW_OVERLAP + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_APPEND_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_DIMENSION_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMICS_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_APPEND_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_STRUCTURE_STRIDE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMICS_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_BUFFER_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_STRUCTURE_STRIDE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RAW_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_BUFFER_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_LD_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RAW_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_STORE_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_LD_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_ADD_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_FORMAT_STORE_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_BITWISE_OPS_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_ADD_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_CMPSTORE_CMPEXCHANGE_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_BITWISE_OPS_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_EXCHANGE_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_CMPSTORE_CMPEXCHANGE_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_SIGNED_MINMAX_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_EXCHANGE_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_UNSIGNED_MINMAX_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_SIGNED_MINMAX_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCH_BOUND_RESOURCE_MAPPED = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_ATOMIC_UNSIGNED_MINMAX_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_OVERFLOW = ( D3D12_MESSAGE_ID_DEVICE_DISPATCH_BOUND_RESOURCE_MAPPED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_ZERO = ( D3D12_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_OVERFLOW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_STRUCTURE_STRIDE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_DISPATCH_THREADGROUPCOUNT_ZERO + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_BUFFER_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_STRUCTURE_STRIDE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_RAW_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_BUFFER_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCH_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_SHADERRESOURCEVIEW_RAW_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_UNSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_DISPATCH_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDOFFSET = ( D3D12_MESSAGE_ID_DEVICE_DISPATCHINDIRECT_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_LARGEOFFSET = ( D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDOFFSET + 1 ) , + D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDDESTINATIONSTATE = ( D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_LARGEOFFSET + 1 ) , + D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDSOURCESTATE = ( D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDDESTINATIONSTATE + 1 ) , + D3D12_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_COPYSTRUCTURECOUNT_INVALIDSOURCESTATE + 1 ) , + D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEWFLOAT_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CHECKFORMATSUPPORT_FORMAT_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_COUNTER_UNSUPPORTED = ( D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEWFLOAT_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_PIXEL_SHADER_WITHOUT_RTV_OR_DSV = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_COUNTER_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_SHADER_ABORT = ( D3D12_MESSAGE_ID_DEVICE_DRAW_PIXEL_SHADER_WITHOUT_RTV_OR_DSV + 1 ) , + D3D12_MESSAGE_ID_SHADER_MESSAGE = ( D3D12_MESSAGE_ID_SHADER_ABORT + 1 ) , + D3D12_MESSAGE_ID_SHADER_ERROR = ( D3D12_MESSAGE_ID_SHADER_MESSAGE + 1 ) , + D3D12_MESSAGE_ID_OFFERRESOURCES_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_SHADER_ERROR + 1 ) , + D3D12_MESSAGE_ID_ENQUEUESETEVENT_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_OFFERRESOURCES_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_ENQUEUESETEVENT_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_ENQUEUESETEVENT_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_ENQUEUESETEVENT_ACCESSDENIED_RETURN = ( D3D12_MESSAGE_ID_ENQUEUESETEVENT_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFORCEDSAMPLECOUNT = ( D3D12_MESSAGE_ID_ENQUEUESETEVENT_ACCESSDENIED_RETURN + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_FORCED_SAMPLE_COUNT = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFORCEDSAMPLECOUNT + 1 ) , + D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDLOGICOPS = ( D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_USE_OF_FORCED_SAMPLE_COUNT + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARRAYWITHDECODER = ( D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDLOGICOPS + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARRAYWITHDECODER = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDARRAYWITHDECODER + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARRAYWITHDECODER = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDARRAYWITHDECODER + 1 ) , + D3D12_MESSAGE_ID_DEVICE_LOCKEDOUT_INTERFACE = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDARRAYWITHDECODER + 1 ) , + D3D12_MESSAGE_ID_OFFERRESOURCES_INVALIDPRIORITY = ( D3D12_MESSAGE_ID_DEVICE_LOCKEDOUT_INTERFACE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDVIEW = ( D3D12_MESSAGE_ID_OFFERRESOURCES_INVALIDPRIORITY + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDVIEW + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEEXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_SHADEREXTENSIONSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEEXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_MINPRECISION = ( D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_SHADEREXTENSIONSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_SHADER_LINKAGE_MINPRECISION + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_UAVSNOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_INVALIDOFFSET = ( D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_UAVSNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_TOOMANYVIEWS = ( D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_INVALIDOFFSET + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_NOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_OMSETRENDERTARGETSANDUNORDEREDACCESSVIEWS_TOOMANYVIEWS + 1 ) , + D3D12_MESSAGE_ID_SWAPDEVICECONTEXTSTATE_NOTSUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_NOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_UPDATESUBRESOURCE_PREFERUPDATESUBRESOURCE1 = ( D3D12_MESSAGE_ID_SWAPDEVICECONTEXTSTATE_NOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_GETDC_INACCESSIBLE = ( D3D12_MESSAGE_ID_UPDATESUBRESOURCE_PREFERUPDATESUBRESOURCE1 + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDRECT = ( D3D12_MESSAGE_ID_GETDC_INACCESSIBLE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_SAMPLE_MASK_IGNORED_ON_FL9 = ( D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDRECT + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE1_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_DRAW_SAMPLE_MASK_IGNORED_ON_FL9 + 1 ) , + D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BY_NAME_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE1_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_ENQUEUESETEVENT_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_DEVICE_OPEN_SHARED_RESOURCE_BY_NAME_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_OFFERRELEASE_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_ENQUEUESETEVENT_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_OFFERRESOURCES_INACCESSIBLE = ( D3D12_MESSAGE_ID_OFFERRELEASE_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDMSAA = ( D3D12_MESSAGE_ID_OFFERRESOURCES_INACCESSIBLE + 1 ) , + D3D12_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDMSAA = ( D3D12_MESSAGE_ID_CREATEVIDEOPROCESSORINPUTVIEW_INVALIDMSAA + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDSOURCERECT = ( D3D12_MESSAGE_ID_CREATEVIDEOPROCESSOROUTPUTVIEW_INVALIDMSAA + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_EMPTYRECT = ( D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDSOURCERECT + 1 ) , + D3D12_MESSAGE_ID_UPDATESUBRESOURCE_EMPTYDESTBOX = ( D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_EMPTYRECT + 1 ) , + D3D12_MESSAGE_ID_COPYSUBRESOURCEREGION_EMPTYSOURCEBOX = ( D3D12_MESSAGE_ID_UPDATESUBRESOURCE_EMPTYDESTBOX + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS = ( D3D12_MESSAGE_ID_COPYSUBRESOURCEREGION_EMPTYSOURCEBOX + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_DEPTHSTENCILVIEW_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_DRAW_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET = ( D3D12_MESSAGE_ID_DEVICE_DRAW_DEPTHSTENCILVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET_DUE_TO_FLIP_PRESENT = ( D3D12_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET_DUE_TO_FLIP_PRESENT = ( D3D12_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET_DUE_TO_FLIP_PRESENT + 1 ) , + D3D12_MESSAGE_ID_GETDATAFORNEWHARDWAREKEY_NULLPARAM = ( D3D12_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_NOT_SET_DUE_TO_FLIP_PRESENT + 1 ) , + D3D12_MESSAGE_ID_CHECKCRYPTOSESSIONSTATUS_NULLPARAM = ( D3D12_MESSAGE_ID_GETDATAFORNEWHARDWAREKEY_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_SETEVENTONHARDWARECONTENTPROTECTIONTILT_NULLPARAM = ( D3D12_MESSAGE_ID_CHECKCRYPTOSESSIONSTATUS_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_GETVIDEODECODERCAPS_NULLPARAM = ( D3D12_MESSAGE_ID_SETEVENTONHARDWARECONTENTPROTECTIONTILT_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_GETVIDEODECODERCAPS_ZEROWIDTHHEIGHT = ( D3D12_MESSAGE_ID_GETVIDEODECODERCAPS_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_NULLPARAM = ( D3D12_MESSAGE_ID_GETVIDEODECODERCAPS_ZEROWIDTHHEIGHT + 1 ) , + D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_INVALIDCOLORSPACE = ( D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_ZEROWIDTHHEIGHT = ( D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_INVALIDCOLORSPACE + 1 ) , + D3D12_MESSAGE_ID_VIDEODECODERENABLEDOWNSAMPLING_NULLPARAM = ( D3D12_MESSAGE_ID_CHECKVIDEODECODERDOWNSAMPLING_ZEROWIDTHHEIGHT + 1 ) , + D3D12_MESSAGE_ID_VIDEODECODERENABLEDOWNSAMPLING_UNSUPPORTED = ( D3D12_MESSAGE_ID_VIDEODECODERENABLEDOWNSAMPLING_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEODECODERUPDATEDOWNSAMPLING_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEODECODERENABLEDOWNSAMPLING_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_VIDEODECODERUPDATEDOWNSAMPLING_UNSUPPORTED = ( D3D12_MESSAGE_ID_VIDEODECODERUPDATEDOWNSAMPLING_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_CHECKVIDEOPROCESSORFORMATCONVERSION_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEODECODERUPDATEDOWNSAMPLING_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCOLORSPACE1_NULLPARAM = ( D3D12_MESSAGE_ID_CHECKVIDEOPROCESSORFORMATCONVERSION_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTCOLORSPACE1_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTCOLORSPACE1_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE1_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTCOLORSPACE1_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE1_INVALIDSTREAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE1_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMCOLORSPACE1_INVALIDSTREAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_INVALIDSTREAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_UNSUPPORTED = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_INVALIDSTREAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETSTREAMCOLORSPACE1_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETSTREAMMIRROR_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETSTREAMMIRROR_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETSTREAMCOLORSPACE1_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETSTREAMMIRROR_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_INVALIDCOLORSPACE = ( D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_ZEROWIDTHHEIGHT = ( D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_INVALIDCOLORSPACE + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTSHADERUSAGE_NULLPARAM = ( D3D12_MESSAGE_ID_RECOMMENDVIDEODECODERDOWNSAMPLING_ZEROWIDTHHEIGHT + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTSHADERUSAGE_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORSETOUTPUTSHADERUSAGE_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_NULLPARAM = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETOUTPUTSHADERUSAGE_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDSTREAMCOUNT = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_NULLPARAM + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_TARGETRECT = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDSTREAMCOUNT + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDSOURCERECT = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_TARGETRECT + 1 ) , + D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDDESTRECT = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDSOURCERECT + 1 ) , + D3D12_MESSAGE_ID_CREATEBUFFER_INVALIDUSAGE = ( D3D12_MESSAGE_ID_VIDEOPROCESSORGETBEHAVIORHINTS_INVALIDDESTRECT + 1 ) , + D3D12_MESSAGE_ID_CREATETEXTURE1D_INVALIDUSAGE = ( D3D12_MESSAGE_ID_CREATEBUFFER_INVALIDUSAGE + 1 ) , + D3D12_MESSAGE_ID_CREATETEXTURE2D_INVALIDUSAGE = ( D3D12_MESSAGE_ID_CREATETEXTURE1D_INVALIDUSAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_LEVEL9_STEPRATE_NOT_1 = ( D3D12_MESSAGE_ID_CREATETEXTURE2D_INVALIDUSAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_LEVEL9_INSTANCING_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_LEVEL9_STEPRATE_NOT_1 + 1 ) , + D3D12_MESSAGE_ID_UPDATETILEMAPPINGS_INVALID_PARAMETER = ( D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_LEVEL9_INSTANCING_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_COPYTILEMAPPINGS_INVALID_PARAMETER = ( D3D12_MESSAGE_ID_UPDATETILEMAPPINGS_INVALID_PARAMETER + 1 ) , + D3D12_MESSAGE_ID_COPYTILES_INVALID_PARAMETER = ( D3D12_MESSAGE_ID_COPYTILEMAPPINGS_INVALID_PARAMETER + 1 ) , + D3D12_MESSAGE_ID_NULL_TILE_MAPPING_ACCESS_WARNING = ( D3D12_MESSAGE_ID_COPYTILES_INVALID_PARAMETER + 1 ) , + D3D12_MESSAGE_ID_NULL_TILE_MAPPING_ACCESS_ERROR = ( D3D12_MESSAGE_ID_NULL_TILE_MAPPING_ACCESS_WARNING + 1 ) , + D3D12_MESSAGE_ID_DIRTY_TILE_MAPPING_ACCESS = ( D3D12_MESSAGE_ID_NULL_TILE_MAPPING_ACCESS_ERROR + 1 ) , + D3D12_MESSAGE_ID_DUPLICATE_TILE_MAPPINGS_IN_COVERED_AREA = ( D3D12_MESSAGE_ID_DIRTY_TILE_MAPPING_ACCESS + 1 ) , + D3D12_MESSAGE_ID_TILE_MAPPINGS_IN_COVERED_AREA_DUPLICATED_OUTSIDE = ( D3D12_MESSAGE_ID_DUPLICATE_TILE_MAPPINGS_IN_COVERED_AREA + 1 ) , + D3D12_MESSAGE_ID_TILE_MAPPINGS_SHARED_BETWEEN_INCOMPATIBLE_RESOURCES = ( D3D12_MESSAGE_ID_TILE_MAPPINGS_IN_COVERED_AREA_DUPLICATED_OUTSIDE + 1 ) , + D3D12_MESSAGE_ID_TILE_MAPPINGS_SHARED_BETWEEN_INPUT_AND_OUTPUT = ( D3D12_MESSAGE_ID_TILE_MAPPINGS_SHARED_BETWEEN_INCOMPATIBLE_RESOURCES + 1 ) , + D3D12_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_INVALIDFLAGS = ( D3D12_MESSAGE_ID_TILE_MAPPINGS_SHARED_BETWEEN_INPUT_AND_OUTPUT + 1 ) , + D3D12_MESSAGE_ID_GETRESOURCETILING_NONTILED_RESOURCE = ( D3D12_MESSAGE_ID_CHECKMULTISAMPLEQUALITYLEVELS_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_NEED_TO_CALL_TILEDRESOURCEBARRIER = ( D3D12_MESSAGE_ID_GETRESOURCETILING_NONTILED_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATEDEVICE_INVALIDARGS = ( D3D12_MESSAGE_ID_NEED_TO_CALL_TILEDRESOURCEBARRIER + 1 ) , + D3D12_MESSAGE_ID_CREATEDEVICE_WARNING = ( D3D12_MESSAGE_ID_CREATEDEVICE_INVALIDARGS + 1 ) , + D3D12_MESSAGE_ID_TILED_RESOURCE_TIER_1_BUFFER_TEXTURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEDEVICE_WARNING + 1 ) , + D3D12_MESSAGE_ID_CREATE_CRYPTOSESSION = ( D3D12_MESSAGE_ID_TILED_RESOURCE_TIER_1_BUFFER_TEXTURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATE_AUTHENTICATEDCHANNEL = ( D3D12_MESSAGE_ID_CREATE_CRYPTOSESSION + 1 ) , + D3D12_MESSAGE_ID_LIVE_CRYPTOSESSION = ( D3D12_MESSAGE_ID_CREATE_AUTHENTICATEDCHANNEL + 1 ) , + D3D12_MESSAGE_ID_LIVE_AUTHENTICATEDCHANNEL = ( D3D12_MESSAGE_ID_LIVE_CRYPTOSESSION + 1 ) , + D3D12_MESSAGE_ID_DESTROY_CRYPTOSESSION = ( D3D12_MESSAGE_ID_LIVE_AUTHENTICATEDCHANNEL + 1 ) , + D3D12_MESSAGE_ID_DESTROY_AUTHENTICATEDCHANNEL = ( D3D12_MESSAGE_ID_DESTROY_CRYPTOSESSION + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALID_SUBRESOURCE = ( D3D12_MESSAGE_ID_DESTROY_AUTHENTICATEDCHANNEL + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALID_TYPE = ( D3D12_MESSAGE_ID_MAP_INVALID_SUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_MAP_UNSUPPORTED_TYPE = ( D3D12_MESSAGE_ID_MAP_INVALID_TYPE + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALID_SUBRESOURCE = ( D3D12_MESSAGE_ID_MAP_UNSUPPORTED_TYPE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_TYPE = ( D3D12_MESSAGE_ID_UNMAP_INVALID_SUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_NULL_POINTER = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_TYPE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SUBRESOURCE = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_NULL_POINTER + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_RESERVED_BITS = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISSING_BIND_FLAGS = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_RESERVED_BITS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_MISC_FLAGS = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISSING_BIND_FLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_MATCHING_STATES = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_MISC_FLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINATION = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_MATCHING_STATES + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_BEFORE_AFTER_MISMATCH = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINATION + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_RESOURCE = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_BEFORE_AFTER_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_SAMPLE_COUNT = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_SAMPLE_COUNT + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINED_FLAGS = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS_FOR_FORMAT = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINED_FLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SPLIT_BARRIER = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS_FOR_FORMAT + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_END = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SPLIT_BARRIER + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_BEGIN = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_END + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAG = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_BEGIN + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMMAND_LIST_TYPE = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAG + 1 ) , + D3D12_MESSAGE_ID_INVALID_SUBRESOURCE_STATE = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMMAND_LIST_TYPE + 1 ) , + D3D12_MESSAGE_ID_INEFFICIENT_PRESENT = ( D3D12_MESSAGE_ID_INVALID_SUBRESOURCE_STATE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CONTENTION = ( D3D12_MESSAGE_ID_INEFFICIENT_PRESENT + 1 ) , + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET = ( D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CONTENTION + 1 ) , + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET_BUNDLE = ( D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CANNOT_RESET = ( D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET_BUNDLE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_OPEN = ( D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CANNOT_RESET + 1 ) , + D3D12_MESSAGE_ID_QUERY_STATE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_OPEN + 1 ) , + D3D12_MESSAGE_ID_INVALID_BUNDLE_API = ( D3D12_MESSAGE_ID_QUERY_STATE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_CLOSED = ( D3D12_MESSAGE_ID_INVALID_BUNDLE_API + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_CLOSED_WITH_INVALID_RESOURCE = ( D3D12_MESSAGE_ID_COMMAND_LIST_CLOSED + 1 ) , + D3D12_MESSAGE_ID_WRONG_COMMAND_ALLOCATOR_TYPE = ( D3D12_MESSAGE_ID_COMMAND_LIST_CLOSED_WITH_INVALID_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_INVALID_INDIRECT_ARGUMENT_BUFFER = ( D3D12_MESSAGE_ID_WRONG_COMMAND_ALLOCATOR_TYPE + 1 ) , + D3D12_MESSAGE_ID_COMPUTE_AND_GRAPHICS_PIPELINE = ( D3D12_MESSAGE_ID_INVALID_INDIRECT_ARGUMENT_BUFFER + 1 ) , + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_SYNC = ( D3D12_MESSAGE_ID_COMPUTE_AND_GRAPHICS_PIPELINE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_SYNC = ( D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_SYNC + 1 ) , + D3D12_MESSAGE_ID_SET_DESCRIPTOR_HEAP_INVALID = ( D3D12_MESSAGE_ID_COMMAND_LIST_SYNC + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUEUE_IMAGE_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_SET_DESCRIPTOR_HEAP_INVALID + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMAND_ALLOCATOR_IMAGE_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_CREATE_QUEUE_IMAGE_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMANDQUEUE = ( D3D12_MESSAGE_ID_CREATE_COMMAND_ALLOCATOR_IMAGE_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMANDALLOCATOR = ( D3D12_MESSAGE_ID_CREATE_COMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_CREATE_PIPELINESTATE = ( D3D12_MESSAGE_ID_CREATE_COMMANDALLOCATOR + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMANDLIST12 = ( D3D12_MESSAGE_ID_CREATE_PIPELINESTATE + 1 ) , + D3D12_MESSAGE_ID_CREATE_IMAGECOMMANDLIST = ( D3D12_MESSAGE_ID_CREATE_COMMANDLIST12 + 1 ) , + D3D12_MESSAGE_ID_CREATE_RESOURCE = ( D3D12_MESSAGE_ID_CREATE_IMAGECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_CREATE_DESCRIPTORHEAP = ( D3D12_MESSAGE_ID_CREATE_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATE_ROOTSIGNATURE = ( D3D12_MESSAGE_ID_CREATE_DESCRIPTORHEAP + 1 ) , + D3D12_MESSAGE_ID_CREATE_LIBRARY = ( D3D12_MESSAGE_ID_CREATE_ROOTSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_CREATE_HEAP = ( D3D12_MESSAGE_ID_CREATE_LIBRARY + 1 ) , + D3D12_MESSAGE_ID_CREATE_MONITOREDFENCE = ( D3D12_MESSAGE_ID_CREATE_HEAP + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUERYHEAP = ( D3D12_MESSAGE_ID_CREATE_MONITOREDFENCE + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMANDSIGNATURE = ( D3D12_MESSAGE_ID_CREATE_QUERYHEAP + 1 ) , + D3D12_MESSAGE_ID_LIVE_COMMANDQUEUE = ( D3D12_MESSAGE_ID_CREATE_COMMANDSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_LIVE_COMMANDALLOCATOR = ( D3D12_MESSAGE_ID_LIVE_COMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_LIVE_PIPELINESTATE = ( D3D12_MESSAGE_ID_LIVE_COMMANDALLOCATOR + 1 ) , + D3D12_MESSAGE_ID_LIVE_COMMANDLIST12 = ( D3D12_MESSAGE_ID_LIVE_PIPELINESTATE + 1 ) , + D3D12_MESSAGE_ID_LIVE_IMAGECOMMANDLIST = ( D3D12_MESSAGE_ID_LIVE_COMMANDLIST12 + 1 ) , + D3D12_MESSAGE_ID_LIVE_RESOURCE = ( D3D12_MESSAGE_ID_LIVE_IMAGECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_LIVE_DESCRIPTORHEAP = ( D3D12_MESSAGE_ID_LIVE_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_LIVE_ROOTSIGNATURE = ( D3D12_MESSAGE_ID_LIVE_DESCRIPTORHEAP + 1 ) , + D3D12_MESSAGE_ID_LIVE_LIBRARY = ( D3D12_MESSAGE_ID_LIVE_ROOTSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_LIVE_HEAP = ( D3D12_MESSAGE_ID_LIVE_LIBRARY + 1 ) , + D3D12_MESSAGE_ID_LIVE_MONITOREDFENCE = ( D3D12_MESSAGE_ID_LIVE_HEAP + 1 ) , + D3D12_MESSAGE_ID_LIVE_QUERYHEAP = ( D3D12_MESSAGE_ID_LIVE_MONITOREDFENCE + 1 ) , + D3D12_MESSAGE_ID_LIVE_COMMANDSIGNATURE = ( D3D12_MESSAGE_ID_LIVE_QUERYHEAP + 1 ) , + D3D12_MESSAGE_ID_DESTROY_COMMANDQUEUE = ( D3D12_MESSAGE_ID_LIVE_COMMANDSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_COMMANDALLOCATOR = ( D3D12_MESSAGE_ID_DESTROY_COMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_PIPELINESTATE = ( D3D12_MESSAGE_ID_DESTROY_COMMANDALLOCATOR + 1 ) , + D3D12_MESSAGE_ID_DESTROY_COMMANDLIST12 = ( D3D12_MESSAGE_ID_DESTROY_PIPELINESTATE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_IMAGECOMMANDLIST = ( D3D12_MESSAGE_ID_DESTROY_COMMANDLIST12 + 1 ) , + D3D12_MESSAGE_ID_DESTROY_RESOURCE = ( D3D12_MESSAGE_ID_DESTROY_IMAGECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_DESTROY_DESCRIPTORHEAP = ( D3D12_MESSAGE_ID_DESTROY_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_ROOTSIGNATURE = ( D3D12_MESSAGE_ID_DESTROY_DESCRIPTORHEAP + 1 ) , + D3D12_MESSAGE_ID_DESTROY_LIBRARY = ( D3D12_MESSAGE_ID_DESTROY_ROOTSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_HEAP = ( D3D12_MESSAGE_ID_DESTROY_LIBRARY + 1 ) , + D3D12_MESSAGE_ID_DESTROY_MONITOREDFENCE = ( D3D12_MESSAGE_ID_DESTROY_HEAP + 1 ) , + D3D12_MESSAGE_ID_DESTROY_QUERYHEAP = ( D3D12_MESSAGE_ID_DESTROY_MONITOREDFENCE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_COMMANDSIGNATURE = ( D3D12_MESSAGE_ID_DESTROY_QUERYHEAP + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDHEAPTYPE = ( D3D12_MESSAGE_ID_DESTROY_COMMANDSIGNATURE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONS = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDHEAPTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDMISCFLAGS = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMISCFLAGS = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_LARGEALLOCATION = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_SMALLALLOCATION = ( D3D12_MESSAGE_ID_CREATERESOURCE_LARGEALLOCATION + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATERESOURCE_SMALLALLOCATION + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDESC = ( D3D12_MESSAGE_ID_CREATERESOURCE_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDINITIALSTATE = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_HAS_PENDING_INITIAL_DATA = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDINITIALSTATE + 1 ) , + D3D12_MESSAGE_ID_POSSIBLY_INVALID_SUBRESOURCE_STATE = ( D3D12_MESSAGE_ID_RESOURCE_HAS_PENDING_INITIAL_DATA + 1 ) , + D3D12_MESSAGE_ID_INVALID_USE_OF_NON_RESIDENT_RESOURCE = ( D3D12_MESSAGE_ID_POSSIBLY_INVALID_SUBRESOURCE_STATE + 1 ) , + D3D12_MESSAGE_ID_POSSIBLE_INVALID_USE_OF_NON_RESIDENT_RESOURCE = ( D3D12_MESSAGE_ID_INVALID_USE_OF_NON_RESIDENT_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_BUNDLE_PIPELINE_STATE_MISMATCH = ( D3D12_MESSAGE_ID_POSSIBLE_INVALID_USE_OF_NON_RESIDENT_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_PRIMITIVE_TOPOLOGY_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_BUNDLE_PIPELINE_STATE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_NUMBER_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_PRIMITIVE_TOPOLOGY_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_NUMBER_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_DEPTH_STENCIL_FORMAT_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_SAMPLE_DESC_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = ( D3D12_MESSAGE_ID_DEPTH_STENCIL_FORMAT_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_NUMBER_MISMATCH_BUNDLE_PIPELINE_STATE = ( D3D12_MESSAGE_ID_DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_BUNDLE_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_NUMBER_MISMATCH_BUNDLE_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_RENDER_TARGET_SAMPLE_DESC_MISMATCH_BUNDLE_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_BUNDLE_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_DEPTH_STENCIL_FORMAT_MISMATCH_BUNDLE_PIPELINE_STATE = ( D3D12_MESSAGE_ID_RENDER_TARGET_SAMPLE_DESC_MISMATCH_BUNDLE_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_BUNDLE_PIPELINE_STATE = ( D3D12_MESSAGE_ID_DEPTH_STENCIL_FORMAT_MISMATCH_BUNDLE_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_CREATESHADER_INVALIDBYTECODE = ( D3D12_MESSAGE_ID_DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_BUNDLE_PIPELINE_STATE + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_NULLDESC = ( D3D12_MESSAGE_ID_CREATESHADER_INVALIDBYTECODE + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_INVALIDSIZE = ( D3D12_MESSAGE_ID_CREATEHEAP_NULLDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDHEAPTYPE = ( D3D12_MESSAGE_ID_CREATEHEAP_INVALIDSIZE + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = ( D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDHEAPTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMEMORYPOOL = ( D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_INVALIDPROPERTIES = ( D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMEMORYPOOL + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_INVALIDALIGNMENT = ( D3D12_MESSAGE_ID_CREATEHEAP_INVALIDPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMISCFLAGS = ( D3D12_MESSAGE_ID_CREATEHEAP_INVALIDALIGNMENT + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_INVALIDMISCFLAGS = ( D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATEHEAP_INVALIDMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATEHEAP_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATEHEAP_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAPPROPERTIES = ( D3D12_MESSAGE_ID_CREATEHEAP_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPTYPE = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAPPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDMEMORYPOOL = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPPROPERTIES = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDMEMORYPOOL + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPMISCFLAGS = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_UNRECOGNIZEDHEAPTYPE = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_INVALIDHEAPTYPE = ( D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_UNRECOGNIZEDHEAPTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_INVALID_DESC = ( D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_INVALIDHEAPTYPE + 1 ) , + D3D12_MESSAGE_ID_INVALID_DESCRIPTOR_HANDLE = ( D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_INVALID_DESC + 1 ) , + D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALID_CONSERVATIVERASTERMODE = ( D3D12_MESSAGE_ID_INVALID_DESCRIPTOR_HANDLE + 1 ) , + D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_SYSTEMVALUE = ( D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALID_CONSERVATIVERASTERMODE + 1 ) , + D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_RESOURCE = ( D3D12_MESSAGE_ID_DEVICE_DRAW_INVALID_SYSTEMVALUE + 1 ) , + D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_DESC = ( D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_LARGE_OFFSET = ( D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_DESC + 1 ) , + D3D12_MESSAGE_ID_CREATE_UNORDEREDACCESS_VIEW_INVALID_COUNTER_USAGE = ( D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_LARGE_OFFSET + 1 ) , + D3D12_MESSAGE_ID_COPY_DESCRIPTORS_INVALID_RANGES = ( D3D12_MESSAGE_ID_CREATE_UNORDEREDACCESS_VIEW_INVALID_COUNTER_USAGE + 1 ) , + D3D12_MESSAGE_ID_COPY_DESCRIPTORS_WRITE_ONLY_DESCRIPTOR = ( D3D12_MESSAGE_ID_COPY_DESCRIPTORS_INVALID_RANGES + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RTV_FORMAT_NOT_UNKNOWN = ( D3D12_MESSAGE_ID_COPY_DESCRIPTORS_WRITE_ONLY_DESCRIPTOR + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_RENDER_TARGET_COUNT = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RTV_FORMAT_NOT_UNKNOWN + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VERTEX_SHADER_NOT_SET = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_RENDER_TARGET_COUNT + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_NOT_SET = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VERTEX_SHADER_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_HS_DS_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERINDEX = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_HS_DS_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_COMPONENTTYPE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERMASK = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_COMPONENTTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SYSTEMVALUE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERMASK + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SYSTEMVALUE + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_MINPRECISION = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_MINPRECISION + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_XOR_DS_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_XOR_DS_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_CONTROL_POINT_COUNT_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_TESSELLATOR_DOMAIN_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_CONTROL_POINT_COUNT_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_TESSELLATOR_DOMAIN_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_FORCED_SAMPLE_COUNT = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_PRIMITIVETOPOLOGY = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_FORCED_SAMPLE_COUNT + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SYSTEMVALUE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_PRIMITIVETOPOLOGY + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SYSTEMVALUE + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DEPTHSTENCILVIEW_NOT_SET = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_INPUT_PRIMITIVE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DEPTHSTENCILVIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_POSITION_NOT_PRESENT = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_INPUT_PRIMITIVE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE_FLAGS = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_POSITION_NOT_PRESENT + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_INDEX_BUFFER_PROPERTIES = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE_FLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_INDEX_BUFFER_PROPERTIES + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_EXECUTE_BUNDLE_OPEN_BUNDLE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE + 1 ) , + D3D12_MESSAGE_ID_EXECUTE_BUNDLE_DESCRIPTOR_HEAP_MISMATCH = ( D3D12_MESSAGE_ID_EXECUTE_BUNDLE_OPEN_BUNDLE + 1 ) , + D3D12_MESSAGE_ID_EXECUTE_BUNDLE_TYPE = ( D3D12_MESSAGE_ID_EXECUTE_BUNDLE_DESCRIPTOR_HEAP_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_DRAW_EMPTY_SCISSOR_RECTANGLE = ( D3D12_MESSAGE_ID_EXECUTE_BUNDLE_TYPE + 1 ) , + D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_BLOB_NOT_FOUND = ( D3D12_MESSAGE_ID_DRAW_EMPTY_SCISSOR_RECTANGLE + 1 ) , + D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_DESERIALIZE_FAILED = ( D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_BLOB_NOT_FOUND + 1 ) , + D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_INVALID_CONFIGURATION = ( D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_DESERIALIZE_FAILED + 1 ) , + D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_NOT_SUPPORTED_ON_DEVICE = ( D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_INVALID_CONFIGURATION + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLRESOURCEPROPERTIES = ( D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_NOT_SUPPORTED_ON_DEVICE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAP = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLRESOURCEPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_GETRESOURCEALLOCATIONINFO_INVALIDRDESCS = ( D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAP + 1 ) , + D3D12_MESSAGE_ID_MAKERESIDENT_NULLOBJECTARRAY = ( D3D12_MESSAGE_ID_GETRESOURCEALLOCATIONINFO_INVALIDRDESCS + 1 ) , + D3D12_MESSAGE_ID_MAKERESIDENT_INVALIDOBJECT = ( D3D12_MESSAGE_ID_MAKERESIDENT_NULLOBJECTARRAY + 1 ) , + D3D12_MESSAGE_ID_EVICT_NULLOBJECTARRAY = ( D3D12_MESSAGE_ID_MAKERESIDENT_INVALIDOBJECT + 1 ) , + D3D12_MESSAGE_ID_EVICT_INVALIDOBJECT = ( D3D12_MESSAGE_ID_EVICT_NULLOBJECTARRAY + 1 ) , + D3D12_MESSAGE_ID_HEAPS_UNSUPPORTED = ( D3D12_MESSAGE_ID_EVICT_INVALIDOBJECT + 1 ) , + D3D12_MESSAGE_ID_SET_DESCRIPTOR_TABLE_INVALID = ( D3D12_MESSAGE_ID_HEAPS_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_INVALID = ( D3D12_MESSAGE_ID_SET_DESCRIPTOR_TABLE_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_BUFFER_VIEW_INVALID = ( D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_ROOT_SHADER_RESOURCE_VIEW_INVALID = ( D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_BUFFER_VIEW_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_ROOT_UNORDERED_ACCESS_VIEW_INVALID = ( D3D12_MESSAGE_ID_SET_ROOT_SHADER_RESOURCE_VIEW_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID_DESC = ( D3D12_MESSAGE_ID_SET_ROOT_UNORDERED_ACCESS_VIEW_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_LARGE_OFFSET = ( D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID_DESC + 1 ) , + D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID_DESC = ( D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_LARGE_OFFSET + 1 ) , + D3D12_MESSAGE_ID_SET_INDEX_BUFFER_LARGE_OFFSET = ( D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID_DESC + 1 ) , + D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID_DESC = ( D3D12_MESSAGE_ID_SET_INDEX_BUFFER_LARGE_OFFSET + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDDIMENSIONALITY = ( D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID_DESC + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDLAYOUT = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDDIMENSIONALITY + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONALITY = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDLAYOUT + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDALIGNMENT = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONALITY + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMIPLEVELS = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDALIGNMENT + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDSAMPLEDESC = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMIPLEVELS + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDLAYOUT = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDSAMPLEDESC + 1 ) , + D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDLAYOUT + 1 ) , + D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID = ( D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID = ( D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID + 1 ) , + D3D12_MESSAGE_ID_SET_RENDER_TARGETS_INVALID = ( D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID + 1 ) , + D3D12_MESSAGE_ID_CREATEQUERY_HEAP_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_SET_RENDER_TARGETS_INVALID + 1 ) , + D3D12_MESSAGE_ID_CREATEQUERY_HEAP_JPEG_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_CREATEQUERY_HEAP_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_BEGIN_END_QUERY_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_CREATEQUERY_HEAP_JPEG_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CLOSE_COMMAND_LIST_OPEN_QUERY = ( D3D12_MESSAGE_ID_BEGIN_END_QUERY_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_RESOLVE_QUERY_DATA_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_CLOSE_COMMAND_LIST_OPEN_QUERY + 1 ) , + D3D12_MESSAGE_ID_SET_PREDICATION_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_RESOLVE_QUERY_DATA_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_TIMESTAMPS_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_SET_PREDICATION_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_UNSTABLE_POWER_STATE = ( D3D12_MESSAGE_ID_TIMESTAMPS_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDFORMAT = ( D3D12_MESSAGE_ID_UNSTABLE_POWER_STATE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDSUBRESOURCERANGE = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDBASEOFFSET = ( D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDSUBRESOURCERANGE + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_HEAP = ( D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDBASEOFFSET + 1 ) , + D3D12_MESSAGE_ID_CREATE_SAMPLER_INVALID = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_HEAP + 1 ) , + D3D12_MESSAGE_ID_CREATECOMMANDSIGNATURE_INVALID = ( D3D12_MESSAGE_ID_CREATE_SAMPLER_INVALID + 1 ) , + D3D12_MESSAGE_ID_EXECUTE_INDIRECT_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_CREATECOMMANDSIGNATURE_INVALID + 1 ) , + D3D12_MESSAGE_ID_GETGPUVIRTUALADDRESS_INVALID_RESOURCE_DIMENSION = ( D3D12_MESSAGE_ID_EXECUTE_INDIRECT_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDPLANEINDEX = ( D3D12_MESSAGE_ID_GETGPUVIRTUALADDRESS_INVALID_RESOURCE_DIMENSION + 4 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_AMBIGUOUSVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDPLANEINDEX = ( D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_AMBIGUOUSVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_AMBIGUOUSVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDPLANEINDEX = ( D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_AMBIGUOUSVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_AMBIGUOUSVIDEOPLANEINDEX = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSCANDATAOFFSET = ( D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_AMBIGUOUSVIDEOPLANEINDEX + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_NOTSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSCANDATAOFFSET + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_DIMENSIONSTOOLARGE = ( D3D12_MESSAGE_ID_JPEGDECODE_NOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDCOMPONENTS = ( D3D12_MESSAGE_ID_JPEGDECODE_DIMENSIONSTOOLARGE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDCOMPONENTS = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDCOMPONENTS + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_DESTINATIONNOT2D = ( D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDCOMPONENTS + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_TILEDRESOURCESUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_DESTINATIONNOT2D + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_GUARDRECTSUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_TILEDRESOURCESUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_FORMATUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_GUARDRECTSUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_JPEGDECODE_FORMATUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDMIPLEVEL = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_EMPTYDESTBOX = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDMIPLEVEL + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXNOT2D = ( D3D12_MESSAGE_ID_JPEGDECODE_EMPTYDESTBOX + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXNOTSUB = ( D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXNOT2D + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXESINTERSECT = ( D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXNOTSUB + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_XSUBSAMPLEMISMATCH = ( D3D12_MESSAGE_ID_JPEGDECODE_DESTBOXESINTERSECT + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_YSUBSAMPLEMISMATCH = ( D3D12_MESSAGE_ID_JPEGDECODE_XSUBSAMPLEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_XSUBSAMPLEODD = ( D3D12_MESSAGE_ID_JPEGDECODE_YSUBSAMPLEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_YSUBSAMPLEODD = ( D3D12_MESSAGE_ID_JPEGDECODE_XSUBSAMPLEODD + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UPSCALEUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_YSUBSAMPLEODD + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_TIER4DOWNSCALETOLARGE = ( D3D12_MESSAGE_ID_JPEGDECODE_UPSCALEUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_TIER3DOWNSCALEUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_TIER4DOWNSCALETOLARGE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_CHROMASIZEMISMATCH = ( D3D12_MESSAGE_ID_JPEGDECODE_TIER3DOWNSCALEUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_LUMACHROMASIZEMISMATCH = ( D3D12_MESSAGE_ID_JPEGDECODE_CHROMASIZEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDNUMDESTINATIONS = ( D3D12_MESSAGE_ID_JPEGDECODE_LUMACHROMASIZEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_SUBBOXUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDNUMDESTINATIONS + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_1DESTUNSUPPORTEDFORMAT = ( D3D12_MESSAGE_ID_JPEGDECODE_SUBBOXUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_3DESTUNSUPPORTEDFORMAT = ( D3D12_MESSAGE_ID_JPEGDECODE_1DESTUNSUPPORTEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_SCALEUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_3DESTUNSUPPORTEDFORMAT + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSOURCESIZE = ( D3D12_MESSAGE_ID_JPEGDECODE_SCALEUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_INVALIDCOPYFLAGS = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDSOURCESIZE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_HAZARD = ( D3D12_MESSAGE_ID_JPEGDECODE_INVALIDCOPYFLAGS + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDSRCBUFFERUSAGE = ( D3D12_MESSAGE_ID_JPEGDECODE_HAZARD + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDSRCBUFFERMISCFLAGS = ( D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDSRCBUFFERUSAGE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDDSTTEXTUREUSAGE = ( D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDSRCBUFFERMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_BACKBUFFERNOTSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDDSTTEXTUREUSAGE + 1 ) , + D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDCOPYFLAGS = ( D3D12_MESSAGE_ID_JPEGDECODE_BACKBUFFERNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_NOTSUPPORTED = ( D3D12_MESSAGE_ID_JPEGDECODE_UNSUPPORTEDCOPYFLAGS + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_INVALIDSCANDATAOFFSET = ( D3D12_MESSAGE_ID_JPEGENCODE_NOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_INVALIDCOMPONENTS = ( D3D12_MESSAGE_ID_JPEGENCODE_INVALIDSCANDATAOFFSET + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_SOURCENOT2D = ( D3D12_MESSAGE_ID_JPEGENCODE_INVALIDCOMPONENTS + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_TILEDRESOURCESUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGENCODE_SOURCENOT2D + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_GUARDRECTSUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGENCODE_TILEDRESOURCESUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_XSUBSAMPLEMISMATCH = ( D3D12_MESSAGE_ID_JPEGENCODE_GUARDRECTSUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_YSUBSAMPLEMISMATCH = ( D3D12_MESSAGE_ID_JPEGENCODE_XSUBSAMPLEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDCOMPONENTS = ( D3D12_MESSAGE_ID_JPEGENCODE_YSUBSAMPLEMISMATCH + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_FORMATUNSUPPORTED = ( D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDCOMPONENTS + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_JPEGENCODE_FORMATUNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_INVALIDMIPLEVEL = ( D3D12_MESSAGE_ID_JPEGENCODE_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_DIMENSIONSTOOLARGE = ( D3D12_MESSAGE_ID_JPEGENCODE_INVALIDMIPLEVEL + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_HAZARD = ( D3D12_MESSAGE_ID_JPEGENCODE_DIMENSIONSTOOLARGE + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDDSTBUFFERUSAGE = ( D3D12_MESSAGE_ID_JPEGENCODE_HAZARD + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDDSTBUFFERMISCFLAGS = ( D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDDSTBUFFERUSAGE + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDSRCTEXTUREUSAGE = ( D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDDSTBUFFERMISCFLAGS + 1 ) , + D3D12_MESSAGE_ID_JPEGENCODE_BACKBUFFERNOTSUPPORTED = ( D3D12_MESSAGE_ID_JPEGENCODE_UNSUPPORTEDSRCTEXTUREUSAGE + 1 ) , + D3D12_MESSAGE_ID_CREATEQUERYORPREDICATE_UNSUPPORTEDCONTEXTTYPEFORQUERY = ( D3D12_MESSAGE_ID_JPEGENCODE_BACKBUFFERNOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_FLUSH1_INVALIDCONTEXTTYPE = ( D3D12_MESSAGE_ID_CREATEQUERYORPREDICATE_UNSUPPORTEDCONTEXTTYPEFORQUERY + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUE = ( D3D12_MESSAGE_ID_FLUSH1_INVALIDCONTEXTTYPE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDCLEARVALUEFORMAT = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUE + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUEFORMAT = ( D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDCLEARVALUEFORMAT + 1 ) , + D3D12_MESSAGE_ID_CREATERESOURCE_CLEARVALUEDENORMFLUSH = ( D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUEFORMAT + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALIDDEPTH = ( D3D12_MESSAGE_ID_CREATERESOURCE_CLEARVALUEDENORMFLUSH + 1 ) , + D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALIDDEPTH + 1 ) , + D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE = ( D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDHEAP = ( D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALIDHEAP = ( D3D12_MESSAGE_ID_MAP_INVALIDHEAP + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_UNMAP_INVALIDHEAP + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_MAP_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_UNMAP_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_MAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDRANGE = ( D3D12_MESSAGE_ID_UNMAP_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALIDRANGE = ( D3D12_MESSAGE_ID_MAP_INVALIDRANGE + 1 ) , + D3D12_MESSAGE_ID_MAP_NULLRANGE = ( D3D12_MESSAGE_ID_UNMAP_INVALIDRANGE + 1 ) , + D3D12_MESSAGE_ID_UNMAP_NULLRANGE = ( D3D12_MESSAGE_ID_MAP_NULLRANGE + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDDATAPOINTER = ( D3D12_MESSAGE_ID_UNMAP_NULLRANGE + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALIDARG_RETURN = ( D3D12_MESSAGE_ID_MAP_INVALIDDATAPOINTER + 1 ) , + D3D12_MESSAGE_ID_MAP_OUTOFMEMORY_RETURN = ( D3D12_MESSAGE_ID_MAP_INVALIDARG_RETURN + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_BUNDLENOTSUPPORTED = ( D3D12_MESSAGE_ID_MAP_OUTOFMEMORY_RETURN + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_COMMANDLISTMISMATCH = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_BUNDLENOTSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_OPENCOMMANDLIST = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_COMMANDLISTMISMATCH + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_FAILEDCOMMANDLIST = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_OPENCOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLDST = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_FAILEDCOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDDSTRESOURCEDIMENSION = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLDST + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_DSTRANGEOUTOFBOUNDS = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDDSTRESOURCEDIMENSION + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLSRC = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_DSTRANGEOUTOFBOUNDS + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDSRCRESOURCEDIMENSION = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLSRC + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_SRCRANGEOUTOFBOUNDS = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDSRCRESOURCEDIMENSION + 1 ) , + D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDCOPYFLAGS = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_SRCRANGEOUTOFBOUNDS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLDST = ( D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDCOPYFLAGS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTTYPE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLDST + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCEDIMENSION = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTTYPE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCEDIMENSION + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTSUBRESOURCE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTOFFSET = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTOFFSET + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDIMENSIONS = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTROWPITCH = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTPLACEMENT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTROWPITCH + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDSPLACEDFOOTPRINTFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTPLACEMENT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_DSTREGIONOUTOFBOUNDS = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDSPLACEDFOOTPRINTFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLSRC = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_DSTREGIONOUTOFBOUNDS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCTYPE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLSRC + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCEDIMENSION = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCTYPE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCEDIMENSION + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCSUBRESOURCE = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCOFFSET = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCOFFSET + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDIMENSIONS = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCROWPITCH = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDIMENSIONS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCPLACEMENT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCROWPITCH + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDSPLACEDFOOTPRINTFORMAT = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCPLACEMENT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_SRCREGIONOUTOFBOUNDS = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDSPLACEDFOOTPRINTFORMAT + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTCOORDINATES = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_SRCREGIONOUTOFBOUNDS + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCBOX = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTCOORDINATES + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_FORMATMISMATCH = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCBOX + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_EMPTYBOX = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_FORMATMISMATCH + 1 ) , + D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDCOPYFLAGS = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_EMPTYBOX + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SUBRESOURCE_INDEX = ( D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDCOPYFLAGS + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_FORMAT = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SUBRESOURCE_INDEX + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_MISMATCH = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_FORMAT + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SAMPLE_COUNT = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_INVALID_SHADER = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SAMPLE_COUNT + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_CS_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_INVALID_SHADER + 1 ) , + D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_MISSING_ROOT_SIGNATURE = ( D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_CS_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALIDCACHEDBLOB = ( D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_MISSING_ROOT_SIGNATURE + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBADAPTERMISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALIDCACHEDBLOB + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDRIVERVERSIONMISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBADAPTERMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDESCMISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDRIVERVERSIONMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBIGNORED = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDESCMISMATCH + 1 ) , + D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDHEAP = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBIGNORED + 1 ) , + D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDHEAP + 1 ) , + D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDBOX = ( D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDBOX + 1 ) , + D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_EMPTYBOX = ( D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDHEAP = ( D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_EMPTYBOX + 1 ) , + D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDHEAP + 1 ) , + D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDBOX = ( D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDSUBRESOURCE = ( D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDBOX + 1 ) , + D3D12_MESSAGE_ID_READFROMSUBRESOURCE_EMPTYBOX = ( D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDSUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_TOO_MANY_NODES_SPECIFIED = ( D3D12_MESSAGE_ID_READFROMSUBRESOURCE_EMPTYBOX + 1 ) , + D3D12_MESSAGE_ID_INVALID_NODE_INDEX = ( D3D12_MESSAGE_ID_TOO_MANY_NODES_SPECIFIED + 1 ) , + D3D12_MESSAGE_ID_GETHEAPPROPERTIES_INVALIDRESOURCE = ( D3D12_MESSAGE_ID_INVALID_NODE_INDEX + 1 ) , + D3D12_MESSAGE_ID_NODE_MASK_MISMATCH = ( D3D12_MESSAGE_ID_GETHEAPPROPERTIES_INVALIDRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_OUTOFMEMORY = ( D3D12_MESSAGE_ID_NODE_MASK_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES = ( D3D12_MESSAGE_ID_COMMAND_LIST_OUTOFMEMORY + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_TOO_MANY_SWAPCHAIN_REFERENCES = ( D3D12_MESSAGE_ID_COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES + 1 ) , + D3D12_MESSAGE_ID_COMMAND_QUEUE_TOO_MANY_SWAPCHAIN_REFERENCES = ( D3D12_MESSAGE_ID_COMMAND_LIST_TOO_MANY_SWAPCHAIN_REFERENCES + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE = ( D3D12_MESSAGE_ID_COMMAND_QUEUE_TOO_MANY_SWAPCHAIN_REFERENCES + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_SETRENDERTARGETS_INVALIDNUMRENDERTARGETS = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_TYPE = ( D3D12_MESSAGE_ID_COMMAND_LIST_SETRENDERTARGETS_INVALIDNUMRENDERTARGETS + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_FLAGS = ( D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_TYPE + 1 ) , + D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFLAGS = ( D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_FLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFORMAT = ( D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATESHAREDHEAP_INVALIDFLAGS = ( D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFORMAT + 1 ) , + D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_UNRECOGNIZEDPROPERTIES = ( D3D12_MESSAGE_ID_CREATESHAREDHEAP_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDSIZE = ( D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_UNRECOGNIZEDPROPERTIES + 1 ) , + D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDOBJECT = ( D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDSIZE + 1 ) , + D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDOBJECT = ( D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDOBJECT + 1 ) , + D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDKEY = ( D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDOBJECT + 1 ) , + D3D12_MESSAGE_ID_KEYEDMUTEX_WRONGSTATE = ( D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDKEY + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_PRIORITY = ( D3D12_MESSAGE_ID_KEYEDMUTEX_WRONGSTATE + 1 ) , + D3D12_MESSAGE_ID_OBJECT_DELETED_WHILE_STILL_IN_USE = ( D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_PRIORITY + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_FLAGS = ( D3D12_MESSAGE_ID_OBJECT_DELETED_WHILE_STILL_IN_USE + 1 ) , + D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_FLAGS + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RENDER_TARGET_DELETED = ( D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_ALL_RENDER_TARGETS_HAVE_UNKNOWN_FORMAT = ( D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RENDER_TARGET_DELETED + 1 ) , + D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_ALL_RENDER_TARGETS_HAVE_UNKNOWN_FORMAT + 1 ) , + D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_GPU_WRITTEN_READBACK_RESOURCE_MAPPED = ( D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS + 1 ) , + D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_NEEDED = ( D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_GPU_WRITTEN_READBACK_RESOURCE_MAPPED + 1 ) , + D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_EMPTY = ( D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_NEEDED + 1 ) , + D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE = ( D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_EMPTY + 1 ) , + D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE = ( D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE + 1 ) , + D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT = ( D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE + 1 ) , + D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT = ( D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC + 1 ) , + D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET = ( D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_ZERO_BARRIERS = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_BEGIN_END_EVENT_MISMATCH = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_ZERO_BARRIERS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_POSSIBLE_BEFORE_AFTER_MISMATCH = ( D3D12_MESSAGE_ID_BEGIN_END_EVENT_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_BEGIN_END = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_POSSIBLE_BEFORE_AFTER_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INVALID_RESOURCE = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_BEGIN_END + 1 ) , + D3D12_MESSAGE_ID_USE_OF_ZERO_REFCOUNT_OBJECT = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INVALID_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_OBJECT_EVICTED_WHILE_STILL_IN_USE = ( D3D12_MESSAGE_ID_USE_OF_ZERO_REFCOUNT_OBJECT + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_DESCRIPTOR_ACCESS_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_OBJECT_EVICTED_WHILE_STILL_IN_USE + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_INVALIDLIBRARYBLOB = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_DESCRIPTOR_ACCESS_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_DRIVERVERSIONMISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_INVALIDLIBRARYBLOB + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_ADAPTERVERSIONMISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_DRIVERVERSIONMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_UNSUPPORTED = ( D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_ADAPTERVERSIONMISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATE_PIPELINELIBRARY = ( D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_LIVE_PIPELINELIBRARY = ( D3D12_MESSAGE_ID_CREATE_PIPELINELIBRARY + 1 ) , + D3D12_MESSAGE_ID_DESTROY_PIPELINELIBRARY = ( D3D12_MESSAGE_ID_LIVE_PIPELINELIBRARY + 1 ) , + D3D12_MESSAGE_ID_STOREPIPELINE_NONAME = ( D3D12_MESSAGE_ID_DESTROY_PIPELINELIBRARY + 1 ) , + D3D12_MESSAGE_ID_STOREPIPELINE_DUPLICATENAME = ( D3D12_MESSAGE_ID_STOREPIPELINE_NONAME + 1 ) , + D3D12_MESSAGE_ID_LOADPIPELINE_NAMENOTFOUND = ( D3D12_MESSAGE_ID_STOREPIPELINE_DUPLICATENAME + 1 ) , + D3D12_MESSAGE_ID_LOADPIPELINE_INVALIDDESC = ( D3D12_MESSAGE_ID_LOADPIPELINE_NAMENOTFOUND + 1 ) , + D3D12_MESSAGE_ID_PIPELINELIBRARY_SERIALIZE_NOTENOUGHMEMORY = ( D3D12_MESSAGE_ID_LOADPIPELINE_INVALIDDESC + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_RT_OUTPUT_MISMATCH = ( D3D12_MESSAGE_ID_PIPELINELIBRARY_SERIALIZE_NOTENOUGHMEMORY + 1 ) , + D3D12_MESSAGE_ID_SETEVENTONMULTIPLEFENCECOMPLETION_INVALIDFLAGS = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_RT_OUTPUT_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATE_QUEUE_VIDEO_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_SETEVENTONMULTIPLEFENCECOMPLETION_INVALIDFLAGS + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMAND_ALLOCATOR_VIDEO_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_CREATE_QUEUE_VIDEO_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATEQUERY_HEAP_VIDEO_DECODE_STATISTICS_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_CREATE_COMMAND_ALLOCATOR_VIDEO_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDLIST = ( D3D12_MESSAGE_ID_CREATEQUERY_HEAP_VIDEO_DECODE_STATISTICS_NOT_SUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEODECODER = ( D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEODECODESTREAM = ( D3D12_MESSAGE_ID_CREATE_VIDEODECODER + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDLIST = ( D3D12_MESSAGE_ID_CREATE_VIDEODECODESTREAM + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEODECODER = ( D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEODECODESTREAM = ( D3D12_MESSAGE_ID_LIVE_VIDEODECODER + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDLIST = ( D3D12_MESSAGE_ID_LIVE_VIDEODECODESTREAM + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEODECODER = ( D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEODECODESTREAM = ( D3D12_MESSAGE_ID_DESTROY_VIDEODECODER + 1 ) , + D3D12_MESSAGE_ID_DECODE_FRAME_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_DESTROY_VIDEODECODESTREAM + 1 ) , + D3D12_MESSAGE_ID_DEPRECATED_API = ( D3D12_MESSAGE_ID_DECODE_FRAME_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE = ( D3D12_MESSAGE_ID_DEPRECATED_API + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_DESCRIPTOR_TABLE_NOT_SET = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_CONSTANT_BUFFER_VIEW_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_DESCRIPTOR_TABLE_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_SHADER_RESOURCE_VIEW_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_CONSTANT_BUFFER_VIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_UNORDERED_ACCESS_VIEW_NOT_SET = ( D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_SHADER_RESOURCE_VIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DISCARD_INVALID_SUBRESOURCE_RANGE = ( D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_UNORDERED_ACCESS_VIEW_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_DISCARD_ONE_SUBRESOURCE_FOR_MIPS_WITH_RECTS = ( D3D12_MESSAGE_ID_DISCARD_INVALID_SUBRESOURCE_RANGE + 1 ) , + D3D12_MESSAGE_ID_DISCARD_NO_RECTS_FOR_NON_TEXTURE2D = ( D3D12_MESSAGE_ID_DISCARD_ONE_SUBRESOURCE_FOR_MIPS_WITH_RECTS + 1 ) , + D3D12_MESSAGE_ID_COPY_ON_SAME_SUBRESOURCE = ( D3D12_MESSAGE_ID_DISCARD_NO_RECTS_FOR_NON_TEXTURE2D + 1 ) , + D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PAGEABLE = ( D3D12_MESSAGE_ID_COPY_ON_SAME_SUBRESOURCE + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UNSUPPORTED = ( D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PAGEABLE + 1 ) , + D3D12_MESSAGE_ID_STATIC_DESCRIPTOR_INVALID_DESCRIPTOR_CHANGE = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_DATA_STATIC_DESCRIPTOR_INVALID_DATA_CHANGE = ( D3D12_MESSAGE_ID_STATIC_DESCRIPTOR_INVALID_DESCRIPTOR_CHANGE + 1 ) , + D3D12_MESSAGE_ID_DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE = ( D3D12_MESSAGE_ID_DATA_STATIC_DESCRIPTOR_INVALID_DATA_CHANGE + 1 ) , + D3D12_MESSAGE_ID_EXECUTE_BUNDLE_STATIC_DESCRIPTOR_DATA_STATIC_NOT_SET = ( D3D12_MESSAGE_ID_DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_ACCESS_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_EXECUTE_BUNDLE_STATIC_DESCRIPTOR_DATA_STATIC_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SAMPLER_MODE_MISMATCH = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_ACCESS_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_CREATE_FENCE_INVALID_FLAGS = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SAMPLER_MODE_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_RESOURCE_BARRIER_DUPLICATE_SUBRESOURCE_TRANSITIONS = ( D3D12_MESSAGE_ID_CREATE_FENCE_INVALID_FLAGS + 1 ) , + D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PRIORITY = ( D3D12_MESSAGE_ID_RESOURCE_BARRIER_DUPLICATE_SUBRESOURCE_TRANSITIONS + 1 ) , + D3D12_MESSAGE_ID_CREATE_PASS = ( D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PRIORITY + 1 ) , + D3D12_MESSAGE_ID_DESTROY_PASS = ( D3D12_MESSAGE_ID_CREATE_PASS + 1 ) , + D3D12_MESSAGE_ID_LIVE_PASS = ( D3D12_MESSAGE_ID_DESTROY_PASS + 1 ) , + D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_LARGE_NUM_DESCRIPTORS = ( D3D12_MESSAGE_ID_LIVE_PASS + 1 ) , + D3D12_MESSAGE_ID_BEGIN_EVENT = ( D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_LARGE_NUM_DESCRIPTORS + 1 ) , + D3D12_MESSAGE_ID_END_EVENT = ( D3D12_MESSAGE_ID_BEGIN_EVENT + 1 ) , + D3D12_MESSAGE_ID_CREATEDEVICE_DEBUG_LAYER_STARTUP_OPTIONS = ( D3D12_MESSAGE_ID_END_EVENT + 1 ) , + D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_DEPTHBOUNDSTEST_UNSUPPORTED = ( D3D12_MESSAGE_ID_CREATEDEVICE_DEBUG_LAYER_STARTUP_OPTIONS + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_DUPLICATE_SUBOBJECT = ( D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_DEPTHBOUNDSTEST_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_UNKNOWN_SUBOBJECT = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_DUPLICATE_SUBOBJECT + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_ZERO_SIZE_STREAM = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_UNKNOWN_SUBOBJECT + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_STREAM = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_ZERO_SIZE_STREAM + 1 ) , + D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CANNOT_DEDUCE_TYPE = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_STREAM + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_STATIC_DESCRIPTOR_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CANNOT_DEDUCE_TYPE + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_PRIVILEGE_FOR_GLOBAL_REALTIME = ( D3D12_MESSAGE_ID_COMMAND_LIST_STATIC_DESCRIPTOR_RESOURCE_DIMENSION_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_HARDWARE_SUPPORT_FOR_GLOBAL_REALTIME = ( D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_PRIVILEGE_FOR_GLOBAL_REALTIME + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_ARCHITECTURE = ( D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_HARDWARE_SUPPORT_FOR_GLOBAL_REALTIME + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DST = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_ARCHITECTURE + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DST_RESOURCE_DIMENSION = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DST + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DST_RANGE_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DST_RESOURCE_DIMENSION + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_SRC = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DST_RANGE_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE_DIMENSION = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_SRC + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_SRC_RANGE_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE_DIMENSION + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_OFFSET_ALIGNMENT = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_SRC_RANGE_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_RESOURCES = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_OFFSET_ALIGNMENT + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_SUBRESOURCE_RANGES = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_RESOURCES + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_RESOURCE = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_SUBRESOURCE_RANGES + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_SUBRESOURCE_RANGE = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_SUBRESOURCE_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_SUBRESOURCE_RANGE + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_RANGE_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_SUBRESOURCE_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_ZERO_DEPENDENCIES = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_RANGE_OUT_OF_BOUNDS + 1 ) , + D3D12_MESSAGE_ID_DEVICE_CREATE_SHARED_HANDLE_INVALIDARG = ( D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_ZERO_DEPENDENCIES + 1 ) , + D3D12_MESSAGE_ID_DESCRIPTOR_HANDLE_WITH_INVALID_RESOURCE = ( D3D12_MESSAGE_ID_DEVICE_CREATE_SHARED_HANDLE_INVALIDARG + 1 ) , + D3D12_MESSAGE_ID_SETDEPTHBOUNDS_INVALIDARGS = ( D3D12_MESSAGE_ID_DESCRIPTOR_HANDLE_WITH_INVALID_RESOURCE + 1 ) , + D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_STATE_IMPRECISE = ( D3D12_MESSAGE_ID_SETDEPTHBOUNDS_INVALIDARGS + 1 ) , + D3D12_MESSAGE_ID_COMMAND_LIST_PIPELINE_STATE_NOT_SET = ( D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_STATE_IMPRECISE + 1 ) , + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_MODEL_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_PIPELINE_STATE_NOT_SET + 1 ) , + D3D12_MESSAGE_ID_OBJECT_ACCESSED_WHILE_STILL_IN_USE = ( D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_MODEL_MISMATCH + 1 ) , + D3D12_MESSAGE_ID_PROGRAMMABLE_MSAA_UNSUPPORTED = ( D3D12_MESSAGE_ID_OBJECT_ACCESSED_WHILE_STILL_IN_USE + 1 ) , + D3D12_MESSAGE_ID_SETSAMPLEPOSITIONS_INVALIDARGS = ( D3D12_MESSAGE_ID_PROGRAMMABLE_MSAA_UNSUPPORTED + 1 ) , + D3D12_MESSAGE_ID_RESOLVESUBRESOURCEREGION_INVALID_RECT = ( D3D12_MESSAGE_ID_SETSAMPLEPOSITIONS_INVALIDARGS + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDQUEUE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCEREGION_INVALID_RECT + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDLIST = ( D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDQUEUE = ( D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDQUEUE = ( D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDLIST = ( D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDQUEUE = ( D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDQUEUE = ( D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDLIST = ( D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDQUEUE = ( D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDLIST + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSOR = ( D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDQUEUE + 1 ) , + D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSSTREAM = ( D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSOR + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSOR = ( D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSSTREAM + 1 ) , + D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSSTREAM = ( D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSOR + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSOR = ( D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSSTREAM + 1 ) , + D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSSTREAM = ( D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSOR + 1 ) , + D3D12_MESSAGE_ID_PROCESS_FRAME_INVALID_PARAMETERS = ( D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSSTREAM + 1 ) , + D3D12_MESSAGE_ID_COPY_INVALIDLAYOUT = ( D3D12_MESSAGE_ID_PROCESS_FRAME_INVALID_PARAMETERS + 1 ) , + D3D12_MESSAGE_ID_CREATE_CRYPTO_SESSION = 1068, + D3D12_MESSAGE_ID_CREATE_CRYPTO_SESSION_POLICY = 1069, + D3D12_MESSAGE_ID_CREATE_PROTECTED_RESOURCE_SESSION = 1070, + D3D12_MESSAGE_ID_LIVE_CRYPTO_SESSION = 1071, + D3D12_MESSAGE_ID_LIVE_CRYPTO_SESSION_POLICY = 1072, + D3D12_MESSAGE_ID_LIVE_PROTECTED_RESOURCE_SESSION = 1073, + D3D12_MESSAGE_ID_DESTROY_CRYPTO_SESSION = 1074, + D3D12_MESSAGE_ID_DESTROY_CRYPTO_SESSION_POLICY = 1075, + D3D12_MESSAGE_ID_DESTROY_PROTECTED_RESOURCE_SESSION = 1076, + D3D12_MESSAGE_ID_PROTECTED_RESOURCE_SESSION_UNSUPPORTED = 1077, + D3D12_MESSAGE_ID_FENCE_INVALIDOPERATION = 1078, + D3D12_MESSAGE_ID_CREATEQUERY_HEAP_COPY_QUEUE_TIMESTAMPS_NOT_SUPPORTED = 1079, + D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_DEFERRED = 1080, + D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMFIRSTUSE = 1081, + D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMCLEAR = 1082, + D3D12_MESSAGE_ID_CREATE_VIDEODECODERHEAP = 1083, + D3D12_MESSAGE_ID_LIVE_VIDEODECODERHEAP = 1084, + D3D12_MESSAGE_ID_DESTROY_VIDEODECODERHEAP = 1085, + D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDARG_RETURN = 1086, + D3D12_MESSAGE_ID_OPENEXISTINGHEAP_OUTOFMEMORY_RETURN = 1087, + D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDADDRESS = 1088, + D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDHANDLE = 1089, + D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_DEST = 1090, + D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_MODE = 1091, + D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_ALIGNMENT = 1092, + D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_NOT_SUPPORTED = 1093, + D3D12_MESSAGE_ID_SETVIEWINSTANCEMASK_INVALIDARGS = 1094, + D3D12_MESSAGE_ID_VIEW_INSTANCING_UNSUPPORTED = 1095, + D3D12_MESSAGE_ID_VIEW_INSTANCING_INVALIDARGS = 1096, + D3D12_MESSAGE_ID_COPYTEXTUREREGION_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 1097, + D3D12_MESSAGE_ID_COPYRESOURCE_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 1098, + D3D12_MESSAGE_ID_CREATE_VIDEO_DECODE_HEAP_CAPS_FAILURE = 1099, + D3D12_MESSAGE_ID_CREATE_VIDEO_DECODE_HEAP_CAPS_UNSUPPORTED = 1100, + D3D12_MESSAGE_ID_VIDEO_DECODE_SUPPORT_INVALID_INPUT = 1101, + D3D12_MESSAGE_ID_CREATE_VIDEO_DECODER_UNSUPPORTED = 1102, + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_METADATA_ERROR = 1103, + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VIEW_INSTANCING_VERTEX_SIZE_EXCEEDED = 1104, + D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RUNTIME_INTERNAL_ERROR = 1105, + D3D12_MESSAGE_ID_NO_VIDEO_API_SUPPORT = 1106, + D3D12_MESSAGE_ID_VIDEO_PROCESS_SUPPORT_INVALID_INPUT = 1107, + D3D12_MESSAGE_ID_CREATE_VIDEO_PROCESSOR_CAPS_FAILURE = 1108, + D3D12_MESSAGE_ID_VIDEO_PROCESS_SUPPORT_UNSUPPORTED_FORMAT = 1109, + D3D12_MESSAGE_ID_VIDEO_DECODE_FRAME_INVALID_ARGUMENT = 1110, + D3D12_MESSAGE_ID_ENQUEUE_MAKE_RESIDENT_INVALID_FLAGS = 1111, + D3D12_MESSAGE_ID_OPENEXISTINGHEAP_UNSUPPORTED = 1112, + D3D12_MESSAGE_ID_VIDEO_PROCESS_FRAMES_INVALID_ARGUMENT = 1113, + D3D12_MESSAGE_ID_VIDEO_DECODE_SUPPORT_UNSUPPORTED = 1114, + D3D12_MESSAGE_ID_CREATE_COMMANDRECORDER = 1115, + D3D12_MESSAGE_ID_LIVE_COMMANDRECORDER = 1116, + D3D12_MESSAGE_ID_DESTROY_COMMANDRECORDER = 1117, + D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_VIDEO_NOT_SUPPORTED = 1118, + D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_INVALID_SUPPORT_FLAGS = 1119, + D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_INVALID_FLAGS = 1120, + D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_MORE_RECORDERS_THAN_LOGICAL_PROCESSORS = 1121, + D3D12_MESSAGE_ID_CREATE_COMMANDPOOL = 1122, + D3D12_MESSAGE_ID_LIVE_COMMANDPOOL = 1123, + D3D12_MESSAGE_ID_DESTROY_COMMANDPOOL = 1124, + D3D12_MESSAGE_ID_CREATE_COMMAND_POOL_INVALID_FLAGS = 1125, + D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_VIDEO_NOT_SUPPORTED = 1126, + D3D12_MESSAGE_ID_COMMAND_RECORDER_SUPPORT_FLAGS_MISMATCH = 1127, + D3D12_MESSAGE_ID_COMMAND_RECORDER_CONTENTION = 1128, + D3D12_MESSAGE_ID_COMMAND_RECORDER_USAGE_WITH_CREATECOMMANDLIST_COMMAND_LIST = 1129, + D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_USAGE_WITH_CREATECOMMANDLIST1_COMMAND_LIST = 1130, + D3D12_MESSAGE_ID_CANNOT_EXECUTE_EMPTY_COMMAND_LIST = 1131, + D3D12_MESSAGE_ID_CANNOT_RESET_COMMAND_POOL_WITH_OPEN_COMMAND_LISTS = 1132, + D3D12_MESSAGE_ID_CANNOT_USE_COMMAND_RECORDER_WITHOUT_CURRENT_TARGET = 1133, + D3D12_MESSAGE_ID_CANNOT_CHANGE_COMMAND_RECORDER_TARGET_WHILE_RECORDING = 1134, + D3D12_MESSAGE_ID_COMMAND_POOL_SYNC = 1135, + D3D12_MESSAGE_ID_EVICT_UNDERFLOW = 1136, + D3D12_MESSAGE_ID_CREATE_META_COMMAND = 1137, + D3D12_MESSAGE_ID_LIVE_META_COMMAND = 1138, + D3D12_MESSAGE_ID_DESTROY_META_COMMAND = 1139, + D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALID_DST_RESOURCE = 1140, + D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALID_SRC_RESOURCE = 1141, + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DST_RESOURCE = 1142, + D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE = 1143, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_NULL_BUFFER = 1144, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_NULL_RESOURCE_DESC = 1145, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_UNSUPPORTED = 1146, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_DIMENSION = 1147, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_FLAGS = 1148, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_OFFSET = 1149, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_DIMENSION = 1150, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_FLAGS = 1151, + D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_OUTOFMEMORY_RETURN = 1152, + D3D12_MESSAGE_ID_CANNOT_CREATE_GRAPHICS_AND_VIDEO_COMMAND_RECORDER = 1153, + D3D12_MESSAGE_ID_UPDATETILEMAPPINGS_POSSIBLY_MISMATCHING_PROPERTIES = 1154, + D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE = 1155, + D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_INCOMPATIBLE_WITH_STRUCTURED_BUFFERS = 1156, + D3D12_MESSAGE_ID_COMPUTE_ONLY_DEVICE_OPERATION_UNSUPPORTED = 1157, + D3D12_MESSAGE_ID_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 1158, + D3D12_MESSAGE_ID_EMIT_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_INVALID = 1159, + D3D12_MESSAGE_ID_COPY_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 1160, + D3D12_MESSAGE_ID_DISPATCH_RAYS_INVALID = 1161, + D3D12_MESSAGE_ID_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_INVALID = 1162, + D3D12_MESSAGE_ID_CREATE_LIFETIMETRACKER = 1163, + D3D12_MESSAGE_ID_LIVE_LIFETIMETRACKER = 1164, + D3D12_MESSAGE_ID_DESTROY_LIFETIMETRACKER = 1165, + D3D12_MESSAGE_ID_DESTROYOWNEDOBJECT_OBJECTNOTOWNED = 1166, + D3D12_MESSAGE_ID_CREATE_TRACKEDWORKLOAD = 1167, + D3D12_MESSAGE_ID_LIVE_TRACKEDWORKLOAD = 1168, + D3D12_MESSAGE_ID_DESTROY_TRACKEDWORKLOAD = 1169, + D3D12_MESSAGE_ID_RENDER_PASS_ERROR = 1170, + D3D12_MESSAGE_ID_META_COMMAND_ID_INVALID = 1171, + D3D12_MESSAGE_ID_META_COMMAND_UNSUPPORTED_PARAMS = 1172, + D3D12_MESSAGE_ID_META_COMMAND_FAILED_ENUMERATION = 1173, + D3D12_MESSAGE_ID_META_COMMAND_PARAMETER_SIZE_MISMATCH = 1174, + D3D12_MESSAGE_ID_UNINITIALIZED_META_COMMAND = 1175, + D3D12_MESSAGE_ID_META_COMMAND_INVALID_GPU_VIRTUAL_ADDRESS = 1176, + D3D12_MESSAGE_ID_CREATE_VIDEOENCODECOMMANDLIST = 1177, + D3D12_MESSAGE_ID_LIVE_VIDEOENCODECOMMANDLIST = 1178, + D3D12_MESSAGE_ID_DESTROY_VIDEOENCODECOMMANDLIST = 1179, + D3D12_MESSAGE_ID_CREATE_VIDEOENCODECOMMANDQUEUE = 1180, + D3D12_MESSAGE_ID_LIVE_VIDEOENCODECOMMANDQUEUE = 1181, + D3D12_MESSAGE_ID_DESTROY_VIDEOENCODECOMMANDQUEUE = 1182, + D3D12_MESSAGE_ID_CREATE_VIDEOMOTIONESTIMATOR = 1183, + D3D12_MESSAGE_ID_LIVE_VIDEOMOTIONESTIMATOR = 1184, + D3D12_MESSAGE_ID_DESTROY_VIDEOMOTIONESTIMATOR = 1185, + D3D12_MESSAGE_ID_CREATE_VIDEOMOTIONVECTORHEAP = 1186, + D3D12_MESSAGE_ID_LIVE_VIDEOMOTIONVECTORHEAP = 1187, + D3D12_MESSAGE_ID_DESTROY_VIDEOMOTIONVECTORHEAP = 1188, + D3D12_MESSAGE_ID_MULTIPLE_TRACKED_WORKLOADS = 1189, + D3D12_MESSAGE_ID_MULTIPLE_TRACKED_WORKLOAD_PAIRS = 1190, + D3D12_MESSAGE_ID_OUT_OF_ORDER_TRACKED_WORKLOAD_PAIR = 1191, + D3D12_MESSAGE_ID_CANNOT_ADD_TRACKED_WORKLOAD = 1192, + D3D12_MESSAGE_ID_INCOMPLETE_TRACKED_WORKLOAD_PAIR = 1193, + D3D12_MESSAGE_ID_CREATE_STATE_OBJECT_ERROR = 1194, + D3D12_MESSAGE_ID_GET_SHADER_IDENTIFIER_ERROR = 1195, + D3D12_MESSAGE_ID_GET_SHADER_STACK_SIZE_ERROR = 1196, + D3D12_MESSAGE_ID_GET_PIPELINE_STACK_SIZE_ERROR = 1197, + D3D12_MESSAGE_ID_SET_PIPELINE_STACK_SIZE_ERROR = 1198, + D3D12_MESSAGE_ID_GET_SHADER_IDENTIFIER_SIZE_INVALID = 1199, + D3D12_MESSAGE_ID_CHECK_DRIVER_MATCHING_IDENTIFIER_INVALID = 1200, + D3D12_MESSAGE_ID_CHECK_DRIVER_MATCHING_IDENTIFIER_DRIVER_REPORTED_ISSUE = 1201, + D3D12_MESSAGE_ID_RENDER_PASS_INVALID_RESOURCE_BARRIER = 1202, + D3D12_MESSAGE_ID_RENDER_PASS_DISALLOWED_API_CALLED = 1203, + D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_NEST_RENDER_PASSES = 1204, + D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_END_WITHOUT_BEGIN = 1205, + D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_CLOSE_COMMAND_LIST = 1206, + D3D12_MESSAGE_ID_RENDER_PASS_GPU_WORK_WHILE_SUSPENDED = 1207, + D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_SUSPEND_RESUME = 1208, + D3D12_MESSAGE_ID_RENDER_PASS_NO_PRIOR_SUSPEND_WITHIN_EXECUTECOMMANDLISTS = 1209, + D3D12_MESSAGE_ID_RENDER_PASS_NO_SUBSEQUENT_RESUME_WITHIN_EXECUTECOMMANDLISTS = 1210, + D3D12_MESSAGE_ID_TRACKED_WORKLOAD_COMMAND_QUEUE_MISMATCH = 1211, + D3D12_MESSAGE_ID_TRACKED_WORKLOAD_NOT_SUPPORTED = 1212, + D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_NO_ACCESS = 1213, + D3D12_MESSAGE_ID_RENDER_PASS_UNSUPPORTED_RESOLVE = 1214, + D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_INVALID_RESOURCE_PTR = 1215, + D3D12_MESSAGE_ID_WINDOWS7_FENCE_OUTOFORDER_SIGNAL = 1216, + D3D12_MESSAGE_ID_WINDOWS7_FENCE_OUTOFORDER_WAIT = 1217, + D3D12_MESSAGE_ID_VIDEO_CREATE_MOTION_ESTIMATOR_INVALID_ARGUMENT = 1218, + D3D12_MESSAGE_ID_VIDEO_CREATE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 1219, + D3D12_MESSAGE_ID_ESTIMATE_MOTION_INVALID_ARGUMENT = 1220, + D3D12_MESSAGE_ID_RESOLVE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 1221, + D3D12_MESSAGE_ID_GETGPUVIRTUALADDRESS_INVALID_HEAP_TYPE = 1222, + D3D12_MESSAGE_ID_SET_BACKGROUND_PROCESSING_MODE_INVALID_ARGUMENT = 1223, + D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE_FOR_FEATURE_LEVEL = 1224, + D3D12_MESSAGE_ID_CREATE_VIDEOEXTENSIONCOMMAND = 1225, + D3D12_MESSAGE_ID_LIVE_VIDEOEXTENSIONCOMMAND = 1226, + D3D12_MESSAGE_ID_DESTROY_VIDEOEXTENSIONCOMMAND = 1227, + D3D12_MESSAGE_ID_INVALID_VIDEO_EXTENSION_COMMAND_ID = 1228, + D3D12_MESSAGE_ID_VIDEO_EXTENSION_COMMAND_INVALID_ARGUMENT = 1229, + D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_NOT_UNIQUE_IN_DXIL_LIBRARY = 1230, + D3D12_MESSAGE_ID_VARIABLE_SHADING_RATE_NOT_ALLOWED_WITH_TIR = 1231, + D3D12_MESSAGE_ID_GEOMETRY_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 1232, + D3D12_MESSAGE_ID_RSSETSHADING_RATE_INVALID_SHADING_RATE = 1233, + D3D12_MESSAGE_ID_RSSETSHADING_RATE_SHADING_RATE_NOT_PERMITTED_BY_CAP = 1234, + D3D12_MESSAGE_ID_RSSETSHADING_RATE_INVALID_COMBINER = 1235, + D3D12_MESSAGE_ID_RSSETSHADINGRATEIMAGE_REQUIRES_TIER_2 = 1236, + D3D12_MESSAGE_ID_RSSETSHADINGRATE_REQUIRES_TIER_1 = 1237, + D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_FORMAT = 1238, + D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_ARRAY_SIZE = 1239, + D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_MIP_LEVEL = 1240, + D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_SAMPLE_COUNT = 1241, + D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_SAMPLE_QUALITY = 1242, + D3D12_MESSAGE_ID_NON_RETAIL_SHADER_MODEL_WONT_VALIDATE = 1243, + D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_NON_RETAIL_SHADER_MODEL_WONT_VALIDATE + 1 ) + } D3D12_MESSAGE_ID; + +static_assert(D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UNSUPPORTED == 1000, "Publicly released SDK D3D12_MESSAGE_ID enum values must not be changed. New enum values must be added to the end of the list."); +static_assert(D3D12_MESSAGE_ID_COPY_INVALIDLAYOUT == 1067, "Publicly released SDK D3D12_MESSAGE_ID enum values must not be changed. New enum values must be added to the end of the list."); +typedef struct D3D12_MESSAGE + { + D3D12_MESSAGE_CATEGORY Category; + D3D12_MESSAGE_SEVERITY Severity; + D3D12_MESSAGE_ID ID; + _Field_size_(DescriptionByteLength) const char *pDescription; + SIZE_T DescriptionByteLength; + } D3D12_MESSAGE; + +typedef struct D3D12_INFO_QUEUE_FILTER_DESC + { + UINT NumCategories; + _Field_size_(NumCategories) D3D12_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + _Field_size_(NumSeverities) D3D12_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + _Field_size_(NumIDs) D3D12_MESSAGE_ID *pIDList; + } D3D12_INFO_QUEUE_FILTER_DESC; + +typedef struct D3D12_INFO_QUEUE_FILTER + { + D3D12_INFO_QUEUE_FILTER_DESC AllowList; + D3D12_INFO_QUEUE_FILTER_DESC DenyList; + } D3D12_INFO_QUEUE_FILTER; + +#define D3D12_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024 + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0012_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0012_v0_0_s_ifspec; + +#ifndef __ID3D12InfoQueue_INTERFACE_DEFINED__ +#define __ID3D12InfoQueue_INTERFACE_DEFINED__ + +/* interface ID3D12InfoQueue */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D12InfoQueue; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0742a90b-c387-483f-b946-30a7e4e61458") + ID3D12InfoQueue : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit( + _In_ UINT64 MessageCountLimit) = 0; + + virtual void STDMETHODCALLTYPE ClearStoredMessages( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetMessage( + _In_ UINT64 MessageIndex, + _Out_writes_bytes_opt_(*pMessageByteLength) D3D12_MESSAGE *pMessage, + _Inout_ SIZE_T *pMessageByteLength) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit( void) = 0; + + virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries( + _In_ D3D12_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetStorageFilter( + _Out_writes_bytes_opt_(*pFilterByteLength) D3D12_INFO_QUEUE_FILTER *pFilter, + _Inout_ SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushStorageFilter( + _In_ D3D12_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopStorageFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries( + _In_ D3D12_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter( + _Out_writes_bytes_opt_(*pFilterByteLength) D3D12_INFO_QUEUE_FILTER *pFilter, + _Inout_ SIZE_T *pFilterByteLength) = 0; + + virtual void STDMETHODCALLTYPE ClearRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter( + _In_ D3D12_INFO_QUEUE_FILTER *pFilter) = 0; + + virtual void STDMETHODCALLTYPE PopRetrievalFilter( void) = 0; + + virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddMessage( + _In_ D3D12_MESSAGE_CATEGORY Category, + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ D3D12_MESSAGE_ID ID, + _In_ LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage( + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ LPCSTR pDescription) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory( + _In_ D3D12_MESSAGE_CATEGORY Category, + _In_ BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity( + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ BOOL bEnable) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBreakOnID( + _In_ D3D12_MESSAGE_ID ID, + _In_ BOOL bEnable) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory( + _In_ D3D12_MESSAGE_CATEGORY Category) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity( + _In_ D3D12_MESSAGE_SEVERITY Severity) = 0; + + virtual BOOL STDMETHODCALLTYPE GetBreakOnID( + _In_ D3D12_MESSAGE_ID ID) = 0; + + virtual void STDMETHODCALLTYPE SetMuteDebugOutput( + _In_ BOOL bMute) = 0; + + virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D12InfoQueueVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D12InfoQueue * This, + REFIID riid, + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D12InfoQueue * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *SetMessageCountLimit )( + ID3D12InfoQueue * This, + _In_ UINT64 MessageCountLimit); + + void ( STDMETHODCALLTYPE *ClearStoredMessages )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *GetMessage )( + ID3D12InfoQueue * This, + _In_ UINT64 MessageIndex, + _Out_writes_bytes_opt_(*pMessageByteLength) D3D12_MESSAGE *pMessage, + _Inout_ SIZE_T *pMessageByteLength); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesAllowedByStorageFilter )( + ID3D12InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDeniedByStorageFilter )( + ID3D12InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessages )( + ID3D12InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumStoredMessagesAllowedByRetrievalFilter )( + ID3D12InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetNumMessagesDiscardedByMessageCountLimit )( + ID3D12InfoQueue * This); + + UINT64 ( STDMETHODCALLTYPE *GetMessageCountLimit )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddStorageFilterEntries )( + ID3D12InfoQueue * This, + _In_ D3D12_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetStorageFilter )( + ID3D12InfoQueue * This, + _Out_writes_bytes_opt_(*pFilterByteLength) D3D12_INFO_QUEUE_FILTER *pFilter, + _Inout_ SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearStorageFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyStorageFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfStorageFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushStorageFilter )( + ID3D12InfoQueue * This, + _In_ D3D12_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopStorageFilter )( + ID3D12InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetStorageFilterStackSize )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddRetrievalFilterEntries )( + ID3D12InfoQueue * This, + _In_ D3D12_INFO_QUEUE_FILTER *pFilter); + + HRESULT ( STDMETHODCALLTYPE *GetRetrievalFilter )( + ID3D12InfoQueue * This, + _Out_writes_bytes_opt_(*pFilterByteLength) D3D12_INFO_QUEUE_FILTER *pFilter, + _Inout_ SIZE_T *pFilterByteLength); + + void ( STDMETHODCALLTYPE *ClearRetrievalFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushEmptyRetrievalFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushCopyOfRetrievalFilter )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *PushRetrievalFilter )( + ID3D12InfoQueue * This, + _In_ D3D12_INFO_QUEUE_FILTER *pFilter); + + void ( STDMETHODCALLTYPE *PopRetrievalFilter )( + ID3D12InfoQueue * This); + + UINT ( STDMETHODCALLTYPE *GetRetrievalFilterStackSize )( + ID3D12InfoQueue * This); + + HRESULT ( STDMETHODCALLTYPE *AddMessage )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_CATEGORY Category, + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ D3D12_MESSAGE_ID ID, + _In_ LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *AddApplicationMessage )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ LPCSTR pDescription); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnCategory )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_CATEGORY Category, + _In_ BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnSeverity )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_SEVERITY Severity, + _In_ BOOL bEnable); + + HRESULT ( STDMETHODCALLTYPE *SetBreakOnID )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_ID ID, + _In_ BOOL bEnable); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnCategory )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_CATEGORY Category); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnSeverity )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_SEVERITY Severity); + + BOOL ( STDMETHODCALLTYPE *GetBreakOnID )( + ID3D12InfoQueue * This, + _In_ D3D12_MESSAGE_ID ID); + + void ( STDMETHODCALLTYPE *SetMuteDebugOutput )( + ID3D12InfoQueue * This, + _In_ BOOL bMute); + + BOOL ( STDMETHODCALLTYPE *GetMuteDebugOutput )( + ID3D12InfoQueue * This); + + END_INTERFACE + } ID3D12InfoQueueVtbl; + + interface ID3D12InfoQueue + { + CONST_VTBL struct ID3D12InfoQueueVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D12InfoQueue_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D12InfoQueue_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D12InfoQueue_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D12InfoQueue_SetMessageCountLimit(This,MessageCountLimit) \ + ( (This)->lpVtbl -> SetMessageCountLimit(This,MessageCountLimit) ) + +#define ID3D12InfoQueue_ClearStoredMessages(This) \ + ( (This)->lpVtbl -> ClearStoredMessages(This) ) + +#define ID3D12InfoQueue_GetMessage(This,MessageIndex,pMessage,pMessageByteLength) \ + ( (This)->lpVtbl -> GetMessage(This,MessageIndex,pMessage,pMessageByteLength) ) + +#define ID3D12InfoQueue_GetNumMessagesAllowedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesAllowedByStorageFilter(This) ) + +#define ID3D12InfoQueue_GetNumMessagesDeniedByStorageFilter(This) \ + ( (This)->lpVtbl -> GetNumMessagesDeniedByStorageFilter(This) ) + +#define ID3D12InfoQueue_GetNumStoredMessages(This) \ + ( (This)->lpVtbl -> GetNumStoredMessages(This) ) + +#define ID3D12InfoQueue_GetNumStoredMessagesAllowedByRetrievalFilter(This) \ + ( (This)->lpVtbl -> GetNumStoredMessagesAllowedByRetrievalFilter(This) ) + +#define ID3D12InfoQueue_GetNumMessagesDiscardedByMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetNumMessagesDiscardedByMessageCountLimit(This) ) + +#define ID3D12InfoQueue_GetMessageCountLimit(This) \ + ( (This)->lpVtbl -> GetMessageCountLimit(This) ) + +#define ID3D12InfoQueue_AddStorageFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddStorageFilterEntries(This,pFilter) ) + +#define ID3D12InfoQueue_GetStorageFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetStorageFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D12InfoQueue_ClearStorageFilter(This) \ + ( (This)->lpVtbl -> ClearStorageFilter(This) ) + +#define ID3D12InfoQueue_PushEmptyStorageFilter(This) \ + ( (This)->lpVtbl -> PushEmptyStorageFilter(This) ) + +#define ID3D12InfoQueue_PushCopyOfStorageFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfStorageFilter(This) ) + +#define ID3D12InfoQueue_PushStorageFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushStorageFilter(This,pFilter) ) + +#define ID3D12InfoQueue_PopStorageFilter(This) \ + ( (This)->lpVtbl -> PopStorageFilter(This) ) + +#define ID3D12InfoQueue_GetStorageFilterStackSize(This) \ + ( (This)->lpVtbl -> GetStorageFilterStackSize(This) ) + +#define ID3D12InfoQueue_AddRetrievalFilterEntries(This,pFilter) \ + ( (This)->lpVtbl -> AddRetrievalFilterEntries(This,pFilter) ) + +#define ID3D12InfoQueue_GetRetrievalFilter(This,pFilter,pFilterByteLength) \ + ( (This)->lpVtbl -> GetRetrievalFilter(This,pFilter,pFilterByteLength) ) + +#define ID3D12InfoQueue_ClearRetrievalFilter(This) \ + ( (This)->lpVtbl -> ClearRetrievalFilter(This) ) + +#define ID3D12InfoQueue_PushEmptyRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushEmptyRetrievalFilter(This) ) + +#define ID3D12InfoQueue_PushCopyOfRetrievalFilter(This) \ + ( (This)->lpVtbl -> PushCopyOfRetrievalFilter(This) ) + +#define ID3D12InfoQueue_PushRetrievalFilter(This,pFilter) \ + ( (This)->lpVtbl -> PushRetrievalFilter(This,pFilter) ) + +#define ID3D12InfoQueue_PopRetrievalFilter(This) \ + ( (This)->lpVtbl -> PopRetrievalFilter(This) ) + +#define ID3D12InfoQueue_GetRetrievalFilterStackSize(This) \ + ( (This)->lpVtbl -> GetRetrievalFilterStackSize(This) ) + +#define ID3D12InfoQueue_AddMessage(This,Category,Severity,ID,pDescription) \ + ( (This)->lpVtbl -> AddMessage(This,Category,Severity,ID,pDescription) ) + +#define ID3D12InfoQueue_AddApplicationMessage(This,Severity,pDescription) \ + ( (This)->lpVtbl -> AddApplicationMessage(This,Severity,pDescription) ) + +#define ID3D12InfoQueue_SetBreakOnCategory(This,Category,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnCategory(This,Category,bEnable) ) + +#define ID3D12InfoQueue_SetBreakOnSeverity(This,Severity,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnSeverity(This,Severity,bEnable) ) + +#define ID3D12InfoQueue_SetBreakOnID(This,ID,bEnable) \ + ( (This)->lpVtbl -> SetBreakOnID(This,ID,bEnable) ) + +#define ID3D12InfoQueue_GetBreakOnCategory(This,Category) \ + ( (This)->lpVtbl -> GetBreakOnCategory(This,Category) ) + +#define ID3D12InfoQueue_GetBreakOnSeverity(This,Severity) \ + ( (This)->lpVtbl -> GetBreakOnSeverity(This,Severity) ) + +#define ID3D12InfoQueue_GetBreakOnID(This,ID) \ + ( (This)->lpVtbl -> GetBreakOnID(This,ID) ) + +#define ID3D12InfoQueue_SetMuteDebugOutput(This,bMute) \ + ( (This)->lpVtbl -> SetMuteDebugOutput(This,bMute) ) + +#define ID3D12InfoQueue_GetMuteDebugOutput(This) \ + ( (This)->lpVtbl -> GetMuteDebugOutput(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D12InfoQueue_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3d12sdklayers_0000_0013 */ +/* [local] */ + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */ +#pragma endregion +DEFINE_GUID(IID_ID3D12Debug,0x344488b7,0x6846,0x474b,0xb9,0x89,0xf0,0x27,0x44,0x82,0x45,0xe0); +DEFINE_GUID(IID_ID3D12Debug1,0xaffaa4ca,0x63fe,0x4d8e,0xb8,0xad,0x15,0x90,0x00,0xaf,0x43,0x04); +DEFINE_GUID(IID_ID3D12Debug2,0x93a665c4,0xa3b2,0x4e5d,0xb6,0x92,0xa2,0x6a,0xe1,0x4e,0x33,0x74); +DEFINE_GUID(IID_ID3D12Debug3,0x5cf4e58f,0xf671,0x4ff1,0xa5,0x42,0x36,0x86,0xe3,0xd1,0x53,0xd1); +DEFINE_GUID(IID_ID3D12DebugDevice1,0xa9b71770,0xd099,0x4a65,0xa6,0x98,0x3d,0xee,0x10,0x02,0x0f,0x88); +DEFINE_GUID(IID_ID3D12DebugDevice,0x3febd6dd,0x4973,0x4787,0x81,0x94,0xe4,0x5f,0x9e,0x28,0x92,0x3e); +DEFINE_GUID(IID_ID3D12DebugDevice2,0x60eccbc1,0x378d,0x4df1,0x89,0x4c,0xf8,0xac,0x5c,0xe4,0xd7,0xdd); +DEFINE_GUID(IID_ID3D12DebugCommandQueue,0x09e0bf36,0x54ac,0x484f,0x88,0x47,0x4b,0xae,0xea,0xb6,0x05,0x3a); +DEFINE_GUID(IID_ID3D12DebugCommandList1,0x102ca951,0x311b,0x4b01,0xb1,0x1f,0xec,0xb8,0x3e,0x06,0x1b,0x37); +DEFINE_GUID(IID_ID3D12DebugCommandList,0x09e0bf36,0x54ac,0x484f,0x88,0x47,0x4b,0xae,0xea,0xb6,0x05,0x3f); +DEFINE_GUID(IID_ID3D12DebugCommandList2,0xaeb575cf,0x4e06,0x48be,0xba,0x3b,0xc4,0x50,0xfc,0x96,0x65,0x2e); +DEFINE_GUID(IID_ID3D12SharingContract,0x0adf7d52,0x929c,0x4e61,0xad,0xdb,0xff,0xed,0x30,0xde,0x66,0xef); +DEFINE_GUID(IID_ID3D12InfoQueue,0x0742a90b,0xc387,0x483f,0xb9,0x46,0x30,0xa7,0xe4,0xe6,0x14,0x58); + + +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0013_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0013_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dcommon.h b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dcommon.h new file mode 100644 index 000000000..2db8805d0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dcommon.h @@ -0,0 +1,1009 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0622 */ +/* @@MIDL_FILE_HEADING( ) */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __d3dcommon_h__ +#define __d3dcommon_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __ID3D10Blob_FWD_DEFINED__ +#define __ID3D10Blob_FWD_DEFINED__ +typedef interface ID3D10Blob ID3D10Blob; + +#endif /* __ID3D10Blob_FWD_DEFINED__ */ + + +#ifndef __ID3DDestructionNotifier_FWD_DEFINED__ +#define __ID3DDestructionNotifier_FWD_DEFINED__ +typedef interface ID3DDestructionNotifier ID3DDestructionNotifier; + +#endif /* __ID3DDestructionNotifier_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_d3dcommon_0000_0000 */ +/* [local] */ + +typedef +enum D3D_DRIVER_TYPE + { + D3D_DRIVER_TYPE_UNKNOWN = 0, + D3D_DRIVER_TYPE_HARDWARE = ( D3D_DRIVER_TYPE_UNKNOWN + 1 ) , + D3D_DRIVER_TYPE_REFERENCE = ( D3D_DRIVER_TYPE_HARDWARE + 1 ) , + D3D_DRIVER_TYPE_NULL = ( D3D_DRIVER_TYPE_REFERENCE + 1 ) , + D3D_DRIVER_TYPE_SOFTWARE = ( D3D_DRIVER_TYPE_NULL + 1 ) , + D3D_DRIVER_TYPE_WARP = ( D3D_DRIVER_TYPE_SOFTWARE + 1 ) + } D3D_DRIVER_TYPE; + +typedef +enum D3D_FEATURE_LEVEL + { + D3D_FEATURE_LEVEL_1_0_CORE = 0x1000, + D3D_FEATURE_LEVEL_9_1 = 0x9100, + D3D_FEATURE_LEVEL_9_2 = 0x9200, + D3D_FEATURE_LEVEL_9_3 = 0x9300, + D3D_FEATURE_LEVEL_10_0 = 0xa000, + D3D_FEATURE_LEVEL_10_1 = 0xa100, + D3D_FEATURE_LEVEL_11_0 = 0xb000, + D3D_FEATURE_LEVEL_11_1 = 0xb100, + D3D_FEATURE_LEVEL_12_0 = 0xc000, + D3D_FEATURE_LEVEL_12_1 = 0xc100 + } D3D_FEATURE_LEVEL; + +#define D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION 2048 +#define D3D_FL9_3_REQ_TEXTURE1D_U_DIMENSION 4096 +#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048 +#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 +#define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512 +#define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096 +#define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256 +#define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2 +#define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535 +#define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575 +#define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1 +#define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 +#define D3D_FL9_1_MAX_TEXTURE_REPEAT 128 +#define D3D_FL9_2_MAX_TEXTURE_REPEAT 2048 +#define D3D_FL9_3_MAX_TEXTURE_REPEAT 8192 +typedef +enum D3D_PRIMITIVE_TOPOLOGY + { + D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1, + D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, + D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, + D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34, + D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35, + D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36, + D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37, + D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38, + D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39, + D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40, + D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41, + D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42, + D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43, + D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44, + D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45, + D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46, + D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47, + D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48, + D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49, + D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50, + D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51, + D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52, + D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53, + D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54, + D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55, + D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56, + D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57, + D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58, + D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59, + D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60, + D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61, + D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62, + D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63, + D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64, + D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D10_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST + } D3D_PRIMITIVE_TOPOLOGY; + +typedef +enum D3D_PRIMITIVE + { + D3D_PRIMITIVE_UNDEFINED = 0, + D3D_PRIMITIVE_POINT = 1, + D3D_PRIMITIVE_LINE = 2, + D3D_PRIMITIVE_TRIANGLE = 3, + D3D_PRIMITIVE_LINE_ADJ = 6, + D3D_PRIMITIVE_TRIANGLE_ADJ = 7, + D3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 8, + D3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 9, + D3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 10, + D3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 11, + D3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 12, + D3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 13, + D3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 14, + D3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 15, + D3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 16, + D3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 17, + D3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 18, + D3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 19, + D3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 20, + D3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 21, + D3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 22, + D3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 23, + D3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 24, + D3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 25, + D3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 26, + D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 27, + D3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 28, + D3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 29, + D3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 30, + D3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 31, + D3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 32, + D3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 33, + D3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 34, + D3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 35, + D3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 36, + D3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 37, + D3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 38, + D3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 39, + D3D10_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D10_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D10_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D10_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D10_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D10_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED, + D3D11_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT, + D3D11_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE, + D3D11_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE, + D3D11_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ, + D3D11_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = D3D_PRIMITIVE_1_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = D3D_PRIMITIVE_2_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = D3D_PRIMITIVE_3_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = D3D_PRIMITIVE_4_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH = D3D_PRIMITIVE_5_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH = D3D_PRIMITIVE_6_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH = D3D_PRIMITIVE_7_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH = D3D_PRIMITIVE_8_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH = D3D_PRIMITIVE_9_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH = D3D_PRIMITIVE_10_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH = D3D_PRIMITIVE_11_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH = D3D_PRIMITIVE_12_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH = D3D_PRIMITIVE_13_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH = D3D_PRIMITIVE_14_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH = D3D_PRIMITIVE_15_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH = D3D_PRIMITIVE_16_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH = D3D_PRIMITIVE_17_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH = D3D_PRIMITIVE_18_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH = D3D_PRIMITIVE_19_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = D3D_PRIMITIVE_20_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH = D3D_PRIMITIVE_21_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH = D3D_PRIMITIVE_22_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH = D3D_PRIMITIVE_23_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH = D3D_PRIMITIVE_24_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH = D3D_PRIMITIVE_25_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH = D3D_PRIMITIVE_26_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH = D3D_PRIMITIVE_27_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH = D3D_PRIMITIVE_28_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH = D3D_PRIMITIVE_29_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH = D3D_PRIMITIVE_30_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = D3D_PRIMITIVE_31_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = D3D_PRIMITIVE_32_CONTROL_POINT_PATCH + } D3D_PRIMITIVE; + +typedef +enum D3D_SRV_DIMENSION + { + D3D_SRV_DIMENSION_UNKNOWN = 0, + D3D_SRV_DIMENSION_BUFFER = 1, + D3D_SRV_DIMENSION_TEXTURE1D = 2, + D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3, + D3D_SRV_DIMENSION_TEXTURE2D = 4, + D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5, + D3D_SRV_DIMENSION_TEXTURE2DMS = 6, + D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, + D3D_SRV_DIMENSION_TEXTURE3D = 8, + D3D_SRV_DIMENSION_TEXTURECUBE = 9, + D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10, + D3D_SRV_DIMENSION_BUFFEREX = 11, + D3D10_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D10_1_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D10_1_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D10_1_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN, + D3D11_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER, + D3D11_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D, + D3D11_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D, + D3D11_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D11_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D, + D3D11_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE, + D3D11_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_BUFFEREX = D3D_SRV_DIMENSION_BUFFEREX + } D3D_SRV_DIMENSION; + +typedef struct _D3D_SHADER_MACRO + { + LPCSTR Name; + LPCSTR Definition; + } D3D_SHADER_MACRO; + +typedef struct _D3D_SHADER_MACRO *LPD3D_SHADER_MACRO; + +DEFINE_GUID(IID_ID3D10Blob, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0000_v0_0_s_ifspec; + +#ifndef __ID3D10Blob_INTERFACE_DEFINED__ +#define __ID3D10Blob_INTERFACE_DEFINED__ + +/* interface ID3D10Blob */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3D10Blob; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8BA5FB08-5195-40e2-AC58-0D989C3A0102") + ID3D10Blob : public IUnknown + { + public: + virtual LPVOID STDMETHODCALLTYPE GetBufferPointer( void) = 0; + + virtual SIZE_T STDMETHODCALLTYPE GetBufferSize( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3D10BlobVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3D10Blob * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3D10Blob * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3D10Blob * This); + + LPVOID ( STDMETHODCALLTYPE *GetBufferPointer )( + ID3D10Blob * This); + + SIZE_T ( STDMETHODCALLTYPE *GetBufferSize )( + ID3D10Blob * This); + + END_INTERFACE + } ID3D10BlobVtbl; + + interface ID3D10Blob + { + CONST_VTBL struct ID3D10BlobVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3D10Blob_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3D10Blob_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3D10Blob_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3D10Blob_GetBufferPointer(This) \ + ( (This)->lpVtbl -> GetBufferPointer(This) ) + +#define ID3D10Blob_GetBufferSize(This) \ + ( (This)->lpVtbl -> GetBufferSize(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3D10Blob_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3dcommon_0000_0001 */ +/* [local] */ + +typedef interface ID3D10Blob* LPD3D10BLOB; +typedef ID3D10Blob ID3DBlob; + +typedef ID3DBlob* LPD3DBLOB; +#define IID_ID3DBlob IID_ID3D10Blob +typedef void ( __stdcall *PFN_DESTRUCTION_CALLBACK )( + void *pData); + + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0001_v0_0_s_ifspec; + +#ifndef __ID3DDestructionNotifier_INTERFACE_DEFINED__ +#define __ID3DDestructionNotifier_INTERFACE_DEFINED__ + +/* interface ID3DDestructionNotifier */ +/* [unique][local][object][uuid] */ + + +EXTERN_C const IID IID_ID3DDestructionNotifier; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("a06eb39a-50da-425b-8c31-4eecd6c270f3") + ID3DDestructionNotifier : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE RegisterDestructionCallback( + /* [annotation] */ + _In_ PFN_DESTRUCTION_CALLBACK callbackFn, + /* [annotation] */ + _In_ void *pData, + /* [annotation] */ + _Out_ UINT *pCallbackID) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnregisterDestructionCallback( + /* [annotation] */ + _In_ UINT callbackID) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ID3DDestructionNotifierVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ID3DDestructionNotifier * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ID3DDestructionNotifier * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ID3DDestructionNotifier * This); + + HRESULT ( STDMETHODCALLTYPE *RegisterDestructionCallback )( + ID3DDestructionNotifier * This, + /* [annotation] */ + _In_ PFN_DESTRUCTION_CALLBACK callbackFn, + /* [annotation] */ + _In_ void *pData, + /* [annotation] */ + _Out_ UINT *pCallbackID); + + HRESULT ( STDMETHODCALLTYPE *UnregisterDestructionCallback )( + ID3DDestructionNotifier * This, + /* [annotation] */ + _In_ UINT callbackID); + + END_INTERFACE + } ID3DDestructionNotifierVtbl; + + interface ID3DDestructionNotifier + { + CONST_VTBL struct ID3DDestructionNotifierVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ID3DDestructionNotifier_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ID3DDestructionNotifier_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ID3DDestructionNotifier_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ID3DDestructionNotifier_RegisterDestructionCallback(This,callbackFn,pData,pCallbackID) \ + ( (This)->lpVtbl -> RegisterDestructionCallback(This,callbackFn,pData,pCallbackID) ) + +#define ID3DDestructionNotifier_UnregisterDestructionCallback(This,callbackID) \ + ( (This)->lpVtbl -> UnregisterDestructionCallback(This,callbackID) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ID3DDestructionNotifier_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_d3dcommon_0000_0002 */ +/* [local] */ + +typedef +enum _D3D_INCLUDE_TYPE + { + D3D_INCLUDE_LOCAL = 0, + D3D_INCLUDE_SYSTEM = ( D3D_INCLUDE_LOCAL + 1 ) , + D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL, + D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM, + D3D_INCLUDE_FORCE_DWORD = 0x7fffffff + } D3D_INCLUDE_TYPE; + +typedef interface ID3DInclude ID3DInclude; +#undef INTERFACE +#define INTERFACE ID3DInclude +DECLARE_INTERFACE(ID3DInclude) +{ + STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE; + STDMETHOD(Close)(THIS_ LPCVOID pData) PURE; +}; +typedef ID3DInclude* LPD3DINCLUDE; +typedef +enum _D3D_SHADER_VARIABLE_CLASS + { + D3D_SVC_SCALAR = 0, + D3D_SVC_VECTOR = ( D3D_SVC_SCALAR + 1 ) , + D3D_SVC_MATRIX_ROWS = ( D3D_SVC_VECTOR + 1 ) , + D3D_SVC_MATRIX_COLUMNS = ( D3D_SVC_MATRIX_ROWS + 1 ) , + D3D_SVC_OBJECT = ( D3D_SVC_MATRIX_COLUMNS + 1 ) , + D3D_SVC_STRUCT = ( D3D_SVC_OBJECT + 1 ) , + D3D_SVC_INTERFACE_CLASS = ( D3D_SVC_STRUCT + 1 ) , + D3D_SVC_INTERFACE_POINTER = ( D3D_SVC_INTERFACE_CLASS + 1 ) , + D3D10_SVC_SCALAR = D3D_SVC_SCALAR, + D3D10_SVC_VECTOR = D3D_SVC_VECTOR, + D3D10_SVC_MATRIX_ROWS = D3D_SVC_MATRIX_ROWS, + D3D10_SVC_MATRIX_COLUMNS = D3D_SVC_MATRIX_COLUMNS, + D3D10_SVC_OBJECT = D3D_SVC_OBJECT, + D3D10_SVC_STRUCT = D3D_SVC_STRUCT, + D3D11_SVC_INTERFACE_CLASS = D3D_SVC_INTERFACE_CLASS, + D3D11_SVC_INTERFACE_POINTER = D3D_SVC_INTERFACE_POINTER, + D3D_SVC_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_CLASS; + +typedef +enum _D3D_SHADER_VARIABLE_FLAGS + { + D3D_SVF_USERPACKED = 1, + D3D_SVF_USED = 2, + D3D_SVF_INTERFACE_POINTER = 4, + D3D_SVF_INTERFACE_PARAMETER = 8, + D3D10_SVF_USERPACKED = D3D_SVF_USERPACKED, + D3D10_SVF_USED = D3D_SVF_USED, + D3D11_SVF_INTERFACE_POINTER = D3D_SVF_INTERFACE_POINTER, + D3D11_SVF_INTERFACE_PARAMETER = D3D_SVF_INTERFACE_PARAMETER, + D3D_SVF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_FLAGS; + +typedef +enum _D3D_SHADER_VARIABLE_TYPE + { + D3D_SVT_VOID = 0, + D3D_SVT_BOOL = 1, + D3D_SVT_INT = 2, + D3D_SVT_FLOAT = 3, + D3D_SVT_STRING = 4, + D3D_SVT_TEXTURE = 5, + D3D_SVT_TEXTURE1D = 6, + D3D_SVT_TEXTURE2D = 7, + D3D_SVT_TEXTURE3D = 8, + D3D_SVT_TEXTURECUBE = 9, + D3D_SVT_SAMPLER = 10, + D3D_SVT_SAMPLER1D = 11, + D3D_SVT_SAMPLER2D = 12, + D3D_SVT_SAMPLER3D = 13, + D3D_SVT_SAMPLERCUBE = 14, + D3D_SVT_PIXELSHADER = 15, + D3D_SVT_VERTEXSHADER = 16, + D3D_SVT_PIXELFRAGMENT = 17, + D3D_SVT_VERTEXFRAGMENT = 18, + D3D_SVT_UINT = 19, + D3D_SVT_UINT8 = 20, + D3D_SVT_GEOMETRYSHADER = 21, + D3D_SVT_RASTERIZER = 22, + D3D_SVT_DEPTHSTENCIL = 23, + D3D_SVT_BLEND = 24, + D3D_SVT_BUFFER = 25, + D3D_SVT_CBUFFER = 26, + D3D_SVT_TBUFFER = 27, + D3D_SVT_TEXTURE1DARRAY = 28, + D3D_SVT_TEXTURE2DARRAY = 29, + D3D_SVT_RENDERTARGETVIEW = 30, + D3D_SVT_DEPTHSTENCILVIEW = 31, + D3D_SVT_TEXTURE2DMS = 32, + D3D_SVT_TEXTURE2DMSARRAY = 33, + D3D_SVT_TEXTURECUBEARRAY = 34, + D3D_SVT_HULLSHADER = 35, + D3D_SVT_DOMAINSHADER = 36, + D3D_SVT_INTERFACE_POINTER = 37, + D3D_SVT_COMPUTESHADER = 38, + D3D_SVT_DOUBLE = 39, + D3D_SVT_RWTEXTURE1D = 40, + D3D_SVT_RWTEXTURE1DARRAY = 41, + D3D_SVT_RWTEXTURE2D = 42, + D3D_SVT_RWTEXTURE2DARRAY = 43, + D3D_SVT_RWTEXTURE3D = 44, + D3D_SVT_RWBUFFER = 45, + D3D_SVT_BYTEADDRESS_BUFFER = 46, + D3D_SVT_RWBYTEADDRESS_BUFFER = 47, + D3D_SVT_STRUCTURED_BUFFER = 48, + D3D_SVT_RWSTRUCTURED_BUFFER = 49, + D3D_SVT_APPEND_STRUCTURED_BUFFER = 50, + D3D_SVT_CONSUME_STRUCTURED_BUFFER = 51, + D3D_SVT_MIN8FLOAT = 52, + D3D_SVT_MIN10FLOAT = 53, + D3D_SVT_MIN16FLOAT = 54, + D3D_SVT_MIN12INT = 55, + D3D_SVT_MIN16INT = 56, + D3D_SVT_MIN16UINT = 57, + D3D10_SVT_VOID = D3D_SVT_VOID, + D3D10_SVT_BOOL = D3D_SVT_BOOL, + D3D10_SVT_INT = D3D_SVT_INT, + D3D10_SVT_FLOAT = D3D_SVT_FLOAT, + D3D10_SVT_STRING = D3D_SVT_STRING, + D3D10_SVT_TEXTURE = D3D_SVT_TEXTURE, + D3D10_SVT_TEXTURE1D = D3D_SVT_TEXTURE1D, + D3D10_SVT_TEXTURE2D = D3D_SVT_TEXTURE2D, + D3D10_SVT_TEXTURE3D = D3D_SVT_TEXTURE3D, + D3D10_SVT_TEXTURECUBE = D3D_SVT_TEXTURECUBE, + D3D10_SVT_SAMPLER = D3D_SVT_SAMPLER, + D3D10_SVT_SAMPLER1D = D3D_SVT_SAMPLER1D, + D3D10_SVT_SAMPLER2D = D3D_SVT_SAMPLER2D, + D3D10_SVT_SAMPLER3D = D3D_SVT_SAMPLER3D, + D3D10_SVT_SAMPLERCUBE = D3D_SVT_SAMPLERCUBE, + D3D10_SVT_PIXELSHADER = D3D_SVT_PIXELSHADER, + D3D10_SVT_VERTEXSHADER = D3D_SVT_VERTEXSHADER, + D3D10_SVT_PIXELFRAGMENT = D3D_SVT_PIXELFRAGMENT, + D3D10_SVT_VERTEXFRAGMENT = D3D_SVT_VERTEXFRAGMENT, + D3D10_SVT_UINT = D3D_SVT_UINT, + D3D10_SVT_UINT8 = D3D_SVT_UINT8, + D3D10_SVT_GEOMETRYSHADER = D3D_SVT_GEOMETRYSHADER, + D3D10_SVT_RASTERIZER = D3D_SVT_RASTERIZER, + D3D10_SVT_DEPTHSTENCIL = D3D_SVT_DEPTHSTENCIL, + D3D10_SVT_BLEND = D3D_SVT_BLEND, + D3D10_SVT_BUFFER = D3D_SVT_BUFFER, + D3D10_SVT_CBUFFER = D3D_SVT_CBUFFER, + D3D10_SVT_TBUFFER = D3D_SVT_TBUFFER, + D3D10_SVT_TEXTURE1DARRAY = D3D_SVT_TEXTURE1DARRAY, + D3D10_SVT_TEXTURE2DARRAY = D3D_SVT_TEXTURE2DARRAY, + D3D10_SVT_RENDERTARGETVIEW = D3D_SVT_RENDERTARGETVIEW, + D3D10_SVT_DEPTHSTENCILVIEW = D3D_SVT_DEPTHSTENCILVIEW, + D3D10_SVT_TEXTURE2DMS = D3D_SVT_TEXTURE2DMS, + D3D10_SVT_TEXTURE2DMSARRAY = D3D_SVT_TEXTURE2DMSARRAY, + D3D10_SVT_TEXTURECUBEARRAY = D3D_SVT_TEXTURECUBEARRAY, + D3D11_SVT_HULLSHADER = D3D_SVT_HULLSHADER, + D3D11_SVT_DOMAINSHADER = D3D_SVT_DOMAINSHADER, + D3D11_SVT_INTERFACE_POINTER = D3D_SVT_INTERFACE_POINTER, + D3D11_SVT_COMPUTESHADER = D3D_SVT_COMPUTESHADER, + D3D11_SVT_DOUBLE = D3D_SVT_DOUBLE, + D3D11_SVT_RWTEXTURE1D = D3D_SVT_RWTEXTURE1D, + D3D11_SVT_RWTEXTURE1DARRAY = D3D_SVT_RWTEXTURE1DARRAY, + D3D11_SVT_RWTEXTURE2D = D3D_SVT_RWTEXTURE2D, + D3D11_SVT_RWTEXTURE2DARRAY = D3D_SVT_RWTEXTURE2DARRAY, + D3D11_SVT_RWTEXTURE3D = D3D_SVT_RWTEXTURE3D, + D3D11_SVT_RWBUFFER = D3D_SVT_RWBUFFER, + D3D11_SVT_BYTEADDRESS_BUFFER = D3D_SVT_BYTEADDRESS_BUFFER, + D3D11_SVT_RWBYTEADDRESS_BUFFER = D3D_SVT_RWBYTEADDRESS_BUFFER, + D3D11_SVT_STRUCTURED_BUFFER = D3D_SVT_STRUCTURED_BUFFER, + D3D11_SVT_RWSTRUCTURED_BUFFER = D3D_SVT_RWSTRUCTURED_BUFFER, + D3D11_SVT_APPEND_STRUCTURED_BUFFER = D3D_SVT_APPEND_STRUCTURED_BUFFER, + D3D11_SVT_CONSUME_STRUCTURED_BUFFER = D3D_SVT_CONSUME_STRUCTURED_BUFFER, + D3D_SVT_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_VARIABLE_TYPE; + +typedef +enum _D3D_SHADER_INPUT_FLAGS + { + D3D_SIF_USERPACKED = 0x1, + D3D_SIF_COMPARISON_SAMPLER = 0x2, + D3D_SIF_TEXTURE_COMPONENT_0 = 0x4, + D3D_SIF_TEXTURE_COMPONENT_1 = 0x8, + D3D_SIF_TEXTURE_COMPONENTS = 0xc, + D3D_SIF_UNUSED = 0x10, + D3D10_SIF_USERPACKED = D3D_SIF_USERPACKED, + D3D10_SIF_COMPARISON_SAMPLER = D3D_SIF_COMPARISON_SAMPLER, + D3D10_SIF_TEXTURE_COMPONENT_0 = D3D_SIF_TEXTURE_COMPONENT_0, + D3D10_SIF_TEXTURE_COMPONENT_1 = D3D_SIF_TEXTURE_COMPONENT_1, + D3D10_SIF_TEXTURE_COMPONENTS = D3D_SIF_TEXTURE_COMPONENTS, + D3D_SIF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_INPUT_FLAGS; + +typedef +enum _D3D_SHADER_INPUT_TYPE + { + D3D_SIT_CBUFFER = 0, + D3D_SIT_TBUFFER = ( D3D_SIT_CBUFFER + 1 ) , + D3D_SIT_TEXTURE = ( D3D_SIT_TBUFFER + 1 ) , + D3D_SIT_SAMPLER = ( D3D_SIT_TEXTURE + 1 ) , + D3D_SIT_UAV_RWTYPED = ( D3D_SIT_SAMPLER + 1 ) , + D3D_SIT_STRUCTURED = ( D3D_SIT_UAV_RWTYPED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED = ( D3D_SIT_STRUCTURED + 1 ) , + D3D_SIT_BYTEADDRESS = ( D3D_SIT_UAV_RWSTRUCTURED + 1 ) , + D3D_SIT_UAV_RWBYTEADDRESS = ( D3D_SIT_BYTEADDRESS + 1 ) , + D3D_SIT_UAV_APPEND_STRUCTURED = ( D3D_SIT_UAV_RWBYTEADDRESS + 1 ) , + D3D_SIT_UAV_CONSUME_STRUCTURED = ( D3D_SIT_UAV_APPEND_STRUCTURED + 1 ) , + D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = ( D3D_SIT_UAV_CONSUME_STRUCTURED + 1 ) , + D3D10_SIT_CBUFFER = D3D_SIT_CBUFFER, + D3D10_SIT_TBUFFER = D3D_SIT_TBUFFER, + D3D10_SIT_TEXTURE = D3D_SIT_TEXTURE, + D3D10_SIT_SAMPLER = D3D_SIT_SAMPLER, + D3D11_SIT_UAV_RWTYPED = D3D_SIT_UAV_RWTYPED, + D3D11_SIT_STRUCTURED = D3D_SIT_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED = D3D_SIT_UAV_RWSTRUCTURED, + D3D11_SIT_BYTEADDRESS = D3D_SIT_BYTEADDRESS, + D3D11_SIT_UAV_RWBYTEADDRESS = D3D_SIT_UAV_RWBYTEADDRESS, + D3D11_SIT_UAV_APPEND_STRUCTURED = D3D_SIT_UAV_APPEND_STRUCTURED, + D3D11_SIT_UAV_CONSUME_STRUCTURED = D3D_SIT_UAV_CONSUME_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER + } D3D_SHADER_INPUT_TYPE; + +typedef +enum _D3D_SHADER_CBUFFER_FLAGS + { + D3D_CBF_USERPACKED = 1, + D3D10_CBF_USERPACKED = D3D_CBF_USERPACKED, + D3D_CBF_FORCE_DWORD = 0x7fffffff + } D3D_SHADER_CBUFFER_FLAGS; + +typedef +enum _D3D_CBUFFER_TYPE + { + D3D_CT_CBUFFER = 0, + D3D_CT_TBUFFER = ( D3D_CT_CBUFFER + 1 ) , + D3D_CT_INTERFACE_POINTERS = ( D3D_CT_TBUFFER + 1 ) , + D3D_CT_RESOURCE_BIND_INFO = ( D3D_CT_INTERFACE_POINTERS + 1 ) , + D3D10_CT_CBUFFER = D3D_CT_CBUFFER, + D3D10_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_CBUFFER = D3D_CT_CBUFFER, + D3D11_CT_TBUFFER = D3D_CT_TBUFFER, + D3D11_CT_INTERFACE_POINTERS = D3D_CT_INTERFACE_POINTERS, + D3D11_CT_RESOURCE_BIND_INFO = D3D_CT_RESOURCE_BIND_INFO + } D3D_CBUFFER_TYPE; + +typedef +enum D3D_NAME + { + D3D_NAME_UNDEFINED = 0, + D3D_NAME_POSITION = 1, + D3D_NAME_CLIP_DISTANCE = 2, + D3D_NAME_CULL_DISTANCE = 3, + D3D_NAME_RENDER_TARGET_ARRAY_INDEX = 4, + D3D_NAME_VIEWPORT_ARRAY_INDEX = 5, + D3D_NAME_VERTEX_ID = 6, + D3D_NAME_PRIMITIVE_ID = 7, + D3D_NAME_INSTANCE_ID = 8, + D3D_NAME_IS_FRONT_FACE = 9, + D3D_NAME_SAMPLE_INDEX = 10, + D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR = 11, + D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = 12, + D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR = 13, + D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR = 14, + D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR = 15, + D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR = 16, + D3D_NAME_BARYCENTRICS = 23, + D3D_NAME_SHADINGRATE = 24, + D3D_NAME_TARGET = 64, + D3D_NAME_DEPTH = 65, + D3D_NAME_COVERAGE = 66, + D3D_NAME_DEPTH_GREATER_EQUAL = 67, + D3D_NAME_DEPTH_LESS_EQUAL = 68, + D3D_NAME_STENCIL_REF = 69, + D3D_NAME_INNER_COVERAGE = 70, + D3D10_NAME_UNDEFINED = D3D_NAME_UNDEFINED, + D3D10_NAME_POSITION = D3D_NAME_POSITION, + D3D10_NAME_CLIP_DISTANCE = D3D_NAME_CLIP_DISTANCE, + D3D10_NAME_CULL_DISTANCE = D3D_NAME_CULL_DISTANCE, + D3D10_NAME_RENDER_TARGET_ARRAY_INDEX = D3D_NAME_RENDER_TARGET_ARRAY_INDEX, + D3D10_NAME_VIEWPORT_ARRAY_INDEX = D3D_NAME_VIEWPORT_ARRAY_INDEX, + D3D10_NAME_VERTEX_ID = D3D_NAME_VERTEX_ID, + D3D10_NAME_PRIMITIVE_ID = D3D_NAME_PRIMITIVE_ID, + D3D10_NAME_INSTANCE_ID = D3D_NAME_INSTANCE_ID, + D3D10_NAME_IS_FRONT_FACE = D3D_NAME_IS_FRONT_FACE, + D3D10_NAME_SAMPLE_INDEX = D3D_NAME_SAMPLE_INDEX, + D3D10_NAME_TARGET = D3D_NAME_TARGET, + D3D10_NAME_DEPTH = D3D_NAME_DEPTH, + D3D10_NAME_COVERAGE = D3D_NAME_COVERAGE, + D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR = D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR = D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR = D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR = D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR = D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR, + D3D11_NAME_DEPTH_GREATER_EQUAL = D3D_NAME_DEPTH_GREATER_EQUAL, + D3D11_NAME_DEPTH_LESS_EQUAL = D3D_NAME_DEPTH_LESS_EQUAL, + D3D11_NAME_STENCIL_REF = D3D_NAME_STENCIL_REF, + D3D11_NAME_INNER_COVERAGE = D3D_NAME_INNER_COVERAGE, + D3D12_NAME_BARYCENTRICS = D3D_NAME_BARYCENTRICS, + D3D12_NAME_SHADINGRATE = D3D_NAME_SHADINGRATE + } D3D_NAME; + +typedef +enum D3D_RESOURCE_RETURN_TYPE + { + D3D_RETURN_TYPE_UNORM = 1, + D3D_RETURN_TYPE_SNORM = 2, + D3D_RETURN_TYPE_SINT = 3, + D3D_RETURN_TYPE_UINT = 4, + D3D_RETURN_TYPE_FLOAT = 5, + D3D_RETURN_TYPE_MIXED = 6, + D3D_RETURN_TYPE_DOUBLE = 7, + D3D_RETURN_TYPE_CONTINUED = 8, + D3D10_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D10_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D10_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D10_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D10_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D10_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM, + D3D11_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM, + D3D11_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT, + D3D11_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT, + D3D11_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT, + D3D11_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_DOUBLE = D3D_RETURN_TYPE_DOUBLE, + D3D11_RETURN_TYPE_CONTINUED = D3D_RETURN_TYPE_CONTINUED + } D3D_RESOURCE_RETURN_TYPE; + +typedef +enum D3D_REGISTER_COMPONENT_TYPE + { + D3D_REGISTER_COMPONENT_UNKNOWN = 0, + D3D_REGISTER_COMPONENT_UINT32 = 1, + D3D_REGISTER_COMPONENT_SINT32 = 2, + D3D_REGISTER_COMPONENT_FLOAT32 = 3, + D3D10_REGISTER_COMPONENT_UNKNOWN = D3D_REGISTER_COMPONENT_UNKNOWN, + D3D10_REGISTER_COMPONENT_UINT32 = D3D_REGISTER_COMPONENT_UINT32, + D3D10_REGISTER_COMPONENT_SINT32 = D3D_REGISTER_COMPONENT_SINT32, + D3D10_REGISTER_COMPONENT_FLOAT32 = D3D_REGISTER_COMPONENT_FLOAT32 + } D3D_REGISTER_COMPONENT_TYPE; + +typedef +enum D3D_TESSELLATOR_DOMAIN + { + D3D_TESSELLATOR_DOMAIN_UNDEFINED = 0, + D3D_TESSELLATOR_DOMAIN_ISOLINE = 1, + D3D_TESSELLATOR_DOMAIN_TRI = 2, + D3D_TESSELLATOR_DOMAIN_QUAD = 3, + D3D11_TESSELLATOR_DOMAIN_UNDEFINED = D3D_TESSELLATOR_DOMAIN_UNDEFINED, + D3D11_TESSELLATOR_DOMAIN_ISOLINE = D3D_TESSELLATOR_DOMAIN_ISOLINE, + D3D11_TESSELLATOR_DOMAIN_TRI = D3D_TESSELLATOR_DOMAIN_TRI, + D3D11_TESSELLATOR_DOMAIN_QUAD = D3D_TESSELLATOR_DOMAIN_QUAD + } D3D_TESSELLATOR_DOMAIN; + +typedef +enum D3D_TESSELLATOR_PARTITIONING + { + D3D_TESSELLATOR_PARTITIONING_UNDEFINED = 0, + D3D_TESSELLATOR_PARTITIONING_INTEGER = 1, + D3D_TESSELLATOR_PARTITIONING_POW2 = 2, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4, + D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = D3D_TESSELLATOR_PARTITIONING_UNDEFINED, + D3D11_TESSELLATOR_PARTITIONING_INTEGER = D3D_TESSELLATOR_PARTITIONING_INTEGER, + D3D11_TESSELLATOR_PARTITIONING_POW2 = D3D_TESSELLATOR_PARTITIONING_POW2, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN + } D3D_TESSELLATOR_PARTITIONING; + +typedef +enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE + { + D3D_TESSELLATOR_OUTPUT_UNDEFINED = 0, + D3D_TESSELLATOR_OUTPUT_POINT = 1, + D3D_TESSELLATOR_OUTPUT_LINE = 2, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4, + D3D11_TESSELLATOR_OUTPUT_UNDEFINED = D3D_TESSELLATOR_OUTPUT_UNDEFINED, + D3D11_TESSELLATOR_OUTPUT_POINT = D3D_TESSELLATOR_OUTPUT_POINT, + D3D11_TESSELLATOR_OUTPUT_LINE = D3D_TESSELLATOR_OUTPUT_LINE, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW + } D3D_TESSELLATOR_OUTPUT_PRIMITIVE; + +typedef +enum D3D_MIN_PRECISION + { + D3D_MIN_PRECISION_DEFAULT = 0, + D3D_MIN_PRECISION_FLOAT_16 = 1, + D3D_MIN_PRECISION_FLOAT_2_8 = 2, + D3D_MIN_PRECISION_RESERVED = 3, + D3D_MIN_PRECISION_SINT_16 = 4, + D3D_MIN_PRECISION_UINT_16 = 5, + D3D_MIN_PRECISION_ANY_16 = 0xf0, + D3D_MIN_PRECISION_ANY_10 = 0xf1 + } D3D_MIN_PRECISION; + +typedef +enum D3D_INTERPOLATION_MODE + { + D3D_INTERPOLATION_UNDEFINED = 0, + D3D_INTERPOLATION_CONSTANT = 1, + D3D_INTERPOLATION_LINEAR = 2, + D3D_INTERPOLATION_LINEAR_CENTROID = 3, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE = 4, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID = 5, + D3D_INTERPOLATION_LINEAR_SAMPLE = 6, + D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE = 7 + } D3D_INTERPOLATION_MODE; + +typedef +enum _D3D_PARAMETER_FLAGS + { + D3D_PF_NONE = 0, + D3D_PF_IN = 0x1, + D3D_PF_OUT = 0x2, + D3D_PF_FORCE_DWORD = 0x7fffffff + } D3D_PARAMETER_FLAGS; + +DEFINE_GUID(WKPDID_D3DDebugObjectName,0x429b8c22,0x9188,0x4b0c,0x87,0x42,0xac,0xb0,0xbf,0x85,0xc2,0x00); +DEFINE_GUID(WKPDID_D3DDebugObjectNameW,0x4cca5fd8,0x921f,0x42c8,0x85,0x66,0x70,0xca,0xf2,0xa9,0xb7,0x41); +DEFINE_GUID(WKPDID_CommentStringW,0xd0149dc0,0x90e8,0x4ec8,0x81, 0x44, 0xe9, 0x00, 0xad, 0x26, 0x6b, 0xb2); +#define D3D_SET_OBJECT_NAME_N_A(pObject, Chars, pName) (pObject)->SetPrivateData(WKPDID_D3DDebugObjectName, Chars, pName) +#define D3D_SET_OBJECT_NAME_A(pObject, pName) D3D_SET_OBJECT_NAME_N_A(pObject, lstrlenA(pName), pName) +#define D3D_SET_OBJECT_NAME_N_W(pObject, Chars, pName) (pObject)->SetPrivateData(WKPDID_D3DDebugObjectNameW, Chars*2, pName) +#define D3D_SET_OBJECT_NAME_W(pObject, pName) D3D_SET_OBJECT_NAME_N_W(pObject, wcslen(pName), pName) +#define D3D_COMPONENT_MASK_X 1 +#define D3D_COMPONENT_MASK_Y 2 +#define D3D_COMPONENT_MASK_Z 4 +#define D3D_COMPONENT_MASK_W 8 +DEFINE_GUID(D3D_TEXTURE_LAYOUT_ROW_MAJOR,0xb5dc234f,0x72bb,0x4bec,0x97,0x05,0x8c,0xf2,0x58,0xdf,0x6b,0x6c); +DEFINE_GUID(D3D_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE,0x4c0f29e3,0x3f5f,0x4d35,0x84,0xc9,0xbc,0x09,0x83,0xb6,0x2c,0x28); + + +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0002_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_d3dcommon_0000_0002_v0_0_s_ifspec; + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dx12.h b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dx12.h new file mode 100644 index 000000000..3aafbd252 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/dxsdk/d3dx12.h @@ -0,0 +1,3440 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() = default; + explicit CD3DX12_RECT( const D3D12_RECT& o ) : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VIEWPORT : public D3D12_VIEWPORT +{ + CD3DX12_VIEWPORT() = default; + explicit CD3DX12_VIEWPORT( const D3D12_VIEWPORT& o ) : + D3D12_VIEWPORT( o ) + {} + explicit CD3DX12_VIEWPORT( + FLOAT topLeftX, + FLOAT topLeftY, + FLOAT width, + FLOAT height, + FLOAT minDepth = D3D12_MIN_DEPTH, + FLOAT maxDepth = D3D12_MAX_DEPTH ) + { + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = width; + Height = height; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3DX12_VIEWPORT( + _In_ ID3D12Resource* pResource, + UINT mipSlice = 0, + FLOAT topLeftX = 0.0f, + FLOAT topLeftY = 0.0f, + FLOAT minDepth = D3D12_MIN_DEPTH, + FLOAT maxDepth = D3D12_MAX_DEPTH ) + { + auto Desc = pResource->GetDesc(); + const UINT64 SubresourceWidth = Desc.Width >> mipSlice; + const UINT64 SubresourceHeight = Desc.Height >> mipSlice; + switch (Desc.Dimension) + { + case D3D12_RESOURCE_DIMENSION_BUFFER: + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = Desc.Width - topLeftX; + Height = 1.0f; + break; + case D3D12_RESOURCE_DIMENSION_TEXTURE1D: + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = (SubresourceWidth ? SubresourceWidth : 1.0f) - topLeftX; + Height = 1.0f; + break; + case D3D12_RESOURCE_DIMENSION_TEXTURE2D: + case D3D12_RESOURCE_DIMENSION_TEXTURE3D: + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = (SubresourceWidth ? SubresourceWidth : 1.0f) - topLeftX; + Height = (SubresourceHeight ? SubresourceHeight: 1.0f) - topLeftY; + break; + default: break; + } + + MinDepth = minDepth; + MaxDepth = maxDepth; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() = default; + explicit CD3DX12_BOX( const D3D12_BOX& o ) : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) + { + left = static_cast(Left); + top = 0; + front = 0; + right = static_cast(Right); + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) + { + left = static_cast(Left); + top = static_cast(Top); + front = 0; + right = static_cast(Right); + bottom = static_cast(Bottom); + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) + { + left = static_cast(Left); + top = static_cast(Top); + front = static_cast(Front); + right = static_cast(Right); + bottom = static_cast(Bottom); + back = static_cast(Back); + } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC1 : public D3D12_DEPTH_STENCIL_DESC1 +{ + CD3DX12_DEPTH_STENCIL_DESC1() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC1& o ) : + D3D12_DEPTH_STENCIL_DESC1( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC& o ) + { + DepthEnable = o.DepthEnable; + DepthWriteMask = o.DepthWriteMask; + DepthFunc = o.DepthFunc; + StencilEnable = o.StencilEnable; + StencilReadMask = o.StencilReadMask; + StencilWriteMask = o.StencilWriteMask; + FrontFace.StencilFailOp = o.FrontFace.StencilFailOp; + FrontFace.StencilDepthFailOp = o.FrontFace.StencilDepthFailOp; + FrontFace.StencilPassOp = o.FrontFace.StencilPassOp; + FrontFace.StencilFunc = o.FrontFace.StencilFunc; + BackFace.StencilFailOp = o.BackFace.StencilFailOp; + BackFace.StencilDepthFailOp = o.BackFace.StencilDepthFailOp; + BackFace.StencilPassOp = o.BackFace.StencilPassOp; + BackFace.StencilFunc = o.BackFace.StencilFunc; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( CD3DX12_DEFAULT ) + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc, + BOOL depthBoundsTestEnable ) + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + DepthBoundsTestEnable = depthBoundsTestEnable; + } + operator D3D12_DEPTH_STENCIL_DESC() const + { + D3D12_DEPTH_STENCIL_DESC D; + D.DepthEnable = DepthEnable; + D.DepthWriteMask = DepthWriteMask; + D.DepthFunc = DepthFunc; + D.StencilEnable = StencilEnable; + D.StencilReadMask = StencilReadMask; + D.StencilWriteMask = StencilWriteMask; + D.FrontFace.StencilFailOp = FrontFace.StencilFailOp; + D.FrontFace.StencilDepthFailOp = FrontFace.StencilDepthFailOp; + D.FrontFace.StencilPassOp = FrontFace.StencilPassOp; + D.FrontFace.StencilFunc = FrontFace.StencilFunc; + D.BackFace.StencilFailOp = BackFace.StencilFailOp; + D.BackFace.StencilDepthFailOp = BackFace.StencilDepthFailOp; + D.BackFace.StencilPassOp = BackFace.StencilPassOp; + D.BackFace.StencilFunc = BackFace.StencilFunc; + return D; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() = default; + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() = default; + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() = default; + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) + { + SizeInBytes = size; + Alignment = alignment; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() = default; + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + bool IsCPUAccessible() const + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() = default; + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + bool IsCPUAccessible() const + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() = default; + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) + { + Format = format; + memset( &Color, 0, sizeof( Color ) ); + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() = default; + explicit CD3DX12_RANGE(const D3D12_RANGE &o) : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) + { + Begin = begin; + End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE_UINT64 : public D3D12_RANGE_UINT64 +{ + CD3DX12_RANGE_UINT64() = default; + explicit CD3DX12_RANGE_UINT64(const D3D12_RANGE_UINT64 &o) : + D3D12_RANGE_UINT64(o) + {} + CD3DX12_RANGE_UINT64( + UINT64 begin, + UINT64 end ) + { + Begin = begin; + End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_RANGE_UINT64 : public D3D12_SUBRESOURCE_RANGE_UINT64 +{ + CD3DX12_SUBRESOURCE_RANGE_UINT64() = default; + explicit CD3DX12_SUBRESOURCE_RANGE_UINT64(const D3D12_SUBRESOURCE_RANGE_UINT64 &o) : + D3D12_SUBRESOURCE_RANGE_UINT64(o) + {} + CD3DX12_SUBRESOURCE_RANGE_UINT64( + UINT subresource, + const D3D12_RANGE_UINT64& range ) + { + Subresource = subresource; + Range = range; + } + CD3DX12_SUBRESOURCE_RANGE_UINT64( + UINT subresource, + UINT64 begin, + UINT64 end ) + { + Subresource = subresource; + Range.Begin = begin; + Range.End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE +{ + CD3DX12_SHADER_BYTECODE() = default; + explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) : + D3D12_SHADER_BYTECODE(o) + {} + CD3DX12_SHADER_BYTECODE( + _In_ ID3DBlob* pShaderBlob ) + { + pShaderBytecode = pShaderBlob->GetBufferPointer(); + BytecodeLength = pShaderBlob->GetBufferSize(); + } + CD3DX12_SHADER_BYTECODE( + const void* _pShaderBytecode, + SIZE_T bytecodeLength ) + { + pShaderBytecode = _pShaderBytecode; + BytecodeLength = bytecodeLength; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() = default; + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() = default; + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() = default; + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() = default; + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() = default; + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() = default; + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() = default; + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() = default; + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + PlacedFootprint = {}; + } + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + PlacedFootprint = {}; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() = default; + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() = default; + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() = default; + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() = default; + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() = default; + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() = default; + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() = default; + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE1 : public D3D12_DESCRIPTOR_RANGE1 +{ + CD3DX12_DESCRIPTOR_RANGE1() = default; + explicit CD3DX12_DESCRIPTOR_RANGE1(const D3D12_DESCRIPTOR_RANGE1 &o) : + D3D12_DESCRIPTOR_RANGE1(o) + {} + CD3DX12_DESCRIPTOR_RANGE1( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE1 &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.Flags = flags; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE1 : public D3D12_ROOT_DESCRIPTOR_TABLE1 +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE1() = default; + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE1(const D3D12_ROOT_DESCRIPTOR_TABLE1 &o) : + D3D12_ROOT_DESCRIPTOR_TABLE1(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE1( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE1 &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR1 : public D3D12_ROOT_DESCRIPTOR1 +{ + CD3DX12_ROOT_DESCRIPTOR1() = default; + explicit CD3DX12_ROOT_DESCRIPTOR1(const D3D12_ROOT_DESCRIPTOR1 &o) : + D3D12_ROOT_DESCRIPTOR1(o) + {} + CD3DX12_ROOT_DESCRIPTOR1( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + Init(shaderRegister, registerSpace, flags); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + Init(*this, shaderRegister, registerSpace, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR1 &table, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + table.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER1 : public D3D12_ROOT_PARAMETER1 +{ + CD3DX12_ROOT_PARAMETER1() = default; + explicit CD3DX12_ROOT_PARAMETER1(const D3D12_ROOT_PARAMETER1 &o) : + D3D12_ROOT_PARAMETER1(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE1::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, flags, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC : public D3D12_VERSIONED_ROOT_SIGNATURE_DESC +{ + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC() = default; + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &o) : + D3D12_VERSIONED_ROOT_SIGNATURE_DESC(o) + {} + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + Desc_1_0 = o; + } + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC1 &o) + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + Desc_1_1 = o; + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_0(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_1(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) + { + Init_1_1(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init_1_0( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_0(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_0( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + desc.Desc_1_0.NumParameters = numParameters; + desc.Desc_1_0.pParameters = _pParameters; + desc.Desc_1_0.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_0.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_0.Flags = flags; + } + + inline void Init_1_1( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + Init_1_1(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_1( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + desc.Desc_1_1.NumParameters = numParameters; + desc.Desc_1_1.pParameters = _pParameters; + desc.Desc_1_1.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_1.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_1.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() = default; + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr = SIZE_T(INT64(ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr = SIZE_T(INT64(ptr) + INT64(offsetScaledByIncrementSize)); + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetScaledByIncrementSize)); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() = default; + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) + { + ptr = UINT64(INT64(ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) + { + ptr = UINT64(INT64(ptr) + INT64(offsetScaledByIncrementSize)); + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) + { + handle.ptr = UINT64(INT64(base.ptr) + INT64(offsetScaledByIncrementSize)); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) + { + handle.ptr = UINT64(INT64(base.ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + } +}; + +//------------------------------------------------------------------------------------------------ +inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format, 0 }; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() = default; + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VIEW_INSTANCING_DESC : public D3D12_VIEW_INSTANCING_DESC +{ + CD3DX12_VIEW_INSTANCING_DESC() = default; + explicit CD3DX12_VIEW_INSTANCING_DESC( const D3D12_VIEW_INSTANCING_DESC& o ) : + D3D12_VIEW_INSTANCING_DESC( o ) + {} + explicit CD3DX12_VIEW_INSTANCING_DESC( CD3DX12_DEFAULT ) + { + ViewInstanceCount = 0; + pViewInstanceLocations = nullptr; + Flags = D3D12_VIEW_INSTANCING_FLAG_NONE; + } + explicit CD3DX12_VIEW_INSTANCING_DESC( + UINT InViewInstanceCount, + const D3D12_VIEW_INSTANCE_LOCATION* InViewInstanceLocations, + D3D12_VIEW_INSTANCING_FLAGS InFlags) + { + ViewInstanceCount = InViewInstanceCount; + pViewInstanceLocations = InViewInstanceLocations; + Flags = InFlags; + } +}; + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) +{ + for (UINT z = 0; z < NumSlices; ++z) + { + auto pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; + auto pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z); + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * LONG_PTR(y), + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) +{ + auto Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) +{ + // Minor validation + auto IntermediateDesc = pIntermediate->GetDesc(); + auto DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > SIZE_T(-1) || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) }; + MemcpySubresource(&DestData, &pSrcData[i], static_cast(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, nullptr); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); + if (pMem == nullptr) + { + return 0; + } + auto pLayouts = reinterpret_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); + + auto Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + auto Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +template +inline ID3D12CommandList * const * CommandListCast(t_CommandListType * const * pp) +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast(pp); +} + +//------------------------------------------------------------------------------------------------ +// D3D12 exports a new method for serializing root signatures in the Windows 10 Anniversary Update. +// To help enable root signature 1.1 features when they are available and not require maintaining +// two code paths for building root signatures, this helper method reconstructs a 1.0 signature when +// 1.1 is not supported. +inline HRESULT D3DX12SerializeVersionedRootSignature( + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, + D3D_ROOT_SIGNATURE_VERSION MaxVersion, + _Outptr_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob) +{ + if (ppErrorBlob != nullptr) + { + *ppErrorBlob = nullptr; + } + + switch (MaxVersion) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + switch (pRootSignatureDesc->Version) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + { + HRESULT hr = S_OK; + const D3D12_ROOT_SIGNATURE_DESC1& desc_1_1 = pRootSignatureDesc->Desc_1_1; + + const SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters; + void* pParameters = (ParametersSize > 0) ? HeapAlloc(GetProcessHeap(), 0, ParametersSize) : nullptr; + if (ParametersSize > 0 && pParameters == nullptr) + { + hr = E_OUTOFMEMORY; + } + auto pParameters_1_0 = reinterpret_cast(pParameters); + + if (SUCCEEDED(hr)) + { + for (UINT n = 0; n < desc_1_1.NumParameters; n++) + { + __analysis_assume(ParametersSize == sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters); + pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType; + pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility; + + switch (desc_1_1.pParameters[n].ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues; + pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace; + pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace; + pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable; + + const SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges; + void* pDescriptorRanges = (DescriptorRangesSize > 0 && SUCCEEDED(hr)) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : nullptr; + if (DescriptorRangesSize > 0 && pDescriptorRanges == nullptr) + { + hr = E_OUTOFMEMORY; + } + auto pDescriptorRanges_1_0 = reinterpret_cast(pDescriptorRanges); + + if (SUCCEEDED(hr)) + { + for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++) + { + __analysis_assume(DescriptorRangesSize == sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges); + pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister; + pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors; + pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart; + pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType; + pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace; + } + } + + D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable; + table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges; + table_1_0.pDescriptorRanges = pDescriptorRanges_1_0; + } + } + } + + if (SUCCEEDED(hr)) + { + CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags); + hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + } + + if (pParameters) + { + for (UINT n = 0; n < desc_1_1.NumParameters; n++) + { + if (desc_1_1.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + { + HeapFree(GetProcessHeap(), 0, reinterpret_cast(const_cast(pParameters_1_0[n].DescriptorTable.pDescriptorRanges))); + } + } + HeapFree(GetProcessHeap(), 0, pParameters); + } + return hr; + } + } + break; + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); + } + + return E_INVALIDARG; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RT_FORMAT_ARRAY : public D3D12_RT_FORMAT_ARRAY +{ + CD3DX12_RT_FORMAT_ARRAY() = default; + explicit CD3DX12_RT_FORMAT_ARRAY(const D3D12_RT_FORMAT_ARRAY& o) + : D3D12_RT_FORMAT_ARRAY(o) + {} + explicit CD3DX12_RT_FORMAT_ARRAY(_In_reads_(NumFormats) const DXGI_FORMAT* pFormats, UINT NumFormats) + { + NumRenderTargets = NumFormats; + memcpy(RTFormats, pFormats, sizeof(RTFormats)); + // assumes ARRAY_SIZE(pFormats) == ARRAY_SIZE(RTFormats) + } +}; + +//------------------------------------------------------------------------------------------------ +// Pipeline State Stream Helpers +//------------------------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------------------------ +// Stream Subobjects, i.e. elements of a stream + +struct DefaultSampleMask { operator UINT() { return UINT_MAX; } }; +struct DefaultSampleDesc { operator DXGI_SAMPLE_DESC() { return DXGI_SAMPLE_DESC{1, 0}; } }; + +#pragma warning(push) +#pragma warning(disable : 4324) +template +class alignas(void*) CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT +{ +private: + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE _Type; + InnerStructType _Inner; +public: + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT() noexcept : _Type(Type), _Inner(DefaultArg()) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT(InnerStructType const& i) : _Type(Type), _Inner(i) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT& operator=(InnerStructType const& i) { _Inner = i; return *this; } + operator InnerStructType const&() const { return _Inner; } + operator InnerStructType&() { return _Inner; } + InnerStructType* operator&() { return &_Inner; } + InnerStructType const* operator&() const { return &_Inner; } +}; +#pragma warning(pop) +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> CD3DX12_PIPELINE_STATE_STREAM_FLAGS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INPUT_LAYOUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT> CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE> CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PRIMITIVE_TOPOLOGY_TYPE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY> CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS> CD3DX12_PIPELINE_STATE_STREAM_VS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS> CD3DX12_PIPELINE_STATE_STREAM_GS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_STREAM_OUTPUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT> CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS> CD3DX12_PIPELINE_STATE_STREAM_HS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS> CD3DX12_PIPELINE_STATE_STREAM_DS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> CD3DX12_PIPELINE_STATE_STREAM_PS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS> CD3DX12_PIPELINE_STATE_STREAM_CS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC1, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, DefaultSampleDesc> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, DefaultSampleMask> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_VIEW_INSTANCING_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING; + +//------------------------------------------------------------------------------------------------ +// Stream Parser Helpers + +struct ID3DX12PipelineParserCallbacks +{ + // Subobject Callbacks + virtual void FlagsCb(D3D12_PIPELINE_STATE_FLAGS) {} + virtual void NodeMaskCb(UINT) {} + virtual void RootSignatureCb(ID3D12RootSignature*) {} + virtual void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC&) {} + virtual void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE) {} + virtual void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE) {} + virtual void VSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void GSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC&) {} + virtual void HSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void DSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void PSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void CSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void BlendStateCb(const D3D12_BLEND_DESC&) {} + virtual void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC&) {} + virtual void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1&) {} + virtual void DSVFormatCb(DXGI_FORMAT) {} + virtual void RasterizerStateCb(const D3D12_RASTERIZER_DESC&) {} + virtual void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY&) {} + virtual void SampleDescCb(const DXGI_SAMPLE_DESC&) {} + virtual void SampleMaskCb(UINT) {} + virtual void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC&) {} + virtual void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE&) {} + + // Error Callbacks + virtual void ErrorBadInputParameter(UINT /*ParameterIndex*/) {} + virtual void ErrorDuplicateSubobject(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE /*DuplicateType*/) {} + virtual void ErrorUnknownSubobject(UINT /*UnknownTypeValue*/) {} + + virtual ~ID3DX12PipelineParserCallbacks() = default; +}; + +// CD3DX12_PIPELINE_STATE_STREAM1 Works on RS3+ (where there is a new view instancing subobject). +// Use CD3DX12_PIPELINE_STATE_STREAM for RS2+ support. +struct CD3DX12_PIPELINE_STATE_STREAM1 +{ + CD3DX12_PIPELINE_STATE_STREAM1() = default; + CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + { + static_cast(DepthStencilState).DepthEnable = false; + } + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + +// CD3DX12_PIPELINE_STATE_STREAM works on RS2+ but does not support new subobject(s) added in RS3+. +// See CD3DX12_PIPELINE_STATE_STREAM1 for instance. +struct CD3DX12_PIPELINE_STATE_STREAM +{ + CD3DX12_PIPELINE_STATE_STREAM() = default; + CD3DX12_PIPELINE_STATE_STREAM(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + {} + CD3DX12_PIPELINE_STATE_STREAM(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + {} + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + +struct CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER : public ID3DX12PipelineParserCallbacks +{ + CD3DX12_PIPELINE_STATE_STREAM1 PipelineStream; + CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER() noexcept + : SeenDSS(false) + { + // Adjust defaults to account for absent members. + PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + // Depth disabled if no DSV format specified. + static_cast(PipelineStream.DepthStencilState).DepthEnable = false; + } + + // ID3DX12PipelineParserCallbacks + void FlagsCb(D3D12_PIPELINE_STATE_FLAGS Flags) override {PipelineStream.Flags = Flags;} + void NodeMaskCb(UINT NodeMask) override {PipelineStream.NodeMask = NodeMask;} + void RootSignatureCb(ID3D12RootSignature* pRootSignature) override {PipelineStream.pRootSignature = pRootSignature;} + void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC& InputLayout) override {PipelineStream.InputLayout = InputLayout;} + void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) override {PipelineStream.IBStripCutValue = IBStripCutValue;} + void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) override {PipelineStream.PrimitiveTopologyType = PrimitiveTopologyType;} + void VSCb(const D3D12_SHADER_BYTECODE& VS) override {PipelineStream.VS = VS;} + void GSCb(const D3D12_SHADER_BYTECODE& GS) override {PipelineStream.GS = GS;} + void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC& StreamOutput) override {PipelineStream.StreamOutput = StreamOutput;} + void HSCb(const D3D12_SHADER_BYTECODE& HS) override {PipelineStream.HS = HS;} + void DSCb(const D3D12_SHADER_BYTECODE& DS) override {PipelineStream.DS = DS;} + void PSCb(const D3D12_SHADER_BYTECODE& PS) override {PipelineStream.PS = PS;} + void CSCb(const D3D12_SHADER_BYTECODE& CS) override {PipelineStream.CS = CS;} + void BlendStateCb(const D3D12_BLEND_DESC& BlendState) override {PipelineStream.BlendState = CD3DX12_BLEND_DESC(BlendState);} + void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DSVFormatCb(DXGI_FORMAT DSVFormat) override + { + PipelineStream.DSVFormat = DSVFormat; + if (!SeenDSS && DSVFormat != DXGI_FORMAT_UNKNOWN) + { + // Re-enable depth for the default state. + static_cast(PipelineStream.DepthStencilState).DepthEnable = true; + } + } + void RasterizerStateCb(const D3D12_RASTERIZER_DESC& RasterizerState) override {PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC(RasterizerState);} + void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY& RTVFormats) override {PipelineStream.RTVFormats = RTVFormats;} + void SampleDescCb(const DXGI_SAMPLE_DESC& SampleDesc) override {PipelineStream.SampleDesc = SampleDesc;} + void SampleMaskCb(UINT SampleMask) override {PipelineStream.SampleMask = SampleMask;} + void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC& ViewInstancingDesc) override {PipelineStream.ViewInstancingDesc = CD3DX12_VIEW_INSTANCING_DESC(ViewInstancingDesc);} + void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE& CachedPSO) override {PipelineStream.CachedPSO = CachedPSO;} + +private: + bool SeenDSS; +}; + +inline D3D12_PIPELINE_STATE_SUBOBJECT_TYPE D3DX12GetBaseSubobjectType(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE SubobjectType) +{ + switch (SubobjectType) + { + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: + return D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL; + default: + return SubobjectType; + } +} + +inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC& Desc, ID3DX12PipelineParserCallbacks* pCallbacks) +{ + if (pCallbacks == nullptr) + { + return E_INVALIDARG; + } + + if (Desc.SizeInBytes == 0 || Desc.pPipelineStateSubobjectStream == nullptr) + { + pCallbacks->ErrorBadInputParameter(1); // first parameter issue + return E_INVALIDARG; + } + + bool SubobjectSeen[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID] = {}; + for (SIZE_T CurOffset = 0, SizeOfSubobject = 0; CurOffset < Desc.SizeInBytes; CurOffset += SizeOfSubobject) + { + BYTE* pStream = static_cast(Desc.pPipelineStateSubobjectStream)+CurOffset; + auto SubobjectType = *reinterpret_cast(pStream); + if (SubobjectType < 0 || SubobjectType >= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID) + { + pCallbacks->ErrorUnknownSubobject(SubobjectType); + return E_INVALIDARG; + } + if (SubobjectSeen[D3DX12GetBaseSubobjectType(SubobjectType)]) + { + pCallbacks->ErrorDuplicateSubobject(SubobjectType); + return E_INVALIDARG; // disallow subobject duplicates in a stream + } + SubobjectSeen[SubobjectType] = true; + switch (SubobjectType) + { + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE: + pCallbacks->RootSignatureCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::pRootSignature); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS: + pCallbacks->VSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::VS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS: + pCallbacks->PSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS: + pCallbacks->DSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS: + pCallbacks->HSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::HS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS: + pCallbacks->GSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::GS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS: + pCallbacks->CSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT: + pCallbacks->StreamOutputCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::StreamOutput); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND: + pCallbacks->BlendStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::BlendState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK: + pCallbacks->SampleMaskCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleMask); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER: + pCallbacks->RasterizerStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RasterizerState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL: + pCallbacks->DepthStencilStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: + pCallbacks->DepthStencilState1Cb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DepthStencilState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT: + pCallbacks->InputLayoutCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::InputLayout); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE: + pCallbacks->IBStripCutValueCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::IBStripCutValue); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY: + pCallbacks->PrimitiveTopologyTypeCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PrimitiveTopologyType); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS: + pCallbacks->RTVFormatsCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RTVFormats); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT: + pCallbacks->DSVFormatCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DSVFormat); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC: + pCallbacks->SampleDescCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleDesc); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK: + pCallbacks->NodeMaskCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::NodeMask); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO: + pCallbacks->CachedPSOCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CachedPSO); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS: + pCallbacks->FlagsCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::Flags); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING: + pCallbacks->ViewInstancingCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM1::ViewInstancingDesc); + break; + default: + pCallbacks->ErrorUnknownSubobject(SubobjectType); + return E_INVALIDARG; + break; + } + } + + return S_OK; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_CLEAR_VALUE &a, const D3D12_CLEAR_VALUE &b) +{ + if (a.Format != b.Format) return false; + if (a.Format == DXGI_FORMAT_D24_UNORM_S8_UINT + || a.Format == DXGI_FORMAT_D16_UNORM + || a.Format == DXGI_FORMAT_D32_FLOAT + || a.Format == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) + { + return (a.DepthStencil.Depth == b.DepthStencil.Depth) && + (a.DepthStencil.Stencil == b.DepthStencil.Stencil); + } else { + return (a.Color[0] == b.Color[0]) && + (a.Color[1] == b.Color[1]) && + (a.Color[2] == b.Color[2]) && + (a.Color[3] == b.Color[3]); + } +} +inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &b) +{ + return a.ClearValue == b.ClearValue; +} +inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &a, const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &b) +{ + if (a.pSrcResource != b.pSrcResource) return false; + if (a.pDstResource != b.pDstResource) return false; + if (a.SubresourceCount != b.SubresourceCount) return false; + if (a.Format != b.Format) return false; + if (a.ResolveMode != b.ResolveMode) return false; + if (a.PreserveResolveSource != b.PreserveResolveSource) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) +{ + if (a.Type != b.Type) return false; + if (a.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR && !(a.Clear == b.Clear)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS &a, const D3D12_RENDER_PASS_ENDING_ACCESS &b) +{ + if (a.Type != b.Type) return false; + if (a.Type == D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE && !(a.Resolve == b.Resolve)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) +{ + if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; + if (!(a.BeginningAccess == b.BeginningAccess)) return false; + if (!(a.EndingAccess == b.EndingAccess)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &b) +{ + if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; + if (!(a.DepthBeginningAccess == b.DepthBeginningAccess)) return false; + if (!(a.StencilBeginningAccess == b.StencilBeginningAccess)) return false; + if (!(a.DepthEndingAccess == b.DepthEndingAccess)) return false; + if (!(a.StencilEndingAccess == b.StencilEndingAccess)) return false; + return true; +} + + +#ifndef D3DX12_NO_STATE_OBJECT_HELPERS + +//================================================================================================ +// D3DX12 State Object Creation Helpers +// +// Helper classes for creating new style state objects out of an arbitrary set of subobjects. +// Uses STL +// +// Start by instantiating CD3DX12_STATE_OBJECT_DESC (see it's public methods). +// One of its methods is CreateSubobject(), which has a comment showing a couple of options for +// defining subobjects using the helper classes for each subobject (CD3DX12_DXIL_LIBRARY_SUBOBJECT +// etc.). The subobject helpers each have methods specific to the subobject for configuring it's +// contents. +// +//================================================================================================ +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------------------------ +class CD3DX12_STATE_OBJECT_DESC +{ +public: + CD3DX12_STATE_OBJECT_DESC() + { + Init(D3D12_STATE_OBJECT_TYPE_COLLECTION); + } + CD3DX12_STATE_OBJECT_DESC(D3D12_STATE_OBJECT_TYPE Type) + { + Init(Type); + } + void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) { m_Desc.Type = Type; } + operator const D3D12_STATE_OBJECT_DESC&() + { + // Do final preparation work + m_RepointedAssociations.clear(); + m_SubobjectArray.clear(); + m_SubobjectArray.reserve(m_Desc.NumSubobjects); + // Flatten subobjects into an array (each flattened subobject still has a + // member that's a pointer to it's desc that's not flattened) + for (auto Iter = m_SubobjectList.begin(); + Iter != m_SubobjectList.end(); Iter++) + { + m_SubobjectArray.push_back(*Iter); + // Store new location in array so we can redirect pointers contained in subobjects + Iter->pSubobjectArrayLocation = &m_SubobjectArray.back(); + } + // For subobjects with pointer fields, create a new copy of those subobject definitions + // with fixed pointers + for (UINT i = 0; i < m_Desc.NumSubobjects; i++) + { + if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION) + { + auto pOriginalSubobjectAssociation = + reinterpret_cast(m_SubobjectArray[i].pDesc); + D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION Repointed = *pOriginalSubobjectAssociation; + auto pWrapper = + static_cast(pOriginalSubobjectAssociation->pSubobjectToAssociate); + Repointed.pSubobjectToAssociate = pWrapper->pSubobjectArrayLocation; + m_RepointedAssociations.push_back(Repointed); + m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back(); + } + } + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr; + return m_Desc; + } + operator const D3D12_STATE_OBJECT_DESC*() + { + // Cast calls the above final preparation work + return &static_cast(*this); + } + + // CreateSubobject creates a sububject helper (e.g. CD3DX12_HIT_GROUP_SUBOBJECT) + // whose lifetime is owned by this class. + // e.g. + // + // CD3DX12_STATE_OBJECT_DESC Collection1(D3D12_STATE_OBJECT_TYPE_COLLECTION); + // auto Lib0 = Collection1.CreateSubobject(); + // Lib0->SetDXILLibrary(&pMyAppDxilLibs[0]); + // Lib0->DefineExport(L"rayGenShader0"); // in practice these export listings might be + // // data/engine driven + // etc. + // + // Alternatively, users can instantiate sububject helpers explicitly, such as via local + // variables instead, passing the state object desc that should point to it into the helper + // constructor (or call mySubobjectHelper.AddToStateObject(Collection1)). + // In this alternative scenario, the user must keep the subobject alive as long as the state + // object it is associated with is alive, else it's pointer references will be stale. + // e.g. + // + // CD3DX12_STATE_OBJECT_DESC RaytracingState2(D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE); + // CD3DX12_DXIL_LIBRARY_SUBOBJECT LibA(RaytracingState2); + // LibA.SetDXILLibrary(&pMyAppDxilLibs[4]); // not manually specifying exports + // // - meaning all exports in the libraries + // // are exported + // etc. + + template + T* CreateSubobject() + { + T* pSubobject = new T(*this); + m_OwnedSubobjectHelpers.emplace_back(pSubobject); + return pSubobject; + } + +private: + D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc) + { + SUBOBJECT_WRAPPER Subobject; + Subobject.pSubobjectArrayLocation = nullptr; + Subobject.Type = Type; + Subobject.pDesc = pDesc; + m_SubobjectList.push_back(Subobject); + m_Desc.NumSubobjects++; + return &m_SubobjectList.back(); + } + void Init(D3D12_STATE_OBJECT_TYPE Type) + { + SetStateObjectType(Type); + m_Desc.pSubobjects = nullptr; + m_Desc.NumSubobjects = 0; + m_SubobjectList.clear(); + m_SubobjectArray.clear(); + m_RepointedAssociations.clear(); + } + typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT + { + D3D12_STATE_SUBOBJECT* pSubobjectArrayLocation; // new location when flattened into array + // for repointing pointers in subobjects + } SUBOBJECT_WRAPPER; + D3D12_STATE_OBJECT_DESC m_Desc; + std::list m_SubobjectList; // Pointers to list nodes handed out so + // these can be edited live + std::vector m_SubobjectArray; // Built at the end, copying list contents + + std::list + m_RepointedAssociations; // subobject type that contains pointers to other subobjects, + // repointed to flattened array + + class StringContainer + { + public: + LPCWSTR LocalCopy(LPCWSTR string, bool bSingleString = false) + { + if (string) + { + if (bSingleString) + { + m_Strings.clear(); + m_Strings.push_back(string); + } + else + { + m_Strings.push_back(string); + } + return m_Strings.back().c_str(); + } + else + { + return nullptr; + } + } + void clear() { m_Strings.clear(); } + private: + std::list m_Strings; + }; + + class SUBOBJECT_HELPER_BASE + { + public: + SUBOBJECT_HELPER_BASE() { Init(); } + virtual ~SUBOBJECT_HELPER_BASE() {} + virtual D3D12_STATE_SUBOBJECT_TYPE Type() const = 0; + void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data()); + } + protected: + virtual void* Data() = 0; + void Init() { m_pSubobject = nullptr; } + D3D12_STATE_SUBOBJECT* m_pSubobject; + }; + +#if(__cplusplus >= 201103L) + std::list> m_OwnedSubobjectHelpers; +#else + class OWNED_HELPER + { + public: + OWNED_HELPER(const SUBOBJECT_HELPER_BASE* pHelper) { m_pHelper = pHelper; } + ~OWNED_HELPER() { delete m_pHelper; } + const SUBOBJECT_HELPER_BASE* m_pHelper; + }; + + std::list m_OwnedSubobjectHelpers; +#endif + + friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT; + friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT; + friend class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT; + friend class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + friend class CD3DX12_HIT_GROUP_SUBOBJECT; + friend class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT; + friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT; + friend class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT; + friend class CD3DX12_NODE_MASK_SUBOBJECT; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DXIL_LIBRARY_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DXIL_LIBRARY_SUBOBJECT() + { + Init(); + } + CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDXILLibrary(D3D12_SHADER_BYTECODE*pCode) + { + static const D3D12_SHADER_BYTECODE Default = {}; + m_Desc.DXILLibrary = pCode ? *pCode : Default; + } + void DefineExport( + LPCWSTR Name, + LPCWSTR ExportToRename = nullptr, + D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) + { + D3D12_EXPORT_DESC Export; + Export.Name = m_Strings.LocalCopy(Name); + Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); + Export.Flags = Flags; + m_Exports.push_back(Export); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + m_Desc.NumExports = static_cast(m_Exports.size()); + } + template + void DefineExports(LPCWSTR(&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + void DefineExports(LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_DXIL_LIBRARY_DESC&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() { return &m_Desc; } + D3D12_DXIL_LIBRARY_DESC m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_EXISTING_COLLECTION_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_EXISTING_COLLECTION_SUBOBJECT() + { + Init(); + } + CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetExistingCollection(ID3D12StateObject*pExistingCollection) + { + m_Desc.pExistingCollection = pExistingCollection; + m_CollectionRef = pExistingCollection; + } + void DefineExport( + LPCWSTR Name, + LPCWSTR ExportToRename = nullptr, + D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) + { + D3D12_EXPORT_DESC Export; + Export.Name = m_Strings.LocalCopy(Name); + Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); + Export.Flags = Flags; + m_Exports.push_back(Export); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + m_Desc.NumExports = static_cast(m_Exports.size()); + } + template + void DefineExports(LPCWSTR(&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + void DefineExports(LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_EXISTING_COLLECTION_DESC&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_CollectionRef = nullptr; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() { return &m_Desc; } + D3D12_EXISTING_COLLECTION_DESC m_Desc; + Microsoft::WRL::ComPtr m_CollectionRef; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT() + { + Init(); + } + CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSubobjectToAssociate(const D3D12_STATE_SUBOBJECT& SubobjectToAssociate) + { + m_Desc.pSubobjectToAssociate = &SubobjectToAssociate; + } + void AddExport(LPCWSTR Export) + { + m_Desc.NumExports++; + m_Exports.push_back(m_Strings.LocalCopy(Export)); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + } + template + void AddExports(LPCWSTR (&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + void AddExports(LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() { return &m_Desc; } + D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION() + { + Init(); + } + CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSubobjectNameToAssociate(LPCWSTR SubobjectToAssociate) + { + m_Desc.SubobjectToAssociate = m_SubobjectName.LocalCopy(SubobjectToAssociate, true); + } + void AddExport(LPCWSTR Export) + { + m_Desc.NumExports++; + m_Exports.push_back(m_Strings.LocalCopy(Export)); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + } + template + void AddExports(LPCWSTR (&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + void AddExports(LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_SubobjectName.clear(); + m_Exports.clear(); + } + void* Data() { return &m_Desc; } + D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_HIT_GROUP_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_HIT_GROUP_SUBOBJECT() + { + Init(); + } + CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetHitGroupExport(LPCWSTR exportName) + { + m_Desc.HitGroupExport = m_Strings[0].LocalCopy(exportName, true); + } + void SetHitGroupType(D3D12_HIT_GROUP_TYPE Type) { m_Desc.Type = Type; } + void SetAnyHitShaderImport(LPCWSTR importName) + { + m_Desc.AnyHitShaderImport = m_Strings[1].LocalCopy(importName, true); + } + void SetClosestHitShaderImport(LPCWSTR importName) + { + m_Desc.ClosestHitShaderImport = m_Strings[2].LocalCopy(importName, true); + } + void SetIntersectionShaderImport(LPCWSTR importName) + { + m_Desc.IntersectionShaderImport = m_Strings[3].LocalCopy(importName, true); + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_HIT_GROUP_DESC&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + for (UINT i = 0; i < m_NumStrings; i++) + { + m_Strings[i].clear(); + } + } + void* Data() { return &m_Desc; } + D3D12_HIT_GROUP_DESC m_Desc; + static const UINT m_NumStrings = 4; + CD3DX12_STATE_OBJECT_DESC::StringContainer + m_Strings[m_NumStrings]; // one string for every entrypoint name +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() + { + Init(); + } + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void Config(UINT MaxPayloadSizeInBytes, UINT MaxAttributeSizeInBytes) + { + m_Desc.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes; + m_Desc.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_RAYTRACING_SHADER_CONFIG&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() { return &m_Desc; } + D3D12_RAYTRACING_SHADER_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() + { + Init(); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void Config(UINT MaxTraceRecursionDepth) + { + m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() { return &m_Desc; } + D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT() + { + Init(); + } + CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetRootSignature(ID3D12RootSignature* pRootSig) + { + m_pRootSig = pRootSig; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator ID3D12RootSignature*() const { return m_pRootSig.Get(); } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_pRootSig = nullptr; + } + void* Data() { return m_pRootSig.GetAddressOf(); } + Microsoft::WRL::ComPtr m_pRootSig; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT() + { + Init(); + } + CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetRootSignature(ID3D12RootSignature* pRootSig) + { + m_pRootSig = pRootSig; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator ID3D12RootSignature*() const { return m_pRootSig.Get(); } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_pRootSig = nullptr; + } + void* Data() { return m_pRootSig.GetAddressOf(); } + Microsoft::WRL::ComPtr m_pRootSig; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() + { + Init(); + } + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetFlags(D3D12_STATE_OBJECT_FLAGS Flags) + { + m_Desc.Flags = Flags; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_STATE_OBJECT_CONFIG&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() { return &m_Desc; } + D3D12_STATE_OBJECT_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_NODE_MASK_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_NODE_MASK_SUBOBJECT() + { + Init(); + } + CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetNodeMask(UINT NodeMask) + { + m_Desc.NodeMask = NodeMask; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const + { + return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK; + } + operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } + operator const D3D12_NODE_MASK&() const { return m_Desc; } +private: + void Init() + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() { return &m_Desc; } + D3D12_NODE_MASK m_Desc; +}; + +#endif // #ifndef D3DX12_NO_STATE_OBJECT_HELPERS + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_cc.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_cc.cpp new file mode 100644 index 000000000..25ae8b324 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_cc.cpp @@ -0,0 +1,56 @@ +#include "gfx_cc.h" + +void gfx_cc_get_features(uint64_t shader_id0, uint32_t shader_id1, struct CCFeatures *cc_features) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 4; k++) { + cc_features->c[i][j][k] = (shader_id0 >> (i * 32 + j * 16 + k * 4)) & 0xf; + } + } + } + + cc_features->opt_alpha = (shader_id1 & SHADER_OPT_ALPHA) != 0; + cc_features->opt_fog = (shader_id1 & SHADER_OPT_FOG) != 0; + cc_features->opt_texture_edge = (shader_id1 & SHADER_OPT_TEXTURE_EDGE) != 0; + cc_features->opt_noise = (shader_id1 & SHADER_OPT_NOISE) != 0; + cc_features->opt_2cyc = (shader_id1 & SHADER_OPT_2CYC) != 0; + cc_features->opt_alpha_threshold = (shader_id1 & SHADER_OPT_ALPHA_THRESHOLD) != 0; + cc_features->opt_invisible = (shader_id1 & SHADER_OPT_INVISIBLE) != 0; + + cc_features->clamp[0][0] = (shader_id1 & SHADER_OPT_TEXEL0_CLAMP_S); + cc_features->clamp[0][1] = (shader_id1 & SHADER_OPT_TEXEL0_CLAMP_T); + cc_features->clamp[1][0] = (shader_id1 & SHADER_OPT_TEXEL1_CLAMP_S); + cc_features->clamp[1][1] = (shader_id1 & SHADER_OPT_TEXEL1_CLAMP_T); + + cc_features->used_textures[0] = false; + cc_features->used_textures[1] = false; + cc_features->num_inputs = 0; + + for (int c = 0; c < 2; c++) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 4; j++) { + if (cc_features->c[c][i][j] >= SHADER_INPUT_1 && cc_features->c[c][i][j] <= SHADER_INPUT_7) { + if (cc_features->c[c][i][j] > cc_features->num_inputs) { + cc_features->num_inputs = cc_features->c[c][i][j]; + } + } + if (cc_features->c[c][i][j] == SHADER_TEXEL0 || cc_features->c[c][i][j] == SHADER_TEXEL0A) { + cc_features->used_textures[0] = true; + } + if (cc_features->c[c][i][j] == SHADER_TEXEL1 || cc_features->c[c][i][j] == SHADER_TEXEL1A) { + cc_features->used_textures[1] = true; + } + } + } + } + + for (int c = 0; c < 2; c++) { + cc_features->do_single[c][0] = cc_features->c[c][0][2] == SHADER_0; + cc_features->do_single[c][1] = cc_features->c[c][1][2] == SHADER_0; + cc_features->do_multiply[c][0] = cc_features->c[c][0][1] == SHADER_0 && cc_features->c[c][0][3] == SHADER_0; + cc_features->do_multiply[c][1] = cc_features->c[c][1][1] == SHADER_0 && cc_features->c[c][1][3] == SHADER_0; + cc_features->do_mix[c][0] = cc_features->c[c][0][1] == cc_features->c[c][0][3]; + cc_features->do_mix[c][1] = cc_features->c[c][1][1] == cc_features->c[c][1][3]; + cc_features->color_alpha_same[c] = ((shader_id0 >> c * 32) & 0xffff) == ((shader_id0 >> (c * 32 + 16)) & 0xffff); + } +} diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_cc.h b/libultraship/libultraship/Lib/Fast3D/gfx_cc.h new file mode 100644 index 000000000..7bf415f84 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_cc.h @@ -0,0 +1,68 @@ +#ifndef GFX_CC_H +#define GFX_CC_H + +#include +#include + +/*enum { + CC_0, + CC_TEXEL0, + CC_TEXEL1, + CC_PRIM, + CC_SHADE, + CC_ENV, + CC_TEXEL0A, + CC_LOD +};*/ + +enum { + SHADER_0, + SHADER_INPUT_1, + SHADER_INPUT_2, + SHADER_INPUT_3, + SHADER_INPUT_4, + SHADER_INPUT_5, + SHADER_INPUT_6, + SHADER_INPUT_7, + SHADER_TEXEL0, + SHADER_TEXEL0A, + SHADER_TEXEL1, + SHADER_TEXEL1A, + SHADER_1, + SHADER_COMBINED +}; + +#define SHADER_OPT_ALPHA (1 << 0) +#define SHADER_OPT_FOG (1 << 1) +#define SHADER_OPT_TEXTURE_EDGE (1 << 2) +#define SHADER_OPT_NOISE (1 << 3) +#define SHADER_OPT_2CYC (1 << 4) +#define SHADER_OPT_ALPHA_THRESHOLD (1 << 5) +#define SHADER_OPT_INVISIBLE (1 << 6) +#define SHADER_OPT_TEXEL0_CLAMP_S (1 << 7) +#define SHADER_OPT_TEXEL0_CLAMP_T (1 << 8) +#define SHADER_OPT_TEXEL1_CLAMP_S (1 << 9) +#define SHADER_OPT_TEXEL1_CLAMP_T (1 << 10) +#define CC_SHADER_OPT_POS 56 + +struct CCFeatures { + uint8_t c[2][2][4]; + bool opt_alpha; + bool opt_fog; + bool opt_texture_edge; + bool opt_noise; + bool opt_2cyc; + bool opt_alpha_threshold; + bool opt_invisible; + bool used_textures[2]; + bool clamp[2][2]; + int num_inputs; + bool do_single[2][2]; + bool do_multiply[2][2]; + bool do_mix[2][2]; + bool color_alpha_same[2]; +}; + +void gfx_cc_get_features(uint64_t shader_id0, uint32_t shader_id1, struct CCFeatures *cc_features); + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.cpp new file mode 100644 index 000000000..c989290c6 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.cpp @@ -0,0 +1,1015 @@ +#ifdef ENABLE_DX11 + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#ifndef _LANGUAGE_C +#define _LANGUAGE_C +#endif +#include + +#include "gfx_cc.h" +#include "gfx_window_manager_api.h" +#include "gfx_rendering_api.h" +#include "gfx_direct3d_common.h" + +#define DECLARE_GFX_DXGI_FUNCTIONS +#include "gfx_dxgi.h" + +#include "gfx_screen_config.h" +#include "../../SohImGuiImpl.h" + +#define THREE_POINT_FILTERING 0 +#define DEBUG_D3D 0 + +using namespace Microsoft::WRL; // For ComPtr + +namespace { + +struct PerFrameCB { + uint32_t noise_frame; + float noise_scale_x; + float noise_scale_y; + uint32_t padding; +}; + +struct PerDrawCB { + struct Texture { + uint32_t width; + uint32_t height; + uint32_t linear_filtering; + uint32_t padding; + } textures[2]; +}; + +struct CoordCB { + float x, y; + float padding[2]; // structure size must be multiple of 16 +}; + +struct TextureData { + ComPtr resource_view; + ComPtr sampler_state; + uint32_t width; + uint32_t height; + bool linear_filtering; +}; + +struct FramebufferData { + ComPtr render_target_view; + ComPtr depth_stencil_view; + uint32_t texture_id; +}; + +struct ShaderProgramD3D11 { + ComPtr vertex_shader; + ComPtr pixel_shader; + ComPtr input_layout; + ComPtr blend_state; + + uint64_t shader_id0; + uint32_t shader_id1; + uint8_t num_inputs; + uint8_t num_floats; + bool used_textures[2]; +}; + +static struct { + HMODULE d3d11_module; + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice; + + HMODULE d3dcompiler_module; + pD3DCompile D3DCompile; + + D3D_FEATURE_LEVEL feature_level; + + ComPtr device; + ComPtr swap_chain; + ComPtr context; + ComPtr backbuffer_view; + ComPtr depth_stencil_view; + ComPtr depth_stencil_srv; + ComPtr rasterizer_state; + ComPtr depth_stencil_state; + ComPtr vertex_buffer; + ComPtr per_frame_cb; + ComPtr per_draw_cb; + ComPtr depth_stencil_texture; + ComPtr depth_stencil_copy_texture; + ComPtr coord_buffer; + ComPtr depth_value_output_buffer; + ComPtr depth_value_output_buffer_copy; + ComPtr depth_value_output_uav; + ComPtr depth_value_sampler; + ComPtr compute_shader; + bool copied_depth_buffer; + +#if DEBUG_D3D + ComPtr debug; +#endif + + DXGI_SAMPLE_DESC sample_description; + + PerFrameCB per_frame_cb_data; + PerDrawCB per_draw_cb_data; + + std::map, struct ShaderProgramD3D11> shader_program_pool; + + std::vector textures; + int current_tile; + uint32_t current_texture_ids[2]; + + std::vector framebuffers; + + // Current state + + struct ShaderProgramD3D11 *shader_program; + + uint32_t current_width, current_height; + uint32_t render_target_height; + + int8_t depth_test; + int8_t depth_mask; + int8_t zmode_decal; + + // Previous states (to prevent setting states needlessly) + + struct ShaderProgramD3D11 *last_shader_program = nullptr; + uint32_t last_vertex_buffer_stride = 0; + ComPtr last_blend_state = nullptr; + ComPtr last_resource_views[2] = { nullptr, nullptr }; + ComPtr last_sampler_states[2] = { nullptr, nullptr }; + int8_t last_depth_test = -1; + int8_t last_depth_mask = -1; + int8_t last_zmode_decal = -1; + D3D_PRIMITIVE_TOPOLOGY last_primitive_topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; +} d3d; + +static LARGE_INTEGER last_time, accumulated_time, frequency; + +void create_depth_stencil_objects(uint32_t width, uint32_t height, ID3D11Texture2D **texture, ID3D11DepthStencilView **view, ID3D11ShaderResourceView **srv) { + D3D11_TEXTURE2D_DESC texture_desc; + texture_desc.Width = width; + texture_desc.Height = height; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.Format = d3d.feature_level >= D3D_FEATURE_LEVEL_10_0 ? + DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R24G8_TYPELESS; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + texture_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | (srv != nullptr ? D3D11_BIND_SHADER_RESOURCE : 0); + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + ThrowIfFailed(d3d.device->CreateTexture2D(&texture_desc, nullptr, texture)); + + D3D11_DEPTH_STENCIL_VIEW_DESC view_desc; + view_desc.Format = d3d.feature_level >= D3D_FEATURE_LEVEL_10_0 ? + DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_D24_UNORM_S8_UINT; + view_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + view_desc.Flags = 0; + view_desc.Texture2D.MipSlice = 0; + + ThrowIfFailed(d3d.device->CreateDepthStencilView(*texture, &view_desc, view)); + + if (srv != nullptr) { + D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc; + srv_desc.Format = d3d.feature_level >= D3D_FEATURE_LEVEL_10_0 ? + DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MostDetailedMip = 0; + srv_desc.Texture2D.MipLevels = -1; + + ThrowIfFailed(d3d.device->CreateShaderResourceView(*texture, &srv_desc, srv)); + } +} + +static void create_render_target_views(bool is_resize) { + DXGI_SWAP_CHAIN_DESC1 desc1; + + if (is_resize) { + // Release previous stuff (if any) + + d3d.backbuffer_view.Reset(); + d3d.depth_stencil_texture.Reset(); + d3d.depth_stencil_view.Reset(); + d3d.depth_stencil_srv.Reset(); + d3d.depth_stencil_copy_texture.Reset(); + + // Resize swap chain buffers + + ThrowIfFailed(d3d.swap_chain->GetDesc1(&desc1)); + ThrowIfFailed(d3d.swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, desc1.Flags), + gfx_dxgi_get_h_wnd(), "Failed to resize IDXGISwapChain buffers."); + } + + // Get new size + + ThrowIfFailed(d3d.swap_chain->GetDesc1(&desc1)); + + // Create back buffer + + ComPtr backbuffer_texture; + ThrowIfFailed(d3d.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *) backbuffer_texture.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to get backbuffer from IDXGISwapChain."); + + ThrowIfFailed(d3d.device->CreateRenderTargetView(backbuffer_texture.Get(), nullptr, d3d.backbuffer_view.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to create render target view."); + + // Create depth buffer + create_depth_stencil_objects(desc1.Width, desc1.Height, d3d.depth_stencil_texture.GetAddressOf(), d3d.depth_stencil_view.GetAddressOf(), d3d.depth_stencil_srv.GetAddressOf()); + + // Create texture that can be used to retrieve depth value + + D3D11_TEXTURE2D_DESC depth_texture = {}; + depth_texture.Width = desc1.Width; + depth_texture.Height = desc1.Height; + depth_texture.MipLevels = 1; + depth_texture.ArraySize = 1; + depth_texture.Format = DXGI_FORMAT_D32_FLOAT; + depth_texture.SampleDesc.Count = 1; + depth_texture.SampleDesc.Quality = 0; + depth_texture.Usage = D3D11_USAGE_STAGING; + depth_texture.BindFlags = 0; + depth_texture.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + depth_texture.MiscFlags = 0; + ThrowIfFailed(d3d.device->CreateTexture2D(&depth_texture, nullptr, d3d.depth_stencil_copy_texture.GetAddressOf())); + + // Save resolution + + d3d.current_width = desc1.Width; + d3d.current_height = desc1.Height; +} + +static void gfx_d3d11_init(void) { + // Load d3d11.dll + d3d.d3d11_module = LoadLibraryW(L"d3d11.dll"); + if (d3d.d3d11_module == nullptr) { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()), gfx_dxgi_get_h_wnd(), "d3d11.dll not found"); + } + d3d.D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d.d3d11_module, "D3D11CreateDevice"); + + // Load D3DCompiler_47.dll + d3d.d3dcompiler_module = LoadLibraryW(L"D3DCompiler_47.dll"); + if (d3d.d3dcompiler_module == nullptr) { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()), gfx_dxgi_get_h_wnd(), "D3DCompiler_47.dll not found"); + } + d3d.D3DCompile = (pD3DCompile)GetProcAddress(d3d.d3dcompiler_module, "D3DCompile"); + + // Create D3D11 device + + gfx_dxgi_create_factory_and_device(DEBUG_D3D, 11, [](IDXGIAdapter1 *adapter, bool test_only) { +#if DEBUG_D3D + UINT device_creation_flags = D3D11_CREATE_DEVICE_DEBUG; +#else + UINT device_creation_flags = 0; +#endif + D3D_FEATURE_LEVEL FeatureLevels[] = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + + HRESULT res = d3d.D3D11CreateDevice( + adapter, + D3D_DRIVER_TYPE_UNKNOWN, // since we use a specific adapter + nullptr, + device_creation_flags, + FeatureLevels, + ARRAYSIZE(FeatureLevels), + D3D11_SDK_VERSION, + test_only ? nullptr : d3d.device.GetAddressOf(), + &d3d.feature_level, + test_only ? nullptr : d3d.context.GetAddressOf()); + + if (test_only) { + return SUCCEEDED(res); + } else { + ThrowIfFailed(res, gfx_dxgi_get_h_wnd(), "Failed to create D3D11 device."); + return true; + } + }); + + // Sample description to be used in back buffer and depth buffer + + d3d.sample_description.Count = 1; + d3d.sample_description.Quality = 0; + + // Create the swap chain + d3d.swap_chain = gfx_dxgi_create_swap_chain(d3d.device.Get()); + + // Create D3D Debug device if in debug mode + +#if DEBUG_D3D + ThrowIfFailed(d3d.device->QueryInterface(__uuidof(ID3D11Debug), (void **) d3d.debug.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to get ID3D11Debug device."); +#endif + + // Create views + + create_render_target_views(false); + + // Create main vertex buffer + + D3D11_BUFFER_DESC vertex_buffer_desc; + ZeroMemory(&vertex_buffer_desc, sizeof(D3D11_BUFFER_DESC)); + + vertex_buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + vertex_buffer_desc.ByteWidth = 256 * 32 * 3 * sizeof(float); // Same as buf_vbo size in gfx_pc + vertex_buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertex_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vertex_buffer_desc.MiscFlags = 0; + + ThrowIfFailed(d3d.device->CreateBuffer(&vertex_buffer_desc, nullptr, d3d.vertex_buffer.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to create vertex buffer."); + + // Create per-frame constant buffer + + D3D11_BUFFER_DESC constant_buffer_desc; + ZeroMemory(&constant_buffer_desc, sizeof(D3D11_BUFFER_DESC)); + + constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + constant_buffer_desc.ByteWidth = sizeof(PerFrameCB); + constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constant_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constant_buffer_desc.MiscFlags = 0; + + ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_frame_cb.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to create per-frame constant buffer."); + + d3d.context->PSSetConstantBuffers(0, 1, d3d.per_frame_cb.GetAddressOf()); + + // Create per-draw constant buffer + + constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC; + constant_buffer_desc.ByteWidth = sizeof(PerDrawCB); + constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constant_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constant_buffer_desc.MiscFlags = 0; + + ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_draw_cb.GetAddressOf()), + gfx_dxgi_get_h_wnd(), "Failed to create per-draw constant buffer."); + + d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf()); + + // Create compute shader that can be used to retrieve depth buffer values + + D3D11_BUFFER_DESC coord_cb_desc; + coord_cb_desc.Usage = D3D11_USAGE_DYNAMIC; + coord_cb_desc.ByteWidth = sizeof(CoordCB); + coord_cb_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + coord_cb_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + coord_cb_desc.MiscFlags = 0; + coord_cb_desc.StructureByteStride = 0; + + ThrowIfFailed(d3d.device->CreateBuffer(&coord_cb_desc, nullptr, d3d.coord_buffer.GetAddressOf())); + + D3D11_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.MinLOD = 0; + sampler_desc.MaxLOD = D3D11_FLOAT32_MAX; + ThrowIfFailed(d3d.device->CreateSamplerState(&sampler_desc, d3d.depth_value_sampler.GetAddressOf())); + + D3D11_BUFFER_DESC output_buffer_desc; + output_buffer_desc.Usage = D3D11_USAGE_DEFAULT; + output_buffer_desc.ByteWidth = sizeof(float); + output_buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + output_buffer_desc.CPUAccessFlags = 0; + output_buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + output_buffer_desc.StructureByteStride = sizeof(float); + ThrowIfFailed(d3d.device->CreateBuffer(&output_buffer_desc, nullptr, d3d.depth_value_output_buffer.GetAddressOf())); + + D3D11_UNORDERED_ACCESS_VIEW_DESC output_buffer_uav_desc; + output_buffer_uav_desc.Format = DXGI_FORMAT_UNKNOWN; + output_buffer_uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + output_buffer_uav_desc.Buffer.FirstElement = 0; + output_buffer_uav_desc.Buffer.NumElements = 1; + output_buffer_uav_desc.Buffer.Flags = 0; + ThrowIfFailed(d3d.device->CreateUnorderedAccessView(d3d.depth_value_output_buffer.Get(), &output_buffer_uav_desc, d3d.depth_value_output_uav.GetAddressOf())); + + output_buffer_desc.Usage = D3D11_USAGE_STAGING; + output_buffer_desc.BindFlags = 0; + output_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + ThrowIfFailed(d3d.device->CreateBuffer(&output_buffer_desc, nullptr, d3d.depth_value_output_buffer_copy.GetAddressOf())); + + const char* shader_source = R"( +sampler my_sampler : register(s0); +Texture2D tex : register(t0); +cbuffer coordCB : register(b0) { + float2 coord; +} + +RWStructuredBuffer output : register(u0); + +[numthreads(1, 1, 1)] +void CSMain(uint3 DTid : SV_DispatchThreadID) { + output[0] = tex.SampleLevel(my_sampler, coord, 0); +} +)"; +#if DEBUG_D3D + UINT compile_flags = D3DCOMPILE_DEBUG; +#else + UINT compile_flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; +#endif + + ComPtr cs, error_blob; + HRESULT hr = d3d.D3DCompile(shader_source, strlen(shader_source), nullptr, nullptr, nullptr, "CSMain", "cs_4_0", compile_flags, 0, cs.GetAddressOf(), error_blob.GetAddressOf()); + + if (FAILED(hr)) { + char* err = (char*)error_blob->GetBufferPointer(); + MessageBoxA(gfx_dxgi_get_h_wnd(), err, "Error", MB_OK | MB_ICONERROR); + throw hr; + } + + ThrowIfFailed(d3d.device->CreateComputeShader(cs->GetBufferPointer(), cs->GetBufferSize(), nullptr, d3d.compute_shader.GetAddressOf())); + + // Create ImGui + + SohImGui::WindowImpl window_impl; + window_impl.backend = SohImGui::Backend::DX11; + window_impl.dx11 = { gfx_dxgi_get_h_wnd(), d3d.context.Get(), d3d.device.Get() }; + SohImGui::Init(window_impl); +} + + +static bool gfx_d3d11_z_is_from_0_to_1(void) { + return true; +} + +static void gfx_d3d11_unload_shader(struct ShaderProgram *old_prg) { +} + +static void gfx_d3d11_load_shader(struct ShaderProgram *new_prg) { + d3d.shader_program = (struct ShaderProgramD3D11 *)new_prg; +} + +static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(uint64_t shader_id0, uint32_t shader_id1) { + CCFeatures cc_features; + gfx_cc_get_features(shader_id0, shader_id1, &cc_features); + + char buf[4096]; + size_t len, num_floats; + + gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, THREE_POINT_FILTERING); + + ComPtr vs, ps; + ComPtr error_blob; + +#if DEBUG_D3D + UINT compile_flags = D3DCOMPILE_DEBUG; +#else + UINT compile_flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; +#endif + + HRESULT hr = d3d.D3DCompile(buf, len, nullptr, nullptr, nullptr, "VSMain", "vs_4_0", compile_flags, 0, vs.GetAddressOf(), error_blob.GetAddressOf()); + + if (FAILED(hr)) { + char* err = (char*)error_blob->GetBufferPointer(); + MessageBoxA(gfx_dxgi_get_h_wnd(), err, "Error", MB_OK | MB_ICONERROR); + throw hr; + } + + hr = d3d.D3DCompile(buf, len, nullptr, nullptr, nullptr, "PSMain", "ps_4_0", compile_flags, 0, ps.GetAddressOf(), error_blob.GetAddressOf()); + + if (FAILED(hr)) { + char* err = (char*)error_blob->GetBufferPointer(); + MessageBoxA(gfx_dxgi_get_h_wnd(), err, "Error", MB_OK | MB_ICONERROR); + throw hr; + } + + struct ShaderProgramD3D11 *prg = &d3d.shader_program_pool[std::make_pair(shader_id0, shader_id1)]; + + ThrowIfFailed(d3d.device->CreateVertexShader(vs->GetBufferPointer(), vs->GetBufferSize(), nullptr, prg->vertex_shader.GetAddressOf())); + ThrowIfFailed(d3d.device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), nullptr, prg->pixel_shader.GetAddressOf())); + + // Input Layout + + D3D11_INPUT_ELEMENT_DESC ied[16]; + uint8_t ied_index = 0; + ied[ied_index++] = { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + for (UINT i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + ied[ied_index++] = { "TEXCOORD", i, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + if (cc_features.clamp[i][0]) { + ied[ied_index++] = { "TEXCLAMPS", i, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + } + if (cc_features.clamp[i][1]) { + ied[ied_index++] = { "TEXCLAMPT", i, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + } + } + } + if (cc_features.opt_fog) { + ied[ied_index++] = { "FOG", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + } + for (unsigned int i = 0; i < cc_features.num_inputs; i++) { + DXGI_FORMAT format = cc_features.opt_alpha ? DXGI_FORMAT_R32G32B32A32_FLOAT : DXGI_FORMAT_R32G32B32_FLOAT; + ied[ied_index++] = { "INPUT", i, format, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }; + } + + ThrowIfFailed(d3d.device->CreateInputLayout(ied, ied_index, vs->GetBufferPointer(), vs->GetBufferSize(), prg->input_layout.GetAddressOf())); + + // Blend state + + D3D11_BLEND_DESC blend_desc; + ZeroMemory(&blend_desc, sizeof(D3D11_BLEND_DESC)); + + if (cc_features.opt_alpha) { + blend_desc.RenderTarget[0].BlendEnable = true; + blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + } else { + blend_desc.RenderTarget[0].BlendEnable = false; + blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + } + + ThrowIfFailed(d3d.device->CreateBlendState(&blend_desc, prg->blend_state.GetAddressOf())); + + // Save some values + + prg->shader_id0 = shader_id0; + prg->shader_id1 = shader_id1; + prg->num_inputs = cc_features.num_inputs; + prg->num_floats = num_floats; + prg->used_textures[0] = cc_features.used_textures[0]; + prg->used_textures[1] = cc_features.used_textures[1]; + + return (struct ShaderProgram *)(d3d.shader_program = prg); +} + +static struct ShaderProgram *gfx_d3d11_lookup_shader(uint64_t shader_id0, uint32_t shader_id1) { + auto it = d3d.shader_program_pool.find(std::make_pair(shader_id0, shader_id1)); + return it == d3d.shader_program_pool.end() ? nullptr : (struct ShaderProgram *)&it->second; +} + +static void gfx_d3d11_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) { + struct ShaderProgramD3D11 *p = (struct ShaderProgramD3D11 *)prg; + + *num_inputs = p->num_inputs; + used_textures[0] = p->used_textures[0]; + used_textures[1] = p->used_textures[1]; +} + +static uint32_t gfx_d3d11_new_texture(void) { + d3d.textures.resize(d3d.textures.size() + 1); + return (uint32_t)(d3d.textures.size() - 1); +} + +static void gfx_d3d11_delete_texture(uint32_t texID) { + //glDeleteTextures(1, &texID); +} + +static void gfx_d3d11_select_texture(int tile, uint32_t texture_id) { + d3d.current_tile = tile; + d3d.current_texture_ids[tile] = texture_id; +} + +static D3D11_TEXTURE_ADDRESS_MODE gfx_cm_to_d3d11(uint32_t val) { + // TODO: handle G_TX_MIRROR | G_TX_CLAMP + if (val & G_TX_CLAMP) { + return D3D11_TEXTURE_ADDRESS_CLAMP; + } + return (val & G_TX_MIRROR) ? D3D11_TEXTURE_ADDRESS_MIRROR : D3D11_TEXTURE_ADDRESS_WRAP; +} + +static void gfx_d3d11_upload_texture(const uint8_t *rgba32_buf, uint32_t width, uint32_t height) { + // Create texture + + D3D11_TEXTURE2D_DESC texture_desc; + ZeroMemory(&texture_desc, sizeof(D3D11_TEXTURE2D_DESC)); + + texture_desc.Width = width; + texture_desc.Height = height; + texture_desc.Usage = D3D11_USAGE_IMMUTABLE; + texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS ? + texture_desc.ArraySize = 1; + texture_desc.MipLevels = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + + D3D11_SUBRESOURCE_DATA resource_data; + resource_data.pSysMem = rgba32_buf; + resource_data.SysMemPitch = width * 4; + resource_data.SysMemSlicePitch = resource_data.SysMemPitch * height; + + ComPtr texture; + ThrowIfFailed(d3d.device->CreateTexture2D(&texture_desc, &resource_data, texture.GetAddressOf())); + + TextureData *texture_data = &d3d.textures[d3d.current_texture_ids[d3d.current_tile]]; + texture_data->width = width; + texture_data->height = height; + + // Create shader resource view from texture + + if (texture_data->resource_view.Get() != nullptr) { + // Free the previous texture in this slot + texture_data->resource_view.Reset(); + } + + ThrowIfFailed(d3d.device->CreateShaderResourceView(texture.Get(), nullptr, texture_data->resource_view.GetAddressOf())); +} + +static void gfx_d3d11_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) { + D3D11_SAMPLER_DESC sampler_desc; + ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC)); + +#if THREE_POINT_FILTERING + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; +#else + sampler_desc.Filter = linear_filter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT; +#endif + sampler_desc.AddressU = gfx_cm_to_d3d11(cms); + sampler_desc.AddressV = gfx_cm_to_d3d11(cmt); + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + sampler_desc.MinLOD = 0; + sampler_desc.MaxLOD = D3D11_FLOAT32_MAX; + + TextureData *texture_data = &d3d.textures[d3d.current_texture_ids[tile]]; + texture_data->linear_filtering = linear_filter; + + // This function is called twice per texture, the first one only to set default values. + // Maybe that could be skipped? Anyway, make sure to release the first default sampler + // state before setting the actual one. + texture_data->sampler_state.Reset(); + + ThrowIfFailed(d3d.device->CreateSamplerState(&sampler_desc, texture_data->sampler_state.GetAddressOf())); +} + +static void gfx_d3d11_set_depth_test_and_mask(bool depth_test, bool depth_mask) { + d3d.depth_test = depth_test; + d3d.depth_mask = depth_mask; +} + +static void gfx_d3d11_set_zmode_decal(bool zmode_decal) { + d3d.zmode_decal = zmode_decal; +} + +static void gfx_d3d11_set_viewport(int x, int y, int width, int height) { + D3D11_VIEWPORT viewport; + viewport.TopLeftX = x; + viewport.TopLeftY = d3d.render_target_height - y - height; + viewport.Width = width; + viewport.Height = height; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + d3d.context->RSSetViewports(1, &viewport); +} + +static void gfx_d3d11_set_scissor(int x, int y, int width, int height) { + D3D11_RECT rect; + rect.left = x; + rect.top = d3d.render_target_height - y - height; + rect.right = x + width; + rect.bottom = d3d.render_target_height - y; + + d3d.context->RSSetScissorRects(1, &rect); +} + +static void gfx_d3d11_set_use_alpha(bool use_alpha) { + // Already part of the pipeline state from shader info +} + +static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { + + if (d3d.last_depth_test != d3d.depth_test || d3d.last_depth_mask != d3d.depth_mask) { + d3d.last_depth_test = d3d.depth_test; + d3d.last_depth_mask = d3d.depth_mask; + + d3d.depth_stencil_state.Reset(); + + D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; + ZeroMemory(&depth_stencil_desc, sizeof(D3D11_DEPTH_STENCIL_DESC)); + + depth_stencil_desc.DepthEnable = d3d.depth_test || d3d.depth_mask; + depth_stencil_desc.DepthWriteMask = d3d.depth_mask ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; + depth_stencil_desc.DepthFunc = d3d.depth_test ? D3D11_COMPARISON_LESS_EQUAL : D3D11_COMPARISON_ALWAYS; + depth_stencil_desc.StencilEnable = false; + + ThrowIfFailed(d3d.device->CreateDepthStencilState(&depth_stencil_desc, d3d.depth_stencil_state.GetAddressOf())); + d3d.context->OMSetDepthStencilState(d3d.depth_stencil_state.Get(), 0); + } + + if (d3d.last_zmode_decal != d3d.zmode_decal) { + d3d.last_zmode_decal = d3d.zmode_decal; + + d3d.rasterizer_state.Reset(); + + D3D11_RASTERIZER_DESC rasterizer_desc; + ZeroMemory(&rasterizer_desc, sizeof(D3D11_RASTERIZER_DESC)); + + rasterizer_desc.FillMode = D3D11_FILL_SOLID; + rasterizer_desc.CullMode = D3D11_CULL_NONE; + rasterizer_desc.FrontCounterClockwise = true; + rasterizer_desc.DepthBias = 0; + rasterizer_desc.SlopeScaledDepthBias = d3d.zmode_decal ? -2.0f : 0.0f; + rasterizer_desc.DepthBiasClamp = 0.0f; + rasterizer_desc.DepthClipEnable = false; + rasterizer_desc.ScissorEnable = true; + rasterizer_desc.MultisampleEnable = false; + rasterizer_desc.AntialiasedLineEnable = false; + + ThrowIfFailed(d3d.device->CreateRasterizerState(&rasterizer_desc, d3d.rasterizer_state.GetAddressOf())); + d3d.context->RSSetState(d3d.rasterizer_state.Get()); + } + + bool textures_changed = false; + + for (int i = 0; i < 2; i++) { + if (d3d.shader_program->used_textures[i]) { + if (d3d.last_resource_views[i].Get() != d3d.textures[d3d.current_texture_ids[i]].resource_view.Get()) { + d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get(); + d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf()); + +#if THREE_POINT_FILTERING + d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width; + d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height; + d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering; + textures_changed = true; +#endif + + if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) { + d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get(); + d3d.context->PSSetSamplers(i, 1, d3d.textures[d3d.current_texture_ids[i]].sampler_state.GetAddressOf()); + } + } + } + } + + // Set per-draw constant buffer + + if (textures_changed) { + D3D11_MAPPED_SUBRESOURCE ms; + ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE)); + d3d.context->Map(d3d.per_draw_cb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms); + memcpy(ms.pData, &d3d.per_draw_cb_data, sizeof(PerDrawCB)); + d3d.context->Unmap(d3d.per_draw_cb.Get(), 0); + } + + // Set vertex buffer data + + D3D11_MAPPED_SUBRESOURCE ms; + ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE)); + d3d.context->Map(d3d.vertex_buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms); + memcpy(ms.pData, buf_vbo, buf_vbo_len * sizeof(float)); + d3d.context->Unmap(d3d.vertex_buffer.Get(), 0); + + uint32_t stride = d3d.shader_program->num_floats * sizeof(float); + uint32_t offset = 0; + + if (d3d.last_vertex_buffer_stride != stride) { + d3d.last_vertex_buffer_stride = stride; + d3d.context->IASetVertexBuffers(0, 1, d3d.vertex_buffer.GetAddressOf(), &stride, &offset); + } + + if (d3d.last_shader_program != d3d.shader_program) { + d3d.last_shader_program = d3d.shader_program; + d3d.context->IASetInputLayout(d3d.shader_program->input_layout.Get()); + d3d.context->VSSetShader(d3d.shader_program->vertex_shader.Get(), 0, 0); + d3d.context->PSSetShader(d3d.shader_program->pixel_shader.Get(), 0, 0); + + if (d3d.last_blend_state.Get() != d3d.shader_program->blend_state.Get()) { + d3d.last_blend_state = d3d.shader_program->blend_state.Get(); + d3d.context->OMSetBlendState(d3d.shader_program->blend_state.Get(), 0, 0xFFFFFFFF); + } + } + + if (d3d.last_primitive_topology != D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST) { + d3d.last_primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + d3d.context->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + } + + d3d.context->Draw(buf_vbo_num_tris * 3, 0); +} + +static void gfx_d3d11_on_resize(void) { + create_render_target_views(true); +} + +static void gfx_d3d11_start_frame(void) { + // Set render targets + + d3d.context->OMSetRenderTargets(1, d3d.backbuffer_view.GetAddressOf(), d3d.depth_stencil_view.Get()); + + // Clear render targets + + const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + d3d.context->ClearRenderTargetView(d3d.backbuffer_view.Get(), clearColor); + d3d.context->ClearDepthStencilView(d3d.depth_stencil_view.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0); + + // Set per-frame constant buffer + + d3d.per_frame_cb_data.noise_frame++; + if (d3d.per_frame_cb_data.noise_frame > 150) { + // No high values, as noise starts to look ugly + d3d.per_frame_cb_data.noise_frame = 0; + } + float aspect_ratio = (float) d3d.current_width / (float) d3d.current_height; + d3d.render_target_height = d3d.current_height; + d3d.per_frame_cb_data.noise_scale_x = 120 * aspect_ratio; // 120 = N64 height resolution (240) / 2 + d3d.per_frame_cb_data.noise_scale_y = 120; + + D3D11_MAPPED_SUBRESOURCE ms; + ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE)); + d3d.context->Map(d3d.per_frame_cb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms); + memcpy(ms.pData, &d3d.per_frame_cb_data, sizeof(PerFrameCB)); + d3d.context->Unmap(d3d.per_frame_cb.Get(), 0); + + d3d.copied_depth_buffer = false; +} + +static void gfx_d3d11_end_frame(void) { + SohImGui::Draw(); + d3d.context->Flush(); +} + +static void gfx_d3d11_finish_render(void) { + d3d.context->Flush(); +} + +void gfx_d3d11_resize_framebuffer(int fb, uint32_t width, uint32_t height) { + FramebufferData& fd = d3d.framebuffers[fb]; + TextureData& td = d3d.textures[fd.texture_id]; + + ComPtr texture, depth_stencil_texture; + + D3D11_TEXTURE2D_DESC texture_desc; + texture_desc.Width = width; + texture_desc.Height = height; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + texture_desc.ArraySize = 1; + texture_desc.MipLevels = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + + ThrowIfFailed(d3d.device->CreateTexture2D(&texture_desc, nullptr, texture.GetAddressOf())); + create_depth_stencil_objects(width, height, depth_stencil_texture.GetAddressOf(), fd.depth_stencil_view.ReleaseAndGetAddressOf(), nullptr); + ThrowIfFailed(d3d.device->CreateRenderTargetView(texture.Get(), nullptr, fd.render_target_view.ReleaseAndGetAddressOf())); + ThrowIfFailed(d3d.device->CreateShaderResourceView(texture.Get(), nullptr, td.resource_view.ReleaseAndGetAddressOf())); + + td.width = width; + td.height = height; +} + +int gfx_d3d11_create_framebuffer(uint32_t width, uint32_t height) { + uint32_t texture_id = gfx_d3d11_new_texture(); + TextureData& t = d3d.textures[texture_id]; + t.width = width; + t.height = height; + + size_t index = d3d.framebuffers.size(); + d3d.framebuffers.resize(d3d.framebuffers.size() + 1); + FramebufferData& data = d3d.framebuffers.back(); + data.texture_id = texture_id; + + uint32_t tile = 0; + uint32_t saved = d3d.current_texture_ids[tile]; + d3d.current_texture_ids[tile] = texture_id; + gfx_d3d11_set_sampler_parameters(0, true, G_TX_WRAP, G_TX_WRAP); + d3d.current_texture_ids[tile] = saved; + + gfx_d3d11_resize_framebuffer(index, width, height); + + return (int)index; +} + +void gfx_d3d11_set_framebuffer(int fb) { + d3d.render_target_height = d3d.textures[d3d.framebuffers[fb].texture_id].height; + + d3d.context->OMSetRenderTargets(1, d3d.framebuffers[fb].render_target_view.GetAddressOf(), d3d.framebuffers[fb].depth_stencil_view.Get()); + + const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + d3d.context->ClearRenderTargetView(d3d.framebuffers[fb].render_target_view.Get(), clearColor); + d3d.context->ClearDepthStencilView(d3d.framebuffers[fb].depth_stencil_view.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0); +} + +void gfx_d3d11_reset_framebuffer(void) { + d3d.render_target_height = d3d.current_height; + d3d.context->OMSetRenderTargets(1, d3d.backbuffer_view.GetAddressOf(), d3d.depth_stencil_view.Get()); +} + +void gfx_d3d11_select_texture_fb(int fbID) { + int tile = 0; + gfx_d3d11_select_texture(tile, d3d.framebuffers[fbID].texture_id); +} + +uint16_t gfx_d3d11_get_pixel_depth(float x, float y) { + D3D11_MAPPED_SUBRESOURCE ms; + + // ImGui overwrites these values, so we cannot set them once at init + d3d.context->CSSetShader(d3d.compute_shader.Get(), nullptr, 0); + d3d.context->CSSetConstantBuffers(0, 1, d3d.coord_buffer.GetAddressOf()); + d3d.context->CSSetSamplers(0, 1, d3d.depth_value_sampler.GetAddressOf()); + d3d.context->CSSetUnorderedAccessViews(0, 1, d3d.depth_value_output_uav.GetAddressOf(), nullptr); + + ThrowIfFailed(d3d.context->Map(d3d.coord_buffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms)); + CoordCB* coord_cb = (CoordCB*)ms.pData; + coord_cb->x = x / d3d.current_width; + // We invert y because the game assumes OpenGL coordinates (bottom-left corner is origin), while DX's origin is top-left corner + coord_cb->y = 1 - y / d3d.current_height; + d3d.context->Unmap(d3d.coord_buffer.Get(), 0); + + // The depth stencil texture can only have one mapping at a time, so temporarily unbind from the OM + d3d.context->OMSetRenderTargets(1, d3d.backbuffer_view.GetAddressOf(), nullptr); + d3d.context->CSSetShaderResources(0, 1, d3d.depth_stencil_srv.GetAddressOf()); + + d3d.context->Dispatch(1, 1, 1); + + d3d.context->CopyResource(d3d.depth_value_output_buffer_copy.Get(), d3d.depth_value_output_buffer.Get()); + ThrowIfFailed(d3d.context->Map(d3d.depth_value_output_buffer_copy.Get(), 0, D3D11_MAP_READ, 0, &ms)); + float res = *(float *)ms.pData; + d3d.context->Unmap(d3d.depth_value_output_buffer_copy.Get(), 0); + + ID3D11ShaderResourceView *null_arr[1] = { nullptr }; + d3d.context->CSSetShaderResources(0, 1, null_arr); + d3d.context->OMSetRenderTargets(1, d3d.backbuffer_view.GetAddressOf(), d3d.depth_stencil_view.Get()); + + return res * 65532.0f; +} + +uint16_t gfx_d3d11_get_pixel_depth_old(float x, float y) { + // This approach, compared to using a compute shader, might have better performance on nvidia cards + + if (!d3d.copied_depth_buffer) { + d3d.context->CopyResource(d3d.depth_stencil_copy_texture.Get(), d3d.depth_stencil_texture.Get()); + d3d.copied_depth_buffer = true; + } + + D3D11_MAPPED_SUBRESOURCE mapping_desc; + d3d.context->Map(d3d.depth_stencil_copy_texture.Get(), 0, D3D11_MAP_READ, 0, &mapping_desc); + float res = 0; + if (mapping_desc.pData != nullptr) { + float *addr = (float *)mapping_desc.pData; + uint32_t num_pixels = mapping_desc.DepthPitch / sizeof(float); + uint32_t width = mapping_desc.RowPitch / sizeof(float); + uint32_t height = width == 0 ? 0 : num_pixels / width; + if (x >= 0 && x < width && y >= 0 && y < height) { + res = addr[width * (height - 1 - (int)y) + (int)x]; + } + } + d3d.context->Unmap(d3d.depth_stencil_copy_texture.Get(), 0); + return res * 65532.0f; +} + +} // namespace + +void* SohImGui::GetTextureByID(int id) { + return d3d.textures[id].resource_view.Get(); +} + +struct GfxRenderingAPI gfx_direct3d11_api = { + gfx_d3d11_z_is_from_0_to_1, + gfx_d3d11_unload_shader, + gfx_d3d11_load_shader, + gfx_d3d11_create_and_load_new_shader, + gfx_d3d11_lookup_shader, + gfx_d3d11_shader_get_info, + gfx_d3d11_new_texture, + gfx_d3d11_select_texture, + gfx_d3d11_upload_texture, + gfx_d3d11_set_sampler_parameters, + gfx_d3d11_set_depth_test_and_mask, + gfx_d3d11_get_pixel_depth, + gfx_d3d11_set_zmode_decal, + gfx_d3d11_set_viewport, + gfx_d3d11_set_scissor, + gfx_d3d11_set_use_alpha, + gfx_d3d11_draw_triangles, + gfx_d3d11_init, + gfx_d3d11_on_resize, + gfx_d3d11_start_frame, + gfx_d3d11_end_frame, + gfx_d3d11_finish_render, + gfx_d3d11_create_framebuffer, + gfx_d3d11_resize_framebuffer, + gfx_d3d11_set_framebuffer, + gfx_d3d11_reset_framebuffer, + gfx_d3d11_select_texture_fb, + gfx_d3d11_delete_texture +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.h b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.h new file mode 100644 index 000000000..67f6406e0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d11.h @@ -0,0 +1,12 @@ +#ifdef ENABLE_DX11 + +#ifndef GFX_DIRECT3D11_H +#define GFX_DIRECT3D11_H + +#include "gfx_rendering_api.h" + +extern struct GfxRenderingAPI gfx_direct3d11_api; + +#endif + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.cpp new file mode 100644 index 000000000..4917d459b --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.cpp @@ -0,0 +1,972 @@ +#ifdef ENABLE_DX12 + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +// This is needed when compiling with MinGW, used in d3d12.h +#define __in_ecount_opt(size) + +#include +#include +#include "dxsdk/d3d12.h" +#include + +#include "gfx_direct3d12_guids.h" + +#include "dxsdk/d3dx12.h" + +#ifndef _LANGUAGE_C +#define _LANGUAGE_C +#endif +#include + +#define DECLARE_GFX_DXGI_FUNCTIONS +#include "gfx_dxgi.h" + +#include "gfx_cc.h" +#include "gfx_window_manager_api.h" +#include "gfx_rendering_api.h" +#include "gfx_direct3d_common.h" + +#include "gfx_screen_config.h" + +#define DEBUG_D3D 0 + +using namespace Microsoft::WRL; // For ComPtr + +namespace { + +struct ShaderProgramD3D12 { + uint32_t shader_id; + uint8_t num_inputs; + bool used_textures[2]; + uint8_t num_floats; + uint8_t num_attribs; + + ComPtr vertex_shader; + ComPtr pixel_shader; + ComPtr root_signature; +}; + +struct PipelineDesc { + uint32_t shader_id; + bool depth_test; + bool depth_mask; + bool zmode_decal; + bool _padding; + + bool operator==(const PipelineDesc& o) const { + return memcmp(this, &o, sizeof(*this)) == 0; + } + + bool operator<(const PipelineDesc& o) const { + return memcmp(this, &o, sizeof(*this)) < 0; + } +}; + +struct TextureHeap { + ComPtr heap; + std::vector free_list; +}; + +struct TextureData { + ComPtr resource; + struct TextureHeap *heap; + uint8_t heap_offset; + + uint64_t last_frame_counter; + uint32_t descriptor_index; + int sampler_parameters; +}; + +struct NoiseCB { + uint32_t noise_frame; + float noise_scale_x; + float noise_scale_y; + uint32_t padding; +}; + +static struct { + HMODULE d3d12_module; + PFN_D3D12_CREATE_DEVICE D3D12CreateDevice; + PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; + + HMODULE d3dcompiler_module; + pD3DCompile D3DCompile; + + struct ShaderProgramD3D12 shader_program_pool[64]; + uint8_t shader_program_pool_size; + + uint32_t current_width, current_height; + + ComPtr device; + ComPtr command_queue; + ComPtr copy_command_queue; + ComPtr swap_chain; + ComPtr rtv_heap; + UINT rtv_descriptor_size; + ComPtr render_targets[2]; + ComPtr command_allocator; + ComPtr copy_command_allocator; + ComPtr command_list; + ComPtr copy_command_list; + ComPtr dsv_heap; + ComPtr depth_stencil_buffer; + ComPtr srv_heap; + UINT srv_descriptor_size; + ComPtr sampler_heap; + UINT sampler_descriptor_size; + + std::map, std::list> texture_heaps; + + std::map>> upload_heaps; + std::vector>> upload_heaps_in_flight; + ComPtr copy_fence; + uint64_t copy_fence_value; + + std::vector textures; + int current_tile; + uint32_t current_texture_ids[2]; + uint32_t srv_pos; + + int frame_index; + ComPtr fence; + HANDLE fence_event; + + uint64_t frame_counter; + + ComPtr noise_cb; + void *mapped_noise_cb_address; + struct NoiseCB noise_cb_data; + + ComPtr vertex_buffer; + void *mapped_vbuf_address; + int vbuf_pos; + + std::vector> resources_to_clean_at_end_of_frame; + std::vector> texture_heap_allocations_to_reclaim_at_end_of_frame; + + std::map> pipeline_states; + bool must_reload_pipeline; + + // Current state: + ID3D12PipelineState *pipeline_state; + struct ShaderProgramD3D12 *shader_program; + bool depth_test; + bool depth_mask; + bool zmode_decal; + + CD3DX12_VIEWPORT viewport; + CD3DX12_RECT scissor; +} d3d; + +static int texture_uploads = 0; +static int max_texture_uploads; + +static D3D12_CPU_DESCRIPTOR_HANDLE get_cpu_descriptor_handle(ComPtr& heap) { +#ifdef __MINGW32__ + // We would like to do this: + // D3D12_CPU_DESCRIPTOR_HANDLE handle = heap->GetCPUDescriptorHandleForHeapStart(); + // but MinGW64 doesn't follow the calling conventions of VC++ for some reason. + // Per MS documentation "User-defined types can be returned by value from global functions and static member functions"... + // "Otherwise, the caller assumes the responsibility of allocating memory and passing a pointer for the return value as the first argument". + // The method here is a non-static member function, and hence we need to pass the address to the return value as a parameter. + // MinGW32 has the same issue. + auto fn = heap->GetCPUDescriptorHandleForHeapStart; + void (STDMETHODCALLTYPE ID3D12DescriptorHeap::*fun)(D3D12_CPU_DESCRIPTOR_HANDLE *out) = (void (STDMETHODCALLTYPE ID3D12DescriptorHeap::*)(D3D12_CPU_DESCRIPTOR_HANDLE *out))fn; + D3D12_CPU_DESCRIPTOR_HANDLE handle; + (heap.Get()->*fun)(&handle); + return handle; +#else + return heap->GetCPUDescriptorHandleForHeapStart(); +#endif +} + +static D3D12_GPU_DESCRIPTOR_HANDLE get_gpu_descriptor_handle(ComPtr& heap) { +#ifdef __MINGW32__ + // See get_cpu_descriptor_handle + auto fn = heap->GetGPUDescriptorHandleForHeapStart; + void (STDMETHODCALLTYPE ID3D12DescriptorHeap::*fun)(D3D12_GPU_DESCRIPTOR_HANDLE *out) = (void (STDMETHODCALLTYPE ID3D12DescriptorHeap::*)(D3D12_GPU_DESCRIPTOR_HANDLE *out))fn; + D3D12_GPU_DESCRIPTOR_HANDLE handle; + (heap.Get()->*fun)(&handle); + return handle; +#else + return heap->GetGPUDescriptorHandleForHeapStart(); +#endif +} + +static D3D12_RESOURCE_ALLOCATION_INFO get_resource_allocation_info(const D3D12_RESOURCE_DESC *resource_desc) { +#ifdef __MINGW32__ + // See get_cpu_descriptor_handle + auto fn = d3d.device->GetResourceAllocationInfo; + void (STDMETHODCALLTYPE ID3D12Device::*fun)(D3D12_RESOURCE_ALLOCATION_INFO *out, UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC *pResourceDescs) = + (void (STDMETHODCALLTYPE ID3D12Device::*)(D3D12_RESOURCE_ALLOCATION_INFO *out, UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC *pResourceDescs))fn; + D3D12_RESOURCE_ALLOCATION_INFO out; + (d3d.device.Get()->*fun)(&out, 0, 1, resource_desc); + return out; +#else + return d3d.device->GetResourceAllocationInfo(0, 1, resource_desc); +#endif +} + +static bool gfx_direct3d12_z_is_from_0_to_1(void) { + return true; +} + +static void gfx_direct3d12_unload_shader(struct ShaderProgram *old_prg) { +} + +static void gfx_direct3d12_load_shader(struct ShaderProgram *new_prg) { + d3d.shader_program = (struct ShaderProgramD3D12 *)new_prg; + d3d.must_reload_pipeline = true; +} + +static struct ShaderProgram *gfx_direct3d12_create_and_load_new_shader(uint32_t shader_id) { + /*static FILE *fp; + if (!fp) { + fp = fopen("shaders.txt", "w"); + } + fprintf(fp, "0x%08x\n", shader_id); + fflush(fp);*/ + + struct ShaderProgramD3D12 *prg = &d3d.shader_program_pool[d3d.shader_program_pool_size++]; + + CCFeatures cc_features; + gfx_cc_get_features(shader_id, &cc_features); + + char buf[2048]; + size_t len, num_floats; + + gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, true, false); + + //fwrite(buf, 1, len, stdout); + + ThrowIfFailed(d3d.D3DCompile(buf, len, nullptr, nullptr, nullptr, "VSMain", "vs_5_1", D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &prg->vertex_shader, nullptr)); + ThrowIfFailed(d3d.D3DCompile(buf, len, nullptr, nullptr, nullptr, "PSMain", "ps_5_1", D3DCOMPILE_OPTIMIZATION_LEVEL3, 0, &prg->pixel_shader, nullptr)); + + ThrowIfFailed(d3d.device->CreateRootSignature(0, prg->pixel_shader->GetBufferPointer(), prg->pixel_shader->GetBufferSize(), IID_PPV_ARGS(&prg->root_signature))); + + prg->shader_id = shader_id; + prg->num_inputs = cc_features.num_inputs; + prg->used_textures[0] = cc_features.used_textures[0]; + prg->used_textures[1] = cc_features.used_textures[1]; + prg->num_floats = num_floats; + //prg->num_attribs = cnt; + + d3d.must_reload_pipeline = true; + return (struct ShaderProgram *)(d3d.shader_program = prg); +} + +static struct ShaderProgram *gfx_direct3d12_lookup_shader(uint32_t shader_id) { + for (size_t i = 0; i < d3d.shader_program_pool_size; i++) { + if (d3d.shader_program_pool[i].shader_id == shader_id) { + return (struct ShaderProgram *)&d3d.shader_program_pool[i]; + } + } + return nullptr; +} + +static void gfx_direct3d12_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) { + struct ShaderProgramD3D12 *p = (struct ShaderProgramD3D12 *)prg; + + *num_inputs = p->num_inputs; + used_textures[0] = p->used_textures[0]; + used_textures[1] = p->used_textures[1]; +} + +static uint32_t gfx_direct3d12_new_texture(void) { + d3d.textures.resize(d3d.textures.size() + 1); + return (uint32_t)(d3d.textures.size() - 1); +} + +static void gfx_direct3d12_select_texture(int tile, uint32_t texture_id) { + d3d.current_tile = tile; + d3d.current_texture_ids[tile] = texture_id; +} + +static void gfx_direct3d12_upload_texture(const uint8_t *rgba32_buf, int width, int height) { + texture_uploads++; + + ComPtr texture_resource; + + // Describe and create a Texture2D. + D3D12_RESOURCE_DESC texture_desc = {}; + texture_desc.MipLevels = 1; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.Width = width; + texture_desc.Height = height; + texture_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + texture_desc.DepthOrArraySize = 1; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + texture_desc.Alignment = ((width + 31) / 32) * ((height + 31) / 32) > 16 ? 0 : D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT; + + D3D12_RESOURCE_ALLOCATION_INFO alloc_info = get_resource_allocation_info(&texture_desc); + + std::list& heaps = d3d.texture_heaps[std::pair(alloc_info.SizeInBytes, alloc_info.Alignment)]; + + struct TextureHeap *found_heap = nullptr; + for (struct TextureHeap& heap : heaps) { + if (!heap.free_list.empty()) { + found_heap = &heap; + } + } + if (found_heap == nullptr) { + heaps.resize(heaps.size() + 1); + found_heap = &heaps.back(); + + // In case of HD textures, make sure too much memory isn't wasted + int textures_per_heap = 524288 / alloc_info.SizeInBytes; + if (textures_per_heap < 1) { + textures_per_heap = 1; + } else if (textures_per_heap > 64) { + textures_per_heap = 64; + } + + D3D12_HEAP_DESC heap_desc = {}; + heap_desc.SizeInBytes = alloc_info.SizeInBytes * textures_per_heap; + if (alloc_info.Alignment == D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT) { + heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + } else { + heap_desc.Alignment = alloc_info.Alignment; + } + heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES; + ThrowIfFailed(d3d.device->CreateHeap(&heap_desc, IID_PPV_ARGS(&found_heap->heap))); + for (int i = 0; i < textures_per_heap; i++) { + found_heap->free_list.push_back(i); + } + } + + uint8_t heap_offset = found_heap->free_list.back(); + found_heap->free_list.pop_back(); + ThrowIfFailed(d3d.device->CreatePlacedResource(found_heap->heap.Get(), heap_offset * alloc_info.SizeInBytes, &texture_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&texture_resource))); + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout; + UINT num_rows; + UINT64 row_size_in_bytes; + UINT64 upload_buffer_size; + d3d.device->GetCopyableFootprints(&texture_desc, 0, 1, 0, &layout, &num_rows, &row_size_in_bytes, &upload_buffer_size); + + std::vector>& upload_heaps = d3d.upload_heaps[upload_buffer_size]; + ComPtr upload_heap; + if (upload_heaps.empty()) { + CD3DX12_HEAP_PROPERTIES hp(D3D12_HEAP_TYPE_UPLOAD); + CD3DX12_RESOURCE_DESC rdb = CD3DX12_RESOURCE_DESC::Buffer(upload_buffer_size); + ThrowIfFailed(d3d.device->CreateCommittedResource( + &hp, + D3D12_HEAP_FLAG_NONE, + &rdb, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&upload_heap))); + } else { + upload_heap = upload_heaps.back(); + upload_heaps.pop_back(); + } + + { + D3D12_SUBRESOURCE_DATA texture_data = {}; + texture_data.pData = rgba32_buf; + texture_data.RowPitch = width * 4; // RGBA + texture_data.SlicePitch = texture_data.RowPitch * height; + + void *data; + upload_heap->Map(0, nullptr, &data); + D3D12_MEMCPY_DEST dest_data = { (uint8_t *)data + layout.Offset, layout.Footprint.RowPitch, SIZE_T(layout.Footprint.RowPitch) * SIZE_T(num_rows) }; + MemcpySubresource(&dest_data, &texture_data, static_cast(row_size_in_bytes), num_rows, layout.Footprint.Depth); + upload_heap->Unmap(0, nullptr); + + CD3DX12_TEXTURE_COPY_LOCATION dst(texture_resource.Get(), 0); + CD3DX12_TEXTURE_COPY_LOCATION src(upload_heap.Get(), layout); + d3d.copy_command_list->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + } + + CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(texture_resource.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + d3d.command_list->ResourceBarrier(1, &barrier); + + d3d.upload_heaps_in_flight.push_back(std::make_pair((size_t)upload_buffer_size, std::move(upload_heap))); + + struct TextureData& td = d3d.textures[d3d.current_texture_ids[d3d.current_tile]]; + if (td.resource.Get() != nullptr) { + d3d.resources_to_clean_at_end_of_frame.push_back(std::move(td.resource)); + d3d.texture_heap_allocations_to_reclaim_at_end_of_frame.push_back(std::make_pair(td.heap, td.heap_offset)); + td.last_frame_counter = 0; + } + td.resource = std::move(texture_resource); + td.heap = found_heap; + td.heap_offset = heap_offset; +} + +static int gfx_cm_to_index(uint32_t val) { + // TODO: handle G_TX_MIRROR | G_TX_CLAMP + if (val & G_TX_CLAMP) { + return 2; + } + return (val & G_TX_MIRROR) ? 1 : 0; +} + +static void gfx_direct3d12_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) { + d3d.textures[d3d.current_texture_ids[tile]].sampler_parameters = linear_filter * 9 + gfx_cm_to_index(cms) * 3 + gfx_cm_to_index(cmt); +} + +static void gfx_direct3d12_set_depth_test(bool depth_test) { + d3d.depth_test = depth_test; + d3d.must_reload_pipeline = true; +} + +static void gfx_direct3d12_set_depth_mask(bool z_upd) { + d3d.depth_mask = z_upd; + d3d.must_reload_pipeline = true; +} + +static void gfx_direct3d12_set_zmode_decal(bool zmode_decal) { + d3d.zmode_decal = zmode_decal; + d3d.must_reload_pipeline = true; +} + +static void gfx_direct3d12_set_viewport(int x, int y, int width, int height) { + d3d.viewport = CD3DX12_VIEWPORT(x, d3d.current_height - y - height, width, height); +} + +static void gfx_direct3d12_set_scissor(int x, int y, int width, int height) { + d3d.scissor = CD3DX12_RECT(x, d3d.current_height - y - height, x + width, d3d.current_height - y); +} + +static void gfx_direct3d12_set_use_alpha(bool use_alpha) { + // Already part of the pipeline state from shader info +} + +static void gfx_direct3d12_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { + struct ShaderProgramD3D12 *prg = d3d.shader_program; + + if (d3d.must_reload_pipeline) { + ComPtr& pipeline_state = d3d.pipeline_states[PipelineDesc{ + prg->shader_id, + d3d.depth_test, + d3d.depth_mask, + d3d.zmode_decal, + 0 + }]; + if (pipeline_state.Get() == nullptr) { + D3D12_INPUT_ELEMENT_DESC ied[7] = { + {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + }; + uint32_t ied_pos = 1; + if (prg->used_textures[0] || prg->used_textures[1]) { + ied[ied_pos++] = D3D12_INPUT_ELEMENT_DESC{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}; + } + if (prg->shader_id & SHADER_OPT_FOG) { + ied[ied_pos++] = D3D12_INPUT_ELEMENT_DESC{"FOG", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}; + } + for (int i = 0; i < prg->num_inputs; i++) { + DXGI_FORMAT format = (prg->shader_id & SHADER_OPT_ALPHA) ? DXGI_FORMAT_R32G32B32A32_FLOAT : DXGI_FORMAT_R32G32B32_FLOAT; + ied[ied_pos++] = D3D12_INPUT_ELEMENT_DESC{"INPUT", (UINT)i, format, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}; + } + + D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {}; + desc.InputLayout = { ied, ied_pos }; + desc.pRootSignature = prg->root_signature.Get(); + desc.VS = CD3DX12_SHADER_BYTECODE(prg->vertex_shader.Get()); + desc.PS = CD3DX12_SHADER_BYTECODE(prg->pixel_shader.Get()); + desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + if (d3d.zmode_decal) { + desc.RasterizerState.SlopeScaledDepthBias = -2.0f; + } + desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + if (prg->shader_id & SHADER_OPT_ALPHA) { + D3D12_BLEND_DESC bd = {}; + bd.AlphaToCoverageEnable = FALSE; + bd.IndependentBlendEnable = FALSE; + static const D3D12_RENDER_TARGET_BLEND_DESC default_rtbd = { + TRUE, FALSE, + D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { + bd.RenderTarget[i] = default_rtbd; + } + desc.BlendState = bd; + } else { + desc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + } + desc.DepthStencilState.DepthEnable = d3d.depth_test; + desc.DepthStencilState.DepthWriteMask = d3d.depth_mask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; + desc.DSVFormat = d3d.depth_test ? DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_UNKNOWN; + desc.SampleMask = UINT_MAX; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.NumRenderTargets = 1; + desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + ThrowIfFailed(d3d.device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&pipeline_state))); + } + d3d.pipeline_state = pipeline_state.Get(); + d3d.must_reload_pipeline = false; + } + + d3d.command_list->SetGraphicsRootSignature(prg->root_signature.Get()); + d3d.command_list->SetPipelineState(d3d.pipeline_state); + + ID3D12DescriptorHeap *heaps[] = { d3d.srv_heap.Get(), d3d.sampler_heap.Get() }; + d3d.command_list->SetDescriptorHeaps(2, heaps); + + int root_param_index = 0; + + if ((prg->shader_id & (SHADER_OPT_ALPHA | SHADER_OPT_NOISE)) == (SHADER_OPT_ALPHA | SHADER_OPT_NOISE)) { + d3d.command_list->SetGraphicsRootConstantBufferView(root_param_index++, d3d.noise_cb->GetGPUVirtualAddress()); + } + + for (int i = 0; i < 2; i++) { + if (prg->used_textures[i]) { + struct TextureData& td = d3d.textures[d3d.current_texture_ids[i]]; + if (td.last_frame_counter != d3d.frame_counter) { + td.descriptor_index = d3d.srv_pos; + td.last_frame_counter = d3d.frame_counter; + + D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {}; + srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MipLevels = 1; + + CD3DX12_CPU_DESCRIPTOR_HANDLE srv_handle(get_cpu_descriptor_handle(d3d.srv_heap), d3d.srv_pos++, d3d.srv_descriptor_size); + d3d.device->CreateShaderResourceView(td.resource.Get(), &srv_desc, srv_handle); + } + + CD3DX12_GPU_DESCRIPTOR_HANDLE srv_gpu_handle(get_gpu_descriptor_handle(d3d.srv_heap), td.descriptor_index, d3d.srv_descriptor_size); + d3d.command_list->SetGraphicsRootDescriptorTable(root_param_index++, srv_gpu_handle); + + CD3DX12_GPU_DESCRIPTOR_HANDLE sampler_gpu_handle(get_gpu_descriptor_handle(d3d.sampler_heap), td.sampler_parameters, d3d.sampler_descriptor_size); + d3d.command_list->SetGraphicsRootDescriptorTable(root_param_index++, sampler_gpu_handle); + } + } + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(get_cpu_descriptor_handle(d3d.rtv_heap), d3d.frame_index, d3d.rtv_descriptor_size); + D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle = get_cpu_descriptor_handle(d3d.dsv_heap); + d3d.command_list->OMSetRenderTargets(1, &rtv_handle, FALSE, &dsv_handle); + + d3d.command_list->RSSetViewports(1, &d3d.viewport); + d3d.command_list->RSSetScissorRects(1, &d3d.scissor); + + int current_pos = d3d.vbuf_pos; + memcpy((uint8_t *)d3d.mapped_vbuf_address + current_pos, buf_vbo, buf_vbo_len * sizeof(float)); + d3d.vbuf_pos += buf_vbo_len * sizeof(float); + static int maxpos; + if (d3d.vbuf_pos > maxpos) { + maxpos = d3d.vbuf_pos; + //printf("NEW MAXPOS: %d\n", maxpos); + } + + D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view; + vertex_buffer_view.BufferLocation = d3d.vertex_buffer->GetGPUVirtualAddress() + current_pos; + vertex_buffer_view.StrideInBytes = buf_vbo_len / (3 * buf_vbo_num_tris) * sizeof(float); + vertex_buffer_view.SizeInBytes = buf_vbo_len * sizeof(float); + + d3d.command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + d3d.command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view); + d3d.command_list->DrawInstanced(3 * buf_vbo_num_tris, 1, 0, 0); +} + +static void gfx_direct3d12_start_frame(void) { + ++d3d.frame_counter; + d3d.srv_pos = 0; + texture_uploads = 0; + ThrowIfFailed(d3d.command_allocator->Reset()); + ThrowIfFailed(d3d.command_list->Reset(d3d.command_allocator.Get(), nullptr)); + + CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition( + d3d.render_targets[d3d.frame_index].Get(), + D3D12_RESOURCE_STATE_PRESENT, + D3D12_RESOURCE_STATE_RENDER_TARGET); + d3d.command_list->ResourceBarrier(1, &barrier); + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(get_cpu_descriptor_handle(d3d.rtv_heap), d3d.frame_index, d3d.rtv_descriptor_size); + D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle = get_cpu_descriptor_handle(d3d.dsv_heap); + d3d.command_list->OMSetRenderTargets(1, &rtv_handle, FALSE, &dsv_handle); + + static unsigned char c; + const float clear_color[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + d3d.command_list->ClearRenderTargetView(rtv_handle, clear_color, 0, nullptr); + d3d.command_list->ClearDepthStencilView(dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); + + d3d.noise_cb_data.noise_frame++; + if (d3d.noise_cb_data.noise_frame > 150) { + // No high values, as noise starts to look ugly + d3d.noise_cb_data.noise_frame = 0; + } + float aspect_ratio = (float) d3d.current_width / (float) d3d.current_height; + d3d.noise_cb_data.noise_scale_x = 120 * aspect_ratio; // 120 = N64 height resolution (240) / 2 + d3d.noise_cb_data.noise_scale_y = 120; + memcpy(d3d.mapped_noise_cb_address, &d3d.noise_cb_data, sizeof(struct NoiseCB)); + + d3d.vbuf_pos = 0; +} + +static void create_render_target_views(void) { + D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = get_cpu_descriptor_handle(d3d.rtv_heap); + for (UINT i = 0; i < 2; i++) { + ThrowIfFailed(d3d.swap_chain->GetBuffer(i, IID_ID3D12Resource, (void **)&d3d.render_targets[i])); + d3d.device->CreateRenderTargetView(d3d.render_targets[i].Get(), nullptr, rtv_handle); + rtv_handle.ptr += d3d.rtv_descriptor_size; + } +} + +static void create_depth_buffer(void) { + DXGI_SWAP_CHAIN_DESC1 desc1; + ThrowIfFailed(d3d.swap_chain->GetDesc1(&desc1)); + UINT width = desc1.Width; + UINT height = desc1.Height; + + d3d.current_width = width; + d3d.current_height = height; + + D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc = {}; + dsv_desc.Format = DXGI_FORMAT_D32_FLOAT; + dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsv_desc.Flags = D3D12_DSV_FLAG_NONE; + + D3D12_CLEAR_VALUE depth_optimized_cv = {}; + depth_optimized_cv.Format = DXGI_FORMAT_D32_FLOAT; + depth_optimized_cv.DepthStencil.Depth = 1.0f; + + D3D12_HEAP_PROPERTIES hp = {}; + hp.Type = D3D12_HEAP_TYPE_DEFAULT; + hp.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + hp.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + hp.CreationNodeMask = 1; + hp.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC rd = {}; + rd.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + rd.Alignment = 0; + rd.Width = width; + rd.Height = height; + rd.DepthOrArraySize = 1; + rd.MipLevels = 0; + rd.Format = DXGI_FORMAT_D32_FLOAT; + rd.SampleDesc.Count = 1; + rd.SampleDesc.Quality = 0; + rd.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + rd.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + ThrowIfFailed(d3d.device->CreateCommittedResource(&hp, D3D12_HEAP_FLAG_NONE, &rd, D3D12_RESOURCE_STATE_DEPTH_WRITE, &depth_optimized_cv, IID_PPV_ARGS(&d3d.depth_stencil_buffer))); + + d3d.device->CreateDepthStencilView(d3d.depth_stencil_buffer.Get(), &dsv_desc, get_cpu_descriptor_handle(d3d.dsv_heap)); +} + +static void gfx_direct3d12_on_resize(void) { + if (d3d.render_targets[0].Get() != nullptr) { + d3d.render_targets[0].Reset(); + d3d.render_targets[1].Reset(); + ThrowIfFailed(d3d.swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)); + d3d.frame_index = d3d.swap_chain->GetCurrentBackBufferIndex(); + create_render_target_views(); + create_depth_buffer(); + } +} + +static void gfx_direct3d12_init(void ) { + // Load d3d12.dll + d3d.d3d12_module = LoadLibraryW(L"d3d12.dll"); + if (d3d.d3d12_module == nullptr) { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()), gfx_dxgi_get_h_wnd(), "d3d12.dll not found"); + } + d3d.D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d.d3d12_module, "D3D12CreateDevice"); +#if DEBUG_D3D + d3d.D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(d3d.d3d12_module, "D3D12GetDebugInterface"); +#endif + + // Load D3DCompiler_47.dll + d3d.d3dcompiler_module = LoadLibraryW(L"D3DCompiler_47.dll"); + if (d3d.d3dcompiler_module == nullptr) { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()), gfx_dxgi_get_h_wnd(), "D3DCompiler_47.dll not found"); + } + d3d.D3DCompile = (pD3DCompile)GetProcAddress(d3d.d3dcompiler_module, "D3DCompile"); + + // Create device + { + UINT debug_flags = 0; +#if DEBUG_D3D + ComPtr debug_controller; + if (SUCCEEDED(d3d.D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)))) { + debug_controller->EnableDebugLayer(); + debug_flags |= DXGI_CREATE_FACTORY_DEBUG; + } +#endif + + gfx_dxgi_create_factory_and_device(DEBUG_D3D, 12, [](IDXGIAdapter1 *adapter, bool test_only) { + HRESULT res = d3d.D3D12CreateDevice( + adapter, + D3D_FEATURE_LEVEL_11_0, + IID_ID3D12Device, + test_only ? nullptr : IID_PPV_ARGS_Helper(&d3d.device)); + + if (test_only) { + return SUCCEEDED(res); + } else { + ThrowIfFailed(res, gfx_dxgi_get_h_wnd(), "Failed to create D3D12 device."); + return true; + } + }); + } + + // Create command queues + { + D3D12_COMMAND_QUEUE_DESC queue_desc = {}; + queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + ThrowIfFailed(d3d.device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&d3d.command_queue))); + } + { + D3D12_COMMAND_QUEUE_DESC queue_desc = {}; + queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queue_desc.Type = D3D12_COMMAND_LIST_TYPE_COPY; + ThrowIfFailed(d3d.device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&d3d.copy_command_queue))); + } + + // Create swap chain + { + ComPtr swap_chain1 = gfx_dxgi_create_swap_chain(d3d.command_queue.Get()); + ThrowIfFailed(swap_chain1->QueryInterface(__uuidof(IDXGISwapChain3), &d3d.swap_chain)); + d3d.frame_index = d3d.swap_chain->GetCurrentBackBufferIndex(); + } + + // Create render target views + { + D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc = {}; + rtv_heap_desc.NumDescriptors = 2; + rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(d3d.device->CreateDescriptorHeap(&rtv_heap_desc, IID_PPV_ARGS(&d3d.rtv_heap))); + d3d.rtv_descriptor_size = d3d.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + create_render_target_views(); + } + + // Create Z-buffer + { + D3D12_DESCRIPTOR_HEAP_DESC dsv_heap_desc = {}; + dsv_heap_desc.NumDescriptors = 1; + dsv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + dsv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + ThrowIfFailed(d3d.device->CreateDescriptorHeap(&dsv_heap_desc, IID_PPV_ARGS(&d3d.dsv_heap))); + + create_depth_buffer(); + } + + // Create SRV heap for texture descriptors + { + D3D12_DESCRIPTOR_HEAP_DESC srv_heap_desc = {}; + srv_heap_desc.NumDescriptors = 1024; // Max unique textures per frame + srv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + srv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + ThrowIfFailed(d3d.device->CreateDescriptorHeap(&srv_heap_desc, IID_PPV_ARGS(&d3d.srv_heap))); + d3d.srv_descriptor_size = d3d.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + // Create sampler heap and descriptors + { + D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = {}; + sampler_heap_desc.NumDescriptors = 18; + sampler_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + sampler_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + ThrowIfFailed(d3d.device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&d3d.sampler_heap))); + d3d.sampler_descriptor_size = d3d.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + + static const D3D12_TEXTURE_ADDRESS_MODE address_modes[] = { + D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE_MIRROR, + D3D12_TEXTURE_ADDRESS_MODE_CLAMP + }; + + D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle = get_cpu_descriptor_handle(d3d.sampler_heap); + int pos = 0; + for (int linear_filter = 0; linear_filter < 2; linear_filter++) { + for (int cms = 0; cms < 3; cms++) { + for (int cmt = 0; cmt < 3; cmt++) { + D3D12_SAMPLER_DESC sampler_desc = {}; + sampler_desc.Filter = linear_filter ? D3D12_FILTER_MIN_MAG_MIP_LINEAR : D3D12_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = address_modes[cms]; + sampler_desc.AddressV = address_modes[cmt]; + sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + sampler_desc.MinLOD = 0; + sampler_desc.MaxLOD = D3D12_FLOAT32_MAX; + sampler_desc.MipLODBias = 0.0f; + sampler_desc.MaxAnisotropy = 1; + sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; + d3d.device->CreateSampler(&sampler_desc, CD3DX12_CPU_DESCRIPTOR_HANDLE(sampler_handle, pos++, d3d.sampler_descriptor_size)); + } + } + } + } + + // Create constant buffer view for noise + { + /*D3D12_DESCRIPTOR_HEAP_DESC cbv_heap_desc = {}; + cbv_heap_desc.NumDescriptors = 1; + cbv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + srv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + ThrowIfFailed(d3d.device->CreateDescriptorHeap*/ + + CD3DX12_HEAP_PROPERTIES hp(D3D12_HEAP_TYPE_UPLOAD); + CD3DX12_RESOURCE_DESC rdb = CD3DX12_RESOURCE_DESC::Buffer(256); + ThrowIfFailed(d3d.device->CreateCommittedResource( + &hp, + D3D12_HEAP_FLAG_NONE, + &rdb, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&d3d.noise_cb))); + + CD3DX12_RANGE read_range(0, 0); // Read not possible from CPU + ThrowIfFailed(d3d.noise_cb->Map(0, &read_range, &d3d.mapped_noise_cb_address)); + } + + ThrowIfFailed(d3d.device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&d3d.command_allocator))); + ThrowIfFailed(d3d.device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&d3d.copy_command_allocator))); + + ThrowIfFailed(d3d.device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, d3d.command_allocator.Get(), nullptr, IID_PPV_ARGS(&d3d.command_list))); + ThrowIfFailed(d3d.device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, d3d.copy_command_allocator.Get(), nullptr, IID_PPV_ARGS(&d3d.copy_command_list))); + + ThrowIfFailed(d3d.command_list->Close()); + + ThrowIfFailed(d3d.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3d.fence))); + d3d.fence_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (d3d.fence_event == nullptr) { + ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); + } + + ThrowIfFailed(d3d.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3d.copy_fence))); + + { + // Create a buffer of 1 MB in size. With a 120 star speed run 192 kB seems to be max usage. + CD3DX12_HEAP_PROPERTIES hp(D3D12_HEAP_TYPE_UPLOAD); + CD3DX12_RESOURCE_DESC rdb = CD3DX12_RESOURCE_DESC::Buffer(256 * 1024 * sizeof(float)); + ThrowIfFailed(d3d.device->CreateCommittedResource( + &hp, + D3D12_HEAP_FLAG_NONE, + &rdb, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&d3d.vertex_buffer))); + + CD3DX12_RANGE read_range(0, 0); // Read not possible from CPU + ThrowIfFailed(d3d.vertex_buffer->Map(0, &read_range, &d3d.mapped_vbuf_address)); + } +} + +static void gfx_direct3d12_end_frame(void) { + if (max_texture_uploads < texture_uploads && texture_uploads != 38 && texture_uploads != 34 && texture_uploads != 29) { + max_texture_uploads = texture_uploads; + } + //printf("Texture uploads: %d %d\n", max_texture_uploads, texture_uploads); + texture_uploads = 0; + + ThrowIfFailed(d3d.copy_command_list->Close()); + { + ID3D12CommandList *lists[] = { d3d.copy_command_list.Get() }; + d3d.copy_command_queue->ExecuteCommandLists(1, lists); + d3d.copy_command_queue->Signal(d3d.copy_fence.Get(), ++d3d.copy_fence_value); + } + + CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition( + d3d.render_targets[d3d.frame_index].Get(), + D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_PRESENT); + d3d.command_list->ResourceBarrier(1, &barrier); + + d3d.command_queue->Wait(d3d.copy_fence.Get(), d3d.copy_fence_value); + + ThrowIfFailed(d3d.command_list->Close()); + + { + ID3D12CommandList *lists[] = { d3d.command_list.Get() }; + d3d.command_queue->ExecuteCommandLists(1, lists); + } + + { + LARGE_INTEGER t0; + QueryPerformanceCounter(&t0); + //printf("Present: %llu %u\n", (unsigned long long)(t0.QuadPart - d3d.qpc_init), d3d.length_in_vsync_frames); + } +} + +static void gfx_direct3d12_finish_render(void) { + LARGE_INTEGER t0, t1, t2; + QueryPerformanceCounter(&t0); + + static UINT64 fence_value; + ThrowIfFailed(d3d.command_queue->Signal(d3d.fence.Get(), ++fence_value)); + if (d3d.fence->GetCompletedValue() < fence_value) { + ThrowIfFailed(d3d.fence->SetEventOnCompletion(fence_value, d3d.fence_event)); + WaitForSingleObject(d3d.fence_event, INFINITE); + } + QueryPerformanceCounter(&t1); + + d3d.resources_to_clean_at_end_of_frame.clear(); + for (std::pair>& heap : d3d.upload_heaps_in_flight) { + d3d.upload_heaps[heap.first].push_back(std::move(heap.second)); + } + d3d.upload_heaps_in_flight.clear(); + for (std::pair& item : d3d.texture_heap_allocations_to_reclaim_at_end_of_frame) { + item.first->free_list.push_back(item.second); + } + d3d.texture_heap_allocations_to_reclaim_at_end_of_frame.clear(); + + QueryPerformanceCounter(&t2); + + d3d.frame_index = d3d.swap_chain->GetCurrentBackBufferIndex(); + + ThrowIfFailed(d3d.copy_command_allocator->Reset()); + ThrowIfFailed(d3d.copy_command_list->Reset(d3d.copy_command_allocator.Get(), nullptr)); + + //printf("done %llu gpu:%d wait:%d freed:%llu frame:%u %u monitor:%u t:%llu\n", (unsigned long long)(t0.QuadPart - d3d.qpc_init), (int)(t1.QuadPart - t0.QuadPart), (int)(t2.QuadPart - t0.QuadPart), (unsigned long long)(t2.QuadPart - d3d.qpc_init), d3d.pending_frame_stats.rbegin()->first, stats.PresentCount, stats.SyncRefreshCount, (unsigned long long)(stats.SyncQPCTime.QuadPart - d3d.qpc_init)); +} + +static uint16_t gfx_direct3d12_get_pixel_depth(float x, float y) { + return 0; // OTRTODO +} + +} // namespace + +struct GfxRenderingAPI gfx_direct3d12_api = { + gfx_direct3d12_z_is_from_0_to_1, + gfx_direct3d12_unload_shader, + gfx_direct3d12_load_shader, + gfx_direct3d12_create_and_load_new_shader, + gfx_direct3d12_lookup_shader, + gfx_direct3d12_shader_get_info, + gfx_direct3d12_new_texture, + gfx_direct3d12_select_texture, + gfx_direct3d12_upload_texture, + gfx_direct3d12_set_sampler_parameters, + gfx_direct3d12_set_depth_test, + gfx_direct3d12_set_depth_mask, + gfx_direct3d12_get_pixel_depth, + gfx_direct3d12_set_zmode_decal, + gfx_direct3d12_set_viewport, + gfx_direct3d12_set_scissor, + gfx_direct3d12_set_use_alpha, + gfx_direct3d12_draw_triangles, + gfx_direct3d12_init, + gfx_direct3d12_on_resize, + gfx_direct3d12_start_frame, + gfx_direct3d12_end_frame, + gfx_direct3d12_finish_render +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.h b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.h new file mode 100644 index 000000000..9a29be45d --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12.h @@ -0,0 +1,12 @@ +#ifdef ENABLE_DX12 + +#ifndef GFX_DIRECT3D12_H +#define GFX_DIRECT3D12_H + +#include "gfx_rendering_api.h" + +extern struct GfxRenderingAPI gfx_direct3d12_api; + +#endif + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12_guids.h b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12_guids.h new file mode 100644 index 000000000..e18a01812 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d12_guids.h @@ -0,0 +1,62 @@ +#ifndef GFX_DIRECT3D12_GUIDS_H +#define GFX_DIRECT3D12_GUIDS_H + +#ifdef __MINGW32__ + +// This file is only needed due to missing MinGW-specific headers for d3d12.h. +// It will define IID_* symbols having the "selectany" attribute (assuming +// d3d12.h was earlier included), as well as make __uuidof(...) work. + +#define DEF_GUID(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + __CRT_UUID_DECL(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const GUID IID_##type = __uuidof(type) + +DEF_GUID(ID3D12Object,0xc4fec28f,0x7966,0x4e95,0x9f,0x94,0xf4,0x31,0xcb,0x56,0xc3,0xb8); +DEF_GUID(ID3D12DeviceChild,0x905db94b,0xa00c,0x4140,0x9d,0xf5,0x2b,0x64,0xca,0x9e,0xa3,0x57); +DEF_GUID(ID3D12RootSignature,0xc54a6b66,0x72df,0x4ee8,0x8b,0xe5,0xa9,0x46,0xa1,0x42,0x92,0x14); +DEF_GUID(ID3D12RootSignatureDeserializer,0x34AB647B,0x3CC8,0x46AC,0x84,0x1B,0xC0,0x96,0x56,0x45,0xC0,0x46); +DEF_GUID(ID3D12VersionedRootSignatureDeserializer,0x7F91CE67,0x090C,0x4BB7,0xB7,0x8E,0xED,0x8F,0xF2,0xE3,0x1D,0xA0); +DEF_GUID(ID3D12Pageable,0x63ee58fb,0x1268,0x4835,0x86,0xda,0xf0,0x08,0xce,0x62,0xf0,0xd6); +DEF_GUID(ID3D12Heap,0x6b3b2502,0x6e51,0x45b3,0x90,0xee,0x98,0x84,0x26,0x5e,0x8d,0xf3); +DEF_GUID(ID3D12Resource,0x696442be,0xa72e,0x4059,0xbc,0x79,0x5b,0x5c,0x98,0x04,0x0f,0xad); +DEF_GUID(ID3D12CommandAllocator,0x6102dee4,0xaf59,0x4b09,0xb9,0x99,0xb4,0x4d,0x73,0xf0,0x9b,0x24); +DEF_GUID(ID3D12Fence,0x0a753dcf,0xc4d8,0x4b91,0xad,0xf6,0xbe,0x5a,0x60,0xd9,0x5a,0x76); +DEF_GUID(ID3D12Fence1,0x433685fe,0xe22b,0x4ca0,0xa8,0xdb,0xb5,0xb4,0xf4,0xdd,0x0e,0x4a); +DEF_GUID(ID3D12PipelineState,0x765a30f3,0xf624,0x4c6f,0xa8,0x28,0xac,0xe9,0x48,0x62,0x24,0x45); +DEF_GUID(ID3D12DescriptorHeap,0x8efb471d,0x616c,0x4f49,0x90,0xf7,0x12,0x7b,0xb7,0x63,0xfa,0x51); +DEF_GUID(ID3D12QueryHeap,0x0d9658ae,0xed45,0x469e,0xa6,0x1d,0x97,0x0e,0xc5,0x83,0xca,0xb4); +DEF_GUID(ID3D12CommandSignature,0xc36a797c,0xec80,0x4f0a,0x89,0x85,0xa7,0xb2,0x47,0x50,0x82,0xd1); +DEF_GUID(ID3D12CommandList,0x7116d91c,0xe7e4,0x47ce,0xb8,0xc6,0xec,0x81,0x68,0xf4,0x37,0xe5); +DEF_GUID(ID3D12GraphicsCommandList,0x5b160d0f,0xac1b,0x4185,0x8b,0xa8,0xb3,0xae,0x42,0xa5,0xa4,0x55); +DEF_GUID(ID3D12GraphicsCommandList1,0x553103fb,0x1fe7,0x4557,0xbb,0x38,0x94,0x6d,0x7d,0x0e,0x7c,0xa7); +DEF_GUID(ID3D12GraphicsCommandList2,0x38C3E585,0xFF17,0x412C,0x91,0x50,0x4F,0xC6,0xF9,0xD7,0x2A,0x28); +DEF_GUID(ID3D12CommandQueue,0x0ec870a6,0x5d7e,0x4c22,0x8c,0xfc,0x5b,0xaa,0xe0,0x76,0x16,0xed); +DEF_GUID(ID3D12Device,0x189819f1,0x1db6,0x4b57,0xbe,0x54,0x18,0x21,0x33,0x9b,0x85,0xf7); +DEF_GUID(ID3D12PipelineLibrary,0xc64226a8,0x9201,0x46af,0xb4,0xcc,0x53,0xfb,0x9f,0xf7,0x41,0x4f); +DEF_GUID(ID3D12PipelineLibrary1,0x80eabf42,0x2568,0x4e5e,0xbd,0x82,0xc3,0x7f,0x86,0x96,0x1d,0xc3); +DEF_GUID(ID3D12Device1,0x77acce80,0x638e,0x4e65,0x88,0x95,0xc1,0xf2,0x33,0x86,0x86,0x3e); +DEF_GUID(ID3D12Device2,0x30baa41e,0xb15b,0x475c,0xa0,0xbb,0x1a,0xf5,0xc5,0xb6,0x43,0x28); +DEF_GUID(ID3D12Device3,0x81dadc15,0x2bad,0x4392,0x93,0xc5,0x10,0x13,0x45,0xc4,0xaa,0x98); +DEF_GUID(ID3D12ProtectedSession,0xA1533D18,0x0AC1,0x4084,0x85,0xB9,0x89,0xA9,0x61,0x16,0x80,0x6B); +DEF_GUID(ID3D12ProtectedResourceSession,0x6CD696F4,0xF289,0x40CC,0x80,0x91,0x5A,0x6C,0x0A,0x09,0x9C,0x3D); +DEF_GUID(ID3D12Device4,0xe865df17,0xa9ee,0x46f9,0xa4,0x63,0x30,0x98,0x31,0x5a,0xa2,0xe5); +DEF_GUID(ID3D12LifetimeOwner,0xe667af9f,0xcd56,0x4f46,0x83,0xce,0x03,0x2e,0x59,0x5d,0x70,0xa8); +DEF_GUID(ID3D12SwapChainAssistant,0xf1df64b6,0x57fd,0x49cd,0x88,0x07,0xc0,0xeb,0x88,0xb4,0x5c,0x8f); +DEF_GUID(ID3D12LifetimeTracker,0x3fd03d36,0x4eb1,0x424a,0xa5,0x82,0x49,0x4e,0xcb,0x8b,0xa8,0x13); +DEF_GUID(ID3D12StateObject,0x47016943,0xfca8,0x4594,0x93,0xea,0xaf,0x25,0x8b,0x55,0x34,0x6d); +DEF_GUID(ID3D12StateObjectProperties,0xde5fa827,0x9bf9,0x4f26,0x89,0xff,0xd7,0xf5,0x6f,0xde,0x38,0x60); +DEF_GUID(ID3D12Device5,0x8b4f173b,0x2fea,0x4b80,0x8f,0x58,0x43,0x07,0x19,0x1a,0xb9,0x5d); +DEF_GUID(ID3D12DeviceRemovedExtendedDataSettings,0x82BC481C,0x6B9B,0x4030,0xAE,0xDB,0x7E,0xE3,0xD1,0xDF,0x1E,0x63); +DEF_GUID(ID3D12DeviceRemovedExtendedData,0x98931D33,0x5AE8,0x4791,0xAA,0x3C,0x1A,0x73,0xA2,0x93,0x4E,0x71); +DEF_GUID(ID3D12Device6,0xc70b221b,0x40e4,0x4a17,0x89,0xaf,0x02,0x5a,0x07,0x27,0xa6,0xdc); +DEF_GUID(ID3D12Resource1,0x9D5E227A,0x4430,0x4161,0x88,0xB3,0x3E,0xCA,0x6B,0xB1,0x6E,0x19); +DEF_GUID(ID3D12Heap1,0x572F7389,0x2168,0x49E3,0x96,0x93,0xD6,0xDF,0x58,0x71,0xBF,0x6D); +DEF_GUID(ID3D12GraphicsCommandList3,0x6FDA83A7,0xB84C,0x4E38,0x9A,0xC8,0xC7,0xBD,0x22,0x01,0x6B,0x3D); +DEF_GUID(ID3D12MetaCommand,0xDBB84C27,0x36CE,0x4FC9,0xB8,0x01,0xF0,0x48,0xC4,0x6A,0xC5,0x70); +DEF_GUID(ID3D12GraphicsCommandList4,0x8754318e,0xd3a9,0x4541,0x98,0xcf,0x64,0x5b,0x50,0xdc,0x48,0x74); +DEF_GUID(ID3D12Tools,0x7071e1f0,0xe84b,0x4b33,0x97,0x4f,0x12,0xfa,0x49,0xde,0x65,0xc5); +DEF_GUID(ID3D12GraphicsCommandList5,0x55050859,0x4024,0x474c,0x87,0xf5,0x64,0x72,0xea,0xee,0x44,0xea); + +#endif + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.cpp new file mode 100644 index 000000000..ca60aef8b --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.cpp @@ -0,0 +1,322 @@ +#if defined(ENABLE_DX11) || defined(ENABLE_DX12) + +#include + +#include "gfx_direct3d_common.h" +#include "gfx_cc.h" + +static void append_str(char *buf, size_t *len, const char *str) { + while (*str != '\0') buf[(*len)++] = *str++; +} + +static void append_line(char *buf, size_t *len, const char *str) { + while (*str != '\0') buf[(*len)++] = *str++; + buf[(*len)++] = '\r'; + buf[(*len)++] = '\n'; +} + +static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) { + if (!only_alpha) { + switch (item) { + default: + case SHADER_0: + return with_alpha ? "float4(0.0, 0.0, 0.0, 0.0)" : "float3(0.0, 0.0, 0.0)"; + case SHADER_1: + return with_alpha ? "float4(1.0, 1.0, 1.0, 1.0)" : "float3(1.0, 1.0, 1.0)"; + case SHADER_INPUT_1: + return with_alpha || !inputs_have_alpha ? "input.input1" : "input.input1.rgb"; + case SHADER_INPUT_2: + return with_alpha || !inputs_have_alpha ? "input.input2" : "input.input2.rgb"; + case SHADER_INPUT_3: + return with_alpha || !inputs_have_alpha ? "input.input3" : "input.input3.rgb"; + case SHADER_INPUT_4: + return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input4.rgb"; + case SHADER_TEXEL0: + return with_alpha ? "texVal0" : "texVal0.rgb"; + case SHADER_TEXEL0A: + return hint_single_element ? "texVal0.a" : (with_alpha ? "float4(texVal0.a, texVal0.a, texVal0.a, texVal0.a)" : "float3(texVal0.a, texVal0.a, texVal0.a)"); + case SHADER_TEXEL1A: + return hint_single_element ? "texVal1.a" : (with_alpha ? "float4(texVal1.a, texVal1.a, texVal1.a, texVal1.a)" : "float3(texVal1.a, texVal1.a, texVal1.a)"); + case SHADER_TEXEL1: + return with_alpha ? "texVal1" : "texVal1.rgb"; + case SHADER_COMBINED: + return with_alpha ? "texel" : "texel.rgb"; + } + } else { + switch (item) { + default: + case SHADER_0: + return "0.0"; + case SHADER_1: + return "1.0"; + case SHADER_INPUT_1: + return "input.input1.a"; + case SHADER_INPUT_2: + return "input.input2.a"; + case SHADER_INPUT_3: + return "input.input3.a"; + case SHADER_INPUT_4: + return "input.input4.a"; + case SHADER_TEXEL0: + return "texVal0.a"; + case SHADER_TEXEL0A: + return "texVal0.a"; + case SHADER_TEXEL1A: + return "texVal1.a"; + case SHADER_TEXEL1: + return "texVal1.a"; + case SHADER_COMBINED: + return "texel.a"; + } + } +} + +static void append_formula(char *buf, size_t *len, const uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) { + if (do_single) { + append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false)); + } else if (do_multiply) { + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, " * "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + } else if (do_mix) { + append_str(buf, len, "lerp("); + append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ", "); + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ", "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + append_str(buf, len, ")"); + } else { + append_str(buf, len, "("); + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, " - "); + append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ") * "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + append_str(buf, len, " + "); + append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false)); + } +} + +void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, const CCFeatures& cc_features, bool include_root_signature, bool three_point_filtering) { + len = 0; + num_floats = 4; + + // Pixel shader input struct + + if (include_root_signature) { + append_str(buf, &len, "#define RS \"RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | DENY_VERTEX_SHADER_ROOT_ACCESS)"); + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_str(buf, &len, ",CBV(b0, visibility = SHADER_VISIBILITY_PIXEL)"); + } + if (cc_features.used_textures[0]) { + append_str(buf, &len, ",DescriptorTable(SRV(t0), visibility = SHADER_VISIBILITY_PIXEL)"); + append_str(buf, &len, ",DescriptorTable(Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL)"); + } + if (cc_features.used_textures[1]) { + append_str(buf, &len, ",DescriptorTable(SRV(t1), visibility = SHADER_VISIBILITY_PIXEL)"); + append_str(buf, &len, ",DescriptorTable(Sampler(s1), visibility = SHADER_VISIBILITY_PIXEL)"); + } + append_line(buf, &len, "\""); + } + + append_line(buf, &len, "struct PSInput {"); + append_line(buf, &len, " float4 position : SV_POSITION;"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + len += sprintf(buf + len, " float2 uv%d : TEXCOORD%d;\r\n", i, i); + num_floats += 2; + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + len += sprintf(buf + len, " float texClamp%s%d : TEXCLAMP%s%d;\r\n", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); + num_floats += 1; + } + } + } + } + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(buf, &len, " float4 screenPos : TEXCOORD2;"); + } + if (cc_features.opt_fog) { + append_line(buf, &len, " float4 fog : FOG;"); + num_floats += 4; + } + for (int i = 0; i < cc_features.num_inputs; i++) { + len += sprintf(buf + len, " float%d input%d : INPUT%d;\r\n", cc_features.opt_alpha ? 4 : 3, i + 1, i); + num_floats += cc_features.opt_alpha ? 4 : 3; + } + append_line(buf, &len, "};"); + + // Textures and samplers + + if (cc_features.used_textures[0]) { + append_line(buf, &len, "Texture2D g_texture0 : register(t0);"); + append_line(buf, &len, "SamplerState g_sampler0 : register(s0);"); + } + if (cc_features.used_textures[1]) { + append_line(buf, &len, "Texture2D g_texture1 : register(t1);"); + append_line(buf, &len, "SamplerState g_sampler1 : register(s1);"); + } + + // Constant buffer and random function + + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(buf, &len, "cbuffer PerFrameCB : register(b0) {"); + append_line(buf, &len, " uint noise_frame;"); + append_line(buf, &len, " float2 noise_scale;"); + append_line(buf, &len, "}"); + + append_line(buf, &len, "float random(in float3 value) {"); + append_line(buf, &len, " float random = dot(value, float3(12.9898, 78.233, 37.719));"); + append_line(buf, &len, " return frac(sin(random) * 143758.5453);"); + append_line(buf, &len, "}"); + } + + // 3 point texture filtering + // Original author: ArthurCarvalho + // Based on GLSL implementation by twinaphex, mupen64plus-libretro project. + + if (three_point_filtering && (cc_features.used_textures[0] || cc_features.used_textures[1])) { + append_line(buf, &len, "cbuffer PerDrawCB : register(b1) {"); + append_line(buf, &len, " struct {"); + append_line(buf, &len, " uint width;"); + append_line(buf, &len, " uint height;"); + append_line(buf, &len, " bool linear_filtering;"); + append_line(buf, &len, " } textures[2];"); + append_line(buf, &len, "}"); + append_line(buf, &len, "#define TEX_OFFSET(tex, tSampler, texCoord, off, texSize) tex.Sample(tSampler, texCoord - off / texSize)"); + append_line(buf, &len, "float4 tex2D3PointFilter(in Texture2D tex, in SamplerState tSampler, in float2 texCoord, in float2 texSize) {"); + append_line(buf, &len, " float2 offset = frac(texCoord * texSize - float2(0.5, 0.5));"); + append_line(buf, &len, " offset -= step(1.0, offset.x + offset.y);"); + append_line(buf, &len, " float4 c0 = TEX_OFFSET(tex, tSampler, texCoord, offset, texSize);"); + append_line(buf, &len, " float4 c1 = TEX_OFFSET(tex, tSampler, texCoord, float2(offset.x - sign(offset.x), offset.y), texSize);"); + append_line(buf, &len, " float4 c2 = TEX_OFFSET(tex, tSampler, texCoord, float2(offset.x, offset.y - sign(offset.y)), texSize);"); + append_line(buf, &len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);"); + append_line(buf, &len, "}"); + } + + // Vertex shader + + append_str(buf, &len, "PSInput VSMain(float4 position : POSITION"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + len += sprintf(buf + len, ", float2 uv%d : TEXCOORD%d", i, i); + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + len += sprintf(buf + len, ", float texClamp%s%d : TEXCLAMP%s%d", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); + } + } + } + } + if (cc_features.opt_fog) { + append_str(buf, &len, ", float4 fog : FOG"); + } + for (int i = 0; i < cc_features.num_inputs; i++) { + len += sprintf(buf + len, ", float%d input%d : INPUT%d", cc_features.opt_alpha ? 4 : 3, i + 1, i); + } + append_line(buf, &len, ") {"); + append_line(buf, &len, " PSInput result;"); + append_line(buf, &len, " result.position = position;"); + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(buf, &len, " result.screenPos = position;"); + } + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + len += sprintf(buf + len, " result.uv%d = uv%d;\r\n", i, i); + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + len += sprintf(buf + len, " result.texClamp%s%d = texClamp%s%d;\r\n", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); + } + } + } + } + + if (cc_features.opt_fog) { + append_line(buf, &len, " result.fog = fog;"); + } + for (int i = 0; i < cc_features.num_inputs; i++) { + len += sprintf(buf + len, " result.input%d = input%d;\r\n", i + 1, i + 1); + } + append_line(buf, &len, " return result;"); + append_line(buf, &len, "}"); + + // Pixel shader + if (include_root_signature) { + append_line(buf, &len, "[RootSignature(RS)]"); + } + append_line(buf, &len, "float4 PSMain(PSInput input) : SV_TARGET {"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + len += sprintf(buf + len, " float2 tc%d = input.uv%d;\r\n", i, i); + bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; + if (!s && !t) { + } else { + len += sprintf(buf + len, " int2 texSize%d;\r\n", i); + len += sprintf(buf + len, " g_texture%d.GetDimensions(texSize%d.x, texSize%d.y);\r\n", i, i, i); + if (s && t) { + len += sprintf(buf + len, " tc%d = clamp(tc%d, 0.5 / texSize%d, float2(input.texClampS%d, input.texClampT%d));\r\n", i, i, i, i, i); + } else if (s) { + len += sprintf(buf + len, " tc%d = float2(clamp(tc%d.x, 0.5 / texSize%d.x, input.texClampS%d), tc%d.y);\n", i, i, i, i, i); + } else { + len += sprintf(buf + len, " tc%d = float2(tc%d.x, clamp(tc%d.y, 0.5 / texSize%d.y, input.texClampT%d));\n", i, i, i, i, i); + } + } + if (three_point_filtering) { + len += sprintf(buf + len, " float4 texVal%d;\r\n", i); + len += sprintf(buf + len, " if (textures[%d].linear_filtering)\r\n", i); + len += sprintf(buf + len, " texVal%d = tex2D3PointFilter(g_texture%d, g_sampler%d, tc%d, float2(textures[%d].width, textures[%d].height));\r\n", i, i, i, i, i, i); + len += sprintf(buf + len, " else\r\n"); + len += sprintf(buf + len, " texVal%d = g_texture%d.Sample(g_sampler%d, tc%d);\r\n", i, i, i, i); + } else { + len += sprintf(buf + len, " float4 texVal%d = g_texture%d.Sample(g_sampler%d, tc%d);\r\n", i, i, i, i); + } + } + } + + append_str(buf, &len, cc_features.opt_alpha ? " float4 texel;" : " float3 texel;"); + for (int c = 0; c < (cc_features.opt_2cyc ? 2 : 1); c++) { + append_str(buf, &len, "texel = "); + if (!cc_features.color_alpha_same[c] && cc_features.opt_alpha) { + append_str(buf, &len, "float4("); + append_formula(buf, &len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], false, false, true); + append_str(buf, &len, ", "); + append_formula(buf, &len, cc_features.c[c], cc_features.do_single[c][1], cc_features.do_multiply[c][1], cc_features.do_mix[c][1], true, true, true); + append_str(buf, &len, ")"); + } else { + append_formula(buf, &len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], cc_features.opt_alpha, false, cc_features.opt_alpha); + } + append_line(buf, &len, ";"); + } + + if (cc_features.opt_texture_edge && cc_features.opt_alpha) { + append_line(buf, &len, " if (texel.a > 0.19) texel.a = 1.0; else discard;"); + } + // TODO discard if alpha is 0? + if (cc_features.opt_fog) { + if (cc_features.opt_alpha) { + append_line(buf, &len, " texel = float4(lerp(texel.rgb, input.fog.rgb, input.fog.a), texel.a);"); + } else { + append_line(buf, &len, " texel = lerp(texel, input.fog.rgb, input.fog.a);"); + } + } + + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(buf, &len, " float2 coords = (input.screenPos.xy / input.screenPos.w) * noise_scale;"); + append_line(buf, &len, " texel.a *= round(saturate(random(float3(floor(coords), noise_frame)) + texel.a - 0.5));"); + } + + if (cc_features.opt_alpha) { + if (cc_features.opt_alpha_threshold) { + append_line(buf, &len, " if (texel.a < 8.0 / 256.0) discard;"); + } + if (cc_features.opt_invisible) { + append_line(buf, &len, " texel.a = 0.0;"); + } + append_line(buf, &len, " return texel;"); + } else { + append_line(buf, &len, " return float4(texel, 1.0);"); + } + append_line(buf, &len, "}"); +} + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.h b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.h new file mode 100644 index 000000000..5df83a349 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_direct3d_common.h @@ -0,0 +1,14 @@ +#if defined(ENABLE_DX11) || defined(ENABLE_DX12) + +#ifndef GFX_DIRECT3D_COMMON_H +#define GFX_DIRECT3D_COMMON_H + +#include + +#include "gfx_cc.h" + +void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, const CCFeatures& cc_features, bool include_root_signature, bool three_point_filtering); + +#endif + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp new file mode 100644 index 000000000..6cfc3cf32 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp @@ -0,0 +1,673 @@ +#if defined(ENABLE_DX11) || defined(ENABLE_DX12) + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + + +#ifndef _LANGUAGE_C +#define _LANGUAGE_C +#endif +#include + +#include "gfx_window_manager_api.h" +#include "gfx_rendering_api.h" +#include "gfx_direct3d_common.h" +#include "gfx_screen_config.h" +#include "gfx_pc.h" +#include "../../SohImGuiImpl.h" + +#define DECLARE_GFX_DXGI_FUNCTIONS +#include "gfx_dxgi.h" + +#define WINCLASS_NAME L"N64GAME" +#define GFX_API_NAME "DirectX" + +#ifdef VERSION_EU +#define FRAME_INTERVAL_US_NUMERATOR_ 60000 +#define FRAME_INTERVAL_US_DENOMINATOR 3 +#else +#define FRAME_INTERVAL_US_NUMERATOR_ 50000 +#define FRAME_INTERVAL_US_DENOMINATOR 3 +#endif + +#define FRAME_INTERVAL_US_NUMERATOR (FRAME_INTERVAL_US_NUMERATOR_ * dxgi.frame_divisor) + +using namespace Microsoft::WRL; // For ComPtr + +static struct { + HWND h_wnd; + bool in_paint; + bool recursive_paint_detected; + uint32_t current_width, current_height; + std::string game_name; + + HMODULE dxgi_module; + HRESULT (__stdcall *CreateDXGIFactory1)(REFIID riid, void **factory); + HRESULT (__stdcall *CreateDXGIFactory2)(UINT flags, REFIID iid, void **factory); + + bool process_dpi_awareness_done; + + RECT last_window_rect; + bool is_full_screen, last_maximized_state; + + ComPtr factory; + ComPtr swap_chain; + HANDLE waitable_object; + uint64_t qpc_init, qpc_freq; + uint64_t frame_timestamp; // in units of 1/FRAME_INTERVAL_US_DENOMINATOR microseconds + std::map frame_stats; + std::set> pending_frame_stats; + bool dropped_frame; + bool zero_latency; + UINT length_in_vsync_frames; + uint32_t frame_divisor; + HANDLE timer; + bool use_timer; + LARGE_INTEGER previous_present_time; + + void (*on_fullscreen_changed)(bool is_now_fullscreen); + void (*run_one_game_iter)(void); + bool (*on_key_down)(int scancode); + bool (*on_key_up)(int scancode); + void (*on_all_keys_up)(void); +} dxgi; + +static void load_dxgi_library(void) { + dxgi.dxgi_module = LoadLibraryW(L"dxgi.dll"); + *(FARPROC *)&dxgi.CreateDXGIFactory1 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory1"); + *(FARPROC *)&dxgi.CreateDXGIFactory2 = GetProcAddress(dxgi.dxgi_module, "CreateDXGIFactory2"); +} + +template +static void run_as_dpi_aware(Fun f) { + // Make sure Windows 8.1 or newer doesn't upscale/downscale the rendered images. + // This is an issue on Windows 8.1 and newer where moving around the window + // between different monitors having different scaling settings will + // by default result in the DirectX image will also be scaled accordingly. + // The resulting scale factor is the curent monitor's scale factor divided by + // the initial monitor's scale factor. Setting per-monitor aware disables scaling. + + // On Windows 10 1607 and later, that is solved by setting the awarenenss per window, + // which is done by using SetThreadDpiAwarenessContext before and after creating + // any window. When the message handler runs, the corresponding context also applies. + + // From windef.h, missing in MinGW. + DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); + #define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1) + #define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2) + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3) + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + #define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5) + + DPI_AWARENESS_CONTEXT (WINAPI *SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); + *(FARPROC *)&SetThreadDpiAwarenessContext = GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetThreadDpiAwarenessContext"); + DPI_AWARENESS_CONTEXT old_awareness_context = nullptr; + if (SetThreadDpiAwarenessContext != nullptr) { + old_awareness_context = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } else { + // Solution for Windows 8.1 and newer, but before Windows 10 1607. + // SetProcessDpiAwareness must be called before any drawing related API is called. + if (!dxgi.process_dpi_awareness_done) { + HMODULE shcore_module = LoadLibraryW(L"SHCore.dll"); + if (shcore_module != nullptr) { + HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS value); + *(FARPROC *)&SetProcessDpiAwareness = GetProcAddress(shcore_module, "SetProcessDpiAwareness"); + if (SetProcessDpiAwareness != nullptr) { + SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); + // Ignore result, will fail if already called or manifest already specifies dpi awareness. + } + FreeLibrary(shcore_module); + } + dxgi.process_dpi_awareness_done = true; + } + } + + f(); + + // Restore the old context + if (SetThreadDpiAwarenessContext != nullptr && old_awareness_context != nullptr) { + SetThreadDpiAwarenessContext(old_awareness_context); + } +} + +static void toggle_borderless_window_full_screen(bool enable, bool call_callback) { + // Windows 7 + flip mode + waitable object can't go to exclusive fullscreen, + // so do borderless instead. If DWM is enabled, this means we get one monitor + // sync interval of latency extra. On Win 10 however (maybe Win 8 too), due to + // "fullscreen optimizations" the latency is eliminated. + + if (enable == dxgi.is_full_screen) { + return; + } + + if (!enable) { + RECT r = dxgi.last_window_rect; + + // Set in window mode with the last saved position and size + SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW); + + if (dxgi.last_maximized_state) { + SetWindowPos(dxgi.h_wnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(dxgi.h_wnd, SW_MAXIMIZE); + } else { + SetWindowPos(dxgi.h_wnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED); + ShowWindow(dxgi.h_wnd, SW_RESTORE); + } + + dxgi.is_full_screen = false; + } else { + // Save if window is maximized or not + WINDOWPLACEMENT window_placement; + window_placement.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(dxgi.h_wnd, &window_placement); + dxgi.last_maximized_state = window_placement.showCmd == SW_SHOWMAXIMIZED; + + // Save window position and size if the window is not maximized + GetWindowRect(dxgi.h_wnd, &dxgi.last_window_rect); + + // Get in which monitor the window is + HMONITOR h_monitor = MonitorFromWindow(dxgi.h_wnd, MONITOR_DEFAULTTONEAREST); + + // Get info from that monitor + MONITORINFOEX monitor_info; + monitor_info.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(h_monitor, &monitor_info); + RECT r = monitor_info.rcMonitor; + + // Set borderless full screen to that monitor + SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); + SetWindowPos(dxgi.h_wnd, HWND_TOP, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED); + + dxgi.is_full_screen = true; + } + + if (dxgi.on_fullscreen_changed != nullptr && call_callback) { + dxgi.on_fullscreen_changed(enable); + } +} + +static void gfx_dxgi_on_resize(void) { + if (dxgi.swap_chain.Get() != nullptr) { + gfx_get_current_rendering_api()->on_resize(); + + DXGI_SWAP_CHAIN_DESC1 desc1; + ThrowIfFailed(dxgi.swap_chain->GetDesc1(&desc1)); + dxgi.current_width = desc1.Width; + dxgi.current_height = desc1.Height; + } +} + +static void onkeydown(WPARAM w_param, LPARAM l_param) { + int key = ((l_param >> 16) & 0x1ff); + if (dxgi.on_key_down != nullptr) { + dxgi.on_key_down(key); + } +} +static void onkeyup(WPARAM w_param, LPARAM l_param) { + int key = ((l_param >> 16) & 0x1ff); + if (dxgi.on_key_up != nullptr) { + dxgi.on_key_up(key); + } +} + +static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) { + SohImGui::EventImpl event_impl; + event_impl.win32 = { h_wnd, static_cast(message), static_cast(w_param), static_cast(l_param) }; + SohImGui::Update(event_impl); + switch (message) { + case WM_SIZE: + gfx_dxgi_on_resize(); + break; + case WM_DESTROY: + exit(0); + case WM_PAINT: + if (dxgi.in_paint) { + dxgi.recursive_paint_detected = true; + return DefWindowProcW(h_wnd, message, w_param, l_param); + } else { + if (dxgi.run_one_game_iter != nullptr) { + dxgi.in_paint = true; + dxgi.run_one_game_iter(); + dxgi.in_paint = false; + if (dxgi.recursive_paint_detected) { + dxgi.recursive_paint_detected = false; + InvalidateRect(h_wnd, nullptr, false); + UpdateWindow(h_wnd); + } + } + } + break; + case WM_ACTIVATEAPP: + if (dxgi.on_all_keys_up != nullptr) { + dxgi.on_all_keys_up(); + } + break; + case WM_KEYDOWN: + onkeydown(w_param, l_param); + break; + case WM_KEYUP: + onkeyup(w_param, l_param); + break; + case WM_SYSKEYDOWN: + if ((w_param == VK_RETURN) && ((l_param & 1 << 30) == 0)) { + toggle_borderless_window_full_screen(!dxgi.is_full_screen, true); + break; + } else { + return DefWindowProcW(h_wnd, message, w_param, l_param); + } + default: + return DefWindowProcW(h_wnd, message, w_param, l_param); + } + return 0; +} + +void gfx_dxgi_init(const char *game_name, bool start_in_fullscreen) { + LARGE_INTEGER qpc_init, qpc_freq; + QueryPerformanceCounter(&qpc_init); + QueryPerformanceFrequency(&qpc_freq); + dxgi.qpc_init = qpc_init.QuadPart; + dxgi.qpc_freq = qpc_freq.QuadPart; + + dxgi.frame_divisor = 1; + dxgi.timer = CreateWaitableTimer(nullptr, false, nullptr); + + // Prepare window title + + char title[512]; + wchar_t w_title[512]; + int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME); + mbstowcs(w_title, title, len + 1); + dxgi.game_name = game_name; + + // Create window + WNDCLASSEXW wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = gfx_dxgi_wnd_proc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = nullptr; + wcex.hIcon = nullptr; + wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.lpszMenuName = nullptr; + wcex.lpszClassName = WINCLASS_NAME; + wcex.hIconSm = nullptr; + + ATOM winclass = RegisterClassExW(&wcex); + + + run_as_dpi_aware([&] () { + // We need to be dpi aware when calculating the size + RECT wr = {0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT}; + AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); + + dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, nullptr, nullptr); + }); + + load_dxgi_library(); + + ShowWindow(dxgi.h_wnd, SW_SHOW); + UpdateWindow(dxgi.h_wnd); + + if (start_in_fullscreen) { + toggle_borderless_window_full_screen(true, false); + } +} + +static void gfx_dxgi_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) { + dxgi.on_fullscreen_changed = on_fullscreen_changed; +} + +static void gfx_dxgi_show_cursor(bool hide) { + /** + * @bug When menubar is open in windowed mode and you toggle fullscreen + * ShowCursor no longer responds. Debugging shows the bool to be correct. + **/ + INFO("renderer: %s", hide ? "true" : "false"); + ShowCursor(hide); +} + +static void gfx_dxgi_set_fullscreen(bool enable) { + toggle_borderless_window_full_screen(enable, true); +} + +static void gfx_dxgi_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) { + dxgi.on_key_down = on_key_down; + dxgi.on_key_up = on_key_up; + dxgi.on_all_keys_up = on_all_keys_up; +} + +static void gfx_dxgi_main_loop(void (*run_one_game_iter)(void)) { + dxgi.run_one_game_iter = run_one_game_iter; + + MSG msg; + while (GetMessage(&msg, nullptr, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +static void gfx_dxgi_get_dimensions(uint32_t *width, uint32_t *height) { + *width = dxgi.current_width; + *height = dxgi.current_height; +} + +static void gfx_dxgi_handle_events(void) { + /*MSG msg; + while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + }*/ +} + +static uint64_t qpc_to_us(uint64_t qpc) { + return qpc / dxgi.qpc_freq * 1000000 + qpc % dxgi.qpc_freq * 1000000 / dxgi.qpc_freq; +} + +static uint64_t qpc_to_100ns(uint64_t qpc) { + return qpc / dxgi.qpc_freq * 10000000 + qpc % dxgi.qpc_freq * 10000000 / dxgi.qpc_freq; +} + +static bool gfx_dxgi_start_frame(void) { + DXGI_FRAME_STATISTICS stats; + if (dxgi.swap_chain->GetFrameStatistics(&stats) == S_OK && (stats.SyncRefreshCount != 0 || stats.SyncQPCTime.QuadPart != 0ULL)) { + { + LARGE_INTEGER t0; + QueryPerformanceCounter(&t0); + //printf("Get frame stats: %llu\n", (unsigned long long)(t0.QuadPart - dxgi.qpc_init)); + } + //printf("stats: %u %u %u %u %u %.6f\n", dxgi.pending_frame_stats.rbegin()->first, dxgi.pending_frame_stats.rbegin()->second, stats.PresentCount, stats.PresentRefreshCount, stats.SyncRefreshCount, (double)(stats.SyncQPCTime.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq); + if (dxgi.frame_stats.empty() || dxgi.frame_stats.rbegin()->second.PresentCount != stats.PresentCount) { + dxgi.frame_stats.insert(std::make_pair(stats.PresentCount, stats)); + } + if (dxgi.frame_stats.size() > 3) { + dxgi.frame_stats.erase(dxgi.frame_stats.begin()); + } + } + if (!dxgi.frame_stats.empty()) { + while (!dxgi.pending_frame_stats.empty() && dxgi.pending_frame_stats.begin()->first < dxgi.frame_stats.rbegin()->first) { + dxgi.pending_frame_stats.erase(dxgi.pending_frame_stats.begin()); + } + } + while (dxgi.pending_frame_stats.size() > 40) { + // Just make sure the list doesn't grow too large if GetFrameStatistics fails. + dxgi.pending_frame_stats.erase(dxgi.pending_frame_stats.begin()); + + // These are not that useful anymore + dxgi.frame_stats.clear(); + } + + dxgi.use_timer = false; + + dxgi.frame_timestamp += FRAME_INTERVAL_US_NUMERATOR; + + if (dxgi.frame_stats.size() >= 2) { + DXGI_FRAME_STATISTICS *first = &dxgi.frame_stats.begin()->second; + DXGI_FRAME_STATISTICS *last = &dxgi.frame_stats.rbegin()->second; + uint64_t sync_qpc_diff = last->SyncQPCTime.QuadPart - first->SyncQPCTime.QuadPart; + UINT sync_vsync_diff = last->SyncRefreshCount - first->SyncRefreshCount; + UINT present_vsync_diff = last->PresentRefreshCount - first->PresentRefreshCount; + UINT present_diff = last->PresentCount - first->PresentCount; + + if (sync_vsync_diff == 0) { + sync_vsync_diff = 1; + } + + double estimated_vsync_interval = (double)sync_qpc_diff / (double)sync_vsync_diff; + uint64_t estimated_vsync_interval_us = qpc_to_us(estimated_vsync_interval); + //printf("Estimated vsync_interval: %d\n", (int)estimated_vsync_interval_us); + if (estimated_vsync_interval_us < 2 || estimated_vsync_interval_us > 1000000) { + // Unreasonable, maybe a monitor change + estimated_vsync_interval_us = 16666; + estimated_vsync_interval = estimated_vsync_interval_us * dxgi.qpc_freq / 1000000; + } + + UINT queued_vsyncs = 0; + bool is_first = true; + for (const std::pair& p : dxgi.pending_frame_stats) { + /*if (is_first && dxgi.zero_latency) { + is_first = false; + continue; + }*/ + queued_vsyncs += p.second; + } + + uint64_t last_frame_present_end_qpc = (last->SyncQPCTime.QuadPart - dxgi.qpc_init) + estimated_vsync_interval * queued_vsyncs; + uint64_t last_end_us = qpc_to_us(last_frame_present_end_qpc); + + double vsyncs_to_wait = (double)(int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) / estimated_vsync_interval_us; + //printf("ts: %llu, last_end_us: %llu, Init v: %f\n", dxgi.frame_timestamp / 3, last_end_us, vsyncs_to_wait); + + if (vsyncs_to_wait <= 0) { + // Too late + + if ((int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) < -66666) { + // The application must have been paused or similar + vsyncs_to_wait = round(((double)FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) / estimated_vsync_interval_us); + if (vsyncs_to_wait < 1) { + vsyncs_to_wait = 1; + } + dxgi.frame_timestamp = FRAME_INTERVAL_US_DENOMINATOR * (last_end_us + vsyncs_to_wait * estimated_vsync_interval_us); + } else { + // Drop frame + //printf("Dropping frame\n"); + dxgi.dropped_frame = true; + return false; + } + } + double orig_wait = vsyncs_to_wait; + if (floor(vsyncs_to_wait) != vsyncs_to_wait) { + uint64_t left = last_end_us + floor(vsyncs_to_wait) * estimated_vsync_interval_us; + uint64_t right = last_end_us + ceil(vsyncs_to_wait) * estimated_vsync_interval_us; + uint64_t adjusted_desired_time = dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR + (last_end_us + (FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) > dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR ? 2000 : -2000); + int64_t diff_left = adjusted_desired_time - left; + int64_t diff_right = right - adjusted_desired_time; + if (diff_left < 0) { + diff_left = -diff_left; + } + if (diff_right < 0) { + diff_right = -diff_right; + } + if (diff_left < diff_right) { + vsyncs_to_wait = floor(vsyncs_to_wait); + } else { + vsyncs_to_wait = ceil(vsyncs_to_wait); + } + if (vsyncs_to_wait == 0) { + //printf("vsyncs_to_wait became 0 so dropping frame\n"); + dxgi.dropped_frame = true; + return false; + } + } + //printf("v: %d\n", (int)vsyncs_to_wait); + if (vsyncs_to_wait > 4) { + // Invalid, so use timer based solution + vsyncs_to_wait = 4; + dxgi.use_timer = true; + } + dxgi.length_in_vsync_frames = vsyncs_to_wait; + } else { + dxgi.length_in_vsync_frames = 1; + dxgi.use_timer = true; + } + + return true; +} + +static void gfx_dxgi_swap_buffers_begin(void) { + //dxgi.length_in_vsync_frames = 1; + LARGE_INTEGER t; + if (dxgi.use_timer) { + QueryPerformanceCounter(&t); + int64_t next = qpc_to_100ns(dxgi.previous_present_time.QuadPart) + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; + int64_t left = next - qpc_to_100ns(t.QuadPart); + if (left > 0) { + LARGE_INTEGER li; + li.QuadPart = -left; + SetWaitableTimer(dxgi.timer, &li, 0, nullptr, nullptr, false); + WaitForSingleObject(dxgi.timer, INFINITE); + } + } + QueryPerformanceCounter(&t); + dxgi.previous_present_time = t; + + ThrowIfFailed(dxgi.swap_chain->Present(dxgi.length_in_vsync_frames, 0)); + UINT this_present_id; + if (dxgi.swap_chain->GetLastPresentCount(&this_present_id) == S_OK) { + dxgi.pending_frame_stats.insert(std::make_pair(this_present_id, dxgi.length_in_vsync_frames)); + } + dxgi.dropped_frame = false; +} + +static void gfx_dxgi_swap_buffers_end(void) { + LARGE_INTEGER t0, t1, t2; + QueryPerformanceCounter(&t0); + QueryPerformanceCounter(&t1); + + if (!dxgi.dropped_frame) { + if (dxgi.waitable_object != nullptr) { + WaitForSingleObject(dxgi.waitable_object, INFINITE); + } + // else TODO: maybe sleep until some estimated time the frame will be shown to reduce lag + } + + DXGI_FRAME_STATISTICS stats; + dxgi.swap_chain->GetFrameStatistics(&stats); + + QueryPerformanceCounter(&t2); + + dxgi.zero_latency = dxgi.pending_frame_stats.rbegin()->first == stats.PresentCount; + + //printf(L"done %I64u gpu:%d wait:%d freed:%I64u frame:%u %u monitor:%u t:%I64u\n", (unsigned long long)(t0.QuadPart - dxgi.qpc_init), (int)(t1.QuadPart - t0.QuadPart), (int)(t2.QuadPart - t0.QuadPart), (unsigned long long)(t2.QuadPart - dxgi.qpc_init), dxgi.pending_frame_stats.rbegin()->first, stats.PresentCount, stats.SyncRefreshCount, (unsigned long long)(stats.SyncQPCTime.QuadPart - dxgi.qpc_init)); +} + +static double gfx_dxgi_get_time(void) { + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return (double)(t.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq; +} + +static void gfx_dxgi_set_frame_divisor(int divisor) { + dxgi.frame_divisor = divisor; +} + +void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)) { + if (dxgi.CreateDXGIFactory2 != nullptr) { + ThrowIfFailed(dxgi.CreateDXGIFactory2(debug ? DXGI_CREATE_FACTORY_DEBUG : 0, __uuidof(IDXGIFactory2), &dxgi.factory)); + } else { + ThrowIfFailed(dxgi.CreateDXGIFactory1(__uuidof(IDXGIFactory2), &dxgi.factory)); + } + + ComPtr adapter; + for (UINT i = 0; dxgi.factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++) { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + if (desc.Flags & 2/*DXGI_ADAPTER_FLAG_SOFTWARE*/) { // declaration missing in mingw headers + continue; + } + if (create_device_fn(adapter.Get(), true)) { + break; + } + } + create_device_fn(adapter.Get(), false); + + char title[512]; + wchar_t w_title[512]; + int len = sprintf(title, "%s (Direct3D %d)", dxgi.game_name.c_str(), d3d_version); + mbstowcs(w_title, title, len + 1); + SetWindowTextW(dxgi.h_wnd, w_title); +} + +ComPtr gfx_dxgi_create_swap_chain(IUnknown *device) { + bool win8 = IsWindows8OrGreater(); // DXGI_SCALING_NONE is only supported on Win8 and beyond + bool dxgi_13 = dxgi.CreateDXGIFactory2 != nullptr; // DXGI 1.3 introduced waitable object + + DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {}; + swap_chain_desc.BufferCount = 2; + swap_chain_desc.Width = 0; + swap_chain_desc.Height = 0; + swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swap_chain_desc.Scaling = win8 ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // Apparently this was backported to Win 7 Platform Update + swap_chain_desc.Flags = dxgi_13 ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0; + swap_chain_desc.SampleDesc.Count = 1; + + run_as_dpi_aware([&] () { + // When setting size for the buffers, the values that DXGI puts into the desc (that can later be retrieved by GetDesc1) + // have been divided by the current scaling factor. By making this call dpi aware, no division will be performed. + // The same goes for IDXGISwapChain::ResizeBuffers(), however that function is currently only called from the message handler. + ThrowIfFailed(dxgi.factory->CreateSwapChainForHwnd(device, dxgi.h_wnd, &swap_chain_desc, nullptr, nullptr, &dxgi.swap_chain)); + }); + ThrowIfFailed(dxgi.factory->MakeWindowAssociation(dxgi.h_wnd, DXGI_MWA_NO_ALT_ENTER)); + + ComPtr swap_chain2; + if (dxgi.swap_chain->QueryInterface(__uuidof(IDXGISwapChain2), &swap_chain2) == S_OK) { + ThrowIfFailed(swap_chain2->SetMaximumFrameLatency(1)); + dxgi.waitable_object = swap_chain2->GetFrameLatencyWaitableObject(); + WaitForSingleObject(dxgi.waitable_object, INFINITE); + } else { + ComPtr device1; + ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&device1))); + ThrowIfFailed(device1->SetMaximumFrameLatency(1)); + } + + ThrowIfFailed(dxgi.swap_chain->GetDesc1(&swap_chain_desc)); + dxgi.current_width = swap_chain_desc.Width; + dxgi.current_height = swap_chain_desc.Height; + + return dxgi.swap_chain; +} + +HWND gfx_dxgi_get_h_wnd(void) { + return dxgi.h_wnd; +} + +void ThrowIfFailed(HRESULT res) { + if (FAILED(res)) { + fprintf(stderr, "Error: 0x%08X\n", res); + throw res; + } +} + +void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) { + if (FAILED(res)) { + char full_message[256]; + sprintf(full_message, "%s\n\nHRESULT: 0x%08X", message, res); + MessageBoxA(h_wnd, full_message, "Error", MB_OK | MB_ICONERROR); + throw res; + } +} + +extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = { + gfx_dxgi_init, + gfx_dxgi_set_keyboard_callbacks, + gfx_dxgi_set_fullscreen_changed_callback, + gfx_dxgi_set_fullscreen, + gfx_dxgi_show_cursor, + gfx_dxgi_main_loop, + gfx_dxgi_get_dimensions, + gfx_dxgi_handle_events, + gfx_dxgi_start_frame, + gfx_dxgi_swap_buffers_begin, + gfx_dxgi_swap_buffers_end, + gfx_dxgi_get_time, + gfx_dxgi_set_frame_divisor, +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.h b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.h new file mode 100644 index 000000000..d590daa66 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.h @@ -0,0 +1,16 @@ +#ifndef GFX_DXGI_H +#define GFX_DXGI_H + +#include "gfx_rendering_api.h" + +#ifdef DECLARE_GFX_DXGI_FUNCTIONS +void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)); +Microsoft::WRL::ComPtr gfx_dxgi_create_swap_chain(IUnknown *device); +HWND gfx_dxgi_get_h_wnd(void); +void ThrowIfFailed(HRESULT res); +void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message); +#endif + +extern struct GfxWindowManagerAPI gfx_dxgi_api; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_glx.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_glx.cpp new file mode 100644 index 000000000..66bb5c182 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_glx.cpp @@ -0,0 +1,618 @@ +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfx_window_manager_api.h" +#include "gfx_screen_config.h" + +#define GFX_API_NAME "GLX - OpenGL" + +#ifdef VERSION_EU +#define FRAME_INTERVAL_US_NUMERATOR 40000 +#define FRAME_INTERVAL_US_DENOMINATOR 1 +#else +#define FRAME_INTERVAL_US_NUMERATOR 100000 +#define FRAME_INTERVAL_US_DENOMINATOR 3 +#endif + +const struct { + const char *name; + int scancode; +} keymap_name_to_scancode[] = { + {"ESC", 0x01}, + {"AE01", 0x02 }, + {"AE02", 0x03 }, + {"AE03", 0x04 }, + {"AE04", 0x05 }, + {"AE05", 0x06 }, + {"AE06", 0x07 }, + {"AE07", 0x08 }, + {"AE08", 0x09 }, + {"AE09", 0x0a }, + {"AE10", 0x0b }, + {"AE11", 0x0c }, + {"AE12", 0x0d }, + {"BKSP", 0x0e }, + {"TAB", 0x0f }, + {"AD01", 0x10 }, + {"AD02", 0x11 }, + {"AD03", 0x12 }, + {"AD04", 0x13 }, + {"AD05", 0x14 }, + {"AD06", 0x15 }, + {"AD07", 0x16 }, + {"AD08", 0x17 }, + {"AD09", 0x18 }, + {"AD10", 0x19 }, + {"AD11", 0x1a }, + {"AD12", 0x1b }, + {"RTRN", 0x1c }, + {"LCTL", 0x1d }, + {"AC01", 0x1e }, + {"AC02", 0x1f }, + {"AC03", 0x20 }, + {"AC04", 0x21 }, + {"AC05", 0x22 }, + {"AC06", 0x23 }, + {"AC07", 0x24 }, + {"AC08", 0x25 }, + {"AC09", 0x26 }, + {"AC10", 0x27 }, + {"AC11", 0x28 }, + {"TLDE", 0x29 }, + {"LFSH", 0x2a }, + {"BKSL", 0x2b }, + {"AB01", 0x2c }, + {"AB02", 0x2d }, + {"AB03", 0x2e }, + {"AB04", 0x2f }, + {"AB05", 0x30 }, + {"AB06", 0x31 }, + {"AB07", 0x32 }, + {"AB08", 0x33 }, + {"AB09", 0x34 }, + {"AB10", 0x35 }, + {"RTSH", 0x36 }, + {"KPMU", 0x37 }, + {"LALT", 0x38 }, + {"SPCE", 0x39 }, + {"CAPS", 0x3a }, + {"FK01", 0x3b }, + {"FK02", 0x3c }, + {"FK03", 0x3d }, + {"FK04", 0x3e }, + {"FK05", 0x3f }, + {"FK06", 0x40 }, + {"FK07", 0x41 }, + {"FK08", 0x42 }, + {"FK09", 0x43 }, + {"FK10", 0x44 }, + {"NMLK", 0x45 }, + {"SCLK", 0x46 }, + {"KP7", 0x47 }, + {"KP8", 0x48 }, + {"KP9", 0x49 }, + {"KPSU", 0x4a }, + {"KP4", 0x4b }, + {"KP5", 0x4c }, + {"KP6", 0x4d }, + {"KPAD", 0x4e }, + {"KP1", 0x4f }, + {"KP2", 0x50 }, + {"KP3", 0x51 }, + {"KP0", 0x52 }, + {"KPDL", 0x53 }, + {"LVL3", 0x54 }, // correct? + {"", 0x55 }, // not mapped? + {"LSGT", 0x56 }, + {"FK11", 0x57 }, + {"FK12", 0x58 }, + {"AB11", 0x59 }, + {"KATA", 0 }, + {"HIRA", 0 }, + {"HENK", 0 }, + {"HKTG", 0 }, + {"MUHE", 0 }, + {"JPCM", 0 }, + {"KPEN", 0x11c }, + {"RCTL", 0x11d }, + {"KPDV", 0x135 }, + {"PRSC", 0x54 }, // ? + {"RALT", 0x138 }, + {"LNFD", 0 }, + {"HOME", 0x147 }, + {"UP", 0x148 }, + {"PGUP", 0x149 }, + {"LEFT", 0x14b }, + {"RGHT", 0x14d }, + {"END", 0x14f }, + {"DOWN", 0x150 }, + {"PGDN", 0x151 }, + {"INS", 0x152 }, + {"DELE", 0x153 }, + {"PAUS", 0x21d }, + {"LWIN", 0x15b }, + {"RWIN", 0x15c }, + {"COMP", 0x15d }, +}; + +static struct { + Display *dpy; + Window root; + Window win; + + Atom atom_wm_state; + Atom atom_wm_state_fullscreen; + Atom atom_wm_delete_window; + + bool is_fullscreen; + void (*on_fullscreen_changed)(bool is_now_fullscreen); + + int keymap[256]; + bool (*on_key_down)(int scancode); + bool (*on_key_up)(int scancode); + void (*on_all_keys_up)(void); + + PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML; + PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML; + PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML; + + PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; + + PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI; + PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI; + + bool has_oml_sync_control; + uint64_t ust0; + int64_t last_msc; + uint64_t wanted_ust; // multiplied by FRAME_INTERVAL_US_DENOMINATOR + uint64_t vsync_interval; + uint64_t last_ust; + int64_t target_msc; + bool dropped_frame; + + bool has_sgi_video_sync; + uint64_t last_sync_counter; + int64_t this_msc; + int64_t this_ust; +} glx; + +static int64_t get_time(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; +} + +static int64_t adjust_sync_counter(uint32_t counter) { + uint32_t hi = glx.last_sync_counter >> 32; + uint32_t lo = (uint32_t)glx.last_sync_counter; + if (lo >= 0x80000000U && counter < 0x80000000U) { + // Wrapped + ++hi; + } + glx.last_sync_counter = ((uint64_t)hi << 32) | counter; + return glx.last_sync_counter; +} + +static int64_t glXWaitVideoSyncSGI_wrapper(void) { + unsigned int counter = 0; + glx.glXWaitVideoSyncSGI(1, 0, &counter); + return adjust_sync_counter(counter); +} + +static int64_t glXGetVideoSyncSGI_wrapper(void) { + unsigned int counter = 0; + glx.glXGetVideoSyncSGI(&counter); + return adjust_sync_counter(counter); +} + +static void init_keymap(void) { + XkbDescPtr desc = XkbGetMap(glx.dpy, 0, XkbUseCoreKbd); + XkbGetNames(glx.dpy, XkbKeyNamesMask, desc); + + for (int i = desc->min_key_code; i <= desc->max_key_code && i < 256; i++) { + char name[XkbKeyNameLength + 1]; + memcpy(name, desc->names->keys[i].name, XkbKeyNameLength); + name[XkbKeyNameLength] = '\0'; + for (size_t j = 0; j < sizeof(keymap_name_to_scancode) / sizeof(keymap_name_to_scancode[0]); j++) { + if (strcmp(keymap_name_to_scancode[j].name, name) == 0) { + glx.keymap[i] = keymap_name_to_scancode[j].scancode; + break; + } + } + } + + XkbFreeNames(desc, XkbKeyNamesMask, True); + XkbFreeKeyboard(desc, 0, True); +} + +static void gfx_glx_show_cursor(bool hide) { + // Removes distracting mouse cursor during fullscreen play + if (hide) { + Cursor hideCursor; + Pixmap bitmapNoData; + XColor black; + static char noData[] = { 0,0,0,0,0,0,0,0 }; + black.red = black.green = black.blue = 0; + + bitmapNoData = XCreateBitmapFromData(glx.dpy, glx.win, noData, 8, 8); + hideCursor = XCreatePixmapCursor(glx.dpy, bitmapNoData, bitmapNoData, + &black, &black, 0, 0); + XDefineCursor(glx.dpy, glx.win, hideCursor); + XSync(glx.dpy, False); + XFreeCursor(glx.dpy, hideCursor); + XFreePixmap(glx.dpy, bitmapNoData); + } else { + XUndefineCursor(glx.dpy, glx.win); + XSync(glx.dpy, False); + } + +} + +static void gfx_glx_set_fullscreen_state(bool on, bool call_callback) { + if (glx.is_fullscreen == on) { + return; + } + glx.is_fullscreen = on; + + XEvent xev; + xev.xany.type = ClientMessage; + xev.xclient.message_type = glx.atom_wm_state; + xev.xclient.format = 32; + xev.xclient.window = glx.win; + xev.xclient.data.l[0] = on; + xev.xclient.data.l[1] = glx.atom_wm_state_fullscreen; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + XSendEvent(glx.dpy, glx.root, 0, SubstructureNotifyMask | SubstructureRedirectMask, &xev); + gfx_glx_ShowHideMouse(on); + + if (glx.on_fullscreen_changed != NULL && call_callback) { + glx.on_fullscreen_changed(on); + } +} + +static bool gfx_glx_check_extension(const char *extensions, const char *extension) { + size_t len = strlen(extension); + const char *pos = extensions; + while ((pos = strstr(pos, extension)) != NULL) { + if ((pos[len] == ' ' || pos[len] == '\0') && (pos == extensions || pos[-1] == ' ')) { + return true; + } + if (pos[len] == '\0') { + break; + } + pos += len + 1; + } + return false; +} + +static void gfx_glx_init(const char *game_name, bool start_in_fullscreen) { + // On NVIDIA proprietary driver, make the driver queue up to two frames on glXSwapBuffers, + // which means that glXSwapBuffers should be non-blocking, + // if we are sure to wait at least one vsync interval between calls. + setenv("__GL_MaxFramesAllowed", "2", true); + + glx.dpy = XOpenDisplay(NULL); + if (glx.dpy == NULL) { + fprintf(stderr, "Cannot connect to X server\n"); + exit(1); + } + int screen = DefaultScreen(glx.dpy); + glx.root = RootWindow(glx.dpy, screen); + + GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; + XVisualInfo *vi = glXChooseVisual(glx.dpy, 0, att); + if (vi == NULL) { + fprintf(stderr, "No appropriate GLX visual found\n"); + exit(1); + } + Colormap cmap = XCreateColormap(glx.dpy, glx.root, vi->visual, AllocNone); + XSetWindowAttributes swa; + swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | FocusChangeMask; + glx.win = XCreateWindow(glx.dpy, glx.root, 0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); + + glx.atom_wm_state = XInternAtom(glx.dpy, "_NET_WM_STATE", False); + glx.atom_wm_state_fullscreen = XInternAtom(glx.dpy, "_NET_WM_STATE_FULLSCREEN", False); + glx.atom_wm_delete_window = XInternAtom(glx.dpy, "WM_DELETE_WINDOW", False); + XSetWMProtocols(glx.dpy, glx.win, &glx.atom_wm_delete_window, 1); + XMapWindow(glx.dpy, glx.win); + + if (start_in_fullscreen) { + gfx_glx_set_fullscreen_state(true, false); + } + + char title[512]; + int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME); + + XStoreName(glx.dpy, glx.win, title); + GLXContext glc = glXCreateContext(glx.dpy, vi, NULL, GL_TRUE); + glXMakeCurrent(glx.dpy, glx.win, glc); + + init_keymap(); + + const char *extensions = glXQueryExtensionsString(glx.dpy, screen); + + if (gfx_glx_check_extension(extensions, "GLX_OML_sync_control")) { + glx.glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glXGetProcAddressARB((const GLubyte *)"glXGetSyncValuesOML"); + glx.glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapBuffersMscOML"); + glx.glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glXGetProcAddressARB((const GLubyte *)"glXWaitForSbcOML"); + } + if (gfx_glx_check_extension(extensions, "GLX_EXT_swap_control")) { + glx.glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT"); + } + if (gfx_glx_check_extension(extensions, "GLX_SGI_swap_control")) { + glx.glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); + } + if (gfx_glx_check_extension(extensions, "GLX_SGI_video_sync")) { + glx.glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVideoSyncSGI"); + glx.glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXWaitVideoSyncSGI"); + } + + int64_t ust, msc, sbc; + if (glx.glXGetSyncValuesOML != NULL && glx.glXGetSyncValuesOML(glx.dpy, glx.win, &ust, &msc, &sbc)) { + glx.has_oml_sync_control = true; + glx.ust0 = (uint64_t)ust; + } else { + glx.ust0 = get_time(); + if (glx.glXSwapIntervalEXT != NULL) { + glx.glXSwapIntervalEXT(glx.dpy, glx.win, 1); + } else if (glx.glXSwapIntervalSGI != NULL) { + glx.glXSwapIntervalSGI(1); + } + if (glx.glXGetVideoSyncSGI != NULL) { + // Try if it really works + unsigned int count; + if (glx.glXGetVideoSyncSGI(&count) == 0) { + glx.last_sync_counter = count; + glx.has_sgi_video_sync = true; + } + } + } + glx.vsync_interval = 16666; +} + +static void gfx_glx_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) { + glx.on_fullscreen_changed = on_fullscreen_changed; +} + +static void gfx_glx_set_fullscreen(bool enable) { + gfx_glx_set_fullscreen_state(enable, true); +} + +static void gfx_glx_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) { + glx.on_key_down = on_key_down; + glx.on_key_up = on_key_up; + glx.on_all_keys_up = on_all_keys_up; +} + +static void gfx_glx_main_loop(void (*run_one_game_iter)(void)) { + while (1) { + run_one_game_iter(); + } +} + +static void gfx_glx_get_dimensions(uint32_t *width, uint32_t *height) { + XWindowAttributes attributes; + XGetWindowAttributes(glx.dpy, glx.win, &attributes); + *width = attributes.width; + *height = attributes.height; +} + +static void gfx_glx_handle_events(void) { + while (XPending(glx.dpy)) { + XEvent xev; + XNextEvent(glx.dpy, &xev); + if (xev.type == FocusOut) { + if (glx.on_all_keys_up != NULL) { + glx.on_all_keys_up(); + } + } + if (xev.type == KeyPress || xev.type == KeyRelease) { + if (xev.xkey.keycode < 256) { + int scancode = glx.keymap[xev.xkey.keycode]; + if (scancode != 0) { + if (xev.type == KeyPress) { + if (scancode == 0x44) { // F10 + gfx_glx_set_fullscreen_state(!glx.is_fullscreen, true); + } + if (glx.on_key_down != NULL) { + glx.on_key_down(scancode); + } + } else { + if (glx.on_key_up != NULL) { + glx.on_key_up(scancode); + } + } + } + } + } + if (xev.type == ClientMessage && xev.xclient.data.l[0] == glx.atom_wm_delete_window) { + exit(0); + } + } +} + +static bool gfx_glx_start_frame(void) { + return true; +} + +static void gfx_glx_swap_buffers_begin(void) { + glx.wanted_ust += FRAME_INTERVAL_US_NUMERATOR; // advance 1/30 seconds on JP/US or 1/25 seconds on EU + + if (!glx.has_oml_sync_control && !glx.has_sgi_video_sync) { + glFlush(); + + uint64_t target = glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR; + uint64_t now; + while (target > (now = (uint64_t)get_time() - glx.ust0)) { + struct timespec ts = {(target - now) / 1000000, ((target - now) % 1000000) * 1000}; + if (nanosleep(&ts, NULL) == 0) { + break; + } + } + + if (target + 2 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR < now) { + if (target + 32 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR >= now) { + printf("Dropping frame\n"); + glx.dropped_frame = true; + return; + } else { + // Reset timer since we are way out of sync + glx.wanted_ust = now * FRAME_INTERVAL_US_DENOMINATOR; + } + } + glXSwapBuffers(glx.dpy, glx.win); + glx.dropped_frame = false; + + return; + } + + double vsyncs_to_wait = (int64_t)(glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR - glx.last_ust) / (double)glx.vsync_interval; + if (vsyncs_to_wait <= 0) { + printf("Dropping frame\n"); + // Drop frame + glx.dropped_frame = true; + return; + } + if (floor(vsyncs_to_wait) != vsyncs_to_wait) { + uint64_t left_ust = glx.last_ust + floor(vsyncs_to_wait) * glx.vsync_interval; + uint64_t right_ust = glx.last_ust + ceil(vsyncs_to_wait) * glx.vsync_interval; + uint64_t adjusted_wanted_ust = glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR + (glx.last_ust + FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR > glx.wanted_ust / FRAME_INTERVAL_US_DENOMINATOR ? 2000 : -2000); + int64_t diff_left = adjusted_wanted_ust - left_ust; + int64_t diff_right = right_ust - adjusted_wanted_ust; + if (diff_left < 0) { + diff_left = -diff_left; + } + if (diff_right < 0) { + diff_right = -diff_right; + } + if (diff_left < diff_right) { + vsyncs_to_wait = floor(vsyncs_to_wait); + } else { + vsyncs_to_wait = ceil(vsyncs_to_wait); + } + if (vsyncs_to_wait <= -4) { + printf("vsyncs_to_wait became -4 or less so dropping frame\n"); + glx.dropped_frame = true; + return; + } else if (vsyncs_to_wait < 1) { + vsyncs_to_wait = 1; + } + } + glx.dropped_frame = false; + //printf("Vsyncs to wait: %d, diff: %d\n", (int)vsyncs_to_wait, (int)(glx.last_ust + (int64_t)vsyncs_to_wait * glx.vsync_interval - glx.wanted_ust / 3)); + if (vsyncs_to_wait > 30) { + // Unreasonable, so change to 2 + vsyncs_to_wait = 2; + } + glx.target_msc = glx.last_msc + vsyncs_to_wait; + + if (glx.has_oml_sync_control) { + glx.glXSwapBuffersMscOML(glx.dpy, glx.win, glx.target_msc, 0, 0); + } else if (glx.has_sgi_video_sync) { + glFlush(); // Try to submit pending work. Don't use glFinish since that busy loops on NVIDIA proprietary driver. + + //uint64_t counter0; + uint64_t counter1, counter2; + + //uint64_t before_wait = get_time(); + + counter1 = glXGetVideoSyncSGI_wrapper(); + //counter0 = counter1; + //int waits = 0; + while (counter1 < (uint64_t)glx.target_msc - 1) { + counter1 = glXWaitVideoSyncSGI_wrapper(); + //++waits; + } + + //uint64_t before = get_time(); + glXSwapBuffers(glx.dpy, glx.win); + + + counter2 = glXGetVideoSyncSGI_wrapper(); + while (counter2 < (uint64_t)glx.target_msc) { + counter2 = glXWaitVideoSyncSGI_wrapper(); + } + uint64_t after = get_time(); + + //printf("%.3f %.3f %.3f\t%.3f\t%u %d %.2f %u %d\n", before_wait * 0.000060, before * 0.000060, after * 0.000060, (after - before) * 0.000060, counter0, counter2 - counter0, vsyncs_to_wait, (unsigned int)glx.target_msc, waits); + glx.this_msc = counter2; + glx.this_ust = after; + } +} + +static void gfx_glx_swap_buffers_end(void) { + if (glx.dropped_frame || (!glx.has_oml_sync_control && !glx.has_sgi_video_sync)) { + return; + } + + int64_t ust, msc, sbc; + if (glx.has_oml_sync_control) { + if (!glx.glXWaitForSbcOML(glx.dpy, glx.win, 0, &ust, &msc, &sbc)) { + // X connection broke or something? + glx.last_ust += (glx.target_msc - glx.last_msc) * glx.vsync_interval; + glx.last_msc = glx.target_msc; + return; + } + } else { + ust = glx.this_ust; + msc = glx.this_msc; + } + uint64_t this_ust = ust - glx.ust0; + uint64_t vsyncs_passed = msc - glx.last_msc; + bool bad_vsync_interval = false; + if (glx.last_ust != 0 && vsyncs_passed != 0) { + uint64_t new_vsync_interval = (this_ust - glx.last_ust) / vsyncs_passed; + if (new_vsync_interval <= 500000) { + // Should be less than 0.5 seconds to be trusted + glx.vsync_interval = new_vsync_interval; + } else { + bad_vsync_interval = true; + } + //printf("glx.vsync_interval: %d\n", (int)glx.vsync_interval); + } + glx.last_ust = this_ust; + glx.last_msc = msc; + if (msc != glx.target_msc) { + printf("Frame too late by %d vsyncs\n", (int)(msc - glx.target_msc)); + } + if (msc - glx.target_msc >= 8 || bad_vsync_interval) { + // Frame arrived way too late, so reset timer from here + printf("Reseting timer\n"); + glx.wanted_ust = this_ust * FRAME_INTERVAL_US_DENOMINATOR; + } +} + +static double gfx_glx_get_time(void) { + return 0.0; +} + +struct GfxWindowManagerAPI gfx_glx = { + gfx_glx_init, + gfx_glx_set_keyboard_callbacks, + gfx_glx_set_fullscreen_changed_callback, + gfx_glx_set_fullscreen, + gfx_glx_show_cursor, + gfx_glx_main_loop, + gfx_glx_get_dimensions, + gfx_glx_handle_events, + gfx_glx_start_frame, + gfx_glx_swap_buffers_begin, + gfx_glx_swap_buffers_end, + gfx_glx_get_time +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_glx.h b/libultraship/libultraship/Lib/Fast3D/gfx_glx.h new file mode 100644 index 000000000..fe78db948 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_glx.h @@ -0,0 +1,8 @@ +#ifndef GFX_GLX_H +#define GFX_GLX_H + +#include "gfx_window_manager_api.h" + +struct GfxWindowManagerAPI gfx_glx; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp new file mode 100644 index 000000000..52815bc1c --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp @@ -0,0 +1,739 @@ +#include "../../Window.h" +#ifdef ENABLE_OPENGL + +#include +#include +#include + +#include + +#ifndef _LANGUAGE_C +#define _LANGUAGE_C +#endif +#include "PR/ultra64/gbi.h" + +#ifdef __MINGW32__ +#define FOR_WINDOWS 1 +#else +#define FOR_WINDOWS 0 +#endif + +#ifdef _MSC_VER +#include +//#define GL_GLEXT_PROTOTYPES 1 +#include +#elif FOR_WINDOWS +#include +#include "SDL.h" +#define GL_GLEXT_PROTOTYPES 1 +#include "SDL_opengl.h" +#else +#include +#define GL_GLEXT_PROTOTYPES 1 +#include +#endif + +#include "gfx_cc.h" +#include "gfx_rendering_api.h" +#include "../../SohImGuiImpl.h" +#include "../../Environment.h" +#include "../../GlobalCtx2.h" +#include "gfx_pc.h" + +using namespace std; + +struct ShaderProgram { + GLuint opengl_program_id; + uint8_t num_inputs; + bool used_textures[2]; + uint8_t num_floats; + GLint attrib_locations[16]; + uint8_t attrib_sizes[16]; + uint8_t num_attribs; + bool used_noise; + GLint frame_count_location; + GLint window_height_location; +}; + +static map, struct ShaderProgram> shader_program_pool; +static GLuint opengl_vbo; + +static uint32_t frame_count; +static uint32_t current_height; +static map> fb2tex; +static bool current_depth_mask; + +static bool gfx_opengl_z_is_from_0_to_1(void) { + return false; +} + +static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) { + size_t num_floats = prg->num_floats; + size_t pos = 0; + + for (int i = 0; i < prg->num_attribs; i++) { + glEnableVertexAttribArray(prg->attrib_locations[i]); + glVertexAttribPointer(prg->attrib_locations[i], prg->attrib_sizes[i], GL_FLOAT, GL_FALSE, num_floats * sizeof(float), (void *) (pos * sizeof(float))); + pos += prg->attrib_sizes[i]; + } +} + +static void gfx_opengl_set_uniforms(struct ShaderProgram *prg) { + if (prg->used_noise) { + glUniform1i(prg->frame_count_location, frame_count); + glUniform1i(prg->window_height_location, current_height); + } +} + +static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) { + if (old_prg != NULL) { + for (int i = 0; i < old_prg->num_attribs; i++) { + glDisableVertexAttribArray(old_prg->attrib_locations[i]); + } + } +} + +static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) { + // if (!new_prg) return; + glUseProgram(new_prg->opengl_program_id); + gfx_opengl_vertex_array_set_attribs(new_prg); + gfx_opengl_set_uniforms(new_prg); +} + +static void append_str(char *buf, size_t *len, const char *str) { + while (*str != '\0') buf[(*len)++] = *str++; +} + +static void append_line(char *buf, size_t *len, const char *str) { + while (*str != '\0') buf[(*len)++] = *str++; + buf[(*len)++] = '\n'; +} + +static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) { + if (!only_alpha) { + switch (item) { + case SHADER_0: + return with_alpha ? "vec4(0.0, 0.0, 0.0, 0.0)" : "vec3(0.0, 0.0, 0.0)"; + case SHADER_1: + return with_alpha ? "vec4(1.0, 1.0, 1.0, 1.0)" : "vec3(1.0, 1.0, 1.0)"; + case SHADER_INPUT_1: + return with_alpha || !inputs_have_alpha ? "vInput1" : "vInput1.rgb"; + case SHADER_INPUT_2: + return with_alpha || !inputs_have_alpha ? "vInput2" : "vInput2.rgb"; + case SHADER_INPUT_3: + return with_alpha || !inputs_have_alpha ? "vInput3" : "vInput3.rgb"; + case SHADER_INPUT_4: + return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput4.rgb"; + case SHADER_TEXEL0: + return with_alpha ? "texVal0" : "texVal0.rgb"; + case SHADER_TEXEL0A: + return hint_single_element ? "texVal0.a" : + (with_alpha ? "vec4(texVal0.a, texVal0.a, texVal0.a, texVal0.a)" : "vec3(texVal0.a, texVal0.a, texVal0.a)"); + case SHADER_TEXEL1A: + return hint_single_element ? "texVal1.a" : + (with_alpha ? "vec4(texVal1.a, texVal1.a, texVal1.a, texVal1.a)" : "vec3(texVal1.a, texVal1.a, texVal1.a)"); + case SHADER_TEXEL1: + return with_alpha ? "texVal1" : "texVal1.rgb"; + case SHADER_COMBINED: + return with_alpha ? "texel" : "texel.rgb"; + } + } else { + switch (item) { + case SHADER_0: + return "0.0"; + case SHADER_1: + return "1.0"; + case SHADER_INPUT_1: + return "vInput1.a"; + case SHADER_INPUT_2: + return "vInput2.a"; + case SHADER_INPUT_3: + return "vInput3.a"; + case SHADER_INPUT_4: + return "vInput4.a"; + case SHADER_TEXEL0: + return "texVal0.a"; + case SHADER_TEXEL0A: + return "texVal0.a"; + case SHADER_TEXEL1A: + return "texVal1.a"; + case SHADER_TEXEL1: + return "texVal1.a"; + case SHADER_COMBINED: + return "texel.a"; + } + } +} + +static void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) { + if (do_single) { + append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false)); + } else if (do_multiply) { + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, " * "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + } else if (do_mix) { + append_str(buf, len, "mix("); + append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ", "); + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ", "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + append_str(buf, len, ")"); + } else { + append_str(buf, len, "("); + append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, " - "); + append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false)); + append_str(buf, len, ") * "); + append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true)); + append_str(buf, len, " + "); + append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false)); + } +} + +static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shader_id0, uint32_t shader_id1) { + struct CCFeatures cc_features; + gfx_cc_get_features(shader_id0, shader_id1, &cc_features); + + char vs_buf[1024]; + char fs_buf[1024]; + size_t vs_len = 0; + size_t fs_len = 0; + size_t num_floats = 4; + + // Vertex shader + append_line(vs_buf, &vs_len, "#version 110"); + append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + vs_len += sprintf(vs_buf + vs_len, "attribute vec2 aTexCoord%d;\n", i); + vs_len += sprintf(vs_buf + vs_len, "varying vec2 vTexCoord%d;\n", i); + num_floats += 2; + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + vs_len += sprintf(vs_buf + vs_len, "attribute float aTexClamp%s%d;\n", j == 0 ? "S" : "T", i); + vs_len += sprintf(vs_buf + vs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); + num_floats += 1; + } + } + } + } + if (cc_features.opt_fog) { + append_line(vs_buf, &vs_len, "attribute vec4 aFog;"); + append_line(vs_buf, &vs_len, "varying vec4 vFog;"); + num_floats += 4; + } + for (int i = 0; i < cc_features.num_inputs; i++) { + vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); + vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); + num_floats += cc_features.opt_alpha ? 4 : 3; + } + append_line(vs_buf, &vs_len, "void main() {"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + vs_len += sprintf(vs_buf + vs_len, "vTexCoord%d = aTexCoord%d;\n", i, i); + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + vs_len += sprintf(vs_buf + vs_len, "vTexClamp%s%d = aTexClamp%s%d;\n", j == 0 ? "S" : "T", i, j == 0 ? "S" : "T", i); + } + } + } + } + if (cc_features.opt_fog) { + append_line(vs_buf, &vs_len, "vFog = aFog;"); + } + for (int i = 0; i < cc_features.num_inputs; i++) { + vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1); + } + append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;"); + append_line(vs_buf, &vs_len, "}"); + + // Fragment shader + append_line(fs_buf, &fs_len, "#version 130"); + //append_line(fs_buf, &fs_len, "precision mediump float;"); + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + fs_len += sprintf(fs_buf + fs_len, "varying vec2 vTexCoord%d;\n", i); + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + fs_len += sprintf(fs_buf + fs_len, "varying float vTexClamp%s%d;\n", j == 0 ? "S" : "T", i); + } + } + } + } + if (cc_features.opt_fog) { + append_line(fs_buf, &fs_len, "varying vec4 vFog;"); + } + for (int i = 0; i < cc_features.num_inputs; i++) { + fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", cc_features.opt_alpha ? 4 : 3, i + 1); + } + if (cc_features.used_textures[0]) { + append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); + } + if (cc_features.used_textures[1]) { + append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;"); + } + + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(fs_buf, &fs_len, "uniform int frame_count;"); + append_line(fs_buf, &fs_len, "uniform int window_height;"); + + append_line(fs_buf, &fs_len, "float random(in vec3 value) {"); + append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));"); + append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);"); + append_line(fs_buf, &fs_len, "}"); + } + + append_line(fs_buf, &fs_len, "void main() {"); + + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; + if (!s && !t) { + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vTexCoord%d);\n", i, i, i); + } else { + fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i); + if (s && t) { + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)));\n", i, i, i, i, i, i); + } else if (s) { + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t));\n", i, i, i, i, i, i); + } else { + fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)));\n", i, i, i, i, i, i); + } + } + } + } + + append_line(fs_buf, &fs_len, cc_features.opt_alpha ? "vec4 texel;" : "vec3 texel;"); + for (int c = 0; c < (cc_features.opt_2cyc ? 2 : 1); c++) { + append_str(fs_buf, &fs_len, "texel = "); + if (!cc_features.color_alpha_same[c] && cc_features.opt_alpha) { + append_str(fs_buf, &fs_len, "vec4("); + append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], false, false, true); + append_str(fs_buf, &fs_len, ", "); + append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][1], cc_features.do_multiply[c][1], cc_features.do_mix[c][1], true, true, true); + append_str(fs_buf, &fs_len, ")"); + } + else { + append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], cc_features.opt_alpha, false, cc_features.opt_alpha); + } + append_line(fs_buf, &fs_len, ";"); + } + // TODO discard if alpha is 0? + if (cc_features.opt_fog) + { + if (cc_features.opt_alpha) + { + append_line(fs_buf, &fs_len, "texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);"); + } + else + { + append_line(fs_buf, &fs_len, "texel = mix(texel, vFog.rgb, vFog.a);"); + } + } + + if (cc_features.opt_texture_edge && cc_features.opt_alpha) { + append_line(fs_buf, &fs_len, "if (texel.a > 0.19) texel.a = 1.0; else discard;"); + } + + if (cc_features.opt_alpha && cc_features.opt_noise) { + append_line(fs_buf, &fs_len, "texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * (240.0 / float(window_height))), float(frame_count))) + texel.a, 0.0, 1.0));"); + } + + if (cc_features.opt_alpha) { + if (cc_features.opt_alpha_threshold) { + append_line(fs_buf, &fs_len, "if (texel.a < 8.0 / 256.0) discard;"); + } + if (cc_features.opt_invisible) { + append_line(fs_buf, &fs_len, "texel.a = 0.0;"); + } + append_line(fs_buf, &fs_len, "gl_FragColor = texel;"); + } else { + append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);"); + } + append_line(fs_buf, &fs_len, "}"); + + vs_buf[vs_len] = '\0'; + fs_buf[fs_len] = '\0'; + + /*puts("Vertex shader:"); + puts(vs_buf); + puts("Fragment shader:"); + puts(fs_buf); + puts("End");*/ + + const GLchar *sources[2] = { vs_buf, fs_buf }; + const GLint lengths[2] = { (GLint) vs_len, (GLint) fs_len }; + GLint success; + + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &sources[0], &lengths[0]); + glCompileShader(vertex_shader); + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); + if (!success) { + GLint max_length = 0; + glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &max_length); + char error_log[1024]; + //fprintf(stderr, "Vertex shader compilation failed\n"); + glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]); + //fprintf(stderr, "%s\n", &error_log[0]); + abort(); + } + + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &sources[1], &lengths[1]); + glCompileShader(fragment_shader); + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); + if (!success) { + GLint max_length = 0; + glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length); + char error_log[1024]; + //fprintf(stderr, "Fragment shader compilation failed\n"); + glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]); + //fprintf(stderr, "%s\n", &error_log[0]); + abort(); + } + + GLuint shader_program = glCreateProgram(); + glAttachShader(shader_program, vertex_shader); + glAttachShader(shader_program, fragment_shader); + glLinkProgram(shader_program); + + size_t cnt = 0; + + struct ShaderProgram* prg = &shader_program_pool[make_pair(shader_id0, shader_id1)]; + prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aVtxPos"); + prg->attrib_sizes[cnt] = 4; + ++cnt; + + for (int i = 0; i < 2; i++) { + if (cc_features.used_textures[i]) { + char name[32]; + sprintf(name, "aTexCoord%d", i); + prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name); + prg->attrib_sizes[cnt] = 2; + ++cnt; + + for (int j = 0; j < 2; j++) { + if (cc_features.clamp[i][j]) { + sprintf(name, "aTexClamp%s%d", j == 0 ? "S" : "T", i); + prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name); + prg->attrib_sizes[cnt] = 1; + ++cnt; + } + } + } + } + + if (cc_features.opt_fog) { + prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aFog"); + prg->attrib_sizes[cnt] = 4; + ++cnt; + } + + for (int i = 0; i < cc_features.num_inputs; i++) { + char name[16]; + sprintf(name, "aInput%d", i + 1); + prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name); + prg->attrib_sizes[cnt] = cc_features.opt_alpha ? 4 : 3; + ++cnt; + } + + prg->opengl_program_id = shader_program; + prg->num_inputs = cc_features.num_inputs; + prg->used_textures[0] = cc_features.used_textures[0]; + prg->used_textures[1] = cc_features.used_textures[1]; + prg->num_floats = num_floats; + prg->num_attribs = cnt; + + gfx_opengl_load_shader(prg); + + if (cc_features.used_textures[0]) { + GLint sampler_location = glGetUniformLocation(shader_program, "uTex0"); + glUniform1i(sampler_location, 0); + } + if (cc_features.used_textures[1]) { + GLint sampler_location = glGetUniformLocation(shader_program, "uTex1"); + glUniform1i(sampler_location, 1); + } + + if (cc_features.opt_alpha && cc_features.opt_noise) { + prg->frame_count_location = glGetUniformLocation(shader_program, "frame_count"); + prg->window_height_location = glGetUniformLocation(shader_program, "window_height"); + prg->used_noise = true; + } else { + prg->used_noise = false; + } + + return prg; +} + +static struct ShaderProgram *gfx_opengl_lookup_shader(uint64_t shader_id0, uint32_t shader_id1) { + auto it = shader_program_pool.find(make_pair(shader_id0, shader_id1)); + return it == shader_program_pool.end() ? nullptr : &it->second; +} + +static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) { + *num_inputs = prg->num_inputs; + used_textures[0] = prg->used_textures[0]; + used_textures[1] = prg->used_textures[1]; +} + +static GLuint gfx_opengl_new_texture(void) { + GLuint ret; + glGenTextures(1, &ret); + return ret; +} + +static void gfx_opengl_delete_texture(uint32_t texID) { + glDeleteTextures(1, &texID); +} + +static void gfx_opengl_select_texture(int tile, GLuint texture_id) { + glActiveTexture(GL_TEXTURE0 + tile); + glBindTexture(GL_TEXTURE_2D, texture_id); +} + +static void gfx_opengl_upload_texture(const uint8_t *rgba32_buf, uint32_t width, uint32_t height) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf); +} + +static uint32_t gfx_cm_to_opengl(uint32_t val) { + switch (val) { + case G_TX_NOMIRROR | G_TX_CLAMP: + return GL_CLAMP_TO_EDGE; + case G_TX_MIRROR | G_TX_WRAP: + return GL_MIRRORED_REPEAT; + case G_TX_MIRROR | G_TX_CLAMP: + return GL_MIRROR_CLAMP_TO_EDGE; + case G_TX_NOMIRROR | G_TX_WRAP: + return GL_REPEAT; + } +} + +static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) { + glActiveTexture(GL_TEXTURE0 + tile); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt)); +} + +static void gfx_opengl_set_depth_test_and_mask(bool depth_test, bool z_upd) { + if (depth_test || z_upd) { + glEnable(GL_DEPTH_TEST); + glDepthMask(z_upd ? GL_TRUE : GL_FALSE); + glDepthFunc(depth_test ? GL_LEQUAL : GL_ALWAYS); + current_depth_mask = z_upd; + } else { + glDisable(GL_DEPTH_TEST); + } +} + +static void gfx_opengl_set_zmode_decal(bool zmode_decal) { + if (zmode_decal) { + glPolygonOffset(-2, -2); + glEnable(GL_POLYGON_OFFSET_FILL); + } else { + glPolygonOffset(0, 0); + glDisable(GL_POLYGON_OFFSET_FILL); + } +} + +static void gfx_opengl_set_viewport(int x, int y, int width, int height) { + glViewport(x, y, width, height); + current_height = height; +} + +static void gfx_opengl_set_scissor(int x, int y, int width, int height) { + glScissor(x, y, width, height); +} + +static void gfx_opengl_set_use_alpha(bool use_alpha) { + if (use_alpha) { + glEnable(GL_BLEND); + } else { + glDisable(GL_BLEND); + } +} + +static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { + //printf("flushing %d tris\n", buf_vbo_num_tris); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW); + glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris); +} + +static unsigned int framebuffer; +static unsigned int textureColorbuffer; +static unsigned int rbo; + +static void gfx_opengl_init(void) { +//#if FOR_WINDOWS + glewInit(); +//#endif + + glGenBuffers(1, &opengl_vbo); + glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo); + + glGenFramebuffers(1, &framebuffer); + glGenTextures(1, &textureColorbuffer); + glGenRenderbuffers(1, &rbo); + + SohUtils::saveEnvironmentVar("framebuffer", std::to_string(textureColorbuffer)); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +static void gfx_opengl_on_resize(void) { +} + +static void gfx_opengl_start_frame(void) { + GLsizei framebuffer_width = gfx_current_dimensions.width; + GLsizei framebuffer_height = gfx_current_dimensions.height; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + std::shared_ptr wnd = Ship::GlobalCtx2::GetInstance()->GetWindow(); + glBindTexture(GL_TEXTURE_2D, textureColorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, framebuffer_width, framebuffer_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, framebuffer_width, framebuffer_height); // use a single renderbuffer object for both a depth AND stencil buffer. + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + frame_count++; + + glDisable(GL_SCISSOR_TEST); + glDepthMask(GL_TRUE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + glEnable(GL_DEPTH_CLAMP); + current_depth_mask = true; +} + +static void gfx_opengl_end_frame(void) { + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + GLint last_program; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glUseProgram(0); + SohImGui::Draw(); + glUseProgram(last_program); +} + +static void gfx_opengl_finish_render(void) { +} + +static int gfx_opengl_create_framebuffer(uint32_t width, uint32_t height) { + GLuint textureColorbuffer; + + glGenTextures(1, &textureColorbuffer); + glBindTexture(GL_TEXTURE_2D, textureColorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + GLuint rbo; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + fb2tex[fbo] = make_pair(textureColorbuffer, rbo); + + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + + return fbo; +} + +static void gfx_opengl_resize_framebuffer(int fb, uint32_t width, uint32_t height) { + glBindTexture(GL_TEXTURE_2D, fb2tex[fb].first); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindRenderbuffer(GL_RENDERBUFFER, fb2tex[fb].second); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); +} + +void gfx_opengl_set_framebuffer(int fb) +{ + glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE); // Set origin to upper left corner, to match N64 and DX11 + glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb); + + glDepthMask(GL_TRUE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthMask(current_depth_mask ? GL_TRUE : GL_FALSE); +} + +void gfx_opengl_reset_framebuffer(void) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glBindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); + glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE); +} + +void gfx_opengl_select_texture_fb(int fbID) +{ + //glDisable(GL_DEPTH_TEST); + glActiveTexture(GL_TEXTURE0 + 0); + glBindTexture(GL_TEXTURE_2D, fb2tex[fbID].first); +} + +static uint16_t gfx_opengl_get_pixel_depth(float x, float y) { + float depth; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return depth * 65532.0f; +} + +struct GfxRenderingAPI gfx_opengl_api = { + gfx_opengl_z_is_from_0_to_1, + gfx_opengl_unload_shader, + gfx_opengl_load_shader, + gfx_opengl_create_and_load_new_shader, + gfx_opengl_lookup_shader, + gfx_opengl_shader_get_info, + gfx_opengl_new_texture, + gfx_opengl_select_texture, + gfx_opengl_upload_texture, + gfx_opengl_set_sampler_parameters, + gfx_opengl_set_depth_test_and_mask, + gfx_opengl_get_pixel_depth, + gfx_opengl_set_zmode_decal, + gfx_opengl_set_viewport, + gfx_opengl_set_scissor, + gfx_opengl_set_use_alpha, + gfx_opengl_draw_triangles, + gfx_opengl_init, + gfx_opengl_on_resize, + gfx_opengl_start_frame, + gfx_opengl_end_frame, + gfx_opengl_finish_render, + gfx_opengl_create_framebuffer, + gfx_opengl_resize_framebuffer, + gfx_opengl_set_framebuffer, + gfx_opengl_reset_framebuffer, + gfx_opengl_select_texture_fb, + gfx_opengl_delete_texture +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.h b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.h new file mode 100644 index 000000000..95be897a2 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.h @@ -0,0 +1,8 @@ +#ifndef GFX_OPENGL_H +#define GFX_OPENGL_H + +#include "gfx_rendering_api.h" + +extern struct GfxRenderingAPI gfx_opengl_api; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp new file mode 100644 index 000000000..3f7bd7f9b --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp @@ -0,0 +1,2731 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef _LANGUAGE_C +#define _LANGUAGE_C +#endif +#include +#include +#include +#include + +#include "gfx_pc.h" +#include "gfx_cc.h" +#include "gfx_window_manager_api.h" +#include "gfx_rendering_api.h" +#include "gfx_screen_config.h" +#include "../../SohHooks.h" + +#include "../../luslog.h" +#include "../StrHash64.h" + +// OTRTODO: fix header files for these +extern "C" { + char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc); + int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc); + Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); + Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); + char* ResourceMgr_LoadTexByCRC(uint64_t crc); + void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData); + char* ResourceMgr_LoadTexByName(char* texPath); + int ResourceMgr_OTRSigCheck(char* imgData); +} + +using namespace std; + +#define SUPPORT_CHECK(x) assert(x) + +// SCALE_M_N: upscale/downscale M-bit integer to N-bit +#define SCALE_5_8(VAL_) (((VAL_) * 0xFF) / 0x1F) +#define SCALE_8_5(VAL_) ((((VAL_) + 4) * 0x1F) / 0xFF) +#define SCALE_4_8(VAL_) ((VAL_) * 0x11) +#define SCALE_8_4(VAL_) ((VAL_) / 0x11) +#define SCALE_3_8(VAL_) ((VAL_) * 0x24) +#define SCALE_8_3(VAL_) ((VAL_) / 0x24) + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define HALF_SCREEN_WIDTH (SCREEN_WIDTH / 2) +#define HALF_SCREEN_HEIGHT (SCREEN_HEIGHT / 2) + +#define RATIO_X (gfx_current_dimensions.width / (2.0f * HALF_SCREEN_WIDTH)) +#define RATIO_Y (gfx_current_dimensions.height / (2.0f * HALF_SCREEN_HEIGHT)) + +#define MAX_BUFFERED 256 +//#define MAX_LIGHTS 2 +#define MAX_LIGHTS 32 +#define MAX_VERTICES 64 + +#define TEXTURE_CACHE_MAX_SIZE 500 + +struct RGBA { + uint8_t r, g, b, a; +}; + +struct XYWidthHeight { + uint16_t x, y, width, height; +}; + +struct LoadedVertex { + float x, y, z, w; + float u, v; + struct RGBA color; + uint8_t clip_rej; +}; + +static struct { + TextureCacheMap map; + list lru; + vector free_texture_ids; +} gfx_texture_cache; + +struct ColorCombiner { + uint64_t shader_id0; + uint32_t shader_id1; + bool used_textures[2]; + struct ShaderProgram *prg[16]; + uint8_t shader_input_mapping[2][7]; +}; + +static map color_combiner_pool; +static map::iterator prev_combiner = color_combiner_pool.end(); + +static struct RSP { + float modelview_matrix_stack[11][4][4]; + uint8_t modelview_matrix_stack_size; + + float MP_matrix[4][4]; + float P_matrix[4][4]; + + Light_t lookat[2]; + Light_t current_lights[MAX_LIGHTS + 1]; + float current_lights_coeffs[MAX_LIGHTS][3]; + float current_lookat_coeffs[2][3]; // lookat_x, lookat_y + uint8_t current_num_lights; // includes ambient light + bool lights_changed; + + uint32_t geometry_mode; + int16_t fog_mul, fog_offset; + + struct { + // U0.16 + uint16_t s, t; + } texture_scaling_factor; + + struct LoadedVertex loaded_vertices[MAX_VERTICES + 4]; +} rsp; + +static struct RDP { + const uint8_t *palette; + struct { + const uint8_t *addr; + uint8_t siz; + uint32_t width; + char* otr_path; + } texture_to_load; + struct { + const uint8_t *addr; + uint32_t size_bytes; + uint32_t full_image_line_size_bytes; + uint32_t line_size_bytes; + char* otr_path; + } loaded_texture[2]; + struct { + uint8_t fmt; + uint8_t siz; + uint8_t cms, cmt; + uint8_t shifts, shiftt; + uint16_t uls, ult, lrs, lrt; // U10.2 + uint32_t line_size_bytes; + uint8_t palette; + uint8_t tmem_index; // 0 or 1 for offset 0 kB or offset 2 kB, respectively + } texture_tile[8]; + bool textures_changed[2]; + + uint8_t first_tile_index; + + uint32_t other_mode_l, other_mode_h; + uint64_t combine_mode; + + uint8_t prim_lod_fraction; + struct RGBA env_color, prim_color, fog_color, fill_color; + struct XYWidthHeight viewport, scissor; + bool viewport_or_scissor_changed; + void *z_buf_address; + void *color_image_address; +} rdp; + +static struct RenderingState { + uint8_t depth_test_and_mask; // 1: depth test, 2: depth mask + bool decal_mode; + bool alpha_blend; + struct XYWidthHeight viewport, scissor; + struct ShaderProgram *shader_program; + TextureCacheNode *textures[2]; +} rendering_state; + +struct GfxDimensions gfx_current_dimensions; +static struct GfxDimensions gfx_prev_dimensions; + +static bool dropped_frame; + +static float buf_vbo[MAX_BUFFERED * (32 * 3)]; // 3 vertices in a triangle and 32 floats per vtx +static size_t buf_vbo_len; +static size_t buf_vbo_num_tris; + +static struct GfxWindowManagerAPI *gfx_wapi; +static struct GfxRenderingAPI *gfx_rapi; + +static int markerOn; +static uintptr_t segmentPointers[16]; + +struct FBInfo { + uint32_t orig_width, orig_height; + uint32_t applied_width, applied_height; +}; + +static bool fbActive = 0; +static map::iterator active_fb; +static map framebuffers; + +#ifdef _MSC_VER +// TODO: Properly implement for MSVC +static unsigned long get_time(void) +{ + return 0; +} +#else +#include +#include +static unsigned long get_time(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (unsigned long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; +} +#endif + +static void gfx_flush(void) { + if (buf_vbo_len > 0) { + int num = buf_vbo_num_tris; + unsigned long t0 = get_time(); + + if (markerOn) + { + int bp = 0; + } + + gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris); + buf_vbo_len = 0; + buf_vbo_num_tris = 0; + unsigned long t1 = get_time(); + /*if (t1 - t0 > 1000) { + printf("f: %d %d\n", num, (int)(t1 - t0)); + }*/ + } +} + +static struct ShaderProgram *gfx_lookup_or_create_shader_program(uint64_t shader_id0, uint32_t shader_id1) { + struct ShaderProgram *prg = gfx_rapi->lookup_shader(shader_id0, shader_id1); + if (prg == NULL) { + gfx_rapi->unload_shader(rendering_state.shader_program); + prg = gfx_rapi->create_and_load_new_shader(shader_id0, shader_id1); + rendering_state.shader_program = prg; + } + return prg; +} + +static const char* ccmux_to_string(uint32_t ccmux) { + static const char* const tbl[] = { + "G_CCMUX_COMBINED", + "G_CCMUX_TEXEL0", + "G_CCMUX_TEXEL1", + "G_CCMUX_PRIMITIVE", + "G_CCMUX_SHADE", + "G_CCMUX_ENVIRONMENT", + "G_CCMUX_1", + "G_CCMUX_COMBINED_ALPHA", + "G_CCMUX_TEXEL0_ALPHA", + "G_CCMUX_TEXEL1_ALPHA", + "G_CCMUX_PRIMITIVE_ALPHA", + "G_CCMUX_SHADE_ALPHA", + "G_CCMUX_ENV_ALPHA", + "G_CCMUX_LOD_FRACTION", + "G_CCMUX_PRIM_LOD_FRAC", + "G_CCMUX_K5", + }; + if (ccmux > 15) { + return "G_CCMUX_0"; + + } + else { + return tbl[ccmux]; + + } + +} + +static const char* acmux_to_string(uint32_t acmux) { + static const char* const tbl[] = { + "G_ACMUX_COMBINED or G_ACMUX_LOD_FRACTION", + "G_ACMUX_TEXEL0", + "G_ACMUX_TEXEL1", + "G_ACMUX_PRIMITIVE", + "G_ACMUX_SHADE", + "G_ACMUX_ENVIRONMENT", + "G_ACMUX_1 or G_ACMUX_PRIM_LOD_FRAC", + "G_ACMUX_0", + }; + return tbl[acmux]; + +} + + +static void gfx_generate_cc(struct ColorCombiner *comb, uint64_t cc_id) { + if (markerOn) + { + int bp = 0; + } + + bool is_2cyc = (cc_id & (uint64_t)SHADER_OPT_2CYC << CC_SHADER_OPT_POS) != 0; + + uint8_t c[2][2][4]; + uint64_t shader_id0 = 0; + uint32_t shader_id1 = (cc_id >> CC_SHADER_OPT_POS); + uint8_t shader_input_mapping[2][7] = {{0}}; + bool used_textures[2] = {false, false}; + for (int i = 0; i < 2 && (i == 0 || is_2cyc); i++) { + uint32_t rgb_a = (cc_id >> (i * 28)) & 0xf; + uint32_t rgb_b = (cc_id >> (i * 28 + 4)) & 0xf; + uint32_t rgb_c = (cc_id >> (i * 28 + 8)) & 0x1f; + uint32_t rgb_d = (cc_id >> (i * 28 + 13)) & 7; + uint32_t alpha_a = (cc_id >> (i * 28 + 16)) & 7; + uint32_t alpha_b = (cc_id >> (i * 28 + 16 + 3)) & 7; + uint32_t alpha_c = (cc_id >> (i * 28 + 16 + 6)) & 7; + uint32_t alpha_d = (cc_id >> (i * 28 + 16 + 9)) & 7; + + if (rgb_a >= 8) rgb_a = G_CCMUX_0; + if (rgb_b >= 8) rgb_b = G_CCMUX_0; + if (rgb_c >= 16) rgb_c = G_CCMUX_0; + if (rgb_d == 7) rgb_d = G_CCMUX_0; + + if (rgb_a == rgb_b || rgb_c == G_CCMUX_0) { + // Normalize + rgb_a = G_CCMUX_0; + rgb_b = G_CCMUX_0; + rgb_c = G_CCMUX_0; + } + if (alpha_a == alpha_b || alpha_c == G_ACMUX_0) { + // Normalize + alpha_a = G_ACMUX_0; + alpha_b = G_ACMUX_0; + alpha_c = G_ACMUX_0; + + } + if (i == 1) { + if (rgb_a != G_CCMUX_COMBINED && rgb_b != G_CCMUX_COMBINED && rgb_c != G_CCMUX_COMBINED && rgb_d != G_CCMUX_COMBINED) { + // First cycle RGB not used, so clear it away + c[0][0][0] = c[0][0][1] = c[0][0][2] = c[0][0][3] = G_CCMUX_0; + } + if (rgb_c != G_CCMUX_COMBINED_ALPHA && alpha_a != G_ACMUX_COMBINED && alpha_b != G_ACMUX_COMBINED && alpha_d != G_ACMUX_COMBINED) + { + // First cycle ALPHA not used, so clear it away + c[0][1][0] = c[0][1][1] = c[0][1][2] = c[0][1][3] = G_ACMUX_0; + } + } + + c[i][0][0] = rgb_a; + c[i][0][1] = rgb_b; + c[i][0][2] = rgb_c; + c[i][0][3] = rgb_d; + c[i][1][0] = alpha_a; + c[i][1][1] = alpha_b; + c[i][1][2] = alpha_c; + c[i][1][3] = alpha_d; + } + if (!is_2cyc) { + for (int i = 0; i < 2; i++) { + for (int k = 0; k < 4; k++) { + c[1][i][k] = i == 0 ? G_CCMUX_0 : G_ACMUX_0; + } + } + } + { + uint8_t input_number[32] = { 0 }; + int next_input_number = SHADER_INPUT_1; + for (int i = 0; i < 2 && (i == 0 || is_2cyc); i++) { + for (int j = 0; j < 4; j++) { + uint32_t val = 0; + switch (c[i][0][j]) { + case G_CCMUX_0: + val = SHADER_0; + break; + case G_CCMUX_1: + val = SHADER_1; + break; + case G_CCMUX_TEXEL0: + val = SHADER_TEXEL0; + used_textures[0] = true; + break; + case G_CCMUX_TEXEL1: + val = SHADER_TEXEL1; + used_textures[1] = true; + break; + case G_CCMUX_TEXEL0_ALPHA: + val = SHADER_TEXEL0A; + used_textures[0] = true; + break; + case G_CCMUX_TEXEL1_ALPHA: + val = SHADER_TEXEL1A; + used_textures[1] = true; + break; + case G_CCMUX_PRIMITIVE: + case G_CCMUX_PRIMITIVE_ALPHA: + case G_CCMUX_PRIM_LOD_FRAC: + case G_CCMUX_SHADE: + case G_CCMUX_ENVIRONMENT: + case G_CCMUX_ENV_ALPHA: + case G_CCMUX_LOD_FRACTION: + if (input_number[c[i][0][j]] == 0) { + shader_input_mapping[0][next_input_number - 1] = c[i][0][j]; + input_number[c[i][0][j]] = next_input_number++; + } + val = input_number[c[i][0][j]]; + break; + case G_CCMUX_COMBINED: + val = SHADER_COMBINED; + break; + default: + fprintf(stderr, "Unsupported ccmux: %d\n", c[i][0][j]); + break; + } + shader_id0 |= (uint64_t)val << (i * 32 + j * 4); + } + } + } + { + uint8_t input_number[16] = { 0 }; + int next_input_number = SHADER_INPUT_1; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 4; j++) { + uint32_t val = 0; + switch (c[i][1][j]) { + case G_ACMUX_0: + val = SHADER_0; + break; + case G_ACMUX_TEXEL0: + val = SHADER_TEXEL0; + used_textures[0] = true; + break; + case G_ACMUX_TEXEL1: + val = SHADER_TEXEL1; + used_textures[1] = true; + break; + case G_ACMUX_LOD_FRACTION: + //case G_ACMUX_COMBINED: same numerical value + if (j != 2) { + val = SHADER_COMBINED; + break; + } + // fallthrough for G_ACMUX_LOD_FRACTION + c[i][1][j] = G_CCMUX_LOD_FRACTION; + case G_ACMUX_1: + //case G_ACMUX_PRIM_LOD_FRAC: same numerical value + if (j != 2) { + val = SHADER_1; + break; + } + // fallthrough for G_ACMUX_PRIM_LOD_FRAC + case G_ACMUX_PRIMITIVE: + case G_ACMUX_SHADE: + case G_ACMUX_ENVIRONMENT: + if (input_number[c[i][1][j]] == 0) { + shader_input_mapping[1][next_input_number - 1] = c[i][1][j]; + input_number[c[i][1][j]] = next_input_number++; + } + val = input_number[c[i][1][j]]; + break; + } + shader_id0 |= (uint64_t)val << (i * 32 + 16 + j * 4); + } + } + } + comb->shader_id0 = shader_id0; + comb->shader_id1 = shader_id1; + comb->used_textures[0] = used_textures[0]; + comb->used_textures[1] = used_textures[1]; + //comb->prg = gfx_lookup_or_create_shader_program(shader_id0, shader_id1); + memcpy(comb->shader_input_mapping, shader_input_mapping, sizeof(shader_input_mapping)); +} + +static struct ColorCombiner *gfx_lookup_or_create_color_combiner(uint64_t cc_id) { + if (prev_combiner != color_combiner_pool.end() && prev_combiner->first == cc_id) { + return &prev_combiner->second; + } + + prev_combiner = color_combiner_pool.find(cc_id); + if (prev_combiner != color_combiner_pool.end()) { + return &prev_combiner->second; + } + gfx_flush(); + prev_combiner = color_combiner_pool.insert(make_pair(cc_id, ColorCombiner())).first; + gfx_generate_cc(&prev_combiner->second, cc_id); + return &prev_combiner->second; +} + +void gfx_texture_cache_clear() +{ + for (const auto& entry : gfx_texture_cache.map) { + gfx_texture_cache.free_texture_ids.push_back(entry.second.texture_id); + } + gfx_texture_cache.map.clear(); + gfx_texture_cache.lru.clear(); +} + +static bool gfx_texture_cache_lookup(int i, TextureCacheNode **n, const uint8_t *orig_addr, uint32_t fmt, uint32_t siz, uint32_t palette_index) { + TextureCacheKey key = { orig_addr, fmt, siz, palette_index }; + auto it = gfx_texture_cache.map.find(key); + + if (it != gfx_texture_cache.map.end()) { + gfx_rapi->select_texture(i, it->second.texture_id); + *n = &*it; + gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, *(list::iterator*)&it->second.lru_location); // move to back + return true; + } + + if (gfx_texture_cache.map.size() >= TEXTURE_CACHE_MAX_SIZE) { + // Remove the texture that was least recently used + it = gfx_texture_cache.lru.front(); + gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id); + gfx_texture_cache.map.erase(it); + gfx_texture_cache.lru.pop_front(); + } + + uint32_t texture_id; + if (!gfx_texture_cache.free_texture_ids.empty()) { + texture_id = gfx_texture_cache.free_texture_ids.back(); + gfx_texture_cache.free_texture_ids.pop_back(); + } else { + texture_id = gfx_rapi->new_texture(); + } + + it = gfx_texture_cache.map.insert(make_pair(key, TextureCacheValue())).first; + TextureCacheNode* node = &*it; + node->second.texture_id = texture_id; + *(list::iterator*)&node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), it); + + gfx_rapi->select_texture(i, texture_id); + gfx_rapi->set_sampler_parameters(i, false, 0, 0); + *n = node; + return false; +} + +static void gfx_texture_cache_delete(const uint8_t* orig_addr) +{ + while (gfx_texture_cache.map.bucket_count() > 0) { + TextureCacheKey key = { orig_addr, 0, 0, 0 }; // bucket index only depends on the address + size_t bucket = gfx_texture_cache.map.bucket(key); + bool again = false; + for (auto it = gfx_texture_cache.map.begin(bucket); it != gfx_texture_cache.map.end(bucket); ++it) { + if (it->first.texture_addr == orig_addr) { + gfx_texture_cache.lru.erase(*(list::iterator*)&it->second.lru_location); + gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id); + gfx_texture_cache.map.erase(it); + again = true; + break; + } + } + if (!again) { + break; + } + } +} + +static void import_texture_rgba16(int tile) { + uint8_t rgba32_buf[480 * 240 * 4]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + //SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes / 2; i++) { + uint16_t col16 = (addr[2 * i] << 8) | addr[2 * i + 1]; + uint8_t a = col16 & 1; + uint8_t r = col16 >> 11; + uint8_t g = (col16 >> 6) & 0x1f; + uint8_t b = (col16 >> 1) & 0x1f; + rgba32_buf[4*i + 0] = SCALE_5_8(r); + rgba32_buf[4*i + 1] = SCALE_5_8(g); + rgba32_buf[4*i + 2] = SCALE_5_8(b); + rgba32_buf[4*i + 3] = a ? 255 : 0; + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_rgba32(int tile) { + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2; + uint32_t height = (size_bytes / 2) / rdp.texture_tile[tile].line_size_bytes; + gfx_rapi->upload_texture(addr, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, addr, width, height); +} + +static void import_texture_ia4(int tile) { + uint8_t rgba32_buf[32768]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes * 2; i++) { + uint8_t byte = addr[i / 2]; + uint8_t part = (byte >> (4 - (i % 2) * 4)) & 0xf; + uint8_t intensity = part >> 1; + uint8_t alpha = part & 1; + uint8_t r = intensity; + uint8_t g = intensity; + uint8_t b = intensity; + rgba32_buf[4*i + 0] = SCALE_3_8(r); + rgba32_buf[4*i + 1] = SCALE_3_8(g); + rgba32_buf[4*i + 2] = SCALE_3_8(b); + rgba32_buf[4*i + 3] = alpha ? 255 : 0; + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes * 2; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_ia8(int tile) { + uint8_t rgba32_buf[16384]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes; i++) { + uint8_t intensity = addr[i] >> 4; + uint8_t alpha = addr[i] & 0xf; + uint8_t r = intensity; + uint8_t g = intensity; + uint8_t b = intensity; + rgba32_buf[4*i + 0] = SCALE_4_8(r); + rgba32_buf[4*i + 1] = SCALE_4_8(g); + rgba32_buf[4*i + 2] = SCALE_4_8(b); + rgba32_buf[4*i + 3] = SCALE_4_8(alpha); + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_ia16(int tile) { + uint8_t rgba32_buf[8192]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes / 2; i++) { + uint8_t intensity = addr[2 * i]; + uint8_t alpha = addr[2 * i + 1]; + uint8_t r = intensity; + uint8_t g = intensity; + uint8_t b = intensity; + rgba32_buf[4*i + 0] = r; + rgba32_buf[4*i + 1] = g; + rgba32_buf[4*i + 2] = b; + rgba32_buf[4*i + 3] = alpha; + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes / 2; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_i4(int tile) { + uint8_t rgba32_buf[32768]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + //SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes * 2; i++) { + uint8_t byte = addr[i / 2]; + uint8_t part = (byte >> (4 - (i % 2) * 4)) & 0xf; + uint8_t intensity = part; + uint8_t r = intensity; + uint8_t g = intensity; + uint8_t b = intensity; + uint8_t a = intensity; + rgba32_buf[4*i + 0] = SCALE_4_8(r); + rgba32_buf[4*i + 1] = SCALE_4_8(g); + rgba32_buf[4*i + 2] = SCALE_4_8(b); + rgba32_buf[4 * i + 3] = SCALE_4_8(a); + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes * 2; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_i8(int tile) { + uint8_t rgba32_buf[16384]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + //SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes; i++) { + uint8_t intensity = addr[i]; + uint8_t r = intensity; + uint8_t g = intensity; + uint8_t b = intensity; + uint8_t a = intensity; + rgba32_buf[4*i + 0] = r; + rgba32_buf[4*i + 1] = g; + rgba32_buf[4*i + 2] = b; + rgba32_buf[4 * i + 3] = a; + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + + +static void import_texture_ci4(int tile) { + uint8_t rgba32_buf[32768]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + const uint8_t *palette = rdp.palette + rdp.texture_tile[tile].palette * 16 * 2; // 16 pixel entries, 16 bits each + SUPPORT_CHECK(full_image_line_size_bytes == line_size_bytes); + + for (uint32_t i = 0; i < size_bytes * 2; i++) { + uint8_t byte = addr[i / 2]; + uint8_t idx = (byte >> (4 - (i % 2) * 4)) & 0xf; + uint16_t col16 = (palette[idx * 2] << 8) | palette[idx * 2 + 1]; // Big endian load + uint8_t a = col16 & 1; + uint8_t r = col16 >> 11; + uint8_t g = (col16 >> 6) & 0x1f; + uint8_t b = (col16 >> 1) & 0x1f; + rgba32_buf[4*i + 0] = SCALE_5_8(r); + rgba32_buf[4*i + 1] = SCALE_5_8(g); + rgba32_buf[4*i + 2] = SCALE_5_8(b); + rgba32_buf[4*i + 3] = a ? 255 : 0; + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes * 2; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture_ci8(int tile) { + uint8_t rgba32_buf[16384]; + const uint8_t* addr = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr; + uint32_t size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t full_image_line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes; + uint32_t line_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes; + + for (uint32_t i = 0, j = 0; i < size_bytes; j += full_image_line_size_bytes - line_size_bytes) + { + for (uint32_t k = 0; k < line_size_bytes; i++, k++, j++) { + uint8_t idx = addr[j]; + uint16_t col16 = (rdp.palette[idx * 2] << 8) | rdp.palette[idx * 2 + 1]; // Big endian load + uint8_t a = col16 & 1; + uint8_t r = col16 >> 11; + uint8_t g = (col16 >> 6) & 0x1f; + uint8_t b = (col16 >> 1) & 0x1f; + rgba32_buf[4 * i + 0] = SCALE_5_8(r); + rgba32_buf[4 * i + 1] = SCALE_5_8(g); + rgba32_buf[4 * i + 2] = SCALE_5_8(b); + rgba32_buf[4 * i + 3] = a ? 255 : 0; + } + } + + uint32_t width = rdp.texture_tile[tile].line_size_bytes; + uint32_t height = size_bytes / rdp.texture_tile[tile].line_size_bytes; + + if (size_bytes > 15000) + { + int bp = 0; + } + + gfx_rapi->upload_texture(rgba32_buf, width, height); + // DumpTexture(rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path, rgba32_buf, width, height); +} + +static void import_texture(int i, int tile) { + uint8_t fmt = rdp.texture_tile[tile].fmt; + uint8_t siz = rdp.texture_tile[tile].siz; + uint32_t tmem_index = rdp.texture_tile[tile].tmem_index; + + // OTRTODO: Move it to a function to be faster + // ModInternal::bindHook(LOOKUP_TEXTURE); + // ModInternal::initBindHook(8, + // HOOK_PARAMETER("gfx_api", gfx_get_current_rendering_api()), + // HOOK_PARAMETER("path", rdp.loaded_texture[tmem_index].otr_path), + // HOOK_PARAMETER("node", &rendering_state.textures[i]), + // HOOK_PARAMETER("fmt", &fmt), + // HOOK_PARAMETER("siz", &siz), + // HOOK_PARAMETER("tile", &i), + // HOOK_PARAMETER("palette", &rdp.texture_tile[tile].palette), + // HOOK_PARAMETER("addr", const_cast(rdp.loaded_texture[tmem_index].addr)) + // ); + // + // if (ModInternal::callBindHook(0)) + // return; + + if (gfx_texture_cache_lookup(i, &rendering_state.textures[i], rdp.loaded_texture[tmem_index].addr, fmt, siz, rdp.texture_tile[tile].palette)) + { + return; + } + + int t0 = get_time(); + if (fmt == G_IM_FMT_RGBA) { + if (siz == G_IM_SIZ_16b) { + import_texture_rgba16(tile); + } else if (siz == G_IM_SIZ_32b) { + import_texture_rgba32(tile); + } else { + //abort(); // OTRTODO: Sometimes, seemingly randomly, we end up here. Could be a bad dlist, could be something F3D does not have supported. Further investigation is needed. + } + } else if (fmt == G_IM_FMT_IA) { + if (siz == G_IM_SIZ_4b) { + import_texture_ia4(tile); + } else if (siz == G_IM_SIZ_8b) { + import_texture_ia8(tile); + } else if (siz == G_IM_SIZ_16b) { + import_texture_ia16(tile); + } else { + abort(); + } + } else if (fmt == G_IM_FMT_CI) { + if (siz == G_IM_SIZ_4b) { + import_texture_ci4(tile); + } else if (siz == G_IM_SIZ_8b) { + import_texture_ci8(tile); + } else { + abort(); + } + } else if (fmt == G_IM_FMT_I) { + if (siz == G_IM_SIZ_4b) { + import_texture_i4(tile); + } else if (siz == G_IM_SIZ_8b) { + import_texture_i8(tile); + } else { + abort(); + } + } else { + abort(); + } + int t1 = get_time(); + //printf("Time diff: %d\n", t1 - t0); +} + +static void gfx_normalize_vector(float v[3]) { + float s = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] /= s; + v[1] /= s; + v[2] /= s; +} + +static void gfx_transposed_matrix_mul(float res[3], const float a[3], const float b[4][4]) { + res[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2]; + res[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2]; + res[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2]; +} + +static void calculate_normal_dir(const Light_t *light, float coeffs[3]) { + float light_dir[3] = { + light->dir[0] / 127.0f, + light->dir[1] / 127.0f, + light->dir[2] / 127.0f + }; + gfx_transposed_matrix_mul(coeffs, light_dir, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]); + gfx_normalize_vector(coeffs); +} + +static void gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4][4]) { + float tmp[4][4]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + tmp[i][j] = a[i][0] * b[0][j] + + a[i][1] * b[1][j] + + a[i][2] * b[2][j] + + a[i][3] * b[3][j]; + } + } + memcpy(res, tmp, sizeof(tmp)); +} + +static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) { + float matrix[4][4]; +#ifndef GBI_FLOATS + // Original GBI where fixed point matrices are used + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j += 2) { + int32_t int_part = addr[i * 2 + j / 2]; + uint32_t frac_part = addr[8 + i * 2 + j / 2]; + matrix[i][j] = (int32_t)((int_part & 0xffff0000) | (frac_part >> 16)) / 65536.0f; + matrix[i][j + 1] = (int32_t)((int_part << 16) | (frac_part & 0xffff)) / 65536.0f; + } + } +#else + // For a modified GBI where fixed point values are replaced with floats + memcpy(matrix, addr, sizeof(matrix)); +#endif + + if (parameters & G_MTX_PROJECTION) { + if (parameters & G_MTX_LOAD) { + memcpy(rsp.P_matrix, matrix, sizeof(matrix)); + } else { + gfx_matrix_mul(rsp.P_matrix, matrix, rsp.P_matrix); + } + } else { // G_MTX_MODELVIEW + if ((parameters & G_MTX_PUSH) && rsp.modelview_matrix_stack_size < 11) { + ++rsp.modelview_matrix_stack_size; + memcpy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 2], sizeof(matrix)); + } + if (parameters & G_MTX_LOAD) { + memcpy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix, sizeof(matrix)); + } else { + gfx_matrix_mul(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]); + } + rsp.lights_changed = 1; + } + gfx_matrix_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix); +} + +static void gfx_sp_pop_matrix(uint32_t count) { + while (count--) { + if (rsp.modelview_matrix_stack_size > 0) { + --rsp.modelview_matrix_stack_size; + if (rsp.modelview_matrix_stack_size > 0) { + gfx_matrix_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix); + } + } + } +} + +static float gfx_adjust_x_for_aspect_ratio(float x) +{ + if (fbActive) + return x; + else + return x * (4.0f / 3.0f) / ((float)gfx_current_dimensions.width / (float)gfx_current_dimensions.height); +} + +static void gfx_adjust_width_height_for_scale(uint32_t& width, uint32_t& height) { + width = round(width * RATIO_Y); + height = round(height * RATIO_Y); + if (width == 0) { + width = 1; + } + if (height == 0) { + height = 1; + } +} + +static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices) { + for (size_t i = 0; i < n_vertices; i++, dest_index++) { + const Vtx_t *v = &vertices[i].v; + const Vtx_tn *vn = &vertices[i].n; + struct LoadedVertex *d = &rsp.loaded_vertices[dest_index]; + + if (markerOn) + { + int bp = 0; + } + + if ((uintptr_t)vertices == 0x14913ec0) + { + int bp = 0; + } + + if (v == NULL) + return; + + float x = v->ob[0] * rsp.MP_matrix[0][0] + v->ob[1] * rsp.MP_matrix[1][0] + v->ob[2] * rsp.MP_matrix[2][0] + rsp.MP_matrix[3][0]; + float y = v->ob[0] * rsp.MP_matrix[0][1] + v->ob[1] * rsp.MP_matrix[1][1] + v->ob[2] * rsp.MP_matrix[2][1] + rsp.MP_matrix[3][1]; + float z = v->ob[0] * rsp.MP_matrix[0][2] + v->ob[1] * rsp.MP_matrix[1][2] + v->ob[2] * rsp.MP_matrix[2][2] + rsp.MP_matrix[3][2]; + float w = v->ob[0] * rsp.MP_matrix[0][3] + v->ob[1] * rsp.MP_matrix[1][3] + v->ob[2] * rsp.MP_matrix[2][3] + rsp.MP_matrix[3][3]; + + if (markerOn) + { + int bp = 0; + } + + x = gfx_adjust_x_for_aspect_ratio(x); + + short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16; + short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16; + + if (rsp.geometry_mode & G_LIGHTING) { + if (rsp.lights_changed) { + for (int i = 0; i < rsp.current_num_lights - 1; i++) { + calculate_normal_dir(&rsp.current_lights[i], rsp.current_lights_coeffs[i]); + } + /*static const Light_t lookat_x = {{0, 0, 0}, 0, {0, 0, 0}, 0, {127, 0, 0}, 0}; + static const Light_t lookat_y = {{0, 0, 0}, 0, {0, 0, 0}, 0, {0, 127, 0}, 0};*/ + calculate_normal_dir(&rsp.lookat[0], rsp.current_lookat_coeffs[0]); + calculate_normal_dir(&rsp.lookat[1], rsp.current_lookat_coeffs[1]); + rsp.lights_changed = false; + } + + int r = rsp.current_lights[rsp.current_num_lights - 1].col[0]; + int g = rsp.current_lights[rsp.current_num_lights - 1].col[1]; + int b = rsp.current_lights[rsp.current_num_lights - 1].col[2]; + + for (int i = 0; i < rsp.current_num_lights - 1; i++) { + float intensity = 0; + intensity += vn->n[0] * rsp.current_lights_coeffs[i][0]; + intensity += vn->n[1] * rsp.current_lights_coeffs[i][1]; + intensity += vn->n[2] * rsp.current_lights_coeffs[i][2]; + intensity /= 127.0f; + if (intensity > 0.0f) { + r += intensity * rsp.current_lights[i].col[0]; + g += intensity * rsp.current_lights[i].col[1]; + b += intensity * rsp.current_lights[i].col[2]; + } + } + + d->color.r = r > 255 ? 255 : r; + d->color.g = g > 255 ? 255 : g; + d->color.b = b > 255 ? 255 : b; + + if (rsp.geometry_mode & G_TEXTURE_GEN) { + float dotx = 0, doty = 0; + dotx += vn->n[0] * rsp.current_lookat_coeffs[0][0]; + dotx += vn->n[1] * rsp.current_lookat_coeffs[0][1]; + dotx += vn->n[2] * rsp.current_lookat_coeffs[0][2]; + doty += vn->n[0] * rsp.current_lookat_coeffs[1][0]; + doty += vn->n[1] * rsp.current_lookat_coeffs[1][1]; + doty += vn->n[2] * rsp.current_lookat_coeffs[1][2]; + + + dotx /= 127.0f; + doty /= 127.0f; + + if (dotx < -1.0f) dotx = -1.0f; + if (dotx > 1.0f) dotx = 1.0f; + if (doty < -1.0f) doty = -1.0f; + if (doty > 1.0f) doty = 1.0f; + + if (rsp.geometry_mode & G_TEXTURE_GEN_LINEAR) { + // Not sure exactly what formula we should use to get accurate values + /*dotx = (2.906921f * dotx * dotx + 1.36114f) * dotx; + doty = (2.906921f * doty * doty + 1.36114f) * doty; + dotx = (dotx + 1.0f) / 4.0f; + doty = (doty + 1.0f) / 4.0f;*/ + dotx = acosf(-dotx) /*/ (3.14159265f)*/ / 4.0f; + doty = acosf(-doty) /*/ (3.14159265f)*/ / 4.0f; + } + else { + dotx = (dotx + 1.0f) / 4.0f; + doty = (doty + 1.0f) / 4.0f; + } + + U = (int32_t)(dotx * rsp.texture_scaling_factor.s); + V = (int32_t)(doty * rsp.texture_scaling_factor.t); + } + } else { + d->color.r = v->cn[0]; + d->color.g = v->cn[1]; + d->color.b = v->cn[2]; + } + + d->u = U; + d->v = V; + + // trivial clip rejection + d->clip_rej = 0; + if (x < -w) d->clip_rej |= 1; + if (x > w) d->clip_rej |= 2; + if (y < -w) d->clip_rej |= 4; + if (y > w) d->clip_rej |= 8; + //if (z < -w) d->clip_rej |= 16; + if (z > w) d->clip_rej |= 32; + + d->x = x; + d->y = y; + d->z = z; + d->w = w; + + if (rsp.geometry_mode & G_FOG) { + if (fabsf(w) < 0.001f) { + // To avoid division by zero + w = 0.001f; + } + + float winv = 1.0f / w; + if (winv < 0.0f) { + winv = 32767.0f; + } + + float fog_z = z * winv * rsp.fog_mul + rsp.fog_offset; + if (fog_z < 0) fog_z = 0; + if (fog_z > 255) fog_z = 255; + d->color.a = fog_z; // Use alpha variable to store fog factor + } else { + d->color.a = v->cn[3]; + } + } +} + +static void gfx_sp_modify_vertex(uint16_t vtx_idx, uint8_t where, uint32_t val) { + SUPPORT_CHECK(where == G_MWO_POINT_ST); + + int16_t s = (int16_t)(val >> 16); + int16_t t = (int16_t)val; + + struct LoadedVertex* v = &rsp.loaded_vertices[vtx_idx]; + v->u = s; + v->v = t; +} + +static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bool is_rect) { + struct LoadedVertex* v1 = &rsp.loaded_vertices[vtx1_idx]; + struct LoadedVertex* v2 = &rsp.loaded_vertices[vtx2_idx]; + struct LoadedVertex* v3 = &rsp.loaded_vertices[vtx3_idx]; + struct LoadedVertex* v_arr[3] = { v1, v2, v3 }; + + //if (rand()%2) return; + + if (v1->clip_rej & v2->clip_rej & v3->clip_rej) { + // The whole triangle lies outside the visible area + return; + } + + if ((rsp.geometry_mode & G_CULL_BOTH) != 0) { + float dx1 = v1->x / (v1->w) - v2->x / (v2->w); + float dy1 = v1->y / (v1->w) - v2->y / (v2->w); + float dx2 = v3->x / (v3->w) - v2->x / (v2->w); + float dy2 = v3->y / (v3->w) - v2->y / (v2->w); + float cross = dx1 * dy2 - dy1 * dx2; + + if ((v1->w < 0) ^ (v2->w < 0) ^ (v3->w < 0)) { + // If one vertex lies behind the eye, negating cross will give the correct result. + // If all vertices lie behind the eye, the triangle will be rejected anyway. + cross = -cross; + } + + switch (rsp.geometry_mode & G_CULL_BOTH) { + case G_CULL_FRONT: + if (cross <= 0) return; + break; + case G_CULL_BACK: + if (cross >= 0) return; + break; + case G_CULL_BOTH: + // Why is this even an option? + return; + } + } + + bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; + bool depth_mask = (rdp.other_mode_l & Z_UPD) == Z_UPD; + uint8_t depth_test_and_mask = (depth_test ? 1 : 0) | (depth_mask ? 2 : 0); + if (depth_test_and_mask != rendering_state.depth_test_and_mask) { + gfx_flush(); + gfx_rapi->set_depth_test_and_mask(depth_test, depth_mask); + rendering_state.depth_test_and_mask = depth_test_and_mask; + } + + bool zmode_decal = (rdp.other_mode_l & ZMODE_DEC) == ZMODE_DEC; + if (zmode_decal != rendering_state.decal_mode) { + gfx_flush(); + gfx_rapi->set_zmode_decal(zmode_decal); + rendering_state.decal_mode = zmode_decal; + } + + if (rdp.viewport_or_scissor_changed) { + if (memcmp(&rdp.viewport, &rendering_state.viewport, sizeof(rdp.viewport)) != 0) { + gfx_flush(); + gfx_rapi->set_viewport(rdp.viewport.x, rdp.viewport.y, rdp.viewport.width, rdp.viewport.height); + rendering_state.viewport = rdp.viewport; + } + if (memcmp(&rdp.scissor, &rendering_state.scissor, sizeof(rdp.scissor)) != 0) { + gfx_flush(); + gfx_rapi->set_scissor(rdp.scissor.x, rdp.scissor.y, rdp.scissor.width, rdp.scissor.height); + rendering_state.scissor = rdp.scissor; + } + rdp.viewport_or_scissor_changed = false; + } + + uint64_t cc_id = rdp.combine_mode; + + //bool use_alpha = (rdp.other_mode_l & (3 << 18)) == G_BL_1MA || (rdp.other_mode_l & (3 << 16)) == G_BL_1MA; + bool use_alpha = (rdp.other_mode_l & (3 << 20)) == (G_BL_CLR_MEM << 20) && (rdp.other_mode_l & (3 << 16)) == (G_BL_1MA << 16); + bool use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG; + bool texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA; + bool use_noise = (rdp.other_mode_l & (3U << G_MDSFT_ALPHACOMPARE)) == G_AC_DITHER; + bool use_2cyc = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE; + bool alpha_threshold = (rdp.other_mode_l & (3U << G_MDSFT_ALPHACOMPARE)) == G_AC_THRESHOLD; + bool invisible = (rdp.other_mode_l & (3 << 24)) == (G_BL_0 << 24) && (rdp.other_mode_l & (3 << 20)) == (G_BL_CLR_MEM << 20); + + if (texture_edge) { + use_alpha = true; + } + + if (use_alpha) cc_id |= (uint64_t)SHADER_OPT_ALPHA << CC_SHADER_OPT_POS; + if (use_fog) cc_id |= (uint64_t)SHADER_OPT_FOG << CC_SHADER_OPT_POS; + if (texture_edge) cc_id |= (uint64_t)SHADER_OPT_TEXTURE_EDGE << CC_SHADER_OPT_POS; + if (use_noise) cc_id |= (uint64_t)SHADER_OPT_NOISE << CC_SHADER_OPT_POS; + if (use_2cyc) cc_id |= (uint64_t)SHADER_OPT_2CYC << CC_SHADER_OPT_POS; + if (alpha_threshold) cc_id |= (uint64_t)SHADER_OPT_ALPHA_THRESHOLD << CC_SHADER_OPT_POS; + if (invisible) cc_id |= (uint64_t)SHADER_OPT_INVISIBLE << CC_SHADER_OPT_POS; + + if (!use_alpha) { + cc_id &= ~((0xfff << 16) | ((uint64_t)0xfff << 44)); + } + + struct ColorCombiner* comb = gfx_lookup_or_create_color_combiner(cc_id); + + uint32_t tm = 0; + uint32_t tex_width[2], tex_height[2], tex_width2[2], tex_height2[2]; + + for (int i = 0; i < 2; i++) { + uint32_t tile = rdp.first_tile_index + i; + if (comb->used_textures[i]) { + if (rdp.textures_changed[i]) { + gfx_flush(); + import_texture(i, tile); + rdp.textures_changed[i] = false; + } + + uint8_t cms = rdp.texture_tile[tile].cms; + uint8_t cmt = rdp.texture_tile[tile].cmt; + + uint32_t tex_size_bytes = rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes; + uint32_t line_size = rdp.texture_tile[tile].line_size_bytes; + + if (line_size == 0) + line_size = 1; + + tex_height[i] = tex_size_bytes / line_size; + switch (rdp.texture_tile[tile].siz) { + case G_IM_SIZ_4b: + line_size <<= 1; + break; + case G_IM_SIZ_8b: + break; + case G_IM_SIZ_16b: + line_size /= G_IM_SIZ_16b_LINE_BYTES; + break; + case G_IM_SIZ_32b: + line_size /= G_IM_SIZ_32b_LINE_BYTES; // this is 2! + tex_height[i] /= 2; + break; + } + tex_width[i] = line_size; + + tex_width2[i] = (rdp.texture_tile[tile].lrs - rdp.texture_tile[tile].uls + 4) / 4; + tex_height2[i] = (rdp.texture_tile[tile].lrt - rdp.texture_tile[tile].ult + 4) / 4; + + uint32_t tex_width1 = tex_width[i] << (cms & G_TX_MIRROR); + uint32_t tex_height1 = tex_height[i] << (cmt & G_TX_MIRROR); + + if ((cms & G_TX_CLAMP) && ((cms & G_TX_MIRROR) || tex_width1 != tex_width2[i])) { + tm |= 1 << 2 * i; + cms &= ~G_TX_CLAMP; + } + if ((cmt & G_TX_CLAMP) && ((cmt & G_TX_MIRROR) || tex_height1 != tex_height2[i])) { + tm |= 1 << 2 * i + 1; + cmt &= ~G_TX_CLAMP; + } + + bool linear_filter = (rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) != G_TF_POINT; + if (linear_filter != rendering_state.textures[i]->second.linear_filter || cms != rendering_state.textures[i]->second.cms || cmt != rendering_state.textures[i]->second.cmt) { + gfx_flush(); + gfx_rapi->set_sampler_parameters(i, linear_filter, cms, cmt); + rendering_state.textures[i]->second.linear_filter = linear_filter; + rendering_state.textures[i]->second.cms = cms; + rendering_state.textures[i]->second.cmt = cmt; + } + } + } + + struct ShaderProgram* prg = comb->prg[tm]; + if (prg == NULL) { + comb->prg[tm] = prg = gfx_lookup_or_create_shader_program(comb->shader_id0, comb->shader_id1 | (tm * SHADER_OPT_TEXEL0_CLAMP_S)); + } + if (prg != rendering_state.shader_program) { + gfx_flush(); + gfx_rapi->unload_shader(rendering_state.shader_program); + gfx_rapi->load_shader(prg); + rendering_state.shader_program = prg; + } + if (use_alpha != rendering_state.alpha_blend) { + gfx_flush(); + gfx_rapi->set_use_alpha(use_alpha); + rendering_state.alpha_blend = use_alpha; + } + uint8_t num_inputs; + bool used_textures[2]; + + if (markerOn) + { + int bp = 0; + } + + gfx_rapi->shader_get_info(prg, &num_inputs, used_textures); + + bool z_is_from_0_to_1 = gfx_rapi->z_is_from_0_to_1(); + + for (int i = 0; i < 3; i++) { + float z = v_arr[i]->z, w = v_arr[i]->w; + if (z_is_from_0_to_1) { + z = (z + w) / 2.0f; + } + + if (markerOn) + { + //z = 10; + } + + buf_vbo[buf_vbo_len++] = v_arr[i]->x; + buf_vbo[buf_vbo_len++] = v_arr[i]->y; + buf_vbo[buf_vbo_len++] = z; + buf_vbo[buf_vbo_len++] = w; + + for (int t = 0; t < 2; t++) { + if (!used_textures[t]) { + continue; + } + float u = v_arr[i]->u / 32.0f; + float v = v_arr[i]->v / 32.0f; + int shifts = rdp.texture_tile[rdp.first_tile_index + t].shifts; + int shiftt = rdp.texture_tile[rdp.first_tile_index + t].shiftt; + if (shifts != 0) { + if (shifts <= 10) { + u /= 1 << shifts; + } else { + u *= 1 << (16 - shifts); + } + } + if (shiftt != 0) { + if (shiftt <= 10) { + v /= 1 << shiftt; + } else { + v *= 1 << (16 - shiftt); + } + + } + + u -= rdp.texture_tile[rdp.first_tile_index + t].uls / 4.0f; + v -= rdp.texture_tile[rdp.first_tile_index + t].ult / 4.0f; + + if ((rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) != G_TF_POINT) { + // Linear filter adds 0.5f to the coordinates + if (!is_rect) { + u += 0.5f; + v += 0.5f; + } + } + + buf_vbo[buf_vbo_len++] = u / tex_width[t]; + buf_vbo[buf_vbo_len++] = v / tex_height[t]; + + if (tm & (1 << 2 * t)) { + buf_vbo[buf_vbo_len++] = (tex_width2[t] - 0.5f) / tex_width[t]; + } + if (tm & (1 << 2 * t + 1)) { + buf_vbo[buf_vbo_len++] = (tex_height2[t] - 0.5f) / tex_height[t]; + } + } + + if (use_fog) { + buf_vbo[buf_vbo_len++] = rdp.fog_color.r / 255.0f; + buf_vbo[buf_vbo_len++] = rdp.fog_color.g / 255.0f; + buf_vbo[buf_vbo_len++] = rdp.fog_color.b / 255.0f; + buf_vbo[buf_vbo_len++] = v_arr[i]->color.a / 255.0f; // fog factor (not alpha) + } + + for (int j = 0; j < num_inputs; j++) { + struct RGBA* color = 0; + struct RGBA tmp; + for (int k = 0; k < 1 + (use_alpha ? 1 : 0); k++) { + switch (comb->shader_input_mapping[k][j]) { + // Note: CCMUX constants and ACMUX constants used here have same value, which is why this works (except LOD fraction). + case G_CCMUX_PRIMITIVE: + color = &rdp.prim_color; + break; + case G_CCMUX_SHADE: + color = &v_arr[i]->color; + break; + case G_CCMUX_ENVIRONMENT: + color = &rdp.env_color; + break; + case G_CCMUX_PRIMITIVE_ALPHA: + { + tmp.r = tmp.g = tmp.b = rdp.prim_color.a; + color = &tmp; + break; + } + case G_CCMUX_ENV_ALPHA: + { + tmp.r = tmp.g = tmp.b = rdp.env_color.a; + color = &tmp; + break; + } + case G_CCMUX_PRIM_LOD_FRAC: + { + tmp.r = tmp.g = tmp.b = rdp.prim_lod_fraction; + color = &tmp; + break; + } + case G_CCMUX_LOD_FRACTION: + { + if (rdp.other_mode_l & G_TL_LOD) { + // "Hack" that works for Bowser - Peach painting + float distance_frac = (v1->w - 3000.0f) / 3000.0f; + if (distance_frac < 0.0f) distance_frac = 0.0f; + if (distance_frac > 1.0f) distance_frac = 1.0f; + tmp.r = tmp.g = tmp.b = tmp.a = distance_frac * 255.0f; + } else { + tmp.r = tmp.g = tmp.b = tmp.a = 255.0f; + } + color = &tmp; + break; + } + case G_ACMUX_PRIM_LOD_FRAC: + tmp.a = rdp.prim_lod_fraction; + color = &tmp; + break; + default: + memset(&tmp, 0, sizeof(tmp)); + color = &tmp; + break; + } + if (k == 0) { + buf_vbo[buf_vbo_len++] = color->r / 255.0f; + buf_vbo[buf_vbo_len++] = color->g / 255.0f; + buf_vbo[buf_vbo_len++] = color->b / 255.0f; + } + else { + if (use_fog && color == &v_arr[i]->color) { + // Shade alpha is 100% for fog + buf_vbo[buf_vbo_len++] = 1.0f; + } + else { + buf_vbo[buf_vbo_len++] = color->a / 255.0f; + } + } + } + } + //struct RGBA *color = &v_arr[i]->color; + //buf_vbo[buf_vbo_len++] = color->r / 255.0f; + //buf_vbo[buf_vbo_len++] = color->g / 255.0f; + //buf_vbo[buf_vbo_len++] = color->b / 255.0f; + //buf_vbo[buf_vbo_len++] = color->a / 255.0f; + } + + if (++buf_vbo_num_tris == MAX_BUFFERED) { + //if (++buf_vbo_num_tris == 1) { + if (markerOn) + { + int bp = 0; + } + gfx_flush(); + } +} + +static void gfx_sp_geometry_mode(uint32_t clear, uint32_t set) { + rsp.geometry_mode &= ~clear; + rsp.geometry_mode |= set; +} + +static void gfx_calc_and_set_viewport(const Vp_t *viewport) { + // 2 bits fraction + float width = 2.0f * viewport->vscale[0] / 4.0f; + float height = 2.0f * viewport->vscale[1] / 4.0f; + float x = (viewport->vtrans[0] / 4.0f) - width / 2.0f; + float y = ((viewport->vtrans[1] / 4.0f) + height / 2.0f); + + if (!fbActive) { + width *= RATIO_X; + height *= RATIO_Y; + x *= RATIO_X; + y = SCREEN_HEIGHT - y; + y *= RATIO_Y; + } else { + width *= RATIO_Y; + height *= RATIO_Y; + x *= RATIO_Y; + y = active_fb->second.orig_height - y; + y *= RATIO_Y; + } + + rdp.viewport.x = x; + rdp.viewport.y = y; + rdp.viewport.width = width; + rdp.viewport.height = height; + + rdp.viewport_or_scissor_changed = true; +} + +static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) { + switch (index) { + case G_MV_VIEWPORT: + gfx_calc_and_set_viewport((const Vp_t *) data); + break; +#if 0 + case G_MV_LOOKATY: + case G_MV_LOOKATX: + memcpy(rsp.current_lookat + (index - G_MV_LOOKATY) / 2, data, sizeof(Light_t)); + //rsp.lights_changed = 1; + break; +#endif +#ifdef F3DEX_GBI_2 + case G_MV_LIGHT: { + int lightidx = offset / 24 - 2; + if (lightidx >= 0 && lightidx <= MAX_LIGHTS) { // skip lookat + // NOTE: reads out of bounds if it is an ambient light + memcpy(rsp.current_lights + lightidx, data, sizeof(Light_t)); + } else if (lightidx < 0) { + memcpy(rsp.lookat + offset / 24, data, sizeof(Light_t)); + } + break; + } +#else + case G_MV_L0: + case G_MV_L1: + case G_MV_L2: + // NOTE: reads out of bounds if it is an ambient light + memcpy(rsp.current_lights + (index - G_MV_L0) / 2, data, sizeof(Light_t)); + break; +#endif + } +} + +static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) { + switch (index) { + case G_MW_NUMLIGHT: +#ifdef F3DEX_GBI_2 + rsp.current_num_lights = data / 24 + 1; // add ambient light +#else + // Ambient light is included + // The 31th bit is a flag that lights should be recalculated + rsp.current_num_lights = (data - 0x80000000U) / 32; +#endif + rsp.lights_changed = 1; + break; + case G_MW_FOG: + rsp.fog_mul = (int16_t)(data >> 16); + rsp.fog_offset = (int16_t)data; + break; + case G_MW_SEGMENT: + int segNumber = offset / 4; + segmentPointers[segNumber] = data; + break; + } +} + +static void gfx_sp_texture(uint16_t sc, uint16_t tc, uint8_t level, uint8_t tile, uint8_t on) { + rsp.texture_scaling_factor.s = sc; + rsp.texture_scaling_factor.t = tc; + if (rdp.first_tile_index != tile) { + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; + } + + if (tile > 8) + { + int bp = 0; + } + + rdp.first_tile_index = tile; +} + +static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32_t lrx, uint32_t lry) { + float x = ulx / 4.0f; + float y = lry / 4.0f; + float width = (lrx - ulx) / 4.0f; + float height = (lry - uly) / 4.0f; + + if (!fbActive) { + x *= RATIO_X; + y = SCREEN_HEIGHT - y; + y *= RATIO_Y; + width *= RATIO_X; + height *= RATIO_Y; + } else { + width *= RATIO_Y; + height *= RATIO_Y; + x *= RATIO_Y; + y = active_fb->second.orig_height - y; + y *= RATIO_Y; + } + + rdp.scissor.x = x; + rdp.scissor.y = y; + rdp.scissor.width = width; + rdp.scissor.height = height; + + rdp.viewport_or_scissor_changed = true; +} + +static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, char* otr_path) { + rdp.texture_to_load.addr = (const uint8_t*)addr; + rdp.texture_to_load.siz = size; + rdp.texture_to_load.width = width; + if ( otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7; + rdp.texture_to_load.otr_path = otr_path; +} + +static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) { + // OTRTODO: + //SUPPORT_CHECK(tmem == 0 || tmem == 256); + + if (cms == G_TX_WRAP && masks == G_TX_NOMASK) { + cms = G_TX_CLAMP; + } + if (cmt == G_TX_WRAP && maskt == G_TX_NOMASK) { + cmt = G_TX_CLAMP; + } + + rdp.texture_tile[tile].palette = palette; // palette should set upper 4 bits of color index in 4b mode + rdp.texture_tile[tile].fmt = fmt; + rdp.texture_tile[tile].siz = siz; + rdp.texture_tile[tile].cms = cms; + rdp.texture_tile[tile].cmt = cmt; + rdp.texture_tile[tile].shifts = shifts; + rdp.texture_tile[tile].shiftt = shiftt; + rdp.texture_tile[tile].line_size_bytes = line * 8; + + if (rdp.texture_tile[tile].line_size_bytes > 15000) + { + int bp = 0; + } + + //rdp.texture_tile[tile].tmem_index = tmem / 256; // tmem is the 64-bit word offset, so 256 words means 2 kB + rdp.texture_tile[tile].tmem_index = tmem != 0; // assume one texture is loaded at address 0 and another texture at any other address + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; +} + +static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint16_t lrs, uint16_t lrt) { + rdp.texture_tile[tile].uls = uls; + rdp.texture_tile[tile].ult = ult; + rdp.texture_tile[tile].lrs = lrs; + rdp.texture_tile[tile].lrt = lrt; + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; +} + +static void gfx_dp_load_tlut(uint8_t tile, uint32_t high_index) { + //SUPPORT_CHECK(tile == G_TX_LOADTILE); + //SUPPORT_CHECK(rdp.texture_to_load.siz == G_IM_SIZ_16b); + + rdp.palette = rdp.texture_to_load.addr; +} + +static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t dxt) { + if (markerOn) + { + int bp = 0; + } + + SUPPORT_CHECK(tile == G_TX_LOADTILE); + SUPPORT_CHECK(uls == 0); + SUPPORT_CHECK(ult == 0); + + // The lrs field rather seems to be number of pixels to load + uint32_t word_size_shift; + switch (rdp.texture_to_load.siz) { + case G_IM_SIZ_4b: + word_size_shift = 0; // Or -1? It's unused in SM64 anyway. + break; + case G_IM_SIZ_8b: + word_size_shift = 0; + break; + case G_IM_SIZ_16b: + word_size_shift = 1; + break; + case G_IM_SIZ_32b: + word_size_shift = 2; + break; + } + uint32_t size_bytes = (lrs + 1) << word_size_shift; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes = size_bytes; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes = size_bytes; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes = size_bytes; + //assert(size_bytes <= 4096 && "bug: too big texture"); + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr = rdp.texture_to_load.addr; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path = rdp.texture_to_load.otr_path; + rdp.textures_changed[rdp.texture_tile[tile].tmem_index] = true; +} + +static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) { + SUPPORT_CHECK(tile == G_TX_LOADTILE); + + uint32_t word_size_shift; + switch (rdp.texture_to_load.siz) { + case G_IM_SIZ_4b: + word_size_shift = 0; + break; + case G_IM_SIZ_8b: + word_size_shift = 0; + break; + case G_IM_SIZ_16b: + word_size_shift = 1; + break; + case G_IM_SIZ_32b: + word_size_shift = 2; + break; + } + + uint32_t size_bytes = ((((lrs - uls) >> G_TEXTURE_IMAGE_FRAC) + 1) * (((lrt - ult) >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift; + uint32_t full_image_line_size_bytes = (rdp.texture_to_load.width + 1) << word_size_shift; + uint32_t line_size_bytes = (((lrs - uls) >> G_TEXTURE_IMAGE_FRAC) + 1) << word_size_shift; + uint32_t start_offset = full_image_line_size_bytes * (ult >> G_TEXTURE_IMAGE_FRAC) + ((uls >> G_TEXTURE_IMAGE_FRAC) << word_size_shift); + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].size_bytes = size_bytes; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].full_image_line_size_bytes = full_image_line_size_bytes; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].line_size_bytes = line_size_bytes; + + assert(size_bytes <= 4096 && "bug: too big texture"); + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].addr = rdp.texture_to_load.addr + start_offset; + rdp.loaded_texture[rdp.texture_tile[tile].tmem_index].otr_path = rdp.texture_to_load.otr_path; + rdp.texture_tile[tile].uls = uls; + rdp.texture_tile[tile].ult = ult; + rdp.texture_tile[tile].lrs = lrs; + rdp.texture_tile[tile].lrt = lrt; + + rdp.textures_changed[rdp.texture_tile[tile].tmem_index] = true; +} + + +/*static uint8_t color_comb_component(uint32_t v) { + switch (v) { + case G_CCMUX_TEXEL0: + return CC_TEXEL0; + case G_CCMUX_TEXEL1: + return CC_TEXEL1; + case G_CCMUX_PRIMITIVE: + return CC_PRIM; + case G_CCMUX_SHADE: + return CC_SHADE; + case G_CCMUX_ENVIRONMENT: + return CC_ENV; + case G_CCMUX_TEXEL0_ALPHA: + return CC_TEXEL0A; + case G_CCMUX_LOD_FRACTION: + return CC_LOD; + default: + return CC_0; + } +} + +static inline uint32_t color_comb(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { + return color_comb_component(a) | + (color_comb_component(b) << 3) | + (color_comb_component(c) << 6) | + (color_comb_component(d) << 9); +} + +static void gfx_dp_set_combine_mode(uint32_t rgb, uint32_t alpha) { + rdp.combine_mode = rgb | (alpha << 12); +}*/ + +static void gfx_dp_set_combine_mode(uint32_t rgb, uint32_t alpha, uint32_t rgb_cyc2, uint32_t alpha_cyc2) { + rdp.combine_mode = rgb | (alpha << 16) | ((uint64_t)rgb_cyc2 << 28) | ((uint64_t)alpha_cyc2 << 44); +} + +static inline uint32_t color_comb(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { + return (a & 0xf) | ((b & 0xf) << 4) | ((c & 0x1f) << 8) | ((d & 7) << 13); +} + +static inline uint32_t alpha_comb(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { + return (a & 7) | ((b & 7) << 3) | ((c & 7) << 6) | ((d & 7) << 9); +} + +static void gfx_dp_set_env_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + rdp.env_color.r = r; + rdp.env_color.g = g; + rdp.env_color.b = b; + rdp.env_color.a = a; +} + +static void gfx_dp_set_prim_color(uint8_t m, uint8_t l, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + rdp.prim_lod_fraction = l; + rdp.prim_color.r = r; + rdp.prim_color.g = g; + rdp.prim_color.b = b; + rdp.prim_color.a = a; +} + +static void gfx_dp_set_fog_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + rdp.fog_color.r = r; + rdp.fog_color.g = g; + rdp.fog_color.b = b; + rdp.fog_color.a = a; +} + +static void gfx_dp_set_fill_color(uint32_t packed_color) { + uint16_t col16 = (uint16_t)packed_color; + uint32_t r = col16 >> 11; + uint32_t g = (col16 >> 6) & 0x1f; + uint32_t b = (col16 >> 1) & 0x1f; + uint32_t a = col16 & 1; + rdp.fill_color.r = SCALE_5_8(r); + rdp.fill_color.g = SCALE_5_8(g); + rdp.fill_color.b = SCALE_5_8(b); + rdp.fill_color.a = a * 255; +} + +static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry) { + uint32_t saved_other_mode_h = rdp.other_mode_h; + uint32_t cycle_type = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)); + + if (cycle_type == G_CYC_COPY) { + rdp.other_mode_h = (rdp.other_mode_h & ~(3U << G_MDSFT_TEXTFILT)) | G_TF_POINT; + } + + // U10.2 coordinates + float ulxf = ulx; + float ulyf = uly; + float lrxf = lrx; + float lryf = lry; + + ulxf = ulxf / (4.0f * HALF_SCREEN_WIDTH) - 1.0f; + ulyf = -(ulyf / (4.0f * HALF_SCREEN_HEIGHT)) + 1.0f; + lrxf = lrxf / (4.0f * HALF_SCREEN_WIDTH) - 1.0f; + lryf = -(lryf / (4.0f * HALF_SCREEN_HEIGHT)) + 1.0f; + + ulxf = gfx_adjust_x_for_aspect_ratio(ulxf); + lrxf = gfx_adjust_x_for_aspect_ratio(lrxf); + + struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0]; + struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1]; + struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2]; + struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3]; + + ul->x = ulxf; + ul->y = ulyf; + ul->z = -1.0f; + ul->w = 1.0f; + + ll->x = ulxf; + ll->y = lryf; + ll->z = -1.0f; + ll->w = 1.0f; + + lr->x = lrxf; + lr->y = lryf; + lr->z = -1.0f; + lr->w = 1.0f; + + ur->x = lrxf; + ur->y = ulyf; + ur->z = -1.0f; + ur->w = 1.0f; + + // The coordinates for texture rectangle shall bypass the viewport setting + struct XYWidthHeight default_viewport = { 0, 0, gfx_current_dimensions.width, gfx_current_dimensions.height }; + struct XYWidthHeight viewport_saved = rdp.viewport; + uint32_t geometry_mode_saved = rsp.geometry_mode; + + rdp.viewport = default_viewport; + rdp.viewport_or_scissor_changed = true; + rsp.geometry_mode = 0; + + gfx_sp_tri1(MAX_VERTICES + 0, MAX_VERTICES + 1, MAX_VERTICES + 3, true); + gfx_sp_tri1(MAX_VERTICES + 1, MAX_VERTICES + 2, MAX_VERTICES + 3, true); + + rsp.geometry_mode = geometry_mode_saved; + rdp.viewport = viewport_saved; + rdp.viewport_or_scissor_changed = true; + + if (cycle_type == G_CYC_COPY) { + rdp.other_mode_h = saved_other_mode_h; + } +} + +static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry, uint8_t tile, int16_t uls, int16_t ult, int16_t dsdx, int16_t dtdy, bool flip) { + //printf("render %d at %d\n", tile, lrx); + uint64_t saved_combine_mode = rdp.combine_mode; + if ((rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_COPY) { + // Per RDP Command Summary Set Tile's shift s and this dsdx should be set to 4 texels + // Divide by 4 to get 1 instead + dsdx >>= 2; + + // Color combiner is turned off in copy mode + gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_TEXEL0), alpha_comb(0, 0, 0, G_ACMUX_TEXEL0), 0, 0); + + // Per documentation one extra pixel is added in this modes to each edge + lrx += 1 << 2; + lry += 1 << 2; + } + + // uls and ult are S10.5 + // dsdx and dtdy are S5.10 + // lrx, lry, ulx, uly are U10.2 + // lrs, lrt are S10.5 + if (flip) { + dsdx = -dsdx; + dtdy = -dtdy; + } + int16_t width = !flip ? lrx - ulx : lry - uly; + int16_t height = !flip ? lry - uly : lrx - ulx; + float lrs = ((uls << 7) + dsdx * width) >> 7; + float lrt = ((ult << 7) + dtdy * height) >> 7; + + struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0]; + struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1]; + struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2]; + struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3]; + ul->u = uls; + ul->v = ult; + lr->u = lrs; + lr->v = lrt; + if (!flip) { + ll->u = uls; + ll->v = lrt; + ur->u = lrs; + ur->v = ult; + } else { + ll->u = lrs; + ll->v = ult; + ur->u = uls; + ur->v = lrt; + } + + uint8_t saved_tile = rdp.first_tile_index; + if (saved_tile != tile) { + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; + } + rdp.first_tile_index = tile; + + gfx_draw_rectangle(ulx, uly, lrx, lry); + if (saved_tile != tile) { + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; + } + rdp.first_tile_index = saved_tile; + rdp.combine_mode = saved_combine_mode; +} + +static void gfx_dp_fill_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry) { + if (rdp.color_image_address == rdp.z_buf_address) { + // Don't clear Z buffer here since we already did it with glClear + return; + } + uint32_t mode = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)); + + // OTRTODO: This is a bit of a hack for widescreen screen fades, but it'll work for now... + if (ulx == 0 && uly == 0 && lrx == (319 * 4) && lry == (239 * 4)) + { + ulx = -1024; + uly = -1024; + lrx = 2048; + lry = 2048; + } + + if (mode == G_CYC_COPY || mode == G_CYC_FILL) { + // Per documentation one extra pixel is added in this modes to each edge + lrx += 1 << 2; + lry += 1 << 2; + } + + for (int i = MAX_VERTICES; i < MAX_VERTICES + 4; i++) { + struct LoadedVertex* v = &rsp.loaded_vertices[i]; + v->color = rdp.fill_color; + } + + uint64_t saved_combine_mode = rdp.combine_mode; + + if (mode == G_CYC_FILL) + gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_SHADE), alpha_comb(0, 0, 0, G_ACMUX_SHADE), 0, 0); + + gfx_draw_rectangle(ulx, uly, lrx, lry); + rdp.combine_mode = saved_combine_mode; +} + +static void gfx_dp_set_z_image(void *z_buf_address) { + rdp.z_buf_address = z_buf_address; +} + +static void gfx_dp_set_color_image(uint32_t format, uint32_t size, uint32_t width, void* address) { + rdp.color_image_address = address; +} + +static void gfx_sp_set_other_mode(uint32_t shift, uint32_t num_bits, uint64_t mode) { + uint64_t mask = (((uint64_t)1 << num_bits) - 1) << shift; + uint64_t om = rdp.other_mode_l | ((uint64_t)rdp.other_mode_h << 32); + om = (om & ~mask) | mode; + rdp.other_mode_l = (uint32_t)om; + rdp.other_mode_h = (uint32_t)(om >> 32); +} + +static void gfx_dp_set_other_mode(uint32_t h, uint32_t l) { + rdp.other_mode_h = h; + rdp.other_mode_l = l; +} + +static void gfx_s2dex_bg_copy(const uObjBg* bg) { + /* + bg->b.imageX = 0; + bg->b.imageW = width * 4; + bg->b.frameX = frameX * 4; + bg->b.imageY = 0; + bg->b.imageH = height * 4; + bg->b.frameY = frameY * 4; + bg->b.imagePtr = source; + bg->b.imageLoad = G_BGLT_LOADTILE; + bg->b.imageFmt = fmt; + bg->b.imageSiz = siz; + bg->b.imagePal = 0; + bg->b.imageFlip = 0; + */ + SUPPORT_CHECK(bg->b.imageSiz == G_IM_SIZ_16b); + gfx_dp_set_texture_image(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, bg->b.imagePtr, nullptr); + gfx_dp_set_tile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0); + gfx_dp_load_block(G_TX_LOADTILE, 0, 0, (bg->b.imageW * bg->b.imageH >> 4) - 1, 0); + gfx_dp_set_tile(bg->b.imageFmt, G_IM_SIZ_16b, bg->b.imageW >> 4, 0, G_TX_RENDERTILE, bg->b.imagePal, 0, 0, 0, 0, 0, 0); + gfx_dp_set_tile_size(G_TX_RENDERTILE, 0, 0, bg->b.imageW, bg->b.imageH); + gfx_dp_texture_rectangle(bg->b.frameX, bg->b.frameY, bg->b.frameX + bg->b.imageW - 4, bg->b.frameY + bg->b.imageH - 4, G_TX_RENDERTILE, bg->b.imageX << 3, bg->b.imageY << 3, 4 << 10, 1 << 10, false); +} + +static inline void* seg_addr(uintptr_t w1) +{ + // Segmented? + if (w1 >= 0xF0000000) + { + uint32_t segNum = (w1 >> 24); + segNum -= 0xF0; + + uint32_t offset = w1 & 0x00FFFFFF; + //offset = 0; // Cursed Malon bug + + if (segmentPointers[segNum] != 0) + return (void*)(segmentPointers[segNum] + offset); + else + return (void*)w1; + } + else + { + return (void*)w1; + } +} + +#define C0(pos, width) ((cmd->words.w0 >> (pos)) & ((1U << width) - 1)) +#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1)) + +int dListBP; +int matrixBP; +uintptr_t clearMtx; + +extern "C" +{ + uintptr_t jsjutanShadowTex = 0; +}; + +static void gfx_run_dl(Gfx* cmd) { + //puts("dl"); + int dummy = 0; + char dlName[128]; + char fileName[128]; + + Gfx* dListStart = cmd; + uint64_t ourHash = -1; + + for (;;) { + uint32_t opcode = cmd->words.w0 >> 24; + //uint32_t opcode = cmd->words.w0 & 0xFF; + + //if (markerOn) + //printf("OP: %02X\n", opcode); + + + switch (opcode) { + // RSP commands: + case G_MARKER: + { + cmd++; + + ourHash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + +#if _DEBUG + //uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + //ResourceMgr_GetNameByCRC(hash, dlName); + //lusprintf(__FILE__, __LINE__, 6, "G_MARKER: %s\n", dlName); +#endif + + markerOn = true; + } + break; + case G_INVALTEXCACHE: + { + uintptr_t texAddr = cmd->words.w1; + + if (texAddr == 0) + gfx_texture_cache_clear(); + else + gfx_texture_cache_delete((const uint8_t*)texAddr); + } + break; + case G_NOOP: + { + uint32_t index = C0(0, 16); + uint32_t type = C0(16, 8); + if (type == 2) { + const char* str = (const char *)cmd->words.w1; + //printf("%s, %u\n", str, index); + } + } + break; + case G_MTX: { + uintptr_t mtxAddr = cmd->words.w1; + + // OTRTODO: Temp way of dealing with gMtxClear. Need something more elegant in the future... + if (mtxAddr == 0xF012DB20 || mtxAddr == 0xF012DB40) + mtxAddr = clearMtx; + +#ifdef F3DEX_GBI_2 + gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, (const int32_t *) seg_addr(mtxAddr)); +#else + gfx_sp_matrix(C0(16, 8), (const int32_t *) seg_addr(cmd->words.w1)); +#endif + break; + } + case G_MTX_OTR: { + cmd++; + + uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + +#if _DEBUG + //char fileName[4096]; + //ResourceMgr_GetNameByCRC(hash, fileName); + + //printf("G_MTX_OTR: %s\n", fileName); +#endif + + int32_t* mtx = ResourceMgr_LoadMtxByCRC(hash); + +#ifdef F3DEX_GBI_2 + if (mtx != NULL) + { + cmd--; + gfx_sp_matrix(C0(0, 8) ^ G_MTX_PUSH, mtx); + cmd++; + } +#else + gfx_sp_matrix(C0(16, 8), (const int32_t*)seg_addr(cmd->words.w1)); +#endif + break; + } + case (uint8_t)G_POPMTX: +#ifdef F3DEX_GBI_2 + gfx_sp_pop_matrix(cmd->words.w1 / 64); +#else + gfx_sp_pop_matrix(1); +#endif + break; + case G_MOVEMEM: +#ifdef F3DEX_GBI_2 + gfx_sp_movemem(C0(0, 8), C0(8, 8) * 8, seg_addr(cmd->words.w1)); +#else + gfx_sp_movemem(C0(16, 8), 0, seg_addr(cmd->words.w1)); +#endif + break; + case (uint8_t)G_MOVEWORD: +#ifdef F3DEX_GBI_2 + gfx_sp_moveword(C0(16, 8), C0(0, 16), cmd->words.w1); +#else + gfx_sp_moveword(C0(0, 8), C0(8, 16), cmd->words.w1); +#endif + break; + case (uint8_t)G_TEXTURE: +#ifdef F3DEX_GBI_2 + gfx_sp_texture(C1(16, 16), C1(0, 16), C0(11, 3), C0(8, 3), C0(1, 7)); +#else + gfx_sp_texture(C1(16, 16), C1(0, 16), C0(11, 3), C0(8, 3), C0(0, 8)); +#endif + break; + case G_VTX: +#ifdef F3DEX_GBI_2 + gfx_sp_vertex(C0(12, 8), C0(1, 7) - C0(12, 8), (const Vtx*)seg_addr(cmd->words.w1)); +#elif defined(F3DEX_GBI) || defined(F3DLP_GBI) + gfx_sp_vertex(C0(10, 6), C0(16, 8) / 2, seg_addr(cmd->words.w1)); +#else + gfx_sp_vertex((C0(0, 16)) / sizeof(Vtx), C0(16, 4), seg_addr(cmd->words.w1)); +#endif + break; + case G_VTX_OTR: + { + uintptr_t offset = cmd->words.w1; + cmd++; + uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + +#if _DEBUG + //char fileName[4096]; + //ResourceMgr_GetNameByCRC(hash, fileName); + + //printf("G_VTX_OTR: %s, 0x%08X\n", fileName, hash); +#endif + if (offset > 0xFFFFF) + { + cmd--; + gfx_sp_vertex(C0(12, 8), C0(1, 7) - C0(12, 8), (Vtx*)offset); + cmd++; + } + else + { + Vtx* vtx = ResourceMgr_LoadVtxByCRC(hash); + + if (vtx != NULL) + { + vtx = (Vtx*)((char*)vtx + offset); + + cmd--; + + if (ourHash != -1) + ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, cmd->words.w1); + + cmd->words.w1 = (uintptr_t)vtx; + + gfx_sp_vertex(C0(12, 8), C0(1, 7) - C0(12, 8), vtx); + cmd++; + } + } + } + break; + case G_MODIFYVTX: + gfx_sp_modify_vertex(C0(1, 15), C0(16, 8), cmd->words.w1); + break; + case G_DL: + if (cmd->words.w1 == dListBP) + { + int bp = 0; + } + + if (C0(16, 1) == 0) { + // Push return address + gfx_run_dl((Gfx *)seg_addr(cmd->words.w1)); + } else { + cmd = (Gfx *)seg_addr(cmd->words.w1); + --cmd; // increase after break + } + break; + case G_DL_OTR: + if (C0(16, 1) == 0) + { + // Push return address + + cmd++; + + uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + +#if _DEBUG + //char fileName[4096]; + //ResourceMgr_GetNameByCRC(hash, fileName); + + //printf("G_DL_OTR: %s\n", fileName); +#endif + + Gfx* gfx = ResourceMgr_LoadGfxByCRC(hash); + + if (gfx != 0) + gfx_run_dl(gfx); + } + else { + cmd = (Gfx*)seg_addr(cmd->words.w1); + cmd++; + --cmd; // increase after break + } + break; + case G_BRANCH_Z_OTR: + { + // Push return address + + uint8_t vbidx = cmd->words.w0 & 0x00000FFF; + uint32_t zval = cmd->words.w1; + + cmd++; + + if (rsp.loaded_vertices[vbidx].z <= zval) + { + + uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + cmd->words.w1; + +#if _DEBUG + //char fileName[4096]; + //ResourceMgr_GetNameByCRC(hash, fileName); + + //printf("G_BRANCH_Z_OTR: %s\n", fileName); +#endif + + Gfx* gfx = ResourceMgr_LoadGfxByCRC(hash); + + if (gfx != 0) + { + cmd = gfx; + --cmd; // increase after break + } + } + } + break; + case (uint8_t)G_ENDDL: + + //if (markerOn) + //printf("END DL ON MARKER\n"); + + markerOn = false; + return; +#ifdef F3DEX_GBI_2 + case G_GEOMETRYMODE: + gfx_sp_geometry_mode(~C0(0, 24), cmd->words.w1); + break; +#else + case (uint8_t)G_SETGEOMETRYMODE: + gfx_sp_geometry_mode(0, cmd->words.w1); + break; + case (uint8_t)G_CLEARGEOMETRYMODE: + gfx_sp_geometry_mode(cmd->words.w1, 0); + break; +#endif + case (uint8_t)G_TRI1: +#ifdef F3DEX_GBI_2 + gfx_sp_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2, false); +#elif defined(F3DEX_GBI) || defined(F3DLP_GBI) + gfx_sp_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2, false); +#else + gfx_sp_tri1(C1(16, 8) / 10, C1(8, 8) / 10, C1(0, 8) / 10, false); +#endif + break; +#ifdef F3DEX_GBI_2 + case G_QUAD: + { + int bp = 0; + // fallthrough + } +#endif +#if defined(F3DEX_GBI) || defined(F3DLP_GBI) + case (uint8_t)G_TRI2: + gfx_sp_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2, false); + gfx_sp_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2, false); + break; +#endif + case (uint8_t)G_SETOTHERMODE_L: +#ifdef F3DEX_GBI_2 + gfx_sp_set_other_mode(31 - C0(8, 8) - C0(0, 8), C0(0, 8) + 1, cmd->words.w1); +#else + gfx_sp_set_other_mode(C0(8, 8), C0(0, 8), cmd->words.w1); +#endif + break; + case (uint8_t)G_SETOTHERMODE_H: +#ifdef F3DEX_GBI_2 + gfx_sp_set_other_mode(63 - C0(8, 8) - C0(0, 8), C0(0, 8) + 1, (uint64_t) cmd->words.w1 << 32); +#else + gfx_sp_set_other_mode(C0(8, 8) + 32, C0(0, 8), (uint64_t) cmd->words.w1 << 32); +#endif + break; + + // RDP Commands: + case G_SETTIMG: { + uintptr_t i = (uintptr_t) seg_addr(cmd->words.w1); + + char* imgData = (char*)i; + + if ((i & 0xF0000000) != 0xF0000000) + if (ResourceMgr_OTRSigCheck(imgData) == 1) + i = (uintptr_t)ResourceMgr_LoadTexByName(imgData); + + gfx_dp_set_texture_image(C0(21, 3), C0(19, 2), C0(0, 10), (void*) i, imgData); + break; + } + case G_SETTIMG_OTR: + { + uintptr_t addr = cmd->words.w1; + cmd++; + uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + (uint64_t)cmd->words.w1; + ResourceMgr_GetNameByCRC(hash, fileName); + char* tex = ResourceMgr_LoadTexByCRC(hash); + + +#if _DEBUG + //ResourceMgr_GetNameByCRC(hash, fileName); + //printf("G_SETTIMG_OTR: %s, %08X\n", fileName, hash); +#endif + + if (addr != NULL) + { + tex = (char*)addr; + } + else + { + tex = ResourceMgr_LoadTexByCRC(hash); + + if (tex != nullptr) + { + cmd--; + uintptr_t oldData = cmd->words.w1; + cmd->words.w1 = (uintptr_t)tex; + + if (ourHash != -1) + ResourceMgr_RegisterResourcePatch(ourHash, cmd - dListStart, oldData); + + cmd++; + } + } + + cmd--; + + + uint32_t fmt = C0(21, 3); + uint32_t size = C0(19, 2); + uint32_t width = C0(0, 10); + + if (tex != NULL) + gfx_dp_set_texture_image(fmt, size, width, tex, fileName); + + cmd++; + } + break; + case G_SETFB: + { + gfx_flush(); + fbActive = 1; + active_fb = framebuffers.find(cmd->words.w1); + gfx_rapi->set_framebuffer(active_fb->first); + } + break; + case G_RESETFB: + { + gfx_flush(); + fbActive = 0; + gfx_rapi->reset_framebuffer(); + break; + } + break; + case G_SETTIMG_FB: + { + gfx_flush(); + gfx_rapi->select_texture_fb(cmd->words.w1); + rdp.textures_changed[0] = false; + rdp.textures_changed[1] = false; + + //if (texPtr != NULL) + //gfx_dp_set_texture_image(C0(21, 3), C0(19, 2), C0(0, 10), texPtr); + } + break; + case G_LOADBLOCK: + gfx_dp_load_block(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); + break; + case G_LOADTILE: + gfx_dp_load_tile(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); + break; + case G_SETTILE: + gfx_dp_set_tile(C0(21, 3), C0(19, 2), C0(9, 9), C0(0, 9), C1(24, 3), C1(20, 4), C1(18, 2), C1(14, 4), C1(10, 4), C1(8, 2), C1(4, 4), C1(0, 4)); + break; + case G_SETTILESIZE: + gfx_dp_set_tile_size(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); + break; + case G_LOADTLUT: + gfx_dp_load_tlut(C1(24, 3), C1(14, 10)); + break; + case G_SETENVCOLOR: + gfx_dp_set_env_color(C1(24, 8), C1(16, 8), C1(8, 8), C1(0, 8)); + break; + case G_SETPRIMCOLOR: + gfx_dp_set_prim_color(C0(8, 8), C0(0, 8), C1(24, 8), C1(16, 8), C1(8, 8), C1(0, 8)); + break; + case G_SETFOGCOLOR: + gfx_dp_set_fog_color(C1(24, 8), C1(16, 8), C1(8, 8), C1(0, 8)); + break; + case G_SETFILLCOLOR: + gfx_dp_set_fill_color(cmd->words.w1); + break; + case G_SETCOMBINE: + gfx_dp_set_combine_mode( + color_comb(C0(20, 4), C1(28, 4), C0(15, 5), C1(15, 3)), + alpha_comb(C0(12, 3), C1(12, 3), C0(9, 3), C1(9, 3)), + color_comb(C0(5, 4), C1(24, 4), C0(0, 5), C1(6, 3)), + alpha_comb(C1(21, 3), C1(3, 3), C1(18, 3), C1(0, 3))); + break; + // G_SETPRIMCOLOR, G_CCMUX_PRIMITIVE, G_ACMUX_PRIMITIVE, is used by Goddard + // G_CCMUX_TEXEL1, LOD_FRACTION is used in Bowser room 1 + case G_TEXRECT: + case G_TEXRECTFLIP: + { + int32_t lrx, lry, tile, ulx, uly; + uint32_t uls, ult, dsdx, dtdy; +#ifdef F3DEX_GBI_2E + lrx = (int32_t)(C0(0, 24) << 8) >> 8; + lry = (int32_t)(C1(0, 24) << 8) >> 8; + tile = C1(24, 3); + ++cmd; + ulx = (int32_t)(C0(0, 24) << 8) >> 8; + uly = (int32_t)(C1(0, 24) << 8) >> 8; + ++cmd; + uls = C0(16, 16); + ult = C0(0, 16); + dsdx = C1(16, 16); + dtdy = C1(0, 16); +#else + lrx = C0(12, 12); + lry = C0(0, 12); + tile = C1(24, 3); + ulx = C1(12, 12); + uly = C1(0, 12); + ++cmd; + uls = C1(16, 16); + ult = C1(0, 16); + ++cmd; + dsdx = C1(16, 16); + dtdy = C1(0, 16); +#endif + gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, opcode == G_TEXRECTFLIP); + break; + } + case G_TEXRECT_WIDE: + { + int32_t lrx, lry, tile, ulx, uly; + uint32_t uls, ult, dsdx, dtdy; + lrx = static_cast((C0(0, 24) << 8)) >> 8; + lry = static_cast((C1(0, 24) << 8)) >> 8; + tile = C1(24, 3); + ++cmd; + ulx = static_cast((C0(0, 24) << 8)) >> 8; + uly = static_cast((C1(0, 24) << 8)) >> 8; + ++cmd; + uls = C0(16, 16); + ult = C0(0, 16); + dsdx = C1(16, 16); + dtdy = C1(0, 16); + gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, opcode == G_TEXRECTFLIP); + break; + } + case G_FILLRECT: +#ifdef F3DEX_GBI_2E + { + int32_t lrx, lry, ulx, uly; + lrx = (int32_t)(C0(0, 24) << 8) >> 8; + lry = (int32_t)(C1(0, 24) << 8) >> 8; + ++cmd; + ulx = (int32_t)(C0(0, 24) << 8) >> 8; + uly = (int32_t)(C1(0, 24) << 8) >> 8; + gfx_dp_fill_rectangle(ulx, uly, lrx, lry); + break; + } +#else + gfx_dp_fill_rectangle(C1(12, 12), C1(0, 12), C0(12, 12), C0(0, 12)); + break; + case G_FILLWIDERECT: + { + int32_t lrx, lry, ulx, uly; + lrx = (int32_t)(C0(0, 24) << 8) >> 8; + lry = (int32_t)(C1(0, 24) << 8) >> 8; + ++cmd; + ulx = (int32_t)(C0(0, 24) << 8) >> 8; + uly = (int32_t)(C1(0, 24) << 8) >> 8; + gfx_dp_fill_rectangle(ulx, uly, lrx, lry); + break; + } +#endif + case G_SETSCISSOR: + gfx_dp_set_scissor(C1(24, 2), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12)); + break; + case G_SETZIMG: + gfx_dp_set_z_image(seg_addr(cmd->words.w1)); + break; + case G_SETCIMG: + gfx_dp_set_color_image(C0(21, 3), C0(19, 2), C0(0, 11), seg_addr(cmd->words.w1)); + break; + case G_RDPSETOTHERMODE: + gfx_dp_set_other_mode(C0(0, 24), cmd->words.w1); + break; + // S2DEX + case G_BG_COPY: + if (!markerOn) + gfx_s2dex_bg_copy((const uObjBg*)cmd->words.w1); // not seg_addr here it seems + + break; + } + ++cmd; + } +} + +static void gfx_sp_reset() { + rsp.modelview_matrix_stack_size = 1; + rsp.current_num_lights = 2; + rsp.lights_changed = true; +} + +void gfx_get_dimensions(uint32_t *width, uint32_t *height) { + gfx_wapi->get_dimensions(width, height); +} + +void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, const char *game_name, bool start_in_fullscreen) { + gfx_wapi = wapi; + gfx_rapi = rapi; + gfx_wapi->init(game_name, start_in_fullscreen); + gfx_rapi->init(); + gfx_current_dimensions.internal_mul = 1; + gfx_current_dimensions.width = SCREEN_WIDTH; + gfx_current_dimensions.height = SCREEN_HEIGHT; + + for (int i = 0; i < 16; i++) + segmentPointers[i] = NULL; + + // Used in the 120 star TAS + static uint32_t precomp_shaders[] = { + 0x01200200, + 0x00000045, + 0x00000200, + 0x01200a00, + 0x00000a00, + 0x01a00045, + 0x00000551, + 0x01045045, + 0x05a00a00, + 0x01200045, + 0x05045045, + 0x01045a00, + 0x01a00a00, + 0x0000038d, + 0x01081081, + 0x0120038d, + 0x03200045, + 0x03200a00, + 0x01a00a6f, + 0x01141045, + 0x07a00a00, + 0x05200200, + 0x03200200, + 0x09200200, + 0x0920038d, + 0x09200045 + }; + for (size_t i = 0; i < sizeof(precomp_shaders) / sizeof(uint32_t); i++) { + //gfx_lookup_or_create_shader_program(precomp_shaders[i]); + } + + ModInternal::bindHook(GFX_INIT); + ModInternal::initBindHook(0); + ModInternal::callBindHook(0); +} + +struct GfxRenderingAPI *gfx_get_current_rendering_api(void) { + return gfx_rapi; +} + +void gfx_start_frame(void) { + gfx_wapi->handle_events(); + // gfx_wapi->get_dimensions(&gfx_current_dimensions.width, &gfx_current_dimensions.height); + if (gfx_current_dimensions.height == 0) { + // Avoid division by zero + gfx_current_dimensions.height = 1; + } + gfx_current_dimensions.aspect_ratio = (float)gfx_current_dimensions.width / (float)gfx_current_dimensions.height; + + if (gfx_current_dimensions.height != gfx_prev_dimensions.height) { + for (auto& fb : framebuffers) { + uint32_t width = fb.second.orig_width, height = fb.second.orig_height; + gfx_adjust_width_height_for_scale(width, height); + if (width != fb.second.applied_width || height != fb.second.applied_height) { + gfx_rapi->resize_framebuffer(fb.first, width, height); + fb.second.applied_width = width; + fb.second.applied_height = height; + } + } + } + gfx_prev_dimensions = gfx_current_dimensions; + + fbActive = 0; +} + +void gfx_run(Gfx *commands) { + gfx_sp_reset(); + + //puts("New frame"); + + if (!gfx_wapi->start_frame()) { + dropped_frame = true; + return; + } + dropped_frame = false; + + double t0 = gfx_wapi->get_time(); + gfx_rapi->start_frame(); + gfx_run_dl(commands); + gfx_flush(); + double t1 = gfx_wapi->get_time(); + //printf("Process %f %f\n", t1, t1 - t0); + gfx_rapi->end_frame(); + gfx_wapi->swap_buffers_begin(); +} + +void gfx_end_frame(void) { + if (!dropped_frame) { + gfx_rapi->finish_render(); + gfx_wapi->swap_buffers_end(); + } +} + +void gfx_set_framedivisor(int divisor) { + gfx_wapi->set_frame_divisor(divisor); +} + +int gfx_create_framebuffer(uint32_t width, uint32_t height) { + uint32_t orig_width = width, orig_height = height; + gfx_adjust_width_height_for_scale(width, height); + int fb = gfx_rapi->create_framebuffer(width, height); + framebuffers[fb] = { orig_width, orig_height, width, height }; + return fb; +} + +void gfx_set_framebuffer(int fb) +{ + gfx_rapi->set_framebuffer(fb); +} + +void gfx_reset_framebuffer() +{ + gfx_rapi->reset_framebuffer(); +} + +uint16_t gfx_get_pixel_depth(float x, float y) { + return gfx_rapi->get_pixel_depth(x * RATIO_Y - (SCREEN_WIDTH * RATIO_Y - gfx_current_dimensions.width) / 2, y * RATIO_Y); +} \ No newline at end of file diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_pc.h b/libultraship/libultraship/Lib/Fast3D/gfx_pc.h new file mode 100644 index 000000000..2e6a5a2a0 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_pc.h @@ -0,0 +1,67 @@ +#ifndef GFX_PC_H +#define GFX_PC_H + +#include +#include +#include + +struct GfxRenderingAPI; +struct GfxWindowManagerAPI; + +struct GfxDimensions +{ + uint32_t internal_mul; + uint32_t width, height; + float aspect_ratio; +}; + +struct TextureCacheKey { + const uint8_t* texture_addr; + uint8_t fmt, siz; + uint8_t palette_index; + + bool operator==(const TextureCacheKey&) const noexcept = default; + + struct Hasher { + size_t operator()(const TextureCacheKey& key) const noexcept { + uintptr_t addr = (uintptr_t)key.texture_addr; + return (size_t)(addr ^ (addr >> 5)); + } + }; +}; + +typedef std::unordered_map TextureCacheMap; +typedef std::pair TextureCacheNode; + +struct TextureCacheValue { + uint32_t texture_id; + uint8_t cms, cmt; + bool linear_filter; + + // Old versions of libstdc++ fail to compile this +#ifdef _MSC_VER + std::list::iterator lru_location; +#else + std::list::iterator lru_location; +#endif +}; + +#ifdef __cplusplus +extern "C" { +#endif +extern struct GfxDimensions gfx_current_dimensions; + +void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name, bool start_in_fullscreen); +struct GfxRenderingAPI* gfx_get_current_rendering_api(void); +void gfx_start_frame(void); +void gfx_run(Gfx* commands); +void gfx_end_frame(void); +void gfx_set_framedivisor(int); +void gfx_texture_cache_clear(); +int gfx_create_framebuffer(uint32_t width, uint32_t height); +uint16_t gfx_get_pixel_depth(float x, float y); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_rendering_api.h b/libultraship/libultraship/Lib/Fast3D/gfx_rendering_api.h new file mode 100644 index 000000000..9283ee236 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_rendering_api.h @@ -0,0 +1,41 @@ +#ifndef GFX_RENDERING_API_H +#define GFX_RENDERING_API_H + +#include +#include +#include + +struct ShaderProgram; + +struct GfxRenderingAPI { + bool (*z_is_from_0_to_1)(void); + void (*unload_shader)(struct ShaderProgram *old_prg); + void (*load_shader)(struct ShaderProgram *new_prg); + struct ShaderProgram *(*create_and_load_new_shader)(uint64_t shader_id0, uint32_t shader_id1); + struct ShaderProgram *(*lookup_shader)(uint64_t shader_id0, uint32_t shader_id1); + void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]); + uint32_t (*new_texture)(void); + void (*select_texture)(int tile, uint32_t texture_id); + void (*upload_texture)(const uint8_t *rgba32_buf, uint32_t width, uint32_t height); + void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt); + void (*set_depth_test_and_mask)(bool depth_test, bool z_upd); + uint16_t (*get_pixel_depth)(float x, float y); + void (*set_zmode_decal)(bool zmode_decal); + void (*set_viewport)(int x, int y, int width, int height); + void (*set_scissor)(int x, int y, int width, int height); + void (*set_use_alpha)(bool use_alpha); + void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris); + void (*init)(void); + void (*on_resize)(void); + void (*start_frame)(void); + void (*end_frame)(void); + void (*finish_render)(void); + int (*create_framebuffer)(uint32_t width, uint32_t height); + void (*resize_framebuffer)(int fb, uint32_t width, uint32_t height); + void (*set_framebuffer)(int fb); + void (*reset_framebuffer)(); + void (*select_texture_fb)(int fbID); + void (*delete_texture)(uint32_t texID); +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_screen_config.h b/libultraship/libultraship/Lib/Fast3D/gfx_screen_config.h new file mode 100644 index 000000000..5b933f853 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_screen_config.h @@ -0,0 +1,7 @@ +#ifndef GFX_SCREEN_CONFIG_H +#define GFX_SCREEN_CONFIG_H + +#define DESIRED_SCREEN_WIDTH 640 +#define DESIRED_SCREEN_HEIGHT 480 + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl.h b/libultraship/libultraship/Lib/Fast3D/gfx_sdl.h new file mode 100644 index 000000000..458eccb54 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl.h @@ -0,0 +1,8 @@ +#ifndef GFX_SDL_H +#define GFX_SDL_H + +#include "gfx_window_manager_api.h" + +extern struct GfxWindowManagerAPI gfx_sdl; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp new file mode 100644 index 000000000..ffc46f369 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -0,0 +1,317 @@ +#include + +#if !defined(__linux__) && defined(ENABLE_OPENGL) + +#ifdef __MINGW32__ +#define FOR_WINDOWS 1 +#else +#define FOR_WINDOWS 0 +#endif + +#if FOR_WINDOWS +#include +#include "SDL.h" +#define GL_GLEXT_PROTOTYPES 1 +#include "SDL_opengl.h" +#else +#include +#define GL_GLEXT_PROTOTYPES 1 +#include +#endif + +#include "../../SohImGuiImpl.h" + +#include "gfx_window_manager_api.h" +#include "gfx_screen_config.h" +#include +#include + +#define GFX_API_NAME "SDL2 - OpenGL" + +static SDL_Window *wnd; +static SDL_GLContext ctx; +static int inverted_scancode_table[512]; +static int vsync_enabled = 0; +static unsigned int window_width = DESIRED_SCREEN_WIDTH; +static unsigned int window_height = DESIRED_SCREEN_HEIGHT; +static bool fullscreen_state; +static void (*on_fullscreen_changed_callback)(bool is_now_fullscreen); +static bool (*on_key_down_callback)(int scancode); +static bool (*on_key_up_callback)(int scancode); +static void (*on_all_keys_up_callback)(void); + +const SDL_Scancode windows_scancode_table[] = +{ + /* 0 1 2 3 4 5 6 7 */ + /* 8 9 A B C D E F */ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */ + SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */ + + SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */ + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */ + + SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */ + SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */ + + SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_PRINTSCREEN,/* 3 */ + SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */ + + SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_HOME, /* 4 */ + SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_5, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_END, /* 4 */ + + SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11, /* 5 */ + SDL_SCANCODE_F12, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 5 */ + + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_F16, /* 6 */ + SDL_SCANCODE_F17, SDL_SCANCODE_F18, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 6 */ + + SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */ +}; + +const SDL_Scancode scancode_rmapping_extended[][2] = { + {SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RETURN}, + {SDL_SCANCODE_RALT, SDL_SCANCODE_LALT}, + {SDL_SCANCODE_RCTRL, SDL_SCANCODE_LCTRL}, + {SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_SLASH}, + //{SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_CAPSLOCK} +}; + +const SDL_Scancode scancode_rmapping_nonextended[][2] = { + {SDL_SCANCODE_KP_7, SDL_SCANCODE_HOME}, + {SDL_SCANCODE_KP_8, SDL_SCANCODE_UP}, + {SDL_SCANCODE_KP_9, SDL_SCANCODE_PAGEUP}, + {SDL_SCANCODE_KP_4, SDL_SCANCODE_LEFT}, + {SDL_SCANCODE_KP_6, SDL_SCANCODE_RIGHT}, + {SDL_SCANCODE_KP_1, SDL_SCANCODE_END}, + {SDL_SCANCODE_KP_2, SDL_SCANCODE_DOWN}, + {SDL_SCANCODE_KP_3, SDL_SCANCODE_PAGEDOWN}, + {SDL_SCANCODE_KP_0, SDL_SCANCODE_INSERT}, + {SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_DELETE}, + {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} +}; + +static void set_fullscreen(bool on, bool call_callback) { + if (fullscreen_state == on) { + return; + } + fullscreen_state = on; + + if (on) { + SDL_DisplayMode mode; + SDL_GetDesktopDisplayMode(0, &mode); + window_width = mode.w; + window_height = mode.h; + SDL_ShowCursor(false); + } else { + window_width = DESIRED_SCREEN_WIDTH; + window_height = DESIRED_SCREEN_HEIGHT; + } + SDL_SetWindowSize(wnd, window_width, window_height); + SDL_SetWindowFullscreen(wnd, on ? SDL_WINDOW_FULLSCREEN : 0); + SDL_SetCursor(SDL_DISABLE); + + if (on_fullscreen_changed_callback != NULL && call_callback) { + on_fullscreen_changed_callback(on); + } +} + +static uint64_t previous_time; +static HANDLE timer; + +static int frameDivisor = 1; + +#define FRAME_INTERVAL_US_NUMERATOR_ 50000 +#define FRAME_INTERVAL_US_DENOMINATOR 3 +#define FRAME_INTERVAL_US_NUMERATOR (FRAME_INTERVAL_US_NUMERATOR_ * frameDivisor) + +static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { + SDL_Init(SDL_INIT_VIDEO); + + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + timer = CreateWaitableTimer(nullptr, false, nullptr); + + //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); + + char title[512]; + int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME); + + wnd = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + + if (start_in_fullscreen) { + set_fullscreen(true, false); + } + + ctx = SDL_GL_CreateContext(wnd); + + SDL_GL_SetSwapInterval(1); + + SohImGui::WindowImpl window_impl; + window_impl.backend = SohImGui::Backend::SDL; + window_impl.sdl = { wnd, ctx }; + SohImGui::Init(window_impl); + + for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { + inverted_scancode_table[windows_scancode_table[i]] = i; + } + + for (size_t i = 0; i < sizeof(scancode_rmapping_extended) / sizeof(scancode_rmapping_extended[0]); i++) { + inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]] + 0x100; + } + + for (size_t i = 0; i < sizeof(scancode_rmapping_nonextended) / sizeof(scancode_rmapping_nonextended[0]); i++) { + inverted_scancode_table[scancode_rmapping_nonextended[i][0]] = inverted_scancode_table[scancode_rmapping_nonextended[i][1]]; + inverted_scancode_table[scancode_rmapping_nonextended[i][1]] += 0x100; + } +} + +static void gfx_sdl_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) { + on_fullscreen_changed_callback = on_fullscreen_changed; +} + +static void gfx_sdl_set_fullscreen(bool enable) { + set_fullscreen(enable, true); +} + +static void gfx_sdl_show_cursor(bool hide) { + SDL_ShowCursor(hide); +} + +static void gfx_sdl_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) { + on_key_down_callback = on_key_down; + on_key_up_callback = on_key_up; + on_all_keys_up_callback = on_all_keys_up; +} + +static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { + while (1) + { + run_one_game_iter(); + } +} + +static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { + *width = window_width; + *height = window_height; +} + +static int translate_scancode(int scancode) { + if (scancode < 512) { + return inverted_scancode_table[scancode]; + } else { + return 0; + } +} + +static void gfx_sdl_onkeydown(int scancode) { + int key = translate_scancode(scancode); + if (on_key_down_callback != NULL) { + on_key_down_callback(key); + } +} + +static void gfx_sdl_onkeyup(int scancode) { + int key = translate_scancode(scancode); + if (on_key_up_callback != NULL) { + on_key_up_callback(key); + } +} + +static void gfx_sdl_handle_events(void) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + SohImGui::EventImpl event_impl; + event_impl.sdl = { &event }; + SohImGui::Update(event_impl); + switch (event.type) { +#ifndef TARGET_WEB + // Scancodes are broken in Emscripten SDL2: https://bugzilla.libsdl.org/show_bug.cgi?id=3259 + case SDL_KEYDOWN: + gfx_sdl_onkeydown(event.key.keysym.scancode); + break; + case SDL_KEYUP: + gfx_sdl_onkeyup(event.key.keysym.scancode); + break; +#endif + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + window_width = event.window.data1; + window_height = event.window.data2; + } + break; + case SDL_QUIT: + exit(0); + } + } +} + +static bool gfx_sdl_start_frame(void) { + return true; +} + +static uint64_t qpc_to_100ns(uint64_t qpc) { + const uint64_t qpc_freq = SDL_GetPerformanceFrequency(); + return qpc / qpc_freq * 10000000 + qpc % qpc_freq * 10000000 / qpc_freq; +} + +static inline void sync_framerate_with_timer(void) { + uint64_t t; + t = SDL_GetPerformanceCounter(); + + const int64_t next = qpc_to_100ns(previous_time) + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; + const int64_t left = next - qpc_to_100ns(t); + if (left > 0) { +#ifdef __linux__ + const timespec spec = { 0, left * 100 }; + nanosleep(&spec, nullptr); +#else + LARGE_INTEGER li; + li.QuadPart = -left; + SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false); + WaitForSingleObject(timer, INFINITE); +#endif + } + + t = SDL_GetPerformanceCounter(); + previous_time = t; +} + +static void gfx_sdl_swap_buffers_begin(void) { + sync_framerate_with_timer(); + SDL_GL_SwapWindow(wnd); +} + +static void gfx_sdl_swap_buffers_end(void) { + +} + +static double gfx_sdl_get_time(void) { + return 0.0; +} + +static void gfx_sdl_set_framedivisor(int divisor) +{ + frameDivisor = divisor; +} + +struct GfxWindowManagerAPI gfx_sdl = { + gfx_sdl_init, + gfx_sdl_set_keyboard_callbacks, + gfx_sdl_set_fullscreen_changed_callback, + gfx_sdl_set_fullscreen, + gfx_sdl_show_cursor, + gfx_sdl_main_loop, + gfx_sdl_get_dimensions, + gfx_sdl_handle_events, + gfx_sdl_start_frame, + gfx_sdl_swap_buffers_begin, + gfx_sdl_swap_buffers_end, + gfx_sdl_get_time, + gfx_sdl_set_framedivisor +}; + +#endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h new file mode 100644 index 000000000..5d7442390 --- /dev/null +++ b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h @@ -0,0 +1,23 @@ +#ifndef GFX_WINDOW_MANAGER_API_H +#define GFX_WINDOW_MANAGER_API_H + +#include +#include + +struct GfxWindowManagerAPI { + void (*init)(const char *game_name, bool start_in_fullscreen); + void (*set_keyboard_callbacks)(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)); + void (*set_fullscreen_changed_callback)(void (*on_fullscreen_changed)(bool is_now_fullscreen)); + void (*set_fullscreen)(bool enable); + void (*show_cursor)(bool hide); + void (*main_loop)(void (*run_one_game_iter)(void)); + void (*get_dimensions)(uint32_t *width, uint32_t *height); + void (*handle_events)(void); + bool (*start_frame)(void); + void (*swap_buffers_begin)(void); + void (*swap_buffers_end)(void); + double (*get_time)(void); // For debug + void (*set_frame_divisor)(int); +}; + +#endif diff --git a/libultraship/libultraship/Lib/GLEW/GL/eglew.h b/libultraship/libultraship/Lib/GLEW/GL/eglew.h new file mode 100644 index 000000000..467014794 --- /dev/null +++ b/libultraship/libultraship/Lib/GLEW/GL/eglew.h @@ -0,0 +1,2618 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2017, Nigel Stewart +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + +/* +** Copyright (c) 2007 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. +*/ + +#ifndef __eglew_h__ +#define __eglew_h__ +#define __EGLEW_H__ + +#ifdef __eglext_h_ +#error eglext.h included before eglew.h +#endif + +#if defined(__egl_h_) +#error egl.h included before eglew.h +#endif + +#define __eglext_h_ + +#define __egl_h_ + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY +#endif +#ifndef EGLAPI +#define EGLAPI extern +#endif + +/* EGL Types */ +#include + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int32_t EGLint; + +typedef unsigned int EGLBoolean; +typedef void *EGLDisplay; +typedef void *EGLConfig; +typedef void *EGLSurface; +typedef void *EGLContext; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); + +typedef unsigned int EGLenum; +typedef void *EGLClientBuffer; + +typedef void *EGLSync; +typedef intptr_t EGLAttrib; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef void *EGLImage; + +typedef void *EGLSyncKHR; +typedef intptr_t EGLAttribKHR; +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +typedef void *EGLImageKHR; +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +typedef int EGLNativeFileDescriptorKHR; +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); +typedef void *EGLDeviceEXT; +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +typedef khronos_utime_nanoseconds_t EGLuint64NV; +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; + +struct EGLClientPixmapHI; + +#define EGL_DONT_CARE ((EGLint)-1) + +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_IMAGE ((EGLImage)0) +#define EGL_NO_SURFACE ((EGLSurface)0) +#define EGL_NO_SYNC ((EGLSync)0) + +#define EGL_UNKNOWN ((EGLint)-1) + +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) + +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); +/* ---------------------------- EGL_VERSION_1_0 ---------------------------- */ + +#ifndef EGL_VERSION_1_0 +#define EGL_VERSION_1_0 1 + +#define EGL_FALSE 0 +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_TRUE 1 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_WINDOW_BIT 0x0004 +#define EGL_SUCCESS 0x3000 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_NONE 0x3038 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_EXTENSIONS 0x3055 +#define EGL_HEIGHT 0x3056 +#define EGL_WIDTH 0x3057 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_DRAW 0x3059 +#define EGL_READ 0x305A +#define EGL_CORE_NATIVE_ENGINE 0x305B + +typedef EGLBoolean ( * PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config); +typedef EGLBoolean ( * PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext ( * PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean ( * PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean ( * PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value); +typedef EGLBoolean ( * PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config); +typedef EGLDisplay ( * PFNEGLGETCURRENTDISPLAYPROC) ( void ); +typedef EGLSurface ( * PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay ( * PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint ( * PFNEGLGETERRORPROC) ( void ); +typedef EGLBoolean ( * PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint * major, EGLint * minor); +typedef EGLBoolean ( * PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean ( * PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value); +typedef const char * ( * PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean ( * PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value); +typedef EGLBoolean ( * PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean ( * PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean ( * PFNEGLWAITGLPROC) ( void ); +typedef EGLBoolean ( * PFNEGLWAITNATIVEPROC) (EGLint engine); + +#define eglChooseConfig EGLEW_GET_FUN(__eglewChooseConfig) +#define eglCopyBuffers EGLEW_GET_FUN(__eglewCopyBuffers) +#define eglCreateContext EGLEW_GET_FUN(__eglewCreateContext) +#define eglCreatePbufferSurface EGLEW_GET_FUN(__eglewCreatePbufferSurface) +#define eglCreatePixmapSurface EGLEW_GET_FUN(__eglewCreatePixmapSurface) +#define eglCreateWindowSurface EGLEW_GET_FUN(__eglewCreateWindowSurface) +#define eglDestroyContext EGLEW_GET_FUN(__eglewDestroyContext) +#define eglDestroySurface EGLEW_GET_FUN(__eglewDestroySurface) +#define eglGetConfigAttrib EGLEW_GET_FUN(__eglewGetConfigAttrib) +#define eglGetConfigs EGLEW_GET_FUN(__eglewGetConfigs) +#define eglGetCurrentDisplay EGLEW_GET_FUN(__eglewGetCurrentDisplay) +#define eglGetCurrentSurface EGLEW_GET_FUN(__eglewGetCurrentSurface) +#define eglGetDisplay EGLEW_GET_FUN(__eglewGetDisplay) +#define eglGetError EGLEW_GET_FUN(__eglewGetError) +#define eglInitialize EGLEW_GET_FUN(__eglewInitialize) +#define eglMakeCurrent EGLEW_GET_FUN(__eglewMakeCurrent) +#define eglQueryContext EGLEW_GET_FUN(__eglewQueryContext) +#define eglQueryString EGLEW_GET_FUN(__eglewQueryString) +#define eglQuerySurface EGLEW_GET_FUN(__eglewQuerySurface) +#define eglSwapBuffers EGLEW_GET_FUN(__eglewSwapBuffers) +#define eglTerminate EGLEW_GET_FUN(__eglewTerminate) +#define eglWaitGL EGLEW_GET_FUN(__eglewWaitGL) +#define eglWaitNative EGLEW_GET_FUN(__eglewWaitNative) + +#define EGLEW_VERSION_1_0 EGLEW_GET_VAR(__EGLEW_VERSION_1_0) + +#endif /* EGL_VERSION_1_0 */ + +/* ---------------------------- EGL_VERSION_1_1 ---------------------------- */ + +#ifndef EGL_VERSION_1_1 +#define EGL_VERSION_1_1 1 + +#define EGL_CONTEXT_LOST 0x300E +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_TARGET 0x3081 +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_BACK_BUFFER 0x3084 + +typedef EGLBoolean ( * PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean ( * PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean ( * PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean ( * PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); + +#define eglBindTexImage EGLEW_GET_FUN(__eglewBindTexImage) +#define eglReleaseTexImage EGLEW_GET_FUN(__eglewReleaseTexImage) +#define eglSurfaceAttrib EGLEW_GET_FUN(__eglewSurfaceAttrib) +#define eglSwapInterval EGLEW_GET_FUN(__eglewSwapInterval) + +#define EGLEW_VERSION_1_1 EGLEW_GET_VAR(__EGLEW_VERSION_1_1) + +#endif /* EGL_VERSION_1_1 */ + +/* ---------------------------- EGL_VERSION_1_2 ---------------------------- */ + +#ifndef EGL_VERSION_1_2 +#define EGL_VERSION_1_2 1 + +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_COLORSPACE 0x3087 +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_CLIENT_APIS 0x308D +#define EGL_RGB_BUFFER 0x308E +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_VERTICAL_RESOLUTION 0x3091 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_DISPLAY_SCALING 10000 + +typedef EGLBoolean ( * PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLSurface ( * PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list); +typedef EGLenum ( * PFNEGLQUERYAPIPROC) ( void ); +typedef EGLBoolean ( * PFNEGLRELEASETHREADPROC) ( void ); +typedef EGLBoolean ( * PFNEGLWAITCLIENTPROC) ( void ); + +#define eglBindAPI EGLEW_GET_FUN(__eglewBindAPI) +#define eglCreatePbufferFromClientBuffer EGLEW_GET_FUN(__eglewCreatePbufferFromClientBuffer) +#define eglQueryAPI EGLEW_GET_FUN(__eglewQueryAPI) +#define eglReleaseThread EGLEW_GET_FUN(__eglewReleaseThread) +#define eglWaitClient EGLEW_GET_FUN(__eglewWaitClient) + +#define EGLEW_VERSION_1_2 EGLEW_GET_VAR(__EGLEW_VERSION_1_2) + +#endif /* EGL_VERSION_1_2 */ + +/* ---------------------------- EGL_VERSION_1_3 ---------------------------- */ + +#ifndef EGL_VERSION_1_3 +#define EGL_VERSION_1_3 1 + +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_CONFORMANT 0x3042 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 + +#define EGLEW_VERSION_1_3 EGLEW_GET_VAR(__EGLEW_VERSION_1_3) + +#endif /* EGL_VERSION_1_3 */ + +/* ---------------------------- EGL_VERSION_1_4 ---------------------------- */ + +#ifndef EGL_VERSION_1_4 +#define EGL_VERSION_1_4 1 + +#define EGL_OPENGL_BIT 0x0008 +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_OPENGL_API 0x30A2 + +typedef EGLContext ( * PFNEGLGETCURRENTCONTEXTPROC) ( void ); + +#define eglGetCurrentContext EGLEW_GET_FUN(__eglewGetCurrentContext) + +#define EGLEW_VERSION_1_4 EGLEW_GET_VAR(__EGLEW_VERSION_1_4) + +#endif /* EGL_VERSION_1_4 */ + +/* ---------------------------- EGL_VERSION_1_5 ---------------------------- */ + +#ifndef EGL_VERSION_1_5 +#define EGL_VERSION_1_5 1 + +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SIGNALED 0x30F2 +#define EGL_UNSIGNALED 0x30F3 +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF + +typedef EGLint ( * PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLImage ( * PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); +typedef EGLSync ( * PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLBoolean ( * PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void * native_display, const EGLAttrib * attrib_list); +typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); +typedef EGLBoolean ( * PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); + +#define eglClientWaitSync EGLEW_GET_FUN(__eglewClientWaitSync) +#define eglCreateImage EGLEW_GET_FUN(__eglewCreateImage) +#define eglCreatePlatformPixmapSurface EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurface) +#define eglCreatePlatformWindowSurface EGLEW_GET_FUN(__eglewCreatePlatformWindowSurface) +#define eglCreateSync EGLEW_GET_FUN(__eglewCreateSync) +#define eglDestroyImage EGLEW_GET_FUN(__eglewDestroyImage) +#define eglDestroySync EGLEW_GET_FUN(__eglewDestroySync) +#define eglGetPlatformDisplay EGLEW_GET_FUN(__eglewGetPlatformDisplay) +#define eglGetSyncAttrib EGLEW_GET_FUN(__eglewGetSyncAttrib) +#define eglWaitSync EGLEW_GET_FUN(__eglewWaitSync) + +#define EGLEW_VERSION_1_5 EGLEW_GET_VAR(__EGLEW_VERSION_1_5) + +#endif /* EGL_VERSION_1_5 */ + +/* ------------------------- EGL_ANDROID_blob_cache ------------------------ */ + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 + +typedef void ( * PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); + +#define eglSetBlobCacheFuncsANDROID EGLEW_GET_FUN(__eglewSetBlobCacheFuncsANDROID) + +#define EGLEW_ANDROID_blob_cache EGLEW_GET_VAR(__EGLEW_ANDROID_blob_cache) + +#endif /* EGL_ANDROID_blob_cache */ + +/* ---------------- EGL_ANDROID_create_native_client_buffer ---------------- */ + +#ifndef EGL_ANDROID_create_native_client_buffer +#define EGL_ANDROID_create_native_client_buffer 1 + +#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 +#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 +#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 +#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 + +typedef EGLClientBuffer ( * PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint * attrib_list); + +#define eglCreateNativeClientBufferANDROID EGLEW_GET_FUN(__eglewCreateNativeClientBufferANDROID) + +#define EGLEW_ANDROID_create_native_client_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_create_native_client_buffer) + +#endif /* EGL_ANDROID_create_native_client_buffer */ + +/* --------------------- EGL_ANDROID_framebuffer_target -------------------- */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 + +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 + +#define EGLEW_ANDROID_framebuffer_target EGLEW_GET_VAR(__EGLEW_ANDROID_framebuffer_target) + +#endif /* EGL_ANDROID_framebuffer_target */ + +/* ----------------- EGL_ANDROID_front_buffer_auto_refresh ----------------- */ + +#ifndef EGL_ANDROID_front_buffer_auto_refresh +#define EGL_ANDROID_front_buffer_auto_refresh 1 + +#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C + +#define EGLEW_ANDROID_front_buffer_auto_refresh EGLEW_GET_VAR(__EGLEW_ANDROID_front_buffer_auto_refresh) + +#endif /* EGL_ANDROID_front_buffer_auto_refresh */ + +/* -------------------- EGL_ANDROID_image_native_buffer -------------------- */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 + +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 + +#define EGLEW_ANDROID_image_native_buffer EGLEW_GET_VAR(__EGLEW_ANDROID_image_native_buffer) + +#endif /* EGL_ANDROID_image_native_buffer */ + +/* --------------------- EGL_ANDROID_native_fence_sync --------------------- */ + +#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 + +typedef EGLint ( * PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); + +#define eglDupNativeFenceFDANDROID EGLEW_GET_FUN(__eglewDupNativeFenceFDANDROID) + +#define EGLEW_ANDROID_native_fence_sync EGLEW_GET_VAR(__EGLEW_ANDROID_native_fence_sync) + +#endif /* EGL_ANDROID_native_fence_sync */ + +/* --------------------- EGL_ANDROID_presentation_time --------------------- */ + +#ifndef EGL_ANDROID_presentation_time +#define EGL_ANDROID_presentation_time 1 + +typedef EGLBoolean ( * PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); + +#define eglPresentationTimeANDROID EGLEW_GET_FUN(__eglewPresentationTimeANDROID) + +#define EGLEW_ANDROID_presentation_time EGLEW_GET_VAR(__EGLEW_ANDROID_presentation_time) + +#endif /* EGL_ANDROID_presentation_time */ + +/* ------------------------- EGL_ANDROID_recordable ------------------------ */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 + +#define EGL_RECORDABLE_ANDROID 0x3142 + +#define EGLEW_ANDROID_recordable EGLEW_GET_VAR(__EGLEW_ANDROID_recordable) + +#endif /* EGL_ANDROID_recordable */ + +/* ---------------- EGL_ANGLE_d3d_share_handle_client_buffer --------------- */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 + +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 + +#define EGLEW_ANGLE_d3d_share_handle_client_buffer EGLEW_GET_VAR(__EGLEW_ANGLE_d3d_share_handle_client_buffer) + +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +/* -------------------------- EGL_ANGLE_device_d3d ------------------------- */ + +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 + +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 + +#define EGLEW_ANGLE_device_d3d EGLEW_GET_VAR(__EGLEW_ANGLE_device_d3d) + +#endif /* EGL_ANGLE_device_d3d */ + +/* -------------------- EGL_ANGLE_query_surface_pointer -------------------- */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 + +typedef EGLBoolean ( * PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void ** value); + +#define eglQuerySurfacePointerANGLE EGLEW_GET_FUN(__eglewQuerySurfacePointerANGLE) + +#define EGLEW_ANGLE_query_surface_pointer EGLEW_GET_VAR(__EGLEW_ANGLE_query_surface_pointer) + +#endif /* EGL_ANGLE_query_surface_pointer */ + +/* ------------- EGL_ANGLE_surface_d3d_texture_2d_share_handle ------------- */ + +#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 + +#define EGLEW_ANGLE_surface_d3d_texture_2d_share_handle EGLEW_GET_VAR(__EGLEW_ANGLE_surface_d3d_texture_2d_share_handle) + +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +/* ---------------------- EGL_ANGLE_window_fixed_size ---------------------- */ + +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 + +#define EGL_FIXED_SIZE_ANGLE 0x3201 + +#define EGLEW_ANGLE_window_fixed_size EGLEW_GET_VAR(__EGLEW_ANGLE_window_fixed_size) + +#endif /* EGL_ANGLE_window_fixed_size */ + +/* --------------------- EGL_ARM_implicit_external_sync -------------------- */ + +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 + +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A + +#define EGLEW_ARM_implicit_external_sync EGLEW_GET_VAR(__EGLEW_ARM_implicit_external_sync) + +#endif /* EGL_ARM_implicit_external_sync */ + +/* ------------------- EGL_ARM_pixmap_multisample_discard ------------------ */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 + +#define EGL_DISCARD_SAMPLES_ARM 0x3286 + +#define EGLEW_ARM_pixmap_multisample_discard EGLEW_GET_VAR(__EGLEW_ARM_pixmap_multisample_discard) + +#endif /* EGL_ARM_pixmap_multisample_discard */ + +/* --------------------------- EGL_EXT_buffer_age -------------------------- */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 + +#define EGL_BUFFER_AGE_EXT 0x313D + +#define EGLEW_EXT_buffer_age EGLEW_GET_VAR(__EGLEW_EXT_buffer_age) + +#endif /* EGL_EXT_buffer_age */ + +/* ----------------------- EGL_EXT_client_extensions ----------------------- */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 + +#define EGLEW_EXT_client_extensions EGLEW_GET_VAR(__EGLEW_EXT_client_extensions) + +#endif /* EGL_EXT_client_extensions */ + +/* ------------------- EGL_EXT_create_context_robustness ------------------- */ + +#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 + +#define EGLEW_EXT_create_context_robustness EGLEW_GET_VAR(__EGLEW_EXT_create_context_robustness) + +#endif /* EGL_EXT_create_context_robustness */ + +/* -------------------------- EGL_EXT_device_base -------------------------- */ + +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 + +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C + +#define EGLEW_EXT_device_base EGLEW_GET_VAR(__EGLEW_EXT_device_base) + +#endif /* EGL_EXT_device_base */ + +/* --------------------------- EGL_EXT_device_drm -------------------------- */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 + +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 + +#define EGLEW_EXT_device_drm EGLEW_GET_VAR(__EGLEW_EXT_device_drm) + +#endif /* EGL_EXT_device_drm */ + +/* ----------------------- EGL_EXT_device_enumeration ---------------------- */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 + +typedef EGLBoolean ( * PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT * devices, EGLint * num_devices); + +#define eglQueryDevicesEXT EGLEW_GET_FUN(__eglewQueryDevicesEXT) + +#define EGLEW_EXT_device_enumeration EGLEW_GET_VAR(__EGLEW_EXT_device_enumeration) + +#endif /* EGL_EXT_device_enumeration */ + +/* ------------------------- EGL_EXT_device_openwf ------------------------- */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 + +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 + +#define EGLEW_EXT_device_openwf EGLEW_GET_VAR(__EGLEW_EXT_device_openwf) + +#endif /* EGL_EXT_device_openwf */ + +/* -------------------------- EGL_EXT_device_query ------------------------- */ + +#ifndef EGL_EXT_device_query +#define EGL_EXT_device_query 1 + +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C + +typedef EGLBoolean ( * PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib * value); +typedef const char * ( * PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib * value); + +#define eglQueryDeviceAttribEXT EGLEW_GET_FUN(__eglewQueryDeviceAttribEXT) +#define eglQueryDeviceStringEXT EGLEW_GET_FUN(__eglewQueryDeviceStringEXT) +#define eglQueryDisplayAttribEXT EGLEW_GET_FUN(__eglewQueryDisplayAttribEXT) + +#define EGLEW_EXT_device_query EGLEW_GET_VAR(__EGLEW_EXT_device_query) + +#endif /* EGL_EXT_device_query */ + +/* ------------------ EGL_EXT_gl_colorspace_bt2020_linear ------------------ */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_linear +#define EGL_EXT_gl_colorspace_bt2020_linear 1 + +#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F + +#define EGLEW_EXT_gl_colorspace_bt2020_linear EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_bt2020_linear) + +#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ + +/* -------------------- EGL_EXT_gl_colorspace_bt2020_pq -------------------- */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_pq +#define EGL_EXT_gl_colorspace_bt2020_pq 1 + +#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 + +#define EGLEW_EXT_gl_colorspace_bt2020_pq EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_bt2020_pq) + +#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ + +/* ------------------- EGL_EXT_gl_colorspace_scrgb_linear ------------------ */ + +#ifndef EGL_EXT_gl_colorspace_scrgb_linear +#define EGL_EXT_gl_colorspace_scrgb_linear 1 + +#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 + +#define EGLEW_EXT_gl_colorspace_scrgb_linear EGLEW_GET_VAR(__EGLEW_EXT_gl_colorspace_scrgb_linear) + +#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ + +/* ---------------------- EGL_EXT_image_dma_buf_import --------------------- */ + +#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 + +#define EGLEW_EXT_image_dma_buf_import EGLEW_GET_VAR(__EGLEW_EXT_image_dma_buf_import) + +#endif /* EGL_EXT_image_dma_buf_import */ + +/* ----------------- EGL_EXT_image_dma_buf_import_modifiers ---------------- */ + +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 + +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A + +typedef EGLBoolean ( * PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +typedef EGLBoolean ( * PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); + +#define eglQueryDmaBufFormatsEXT EGLEW_GET_FUN(__eglewQueryDmaBufFormatsEXT) +#define eglQueryDmaBufModifiersEXT EGLEW_GET_FUN(__eglewQueryDmaBufModifiersEXT) + +#define EGLEW_EXT_image_dma_buf_import_modifiers EGLEW_GET_VAR(__EGLEW_EXT_image_dma_buf_import_modifiers) + +#endif /* EGL_EXT_image_dma_buf_import_modifiers */ + +/* ------------------------ EGL_EXT_multiview_window ----------------------- */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 + +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 + +#define EGLEW_EXT_multiview_window EGLEW_GET_VAR(__EGLEW_EXT_multiview_window) + +#endif /* EGL_EXT_multiview_window */ + +/* -------------------------- EGL_EXT_output_base -------------------------- */ + +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 + +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F + +typedef EGLBoolean ( * PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib * attrib_list, EGLOutputLayerEXT * layers, EGLint max_layers, EGLint * num_layers); +typedef EGLBoolean ( * PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib * attrib_list, EGLOutputPortEXT * ports, EGLint max_ports, EGLint * num_ports); +typedef EGLBoolean ( * PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean ( * PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean ( * PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib * value); +typedef const char * ( * PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean ( * PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib * value); +typedef const char * ( * PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); + +#define eglGetOutputLayersEXT EGLEW_GET_FUN(__eglewGetOutputLayersEXT) +#define eglGetOutputPortsEXT EGLEW_GET_FUN(__eglewGetOutputPortsEXT) +#define eglOutputLayerAttribEXT EGLEW_GET_FUN(__eglewOutputLayerAttribEXT) +#define eglOutputPortAttribEXT EGLEW_GET_FUN(__eglewOutputPortAttribEXT) +#define eglQueryOutputLayerAttribEXT EGLEW_GET_FUN(__eglewQueryOutputLayerAttribEXT) +#define eglQueryOutputLayerStringEXT EGLEW_GET_FUN(__eglewQueryOutputLayerStringEXT) +#define eglQueryOutputPortAttribEXT EGLEW_GET_FUN(__eglewQueryOutputPortAttribEXT) +#define eglQueryOutputPortStringEXT EGLEW_GET_FUN(__eglewQueryOutputPortStringEXT) + +#define EGLEW_EXT_output_base EGLEW_GET_VAR(__EGLEW_EXT_output_base) + +#endif /* EGL_EXT_output_base */ + +/* --------------------------- EGL_EXT_output_drm -------------------------- */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 + +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 + +#define EGLEW_EXT_output_drm EGLEW_GET_VAR(__EGLEW_EXT_output_drm) + +#endif /* EGL_EXT_output_drm */ + +/* ------------------------- EGL_EXT_output_openwf ------------------------- */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 + +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 + +#define EGLEW_EXT_output_openwf EGLEW_GET_VAR(__EGLEW_EXT_output_openwf) + +#endif /* EGL_EXT_output_openwf */ + +/* ----------------------- EGL_EXT_pixel_format_float ---------------------- */ + +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float 1 + +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B + +#define EGLEW_EXT_pixel_format_float EGLEW_GET_VAR(__EGLEW_EXT_pixel_format_float) + +#endif /* EGL_EXT_pixel_format_float */ + +/* ------------------------- EGL_EXT_platform_base ------------------------- */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 + +typedef EGLSurface ( * PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list); +typedef EGLSurface ( * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list); +typedef EGLDisplay ( * PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void * native_display, const EGLint * attrib_list); + +#define eglCreatePlatformPixmapSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformPixmapSurfaceEXT) +#define eglCreatePlatformWindowSurfaceEXT EGLEW_GET_FUN(__eglewCreatePlatformWindowSurfaceEXT) +#define eglGetPlatformDisplayEXT EGLEW_GET_FUN(__eglewGetPlatformDisplayEXT) + +#define EGLEW_EXT_platform_base EGLEW_GET_VAR(__EGLEW_EXT_platform_base) + +#endif /* EGL_EXT_platform_base */ + +/* ------------------------ EGL_EXT_platform_device ------------------------ */ + +#ifndef EGL_EXT_platform_device +#define EGL_EXT_platform_device 1 + +#define EGL_PLATFORM_DEVICE_EXT 0x313F + +#define EGLEW_EXT_platform_device EGLEW_GET_VAR(__EGLEW_EXT_platform_device) + +#endif /* EGL_EXT_platform_device */ + +/* ------------------------ EGL_EXT_platform_wayland ----------------------- */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 + +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 + +#define EGLEW_EXT_platform_wayland EGLEW_GET_VAR(__EGLEW_EXT_platform_wayland) + +#endif /* EGL_EXT_platform_wayland */ + +/* -------------------------- EGL_EXT_platform_x11 ------------------------- */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 + +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 + +#define EGLEW_EXT_platform_x11 EGLEW_GET_VAR(__EGLEW_EXT_platform_x11) + +#endif /* EGL_EXT_platform_x11 */ + +/* ----------------------- EGL_EXT_protected_content ----------------------- */ + +#ifndef EGL_EXT_protected_content +#define EGL_EXT_protected_content 1 + +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 + +#define EGLEW_EXT_protected_content EGLEW_GET_VAR(__EGLEW_EXT_protected_content) + +#endif /* EGL_EXT_protected_content */ + +/* ----------------------- EGL_EXT_protected_surface ----------------------- */ + +#ifndef EGL_EXT_protected_surface +#define EGL_EXT_protected_surface 1 + +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 + +#define EGLEW_EXT_protected_surface EGLEW_GET_VAR(__EGLEW_EXT_protected_surface) + +#endif /* EGL_EXT_protected_surface */ + +/* ------------------- EGL_EXT_stream_consumer_egloutput ------------------- */ + +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 + +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); + +#define eglStreamConsumerOutputEXT EGLEW_GET_FUN(__eglewStreamConsumerOutputEXT) + +#define EGLEW_EXT_stream_consumer_egloutput EGLEW_GET_VAR(__EGLEW_EXT_stream_consumer_egloutput) + +#endif /* EGL_EXT_stream_consumer_egloutput */ + +/* ------------------- EGL_EXT_surface_SMPTE2086_metadata ------------------ */ + +#ifndef EGL_EXT_surface_SMPTE2086_metadata +#define EGL_EXT_surface_SMPTE2086_metadata 1 + +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 +#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 +#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 +#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 +#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A + +#define EGLEW_EXT_surface_SMPTE2086_metadata EGLEW_GET_VAR(__EGLEW_EXT_surface_SMPTE2086_metadata) + +#endif /* EGL_EXT_surface_SMPTE2086_metadata */ + +/* -------------------- EGL_EXT_swap_buffers_with_damage ------------------- */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 + +typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects); + +#define eglSwapBuffersWithDamageEXT EGLEW_GET_FUN(__eglewSwapBuffersWithDamageEXT) + +#define EGLEW_EXT_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_EXT_swap_buffers_with_damage) + +#endif /* EGL_EXT_swap_buffers_with_damage */ + +/* -------------------------- EGL_EXT_yuv_surface -------------------------- */ + +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 + +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D + +#define EGLEW_EXT_yuv_surface EGLEW_GET_VAR(__EGLEW_EXT_yuv_surface) + +#endif /* EGL_EXT_yuv_surface */ + +/* -------------------------- EGL_HI_clientpixmap -------------------------- */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 + +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 + +typedef EGLSurface ( * PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI * pixmap); + +#define eglCreatePixmapSurfaceHI EGLEW_GET_FUN(__eglewCreatePixmapSurfaceHI) + +#define EGLEW_HI_clientpixmap EGLEW_GET_VAR(__EGLEW_HI_clientpixmap) + +#endif /* EGL_HI_clientpixmap */ + +/* -------------------------- EGL_HI_colorformats -------------------------- */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 + +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 + +#define EGLEW_HI_colorformats EGLEW_GET_VAR(__EGLEW_HI_colorformats) + +#endif /* EGL_HI_colorformats */ + +/* ------------------------ EGL_IMG_context_priority ----------------------- */ + +#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 + +#define EGLEW_IMG_context_priority EGLEW_GET_VAR(__EGLEW_IMG_context_priority) + +#endif /* EGL_IMG_context_priority */ + +/* ---------------------- EGL_IMG_image_plane_attribs ---------------------- */ + +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 + +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 + +#define EGLEW_IMG_image_plane_attribs EGLEW_GET_VAR(__EGLEW_IMG_image_plane_attribs) + +#endif /* EGL_IMG_image_plane_attribs */ + +/* ---------------------------- EGL_KHR_cl_event --------------------------- */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 + +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF + +#define EGLEW_KHR_cl_event EGLEW_GET_VAR(__EGLEW_KHR_cl_event) + +#endif /* EGL_KHR_cl_event */ + +/* --------------------------- EGL_KHR_cl_event2 --------------------------- */ + +#ifndef EGL_KHR_cl_event2 +#define EGL_KHR_cl_event2 1 + +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF + +typedef EGLSyncKHR ( * PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR * attrib_list); + +#define eglCreateSync64KHR EGLEW_GET_FUN(__eglewCreateSync64KHR) + +#define EGLEW_KHR_cl_event2 EGLEW_GET_VAR(__EGLEW_KHR_cl_event2) + +#endif /* EGL_KHR_cl_event2 */ + +/* ----------------- EGL_KHR_client_get_all_proc_addresses ----------------- */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 + +#define EGLEW_KHR_client_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_client_get_all_proc_addresses) + +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +/* ------------------------- EGL_KHR_config_attribs ------------------------ */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 + +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#define EGL_CONFORMANT_KHR 0x3042 + +#define EGLEW_KHR_config_attribs EGLEW_GET_VAR(__EGLEW_KHR_config_attribs) + +#endif /* EGL_KHR_config_attribs */ + +/* --------------------- EGL_KHR_context_flush_control --------------------- */ + +#ifndef EGL_KHR_context_flush_control +#define EGL_KHR_context_flush_control 1 + +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 + +#define EGLEW_KHR_context_flush_control EGLEW_GET_VAR(__EGLEW_KHR_context_flush_control) + +#endif /* EGL_KHR_context_flush_control */ + +/* ------------------------- EGL_KHR_create_context ------------------------ */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 + +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#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 EGLEW_KHR_create_context EGLEW_GET_VAR(__EGLEW_KHR_create_context) + +#endif /* EGL_KHR_create_context */ + +/* -------------------- EGL_KHR_create_context_no_error -------------------- */ + +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 + +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 + +#define EGLEW_KHR_create_context_no_error EGLEW_GET_VAR(__EGLEW_KHR_create_context_no_error) + +#endif /* EGL_KHR_create_context_no_error */ + +/* ----------------------------- EGL_KHR_debug ----------------------------- */ + +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 + +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC + +typedef EGLint ( * PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib * attrib_list); +typedef EGLint ( * PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +typedef EGLBoolean ( * PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib * value); + +#define eglDebugMessageControlKHR EGLEW_GET_FUN(__eglewDebugMessageControlKHR) +#define eglLabelObjectKHR EGLEW_GET_FUN(__eglewLabelObjectKHR) +#define eglQueryDebugKHR EGLEW_GET_FUN(__eglewQueryDebugKHR) + +#define EGLEW_KHR_debug EGLEW_GET_VAR(__EGLEW_KHR_debug) + +#endif /* EGL_KHR_debug */ + +/* --------------------------- EGL_KHR_fence_sync -------------------------- */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 + +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 + +#define EGLEW_KHR_fence_sync EGLEW_GET_VAR(__EGLEW_KHR_fence_sync) + +#endif /* EGL_KHR_fence_sync */ + +/* --------------------- EGL_KHR_get_all_proc_addresses -------------------- */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 + +#define EGLEW_KHR_get_all_proc_addresses EGLEW_GET_VAR(__EGLEW_KHR_get_all_proc_addresses) + +#endif /* EGL_KHR_get_all_proc_addresses */ + +/* ------------------------- EGL_KHR_gl_colorspace ------------------------- */ + +#ifndef EGL_KHR_gl_colorspace +#define EGL_KHR_gl_colorspace 1 + +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#define EGL_GL_COLORSPACE_KHR 0x309D + +#define EGLEW_KHR_gl_colorspace EGLEW_GET_VAR(__EGLEW_KHR_gl_colorspace) + +#endif /* EGL_KHR_gl_colorspace */ + +/* --------------------- EGL_KHR_gl_renderbuffer_image --------------------- */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 + +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 + +#define EGLEW_KHR_gl_renderbuffer_image EGLEW_GET_VAR(__EGLEW_KHR_gl_renderbuffer_image) + +#endif /* EGL_KHR_gl_renderbuffer_image */ + +/* ---------------------- EGL_KHR_gl_texture_2D_image ---------------------- */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 + +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC + +#define EGLEW_KHR_gl_texture_2D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_2D_image) + +#endif /* EGL_KHR_gl_texture_2D_image */ + +/* ---------------------- EGL_KHR_gl_texture_3D_image ---------------------- */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 + +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD + +#define EGLEW_KHR_gl_texture_3D_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_3D_image) + +#endif /* EGL_KHR_gl_texture_3D_image */ + +/* -------------------- EGL_KHR_gl_texture_cubemap_image ------------------- */ + +#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 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 + +#define EGLEW_KHR_gl_texture_cubemap_image EGLEW_GET_VAR(__EGLEW_KHR_gl_texture_cubemap_image) + +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +/* ----------------------------- EGL_KHR_image ----------------------------- */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 + +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 + +typedef EGLImageKHR ( * PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); + +#define eglCreateImageKHR EGLEW_GET_FUN(__eglewCreateImageKHR) +#define eglDestroyImageKHR EGLEW_GET_FUN(__eglewDestroyImageKHR) + +#define EGLEW_KHR_image EGLEW_GET_VAR(__EGLEW_KHR_image) + +#endif /* EGL_KHR_image */ + +/* --------------------------- EGL_KHR_image_base -------------------------- */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 + +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 + +#define EGLEW_KHR_image_base EGLEW_GET_VAR(__EGLEW_KHR_image_base) + +#endif /* EGL_KHR_image_base */ + +/* -------------------------- EGL_KHR_image_pixmap ------------------------- */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 + +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 + +#define EGLEW_KHR_image_pixmap EGLEW_GET_VAR(__EGLEW_KHR_image_pixmap) + +#endif /* EGL_KHR_image_pixmap */ + +/* -------------------------- EGL_KHR_lock_surface ------------------------- */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 + +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF + +typedef EGLBoolean ( * PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); + +#define eglLockSurfaceKHR EGLEW_GET_FUN(__eglewLockSurfaceKHR) +#define eglUnlockSurfaceKHR EGLEW_GET_FUN(__eglewUnlockSurfaceKHR) + +#define EGLEW_KHR_lock_surface EGLEW_GET_VAR(__EGLEW_KHR_lock_surface) + +#endif /* EGL_KHR_lock_surface */ + +/* ------------------------- EGL_KHR_lock_surface2 ------------------------- */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 + +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 + +#define EGLEW_KHR_lock_surface2 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface2) + +#endif /* EGL_KHR_lock_surface2 */ + +/* ------------------------- EGL_KHR_lock_surface3 ------------------------- */ + +#ifndef EGL_KHR_lock_surface3 +#define EGL_KHR_lock_surface3 1 + +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 + +typedef EGLBoolean ( * PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR * value); + +#define eglQuerySurface64KHR EGLEW_GET_FUN(__eglewQuerySurface64KHR) + +#define EGLEW_KHR_lock_surface3 EGLEW_GET_VAR(__EGLEW_KHR_lock_surface3) + +#endif /* EGL_KHR_lock_surface3 */ + +/* --------------------- EGL_KHR_mutable_render_buffer --------------------- */ + +#ifndef EGL_KHR_mutable_render_buffer +#define EGL_KHR_mutable_render_buffer 1 + +#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 + +#define EGLEW_KHR_mutable_render_buffer EGLEW_GET_VAR(__EGLEW_KHR_mutable_render_buffer) + +#endif /* EGL_KHR_mutable_render_buffer */ + +/* ----------------------- EGL_KHR_no_config_context ----------------------- */ + +#ifndef EGL_KHR_no_config_context +#define EGL_KHR_no_config_context 1 + +#define EGLEW_KHR_no_config_context EGLEW_GET_VAR(__EGLEW_KHR_no_config_context) + +#endif /* EGL_KHR_no_config_context */ + +/* ------------------------- EGL_KHR_partial_update ------------------------ */ + +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 + +#define EGL_BUFFER_AGE_KHR 0x313D + +typedef EGLBoolean ( * PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects); + +#define eglSetDamageRegionKHR EGLEW_GET_FUN(__eglewSetDamageRegionKHR) + +#define EGLEW_KHR_partial_update EGLEW_GET_VAR(__EGLEW_KHR_partial_update) + +#endif /* EGL_KHR_partial_update */ + +/* ------------------------ EGL_KHR_platform_android ----------------------- */ + +#ifndef EGL_KHR_platform_android +#define EGL_KHR_platform_android 1 + +#define EGL_PLATFORM_ANDROID_KHR 0x3141 + +#define EGLEW_KHR_platform_android EGLEW_GET_VAR(__EGLEW_KHR_platform_android) + +#endif /* EGL_KHR_platform_android */ + +/* -------------------------- EGL_KHR_platform_gbm ------------------------- */ + +#ifndef EGL_KHR_platform_gbm +#define EGL_KHR_platform_gbm 1 + +#define EGL_PLATFORM_GBM_KHR 0x31D7 + +#define EGLEW_KHR_platform_gbm EGLEW_GET_VAR(__EGLEW_KHR_platform_gbm) + +#endif /* EGL_KHR_platform_gbm */ + +/* ------------------------ EGL_KHR_platform_wayland ----------------------- */ + +#ifndef EGL_KHR_platform_wayland +#define EGL_KHR_platform_wayland 1 + +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 + +#define EGLEW_KHR_platform_wayland EGLEW_GET_VAR(__EGLEW_KHR_platform_wayland) + +#endif /* EGL_KHR_platform_wayland */ + +/* -------------------------- EGL_KHR_platform_x11 ------------------------- */ + +#ifndef EGL_KHR_platform_x11 +#define EGL_KHR_platform_x11 1 + +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 + +#define EGLEW_KHR_platform_x11 EGLEW_GET_VAR(__EGLEW_KHR_platform_x11) + +#endif /* EGL_KHR_platform_x11 */ + +/* ------------------------- EGL_KHR_reusable_sync ------------------------- */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 + +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#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_FOREVER_KHR 0xFFFFFFFFFFFFFFFF + +typedef EGLint ( * PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLSyncKHR ( * PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint * value); +typedef EGLBoolean ( * PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); + +#define eglClientWaitSyncKHR EGLEW_GET_FUN(__eglewClientWaitSyncKHR) +#define eglCreateSyncKHR EGLEW_GET_FUN(__eglewCreateSyncKHR) +#define eglDestroySyncKHR EGLEW_GET_FUN(__eglewDestroySyncKHR) +#define eglGetSyncAttribKHR EGLEW_GET_FUN(__eglewGetSyncAttribKHR) +#define eglSignalSyncKHR EGLEW_GET_FUN(__eglewSignalSyncKHR) + +#define EGLEW_KHR_reusable_sync EGLEW_GET_VAR(__EGLEW_KHR_reusable_sync) + +#endif /* EGL_KHR_reusable_sync */ + +/* ----------------------------- EGL_KHR_stream ---------------------------- */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 + +#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 + +typedef EGLStreamKHR ( * PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean ( * PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint * value); +typedef EGLBoolean ( * PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR * value); +typedef EGLBoolean ( * PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); + +#define eglCreateStreamKHR EGLEW_GET_FUN(__eglewCreateStreamKHR) +#define eglDestroyStreamKHR EGLEW_GET_FUN(__eglewDestroyStreamKHR) +#define eglQueryStreamKHR EGLEW_GET_FUN(__eglewQueryStreamKHR) +#define eglQueryStreamu64KHR EGLEW_GET_FUN(__eglewQueryStreamu64KHR) +#define eglStreamAttribKHR EGLEW_GET_FUN(__eglewStreamAttribKHR) + +#define EGLEW_KHR_stream EGLEW_GET_VAR(__EGLEW_KHR_stream) + +#endif /* EGL_KHR_stream */ + +/* ------------------------- EGL_KHR_stream_attrib ------------------------- */ + +#ifndef EGL_KHR_stream_attrib +#define EGL_KHR_stream_attrib 1 + +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 + +typedef EGLStreamKHR ( * PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib * attrib_list); +typedef EGLBoolean ( * PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib * value); +typedef EGLBoolean ( * PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib * attrib_list); +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib * attrib_list); + +#define eglCreateStreamAttribKHR EGLEW_GET_FUN(__eglewCreateStreamAttribKHR) +#define eglQueryStreamAttribKHR EGLEW_GET_FUN(__eglewQueryStreamAttribKHR) +#define eglSetStreamAttribKHR EGLEW_GET_FUN(__eglewSetStreamAttribKHR) +#define eglStreamConsumerAcquireAttribKHR EGLEW_GET_FUN(__eglewStreamConsumerAcquireAttribKHR) +#define eglStreamConsumerReleaseAttribKHR EGLEW_GET_FUN(__eglewStreamConsumerReleaseAttribKHR) + +#define EGLEW_KHR_stream_attrib EGLEW_GET_VAR(__EGLEW_KHR_stream_attrib) + +#endif /* EGL_KHR_stream_attrib */ + +/* ------------------- EGL_KHR_stream_consumer_gltexture ------------------- */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 + +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E + +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); + +#define eglStreamConsumerAcquireKHR EGLEW_GET_FUN(__eglewStreamConsumerAcquireKHR) +#define eglStreamConsumerGLTextureExternalKHR EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalKHR) +#define eglStreamConsumerReleaseKHR EGLEW_GET_FUN(__eglewStreamConsumerReleaseKHR) + +#define EGLEW_KHR_stream_consumer_gltexture EGLEW_GET_VAR(__EGLEW_KHR_stream_consumer_gltexture) + +#endif /* EGL_KHR_stream_consumer_gltexture */ + +/* -------------------- EGL_KHR_stream_cross_process_fd -------------------- */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 + +typedef EGLStreamKHR ( * PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +typedef EGLNativeFileDescriptorKHR ( * PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); + +#define eglCreateStreamFromFileDescriptorKHR EGLEW_GET_FUN(__eglewCreateStreamFromFileDescriptorKHR) +#define eglGetStreamFileDescriptorKHR EGLEW_GET_FUN(__eglewGetStreamFileDescriptorKHR) + +#define EGLEW_KHR_stream_cross_process_fd EGLEW_GET_VAR(__EGLEW_KHR_stream_cross_process_fd) + +#endif /* EGL_KHR_stream_cross_process_fd */ + +/* -------------------------- EGL_KHR_stream_fifo -------------------------- */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 + +#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 + +typedef EGLBoolean ( * PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR * value); + +#define eglQueryStreamTimeKHR EGLEW_GET_FUN(__eglewQueryStreamTimeKHR) + +#define EGLEW_KHR_stream_fifo EGLEW_GET_VAR(__EGLEW_KHR_stream_fifo) + +#endif /* EGL_KHR_stream_fifo */ + +/* ----------------- EGL_KHR_stream_producer_aldatalocator ----------------- */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 + +#define EGLEW_KHR_stream_producer_aldatalocator EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_aldatalocator) + +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +/* ------------------- EGL_KHR_stream_producer_eglsurface ------------------ */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 + +#define EGL_STREAM_BIT_KHR 0x0800 + +typedef EGLSurface ( * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint * attrib_list); + +#define eglCreateStreamProducerSurfaceKHR EGLEW_GET_FUN(__eglewCreateStreamProducerSurfaceKHR) + +#define EGLEW_KHR_stream_producer_eglsurface EGLEW_GET_VAR(__EGLEW_KHR_stream_producer_eglsurface) + +#endif /* EGL_KHR_stream_producer_eglsurface */ + +/* ---------------------- EGL_KHR_surfaceless_context ---------------------- */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 + +#define EGLEW_KHR_surfaceless_context EGLEW_GET_VAR(__EGLEW_KHR_surfaceless_context) + +#endif /* EGL_KHR_surfaceless_context */ + +/* -------------------- EGL_KHR_swap_buffers_with_damage ------------------- */ + +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 + +typedef EGLBoolean ( * PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint * rects, EGLint n_rects); + +#define eglSwapBuffersWithDamageKHR EGLEW_GET_FUN(__eglewSwapBuffersWithDamageKHR) + +#define EGLEW_KHR_swap_buffers_with_damage EGLEW_GET_VAR(__EGLEW_KHR_swap_buffers_with_damage) + +#endif /* EGL_KHR_swap_buffers_with_damage */ + +/* ------------------------ EGL_KHR_vg_parent_image ------------------------ */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 + +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA + +#define EGLEW_KHR_vg_parent_image EGLEW_GET_VAR(__EGLEW_KHR_vg_parent_image) + +#endif /* EGL_KHR_vg_parent_image */ + +/* --------------------------- EGL_KHR_wait_sync --------------------------- */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 + +typedef EGLint ( * PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); + +#define eglWaitSyncKHR EGLEW_GET_FUN(__eglewWaitSyncKHR) + +#define EGLEW_KHR_wait_sync EGLEW_GET_VAR(__EGLEW_KHR_wait_sync) + +#endif /* EGL_KHR_wait_sync */ + +/* --------------------------- EGL_MESA_drm_image -------------------------- */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 + +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 + +typedef EGLImageKHR ( * PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint * name, EGLint * handle, EGLint * stride); + +#define eglCreateDRMImageMESA EGLEW_GET_FUN(__eglewCreateDRMImageMESA) +#define eglExportDRMImageMESA EGLEW_GET_FUN(__eglewExportDRMImageMESA) + +#define EGLEW_MESA_drm_image EGLEW_GET_VAR(__EGLEW_MESA_drm_image) + +#endif /* EGL_MESA_drm_image */ + +/* --------------------- EGL_MESA_image_dma_buf_export --------------------- */ + +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 + +typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int * fds, EGLint * strides, EGLint * offsets); +typedef EGLBoolean ( * PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int * fourcc, int * num_planes, EGLuint64KHR * modifiers); + +#define eglExportDMABUFImageMESA EGLEW_GET_FUN(__eglewExportDMABUFImageMESA) +#define eglExportDMABUFImageQueryMESA EGLEW_GET_FUN(__eglewExportDMABUFImageQueryMESA) + +#define EGLEW_MESA_image_dma_buf_export EGLEW_GET_VAR(__EGLEW_MESA_image_dma_buf_export) + +#endif /* EGL_MESA_image_dma_buf_export */ + +/* ------------------------- EGL_MESA_platform_gbm ------------------------- */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 + +#define EGL_PLATFORM_GBM_MESA 0x31D7 + +#define EGLEW_MESA_platform_gbm EGLEW_GET_VAR(__EGLEW_MESA_platform_gbm) + +#endif /* EGL_MESA_platform_gbm */ + +/* --------------------- EGL_MESA_platform_surfaceless --------------------- */ + +#ifndef EGL_MESA_platform_surfaceless +#define EGL_MESA_platform_surfaceless 1 + +#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD + +#define EGLEW_MESA_platform_surfaceless EGLEW_GET_VAR(__EGLEW_MESA_platform_surfaceless) + +#endif /* EGL_MESA_platform_surfaceless */ + +/* -------------------------- EGL_NOK_swap_region -------------------------- */ + +#ifndef EGL_NOK_swap_region +#define EGL_NOK_swap_region 1 + +typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint * rects); + +#define eglSwapBuffersRegionNOK EGLEW_GET_FUN(__eglewSwapBuffersRegionNOK) + +#define EGLEW_NOK_swap_region EGLEW_GET_VAR(__EGLEW_NOK_swap_region) + +#endif /* EGL_NOK_swap_region */ + +/* -------------------------- EGL_NOK_swap_region2 ------------------------- */ + +#ifndef EGL_NOK_swap_region2 +#define EGL_NOK_swap_region2 1 + +typedef EGLBoolean ( * PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint * rects); + +#define eglSwapBuffersRegion2NOK EGLEW_GET_FUN(__eglewSwapBuffersRegion2NOK) + +#define EGLEW_NOK_swap_region2 EGLEW_GET_VAR(__EGLEW_NOK_swap_region2) + +#endif /* EGL_NOK_swap_region2 */ + +/* ---------------------- EGL_NOK_texture_from_pixmap ---------------------- */ + +#ifndef EGL_NOK_texture_from_pixmap +#define EGL_NOK_texture_from_pixmap 1 + +#define EGL_Y_INVERTED_NOK 0x307F + +#define EGLEW_NOK_texture_from_pixmap EGLEW_GET_VAR(__EGLEW_NOK_texture_from_pixmap) + +#endif /* EGL_NOK_texture_from_pixmap */ + +/* ------------------------ EGL_NV_3dvision_surface ------------------------ */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 + +#define EGL_AUTO_STEREO_NV 0x3136 + +#define EGLEW_NV_3dvision_surface EGLEW_GET_VAR(__EGLEW_NV_3dvision_surface) + +#endif /* EGL_NV_3dvision_surface */ + +/* ------------------------- EGL_NV_coverage_sample ------------------------ */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 + +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 + +#define EGLEW_NV_coverage_sample EGLEW_GET_VAR(__EGLEW_NV_coverage_sample) + +#endif /* EGL_NV_coverage_sample */ + +/* --------------------- EGL_NV_coverage_sample_resolve -------------------- */ + +#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 + +#define EGLEW_NV_coverage_sample_resolve EGLEW_GET_VAR(__EGLEW_NV_coverage_sample_resolve) + +#endif /* EGL_NV_coverage_sample_resolve */ + +/* --------------------------- EGL_NV_cuda_event --------------------------- */ + +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 + +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D + +#define EGLEW_NV_cuda_event EGLEW_GET_VAR(__EGLEW_NV_cuda_event) + +#endif /* EGL_NV_cuda_event */ + +/* ------------------------- EGL_NV_depth_nonlinear ------------------------ */ + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 + +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 + +#define EGLEW_NV_depth_nonlinear EGLEW_GET_VAR(__EGLEW_NV_depth_nonlinear) + +#endif /* EGL_NV_depth_nonlinear */ + +/* --------------------------- EGL_NV_device_cuda -------------------------- */ + +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 + +#define EGL_CUDA_DEVICE_NV 0x323A + +#define EGLEW_NV_device_cuda EGLEW_GET_VAR(__EGLEW_NV_device_cuda) + +#endif /* EGL_NV_device_cuda */ + +/* -------------------------- EGL_NV_native_query -------------------------- */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 + +typedef EGLBoolean ( * PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType * display_id); +typedef EGLBoolean ( * PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType * pixmap); +typedef EGLBoolean ( * PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType * window); + +#define eglQueryNativeDisplayNV EGLEW_GET_FUN(__eglewQueryNativeDisplayNV) +#define eglQueryNativePixmapNV EGLEW_GET_FUN(__eglewQueryNativePixmapNV) +#define eglQueryNativeWindowNV EGLEW_GET_FUN(__eglewQueryNativeWindowNV) + +#define EGLEW_NV_native_query EGLEW_GET_VAR(__EGLEW_NV_native_query) + +#endif /* EGL_NV_native_query */ + +/* ---------------------- EGL_NV_post_convert_rounding --------------------- */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 + +#define EGLEW_NV_post_convert_rounding EGLEW_GET_VAR(__EGLEW_NV_post_convert_rounding) + +#endif /* EGL_NV_post_convert_rounding */ + +/* ------------------------- EGL_NV_post_sub_buffer ------------------------ */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 + +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE + +typedef EGLBoolean ( * PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); + +#define eglPostSubBufferNV EGLEW_GET_FUN(__eglewPostSubBufferNV) + +#define EGLEW_NV_post_sub_buffer EGLEW_GET_VAR(__EGLEW_NV_post_sub_buffer) + +#endif /* EGL_NV_post_sub_buffer */ + +/* ------------------ EGL_NV_robustness_video_memory_purge ----------------- */ + +#ifndef EGL_NV_robustness_video_memory_purge +#define EGL_NV_robustness_video_memory_purge 1 + +#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C + +#define EGLEW_NV_robustness_video_memory_purge EGLEW_GET_VAR(__EGLEW_NV_robustness_video_memory_purge) + +#endif /* EGL_NV_robustness_video_memory_purge */ + +/* ------------------ EGL_NV_stream_consumer_gltexture_yuv ----------------- */ + +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 + +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E + +typedef EGLBoolean ( * PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); + +#define eglStreamConsumerGLTextureExternalAttribsNV EGLEW_GET_FUN(__eglewStreamConsumerGLTextureExternalAttribsNV) + +#define EGLEW_NV_stream_consumer_gltexture_yuv EGLEW_GET_VAR(__EGLEW_NV_stream_consumer_gltexture_yuv) + +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +/* ---------------------- EGL_NV_stream_cross_display ---------------------- */ + +#ifndef EGL_NV_stream_cross_display +#define EGL_NV_stream_cross_display 1 + +#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E + +#define EGLEW_NV_stream_cross_display EGLEW_GET_VAR(__EGLEW_NV_stream_cross_display) + +#endif /* EGL_NV_stream_cross_display */ + +/* ----------------------- EGL_NV_stream_cross_object ---------------------- */ + +#ifndef EGL_NV_stream_cross_object +#define EGL_NV_stream_cross_object 1 + +#define EGL_STREAM_CROSS_OBJECT_NV 0x334D + +#define EGLEW_NV_stream_cross_object EGLEW_GET_VAR(__EGLEW_NV_stream_cross_object) + +#endif /* EGL_NV_stream_cross_object */ + +/* --------------------- EGL_NV_stream_cross_partition --------------------- */ + +#ifndef EGL_NV_stream_cross_partition +#define EGL_NV_stream_cross_partition 1 + +#define EGL_STREAM_CROSS_PARTITION_NV 0x323F + +#define EGLEW_NV_stream_cross_partition EGLEW_GET_VAR(__EGLEW_NV_stream_cross_partition) + +#endif /* EGL_NV_stream_cross_partition */ + +/* ---------------------- EGL_NV_stream_cross_process ---------------------- */ + +#ifndef EGL_NV_stream_cross_process +#define EGL_NV_stream_cross_process 1 + +#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 + +#define EGLEW_NV_stream_cross_process EGLEW_GET_VAR(__EGLEW_NV_stream_cross_process) + +#endif /* EGL_NV_stream_cross_process */ + +/* ----------------------- EGL_NV_stream_cross_system ---------------------- */ + +#ifndef EGL_NV_stream_cross_system +#define EGL_NV_stream_cross_system 1 + +#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F + +#define EGLEW_NV_stream_cross_system EGLEW_GET_VAR(__EGLEW_NV_stream_cross_system) + +#endif /* EGL_NV_stream_cross_system */ + +/* ------------------------ EGL_NV_stream_fifo_next ------------------------ */ + +#ifndef EGL_NV_stream_fifo_next +#define EGL_NV_stream_fifo_next 1 + +#define EGL_PENDING_FRAME_NV 0x3329 +#define EGL_STREAM_TIME_PENDING_NV 0x332A + +#define EGLEW_NV_stream_fifo_next EGLEW_GET_VAR(__EGLEW_NV_stream_fifo_next) + +#endif /* EGL_NV_stream_fifo_next */ + +/* --------------------- EGL_NV_stream_fifo_synchronous -------------------- */ + +#ifndef EGL_NV_stream_fifo_synchronous +#define EGL_NV_stream_fifo_synchronous 1 + +#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 + +#define EGLEW_NV_stream_fifo_synchronous EGLEW_GET_VAR(__EGLEW_NV_stream_fifo_synchronous) + +#endif /* EGL_NV_stream_fifo_synchronous */ + +/* ----------------------- EGL_NV_stream_frame_limits ---------------------- */ + +#ifndef EGL_NV_stream_frame_limits +#define EGL_NV_stream_frame_limits 1 + +#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 +#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 + +#define EGLEW_NV_stream_frame_limits EGLEW_GET_VAR(__EGLEW_NV_stream_frame_limits) + +#endif /* EGL_NV_stream_frame_limits */ + +/* ------------------------- EGL_NV_stream_metadata ------------------------ */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 + +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +#define EGL_PENDING_METADATA_NV 0x3328 + +typedef EGLBoolean ( * PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib * value); +typedef EGLBoolean ( * PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void * data); +typedef EGLBoolean ( * PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void * data); + +#define eglQueryDisplayAttribNV EGLEW_GET_FUN(__eglewQueryDisplayAttribNV) +#define eglQueryStreamMetadataNV EGLEW_GET_FUN(__eglewQueryStreamMetadataNV) +#define eglSetStreamMetadataNV EGLEW_GET_FUN(__eglewSetStreamMetadataNV) + +#define EGLEW_NV_stream_metadata EGLEW_GET_VAR(__EGLEW_NV_stream_metadata) + +#endif /* EGL_NV_stream_metadata */ + +/* -------------------------- EGL_NV_stream_remote ------------------------- */ + +#ifndef EGL_NV_stream_remote +#define EGL_NV_stream_remote 1 + +#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 +#define EGL_STREAM_TYPE_NV 0x3241 +#define EGL_STREAM_PROTOCOL_NV 0x3242 +#define EGL_STREAM_ENDPOINT_NV 0x3243 +#define EGL_STREAM_LOCAL_NV 0x3244 +#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 +#define EGL_STREAM_PRODUCER_NV 0x3247 +#define EGL_STREAM_CONSUMER_NV 0x3248 + +#define EGLEW_NV_stream_remote EGLEW_GET_VAR(__EGLEW_NV_stream_remote) + +#endif /* EGL_NV_stream_remote */ + +/* -------------------------- EGL_NV_stream_reset -------------------------- */ + +#ifndef EGL_NV_stream_reset +#define EGL_NV_stream_reset 1 + +#define EGL_SUPPORT_RESET_NV 0x3334 +#define EGL_SUPPORT_REUSE_NV 0x3335 + +typedef EGLBoolean ( * PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); + +#define eglResetStreamNV EGLEW_GET_FUN(__eglewResetStreamNV) + +#define EGLEW_NV_stream_reset EGLEW_GET_VAR(__EGLEW_NV_stream_reset) + +#endif /* EGL_NV_stream_reset */ + +/* -------------------------- EGL_NV_stream_socket ------------------------- */ + +#ifndef EGL_NV_stream_socket +#define EGL_NV_stream_socket 1 + +#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B +#define EGL_SOCKET_HANDLE_NV 0x324C +#define EGL_SOCKET_TYPE_NV 0x324D + +#define EGLEW_NV_stream_socket EGLEW_GET_VAR(__EGLEW_NV_stream_socket) + +#endif /* EGL_NV_stream_socket */ + +/* ----------------------- EGL_NV_stream_socket_inet ----------------------- */ + +#ifndef EGL_NV_stream_socket_inet +#define EGL_NV_stream_socket_inet 1 + +#define EGL_SOCKET_TYPE_INET_NV 0x324F + +#define EGLEW_NV_stream_socket_inet EGLEW_GET_VAR(__EGLEW_NV_stream_socket_inet) + +#endif /* EGL_NV_stream_socket_inet */ + +/* ----------------------- EGL_NV_stream_socket_unix ----------------------- */ + +#ifndef EGL_NV_stream_socket_unix +#define EGL_NV_stream_socket_unix 1 + +#define EGL_SOCKET_TYPE_UNIX_NV 0x324E + +#define EGLEW_NV_stream_socket_unix EGLEW_GET_VAR(__EGLEW_NV_stream_socket_unix) + +#endif /* EGL_NV_stream_socket_unix */ + +/* --------------------------- EGL_NV_stream_sync -------------------------- */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 + +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_NEW_FRAME_NV 0x321F + +typedef EGLSyncKHR ( * PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint * attrib_list); + +#define eglCreateStreamSyncNV EGLEW_GET_FUN(__eglewCreateStreamSyncNV) + +#define EGLEW_NV_stream_sync EGLEW_GET_VAR(__EGLEW_NV_stream_sync) + +#endif /* EGL_NV_stream_sync */ + +/* ------------------------------ EGL_NV_sync ------------------------------ */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 + +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#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_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_FOREVER_NV 0xFFFFFFFFFFFFFFFF + +typedef EGLint ( * PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLSyncNV ( * PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint * attrib_list); +typedef EGLBoolean ( * PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean ( * PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLBoolean ( * PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint * value); +typedef EGLBoolean ( * PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); + +#define eglClientWaitSyncNV EGLEW_GET_FUN(__eglewClientWaitSyncNV) +#define eglCreateFenceSyncNV EGLEW_GET_FUN(__eglewCreateFenceSyncNV) +#define eglDestroySyncNV EGLEW_GET_FUN(__eglewDestroySyncNV) +#define eglFenceNV EGLEW_GET_FUN(__eglewFenceNV) +#define eglGetSyncAttribNV EGLEW_GET_FUN(__eglewGetSyncAttribNV) +#define eglSignalSyncNV EGLEW_GET_FUN(__eglewSignalSyncNV) + +#define EGLEW_NV_sync EGLEW_GET_VAR(__EGLEW_NV_sync) + +#endif /* EGL_NV_sync */ + +/* --------------------------- EGL_NV_system_time -------------------------- */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 + +typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) ( void ); +typedef EGLuint64NV ( * PFNEGLGETSYSTEMTIMENVPROC) ( void ); + +#define eglGetSystemTimeFrequencyNV EGLEW_GET_FUN(__eglewGetSystemTimeFrequencyNV) +#define eglGetSystemTimeNV EGLEW_GET_FUN(__eglewGetSystemTimeNV) + +#define EGLEW_NV_system_time EGLEW_GET_VAR(__EGLEW_NV_system_time) + +#endif /* EGL_NV_system_time */ + +/* --------------------- EGL_TIZEN_image_native_buffer --------------------- */ + +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 + +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 + +#define EGLEW_TIZEN_image_native_buffer EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_buffer) + +#endif /* EGL_TIZEN_image_native_buffer */ + +/* --------------------- EGL_TIZEN_image_native_surface -------------------- */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 + +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 + +#define EGLEW_TIZEN_image_native_surface EGLEW_GET_VAR(__EGLEW_TIZEN_image_native_surface) + +#endif /* EGL_TIZEN_image_native_surface */ + +/* ------------------------------------------------------------------------- */ + +#define EGLEW_FUN_EXPORT GLEW_FUN_EXPORT +#define EGLEW_VAR_EXPORT GLEW_VAR_EXPORT + +EGLEW_FUN_EXPORT PFNEGLCHOOSECONFIGPROC __eglewChooseConfig; +EGLEW_FUN_EXPORT PFNEGLCOPYBUFFERSPROC __eglewCopyBuffers; +EGLEW_FUN_EXPORT PFNEGLCREATECONTEXTPROC __eglewCreateContext; +EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERSURFACEPROC __eglewCreatePbufferSurface; +EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEPROC __eglewCreatePixmapSurface; +EGLEW_FUN_EXPORT PFNEGLCREATEWINDOWSURFACEPROC __eglewCreateWindowSurface; +EGLEW_FUN_EXPORT PFNEGLDESTROYCONTEXTPROC __eglewDestroyContext; +EGLEW_FUN_EXPORT PFNEGLDESTROYSURFACEPROC __eglewDestroySurface; +EGLEW_FUN_EXPORT PFNEGLGETCONFIGATTRIBPROC __eglewGetConfigAttrib; +EGLEW_FUN_EXPORT PFNEGLGETCONFIGSPROC __eglewGetConfigs; +EGLEW_FUN_EXPORT PFNEGLGETCURRENTDISPLAYPROC __eglewGetCurrentDisplay; +EGLEW_FUN_EXPORT PFNEGLGETCURRENTSURFACEPROC __eglewGetCurrentSurface; +EGLEW_FUN_EXPORT PFNEGLGETDISPLAYPROC __eglewGetDisplay; +EGLEW_FUN_EXPORT PFNEGLGETERRORPROC __eglewGetError; +EGLEW_FUN_EXPORT PFNEGLINITIALIZEPROC __eglewInitialize; +EGLEW_FUN_EXPORT PFNEGLMAKECURRENTPROC __eglewMakeCurrent; +EGLEW_FUN_EXPORT PFNEGLQUERYCONTEXTPROC __eglewQueryContext; +EGLEW_FUN_EXPORT PFNEGLQUERYSTRINGPROC __eglewQueryString; +EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPROC __eglewQuerySurface; +EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSPROC __eglewSwapBuffers; +EGLEW_FUN_EXPORT PFNEGLTERMINATEPROC __eglewTerminate; +EGLEW_FUN_EXPORT PFNEGLWAITGLPROC __eglewWaitGL; +EGLEW_FUN_EXPORT PFNEGLWAITNATIVEPROC __eglewWaitNative; + +EGLEW_FUN_EXPORT PFNEGLBINDTEXIMAGEPROC __eglewBindTexImage; +EGLEW_FUN_EXPORT PFNEGLRELEASETEXIMAGEPROC __eglewReleaseTexImage; +EGLEW_FUN_EXPORT PFNEGLSURFACEATTRIBPROC __eglewSurfaceAttrib; +EGLEW_FUN_EXPORT PFNEGLSWAPINTERVALPROC __eglewSwapInterval; + +EGLEW_FUN_EXPORT PFNEGLBINDAPIPROC __eglewBindAPI; +EGLEW_FUN_EXPORT PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC __eglewCreatePbufferFromClientBuffer; +EGLEW_FUN_EXPORT PFNEGLQUERYAPIPROC __eglewQueryAPI; +EGLEW_FUN_EXPORT PFNEGLRELEASETHREADPROC __eglewReleaseThread; +EGLEW_FUN_EXPORT PFNEGLWAITCLIENTPROC __eglewWaitClient; + +EGLEW_FUN_EXPORT PFNEGLGETCURRENTCONTEXTPROC __eglewGetCurrentContext; + +EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCPROC __eglewClientWaitSync; +EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEPROC __eglewCreateImage; +EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC __eglewCreatePlatformPixmapSurface; +EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEPROC __eglewCreatePlatformWindowSurface; +EGLEW_FUN_EXPORT PFNEGLCREATESYNCPROC __eglewCreateSync; +EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEPROC __eglewDestroyImage; +EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCPROC __eglewDestroySync; +EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYPROC __eglewGetPlatformDisplay; +EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBPROC __eglewGetSyncAttrib; +EGLEW_FUN_EXPORT PFNEGLWAITSYNCPROC __eglewWaitSync; + +EGLEW_FUN_EXPORT PFNEGLSETBLOBCACHEFUNCSANDROIDPROC __eglewSetBlobCacheFuncsANDROID; + +EGLEW_FUN_EXPORT PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC __eglewCreateNativeClientBufferANDROID; + +EGLEW_FUN_EXPORT PFNEGLDUPNATIVEFENCEFDANDROIDPROC __eglewDupNativeFenceFDANDROID; + +EGLEW_FUN_EXPORT PFNEGLPRESENTATIONTIMEANDROIDPROC __eglewPresentationTimeANDROID; + +EGLEW_FUN_EXPORT PFNEGLQUERYSURFACEPOINTERANGLEPROC __eglewQuerySurfacePointerANGLE; + +EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESEXTPROC __eglewQueryDevicesEXT; + +EGLEW_FUN_EXPORT PFNEGLQUERYDEVICEATTRIBEXTPROC __eglewQueryDeviceAttribEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYDEVICESTRINGEXTPROC __eglewQueryDeviceStringEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBEXTPROC __eglewQueryDisplayAttribEXT; + +EGLEW_FUN_EXPORT PFNEGLQUERYDMABUFFORMATSEXTPROC __eglewQueryDmaBufFormatsEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYDMABUFMODIFIERSEXTPROC __eglewQueryDmaBufModifiersEXT; + +EGLEW_FUN_EXPORT PFNEGLGETOUTPUTLAYERSEXTPROC __eglewGetOutputLayersEXT; +EGLEW_FUN_EXPORT PFNEGLGETOUTPUTPORTSEXTPROC __eglewGetOutputPortsEXT; +EGLEW_FUN_EXPORT PFNEGLOUTPUTLAYERATTRIBEXTPROC __eglewOutputLayerAttribEXT; +EGLEW_FUN_EXPORT PFNEGLOUTPUTPORTATTRIBEXTPROC __eglewOutputPortAttribEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC __eglewQueryOutputLayerAttribEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC __eglewQueryOutputLayerStringEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC __eglewQueryOutputPortAttribEXT; +EGLEW_FUN_EXPORT PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC __eglewQueryOutputPortStringEXT; + +EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC __eglewCreatePlatformPixmapSurfaceEXT; +EGLEW_FUN_EXPORT PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC __eglewCreatePlatformWindowSurfaceEXT; +EGLEW_FUN_EXPORT PFNEGLGETPLATFORMDISPLAYEXTPROC __eglewGetPlatformDisplayEXT; + +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMEROUTPUTEXTPROC __eglewStreamConsumerOutputEXT; + +EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC __eglewSwapBuffersWithDamageEXT; + +EGLEW_FUN_EXPORT PFNEGLCREATEPIXMAPSURFACEHIPROC __eglewCreatePixmapSurfaceHI; + +EGLEW_FUN_EXPORT PFNEGLCREATESYNC64KHRPROC __eglewCreateSync64KHR; + +EGLEW_FUN_EXPORT PFNEGLDEBUGMESSAGECONTROLKHRPROC __eglewDebugMessageControlKHR; +EGLEW_FUN_EXPORT PFNEGLLABELOBJECTKHRPROC __eglewLabelObjectKHR; +EGLEW_FUN_EXPORT PFNEGLQUERYDEBUGKHRPROC __eglewQueryDebugKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATEIMAGEKHRPROC __eglewCreateImageKHR; +EGLEW_FUN_EXPORT PFNEGLDESTROYIMAGEKHRPROC __eglewDestroyImageKHR; + +EGLEW_FUN_EXPORT PFNEGLLOCKSURFACEKHRPROC __eglewLockSurfaceKHR; +EGLEW_FUN_EXPORT PFNEGLUNLOCKSURFACEKHRPROC __eglewUnlockSurfaceKHR; + +EGLEW_FUN_EXPORT PFNEGLQUERYSURFACE64KHRPROC __eglewQuerySurface64KHR; + +EGLEW_FUN_EXPORT PFNEGLSETDAMAGEREGIONKHRPROC __eglewSetDamageRegionKHR; + +EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCKHRPROC __eglewClientWaitSyncKHR; +EGLEW_FUN_EXPORT PFNEGLCREATESYNCKHRPROC __eglewCreateSyncKHR; +EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCKHRPROC __eglewDestroySyncKHR; +EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBKHRPROC __eglewGetSyncAttribKHR; +EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCKHRPROC __eglewSignalSyncKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATESTREAMKHRPROC __eglewCreateStreamKHR; +EGLEW_FUN_EXPORT PFNEGLDESTROYSTREAMKHRPROC __eglewDestroyStreamKHR; +EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMKHRPROC __eglewQueryStreamKHR; +EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMU64KHRPROC __eglewQueryStreamu64KHR; +EGLEW_FUN_EXPORT PFNEGLSTREAMATTRIBKHRPROC __eglewStreamAttribKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATESTREAMATTRIBKHRPROC __eglewCreateStreamAttribKHR; +EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMATTRIBKHRPROC __eglewQueryStreamAttribKHR; +EGLEW_FUN_EXPORT PFNEGLSETSTREAMATTRIBKHRPROC __eglewSetStreamAttribKHR; +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC __eglewStreamConsumerAcquireAttribKHR; +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC __eglewStreamConsumerReleaseAttribKHR; + +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERACQUIREKHRPROC __eglewStreamConsumerAcquireKHR; +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC __eglewStreamConsumerGLTextureExternalKHR; +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERRELEASEKHRPROC __eglewStreamConsumerReleaseKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC __eglewCreateStreamFromFileDescriptorKHR; +EGLEW_FUN_EXPORT PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC __eglewGetStreamFileDescriptorKHR; + +EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMTIMEKHRPROC __eglewQueryStreamTimeKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC __eglewCreateStreamProducerSurfaceKHR; + +EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC __eglewSwapBuffersWithDamageKHR; + +EGLEW_FUN_EXPORT PFNEGLWAITSYNCKHRPROC __eglewWaitSyncKHR; + +EGLEW_FUN_EXPORT PFNEGLCREATEDRMIMAGEMESAPROC __eglewCreateDRMImageMESA; +EGLEW_FUN_EXPORT PFNEGLEXPORTDRMIMAGEMESAPROC __eglewExportDRMImageMESA; + +EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEMESAPROC __eglewExportDMABUFImageMESA; +EGLEW_FUN_EXPORT PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC __eglewExportDMABUFImageQueryMESA; + +EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGIONNOKPROC __eglewSwapBuffersRegionNOK; + +EGLEW_FUN_EXPORT PFNEGLSWAPBUFFERSREGION2NOKPROC __eglewSwapBuffersRegion2NOK; + +EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEDISPLAYNVPROC __eglewQueryNativeDisplayNV; +EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEPIXMAPNVPROC __eglewQueryNativePixmapNV; +EGLEW_FUN_EXPORT PFNEGLQUERYNATIVEWINDOWNVPROC __eglewQueryNativeWindowNV; + +EGLEW_FUN_EXPORT PFNEGLPOSTSUBBUFFERNVPROC __eglewPostSubBufferNV; + +EGLEW_FUN_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC __eglewStreamConsumerGLTextureExternalAttribsNV; + +EGLEW_FUN_EXPORT PFNEGLQUERYDISPLAYATTRIBNVPROC __eglewQueryDisplayAttribNV; +EGLEW_FUN_EXPORT PFNEGLQUERYSTREAMMETADATANVPROC __eglewQueryStreamMetadataNV; +EGLEW_FUN_EXPORT PFNEGLSETSTREAMMETADATANVPROC __eglewSetStreamMetadataNV; + +EGLEW_FUN_EXPORT PFNEGLRESETSTREAMNVPROC __eglewResetStreamNV; + +EGLEW_FUN_EXPORT PFNEGLCREATESTREAMSYNCNVPROC __eglewCreateStreamSyncNV; + +EGLEW_FUN_EXPORT PFNEGLCLIENTWAITSYNCNVPROC __eglewClientWaitSyncNV; +EGLEW_FUN_EXPORT PFNEGLCREATEFENCESYNCNVPROC __eglewCreateFenceSyncNV; +EGLEW_FUN_EXPORT PFNEGLDESTROYSYNCNVPROC __eglewDestroySyncNV; +EGLEW_FUN_EXPORT PFNEGLFENCENVPROC __eglewFenceNV; +EGLEW_FUN_EXPORT PFNEGLGETSYNCATTRIBNVPROC __eglewGetSyncAttribNV; +EGLEW_FUN_EXPORT PFNEGLSIGNALSYNCNVPROC __eglewSignalSyncNV; + +EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC __eglewGetSystemTimeFrequencyNV; +EGLEW_FUN_EXPORT PFNEGLGETSYSTEMTIMENVPROC __eglewGetSystemTimeNV; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_0; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_1; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_2; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_3; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_4; +EGLEW_VAR_EXPORT GLboolean __EGLEW_VERSION_1_5; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_blob_cache; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_create_native_client_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_framebuffer_target; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_front_buffer_auto_refresh; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_image_native_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_native_fence_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_presentation_time; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANDROID_recordable; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_d3d_share_handle_client_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_device_d3d; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_query_surface_pointer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_surface_d3d_texture_2d_share_handle; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ANGLE_window_fixed_size; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_implicit_external_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_ARM_pixmap_multisample_discard; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_buffer_age; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_client_extensions; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_create_context_robustness; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_base; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_drm; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_enumeration; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_openwf; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_device_query; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_bt2020_linear; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_bt2020_pq; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_gl_colorspace_scrgb_linear; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_dma_buf_import; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_image_dma_buf_import_modifiers; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_multiview_window; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_base; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_drm; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_output_openwf; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_pixel_format_float; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_base; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_device; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_wayland; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_platform_x11; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_content; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_protected_surface; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_stream_consumer_egloutput; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_surface_SMPTE2086_metadata; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_swap_buffers_with_damage; +EGLEW_VAR_EXPORT GLboolean __EGLEW_EXT_yuv_surface; +EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_clientpixmap; +EGLEW_VAR_EXPORT GLboolean __EGLEW_HI_colorformats; +EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_context_priority; +EGLEW_VAR_EXPORT GLboolean __EGLEW_IMG_image_plane_attribs; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_cl_event2; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_client_get_all_proc_addresses; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_config_attribs; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_context_flush_control; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_create_context_no_error; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_debug; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_fence_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_get_all_proc_addresses; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_colorspace; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_renderbuffer_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_2D_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_3D_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_gl_texture_cubemap_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_base; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_image_pixmap; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface2; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_lock_surface3; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_mutable_render_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_no_config_context; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_partial_update; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_android; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_gbm; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_wayland; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_platform_x11; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_reusable_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_attrib; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_consumer_gltexture; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_cross_process_fd; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_fifo; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_aldatalocator; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_stream_producer_eglsurface; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_surfaceless_context; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_swap_buffers_with_damage; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_vg_parent_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_KHR_wait_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_drm_image; +EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_image_dma_buf_export; +EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_platform_gbm; +EGLEW_VAR_EXPORT GLboolean __EGLEW_MESA_platform_surfaceless; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_swap_region2; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NOK_texture_from_pixmap; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_3dvision_surface; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_coverage_sample_resolve; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_cuda_event; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_depth_nonlinear; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_device_cuda; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_native_query; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_convert_rounding; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_post_sub_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_robustness_video_memory_purge; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_consumer_gltexture_yuv; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_display; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_object; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_partition; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_process; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_cross_system; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_fifo_next; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_fifo_synchronous; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_frame_limits; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_metadata; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_remote; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_reset; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket_inet; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_socket_unix; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_stream_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_sync; +EGLEW_VAR_EXPORT GLboolean __EGLEW_NV_system_time; +EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_buffer; +EGLEW_VAR_EXPORT GLboolean __EGLEW_TIZEN_image_native_surface; +/* ------------------------------------------------------------------------ */ + +GLEWAPI GLenum GLEWAPIENTRY eglewInit (EGLDisplay display); +GLEWAPI GLboolean GLEWAPIENTRY eglewIsSupported (const char *name); + +#define EGLEW_GET_VAR(x) (*(const GLboolean*)&x) +#define EGLEW_GET_FUN(x) x + +GLEWAPI GLboolean GLEWAPIENTRY eglewGetExtension (const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* __eglew_h__ */ diff --git a/libultraship/libultraship/Lib/GLEW/GL/glew.h b/libultraship/libultraship/Lib/GLEW/GL/glew.h new file mode 100644 index 000000000..b5b6987fc --- /dev/null +++ b/libultraship/libultraship/Lib/GLEW/GL/glew.h @@ -0,0 +1,23686 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2017, Nigel Stewart +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + +/* +** Copyright (c) 2007 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. +*/ + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) || defined(_GL_H) || defined(__X_GL_H) +#error gl.h included before glew.h +#endif +#if defined(__gl2_h_) +#error gl2.h included before glew.h +#endif +#if defined(__gltypes_h_) +#error gltypes.h included before glew.h +#endif +#if defined(__REGAL_H__) +#error Regal.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __gl2_h_ +#define __GL_H__ +#define _GL_H +#define __gltypes_h_ +#define __REGAL_H__ +#define __X_GL_H +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) + +/* + * GLEW does not include to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* and */ +#ifdef APIENTRY +# ifndef GLAPIENTRY +# define GLAPIENTRY APIENTRY +# endif +# ifndef GLEWAPIENTRY +# define GLEWAPIENTRY APIENTRY +# endif +#else +#define GLEW_APIENTRY_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) || (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# ifndef GLAPIENTRY +# define GLAPIENTRY __stdcall +# endif +# ifndef GLEWAPIENTRY +# define GLEWAPIENTRY __stdcall +# endif +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* and */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) && !defined(__MINGW64__) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__MINGW32__) || defined(__CYGWIN__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +/* + * GLEW_STATIC is defined for static library. + * GLEW_BUILD is defined for building the DLL library. + */ + +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include + +/* SGI MIPSPro doesn't like stdint.h in C++ mode */ +/* ID: 3376260 Solaris 9 has inttypes.h, but not stdint.h */ + +#if (defined(__sgi) || defined(__sun)) && !defined(__GNUC__) +#include +#else +#include +#endif + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY + +/* + * GLEW_STATIC is defined for static library. + */ + +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# if defined(__GNUC__) && __GNUC__>=4 +# define GLEWAPI extern __attribute__ ((visibility("default"))) +# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# define GLEWAPI extern __global +# else +# define GLEWAPI extern +# endif +#endif + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif + +#endif /* _WIN32 */ + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef GLEWAPIENTRY +#define GLEWAPIENTRY +#endif + +#define GLEW_VAR_EXPORT GLEWAPI +#define GLEW_FUN_EXPORT GLEWAPI + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLulong; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; +#if defined(_MSC_VER) && _MSC_VER < 1400 +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#elif defined(_MSC_VER) || defined(__BORLANDC__) +typedef signed long long GLint64EXT; +typedef unsigned long long GLuint64EXT; +#else +# if defined(__MINGW32__) || defined(__CYGWIN__) +#include +# endif +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +typedef GLint64EXT GLint64; +typedef GLuint64EXT GLuint64; +typedef struct __GLsync *GLsync; + +typedef char GLchar; + +#define GL_ZERO 0 +#define GL_FALSE 0 +#define GL_LOGIC_OP 0x0BF1 +#define GL_NONE 0 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_NO_ERROR 0 +#define GL_POINTS 0x0000 +#define GL_CURRENT_BIT 0x00000001 +#define GL_TRUE 1 +#define GL_ONE 1 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_POINT_BIT 0x00000002 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_BIT 0x00000004 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON 0x0009 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#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_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_STENCIL_BUFFER_BIT 0x00000400 +#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_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#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_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#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_ACCUM_CLEAR_VALUE 0x0B80 +#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_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#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_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#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_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#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_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#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_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#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_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#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_S 0x2000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#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_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_R3_G3_B2 0x2A10 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_HINT_BIT 0x00008000 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#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_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#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_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const void *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, void* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +#ifndef GLEW_NO_GLU +# ifdef __APPLE__ +# include +# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +# define GLEW_NO_GLU +# endif +# endif +#endif + +#ifndef GLEW_NO_GLU +/* this is where we can safely include GLU */ +# if defined(__APPLE__) && defined(__MACH__) +# include +# else +# include +# endif +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#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_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_RESCALE_NORMAL 0x803A +#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_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_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#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_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ---------------------------- GL_VERSION_1_2_1 --------------------------- */ + +#ifndef GL_VERSION_1_2_1 +#define GL_VERSION_1_2_1 1 + +#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1) + +#endif /* GL_VERSION_1_2_1 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#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_CLAMP_TO_BORDER 0x812D +#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_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_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#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_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#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_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_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#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_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#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_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri) +#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#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_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_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 + +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef void* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#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_PROGRAM_TWO_SIDE 0x8643 +#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_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#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 + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* ----------------------------- GL_VERSION_2_1 ---------------------------- */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 + +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#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_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + +#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv) +#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv) +#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv) +#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv) +#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv) +#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv) + +#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1) + +#endif /* GL_VERSION_2_1 */ + +/* ----------------------------- GL_VERSION_3_0 ---------------------------- */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 + +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#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_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#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_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#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_ALPHA_INTEGER 0x8D97 +#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 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawBuffer, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawBuffer, const GLint* value); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawBuffer, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum cap, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum cap, GLuint index); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum pname, GLuint index, GLboolean* data); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name); +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum cap, GLuint index); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort* v0); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void*pointer); + +#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender) +#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback) +#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation) +#define glClampColor GLEW_GET_FUN(__glewClampColor) +#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi) +#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv) +#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv) +#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv) +#define glColorMaski GLEW_GET_FUN(__glewColorMaski) +#define glDisablei GLEW_GET_FUN(__glewDisablei) +#define glEnablei GLEW_GET_FUN(__glewEnablei) +#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender) +#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback) +#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v) +#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation) +#define glGetStringi GLEW_GET_FUN(__glewGetStringi) +#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv) +#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv) +#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying) +#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv) +#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv) +#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv) +#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi) +#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv) +#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv) +#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings) +#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui) +#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv) +#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui) +#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv) +#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui) +#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv) +#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui) +#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv) +#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i) +#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv) +#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui) +#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv) +#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i) +#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv) +#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui) +#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv) +#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i) +#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv) +#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui) +#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv) +#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv) +#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i) +#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv) +#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv) +#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv) +#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui) +#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv) +#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv) +#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer) + +#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0) + +#endif /* GL_VERSION_3_0 */ + +/* ----------------------------- GL_VERSION_3_1 ---------------------------- */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 + +#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_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#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_BUFFER_FORMAT 0x8C2E +#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_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#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_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalFormat, GLuint buffer); + +#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced) +#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced) +#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex) +#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer) + +#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1) + +#endif /* GL_VERSION_3_1 */ + +/* ----------------------------- GL_VERSION_3_2 ---------------------------- */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 + +#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_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#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_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 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum value, GLint64 * data); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum pname, GLuint index, GLint64 * data); + +#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture) +#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v) +#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v) + +#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2) + +#endif /* GL_VERSION_3_2 */ + +/* ----------------------------- GL_VERSION_3_3 ---------------------------- */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_RGB10_A2UI 0x906F + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor) + +#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3) + +#endif /* GL_VERSION_3_3 */ + +/* ----------------------------- GL_VERSION_4_0 ---------------------------- */ + +#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_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F +#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 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); + +#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei) +#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi) +#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei) +#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci) +#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading) + +#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0) + +#endif /* GL_VERSION_4_0 */ + +/* ----------------------------- GL_VERSION_4_1 ---------------------------- */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 + +#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1) + +#endif /* GL_VERSION_4_1 */ + +/* ----------------------------- GL_VERSION_4_2 ---------------------------- */ + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 + +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#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_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 + +#define GLEW_VERSION_4_2 GLEW_GET_VAR(__GLEW_VERSION_4_2) + +#endif /* GL_VERSION_4_2 */ + +/* ----------------------------- GL_VERSION_4_3 ---------------------------- */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 + +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E + +#define GLEW_VERSION_4_3 GLEW_GET_VAR(__GLEW_VERSION_4_3) + +#endif /* GL_VERSION_4_3 */ + +/* ----------------------------- GL_VERSION_4_4 ---------------------------- */ + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 + +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A + +#define GLEW_VERSION_4_4 GLEW_GET_VAR(__GLEW_VERSION_4_4) + +#endif /* GL_VERSION_4_4 */ + +/* ----------------------------- GL_VERSION_4_5 ---------------------------- */ + +#ifndef GL_VERSION_4_5 +#define GL_VERSION_4_5 1 + +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 + +typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEPROC) (GLenum tex, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); + +#define glGetGraphicsResetStatus GLEW_GET_FUN(__glewGetGraphicsResetStatus) +#define glGetnCompressedTexImage GLEW_GET_FUN(__glewGetnCompressedTexImage) +#define glGetnTexImage GLEW_GET_FUN(__glewGetnTexImage) +#define glGetnUniformdv GLEW_GET_FUN(__glewGetnUniformdv) + +#define GLEW_VERSION_4_5 GLEW_GET_VAR(__GLEW_VERSION_4_5) + +#endif /* GL_VERSION_4_5 */ + +/* ----------------------------- GL_VERSION_4_6 ---------------------------- */ + +#ifndef GL_VERSION_4_6 +#define GL_VERSION_4_6 1 + +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); + +#define glMultiDrawArraysIndirectCount GLEW_GET_FUN(__glewMultiDrawArraysIndirectCount) +#define glMultiDrawElementsIndirectCount GLEW_GET_FUN(__glewMultiDrawElementsIndirectCount) +#define glSpecializeShader GLEW_GET_FUN(__glewSpecializeShader) + +#define GLEW_VERSION_4_6 GLEW_GET_VAR(__GLEW_VERSION_4_6) + +#endif /* GL_VERSION_4_6 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#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 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#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 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ----------------------- GL_AMD_blend_minmax_factor ---------------------- */ + +#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 + +#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor) + +#endif /* GL_AMD_blend_minmax_factor */ + +/* --------------------- GL_AMD_compressed_3DC_texture --------------------- */ + +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 + +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA + +#define GLEW_AMD_compressed_3DC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_3DC_texture) + +#endif /* GL_AMD_compressed_3DC_texture */ + +/* --------------------- GL_AMD_compressed_ATC_texture --------------------- */ + +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 + +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 + +#define GLEW_AMD_compressed_ATC_texture GLEW_GET_VAR(__GLEW_AMD_compressed_ATC_texture) + +#endif /* GL_AMD_compressed_ATC_texture */ + +/* ----------------------- GL_AMD_conservative_depth ----------------------- */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 + +#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth) + +#endif /* GL_AMD_conservative_depth */ + +/* -------------------------- GL_AMD_debug_output -------------------------- */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 + +#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 (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message); + +#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD) +#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD) +#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD) +#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD) + +#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output) + +#endif /* GL_AMD_debug_output */ + +/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */ + +#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 + +#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate) + +#endif /* GL_AMD_depth_clamp_separate */ + +/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD) +#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD) +#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD) +#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD) + +#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend) + +#endif /* GL_AMD_draw_buffers_blend */ + +/* ------------------ GL_AMD_framebuffer_sample_positions ------------------ */ + +#ifndef GL_AMD_framebuffer_sample_positions +#define GL_AMD_framebuffer_sample_positions 1 + +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE +#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF +#define GL_ALL_PIXELS_AMD 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat* values); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat* values); + +#define glFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewFramebufferSamplePositionsfvAMD) +#define glGetFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetFramebufferParameterfvAMD) +#define glGetNamedFramebufferParameterfvAMD GLEW_GET_FUN(__glewGetNamedFramebufferParameterfvAMD) +#define glNamedFramebufferSamplePositionsfvAMD GLEW_GET_FUN(__glewNamedFramebufferSamplePositionsfvAMD) + +#define GLEW_AMD_framebuffer_sample_positions GLEW_GET_VAR(__GLEW_AMD_framebuffer_sample_positions) + +#endif /* GL_AMD_framebuffer_sample_positions */ + +/* --------------------------- GL_AMD_gcn_shader --------------------------- */ + +#ifndef GL_AMD_gcn_shader +#define GL_AMD_gcn_shader 1 + +#define GLEW_AMD_gcn_shader GLEW_GET_VAR(__GLEW_AMD_gcn_shader) + +#endif /* GL_AMD_gcn_shader */ + +/* ---------------------- GL_AMD_gpu_shader_half_float --------------------- */ + +#ifndef GL_AMD_gpu_shader_half_float +#define GL_AMD_gpu_shader_half_float 1 + +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_FLOAT16_MAT2_AMD 0x91C5 +#define GL_FLOAT16_MAT3_AMD 0x91C6 +#define GL_FLOAT16_MAT4_AMD 0x91C7 +#define GL_FLOAT16_MAT2x3_AMD 0x91C8 +#define GL_FLOAT16_MAT2x4_AMD 0x91C9 +#define GL_FLOAT16_MAT3x2_AMD 0x91CA +#define GL_FLOAT16_MAT3x4_AMD 0x91CB +#define GL_FLOAT16_MAT4x2_AMD 0x91CC +#define GL_FLOAT16_MAT4x3_AMD 0x91CD + +#define GLEW_AMD_gpu_shader_half_float GLEW_GET_VAR(__GLEW_AMD_gpu_shader_half_float) + +#endif /* GL_AMD_gpu_shader_half_float */ + +/* ------------------------ GL_AMD_gpu_shader_int16 ------------------------ */ + +#ifndef GL_AMD_gpu_shader_int16 +#define GL_AMD_gpu_shader_int16 1 + +#define GLEW_AMD_gpu_shader_int16 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int16) + +#endif /* GL_AMD_gpu_shader_int16 */ + +/* ------------------------ GL_AMD_gpu_shader_int64 ------------------------ */ + +#ifndef GL_AMD_gpu_shader_int64 +#define GL_AMD_gpu_shader_int64 1 + +#define GLEW_AMD_gpu_shader_int64 GLEW_GET_VAR(__GLEW_AMD_gpu_shader_int64) + +#endif /* GL_AMD_gpu_shader_int64 */ + +/* ---------------------- GL_AMD_interleaved_elements ---------------------- */ + +#ifndef GL_AMD_interleaved_elements +#define GL_AMD_interleaved_elements 1 + +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RG8UI 0x8238 +#define GL_RG16UI 0x823A +#define GL_RGBA8UI 0x8D7C +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); + +#define glVertexAttribParameteriAMD GLEW_GET_FUN(__glewVertexAttribParameteriAMD) + +#define GLEW_AMD_interleaved_elements GLEW_GET_VAR(__GLEW_AMD_interleaved_elements) + +#endif /* GL_AMD_interleaved_elements */ + +/* ----------------------- GL_AMD_multi_draw_indirect ---------------------- */ + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); + +#define glMultiDrawArraysIndirectAMD GLEW_GET_FUN(__glewMultiDrawArraysIndirectAMD) +#define glMultiDrawElementsIndirectAMD GLEW_GET_FUN(__glewMultiDrawElementsIndirectAMD) + +#define GLEW_AMD_multi_draw_indirect GLEW_GET_VAR(__GLEW_AMD_multi_draw_indirect) + +#endif /* GL_AMD_multi_draw_indirect */ + +/* ------------------------- GL_AMD_name_gen_delete ------------------------ */ + +#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 (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names); +typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); + +#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD) +#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD) +#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD) + +#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete) + +#endif /* GL_AMD_name_gen_delete */ + +/* ---------------------- GL_AMD_occlusion_query_event --------------------- */ + +#ifndef GL_AMD_occlusion_query_event +#define GL_AMD_occlusion_query_event 1 + +#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_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); + +#define glQueryObjectParameteruiAMD GLEW_GET_FUN(__glewQueryObjectParameteruiAMD) + +#define GLEW_AMD_occlusion_query_event GLEW_GET_VAR(__GLEW_AMD_occlusion_query_event) + +#endif /* GL_AMD_occlusion_query_event */ + +/* ----------------------- GL_AMD_performance_monitor ---------------------- */ + +#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 (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString); +typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); + +#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD) +#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD) +#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD) +#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD) +#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD) +#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD) +#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD) +#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD) +#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD) +#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD) +#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD) + +#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor) + +#endif /* GL_AMD_performance_monitor */ + +/* -------------------------- GL_AMD_pinned_memory ------------------------- */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 + +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 + +#define GLEW_AMD_pinned_memory GLEW_GET_VAR(__GLEW_AMD_pinned_memory) + +#endif /* GL_AMD_pinned_memory */ + +/* ----------------------- GL_AMD_program_binary_Z400 ---------------------- */ + +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 + +#define GL_Z400_BINARY_AMD 0x8740 + +#define GLEW_AMD_program_binary_Z400 GLEW_GET_VAR(__GLEW_AMD_program_binary_Z400) + +#endif /* GL_AMD_program_binary_Z400 */ + +/* ----------------------- GL_AMD_query_buffer_object ---------------------- */ + +#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 + +#define GLEW_AMD_query_buffer_object GLEW_GET_VAR(__GLEW_AMD_query_buffer_object) + +#endif /* GL_AMD_query_buffer_object */ + +/* ------------------------ GL_AMD_sample_positions ------------------------ */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 + +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F + +typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val); + +#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD) + +#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions) + +#endif /* GL_AMD_sample_positions */ + +/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture) + +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +/* -------------------- GL_AMD_shader_atomic_counter_ops ------------------- */ + +#ifndef GL_AMD_shader_atomic_counter_ops +#define GL_AMD_shader_atomic_counter_ops 1 + +#define GLEW_AMD_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_AMD_shader_atomic_counter_ops) + +#endif /* GL_AMD_shader_atomic_counter_ops */ + +/* -------------------------- GL_AMD_shader_ballot ------------------------- */ + +#ifndef GL_AMD_shader_ballot +#define GL_AMD_shader_ballot 1 + +#define GLEW_AMD_shader_ballot GLEW_GET_VAR(__GLEW_AMD_shader_ballot) + +#endif /* GL_AMD_shader_ballot */ + +/* ---------------- GL_AMD_shader_explicit_vertex_parameter ---------------- */ + +#ifndef GL_AMD_shader_explicit_vertex_parameter +#define GL_AMD_shader_explicit_vertex_parameter 1 + +#define GLEW_AMD_shader_explicit_vertex_parameter GLEW_GET_VAR(__GLEW_AMD_shader_explicit_vertex_parameter) + +#endif /* GL_AMD_shader_explicit_vertex_parameter */ + +/* ---------------------- GL_AMD_shader_stencil_export --------------------- */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 + +#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export) + +#endif /* GL_AMD_shader_stencil_export */ + +/* ------------------- GL_AMD_shader_stencil_value_export ------------------ */ + +#ifndef GL_AMD_shader_stencil_value_export +#define GL_AMD_shader_stencil_value_export 1 + +#define GLEW_AMD_shader_stencil_value_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_value_export) + +#endif /* GL_AMD_shader_stencil_value_export */ + +/* ---------------------- GL_AMD_shader_trinary_minmax --------------------- */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 + +#define GLEW_AMD_shader_trinary_minmax GLEW_GET_VAR(__GLEW_AMD_shader_trinary_minmax) + +#endif /* GL_AMD_shader_trinary_minmax */ + +/* ------------------------- GL_AMD_sparse_texture ------------------------- */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 + +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +#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 + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); + +#define glTexStorageSparseAMD GLEW_GET_FUN(__glewTexStorageSparseAMD) +#define glTextureStorageSparseAMD GLEW_GET_FUN(__glewTextureStorageSparseAMD) + +#define GLEW_AMD_sparse_texture GLEW_GET_VAR(__GLEW_AMD_sparse_texture) + +#endif /* GL_AMD_sparse_texture */ + +/* ------------------- GL_AMD_stencil_operation_extended ------------------- */ + +#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 (GLAPIENTRY * PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); + +#define glStencilOpValueAMD GLEW_GET_FUN(__glewStencilOpValueAMD) + +#define GLEW_AMD_stencil_operation_extended GLEW_GET_VAR(__GLEW_AMD_stencil_operation_extended) + +#endif /* GL_AMD_stencil_operation_extended */ + +/* --------------------- GL_AMD_texture_gather_bias_lod -------------------- */ + +#ifndef GL_AMD_texture_gather_bias_lod +#define GL_AMD_texture_gather_bias_lod 1 + +#define GLEW_AMD_texture_gather_bias_lod GLEW_GET_VAR(__GLEW_AMD_texture_gather_bias_lod) + +#endif /* GL_AMD_texture_gather_bias_lod */ + +/* ------------------------ GL_AMD_texture_texture4 ------------------------ */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 + +#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4) + +#endif /* GL_AMD_texture_texture4 */ + +/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 + +#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles) + +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +/* ----------------------- GL_AMD_transform_feedback4 ---------------------- */ + +#ifndef GL_AMD_transform_feedback4 +#define GL_AMD_transform_feedback4 1 + +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 + +#define GLEW_AMD_transform_feedback4 GLEW_GET_VAR(__GLEW_AMD_transform_feedback4) + +#endif /* GL_AMD_transform_feedback4 */ + +/* ----------------------- GL_AMD_vertex_shader_layer ---------------------- */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 + +#define GLEW_AMD_vertex_shader_layer GLEW_GET_VAR(__GLEW_AMD_vertex_shader_layer) + +#endif /* GL_AMD_vertex_shader_layer */ + +/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */ + +#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 (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); + +#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD) +#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD) + +#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator) + +#endif /* GL_AMD_vertex_shader_tessellator */ + +/* ------------------ GL_AMD_vertex_shader_viewport_index ------------------ */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 + +#define GLEW_AMD_vertex_shader_viewport_index GLEW_GET_VAR(__GLEW_AMD_vertex_shader_viewport_index) + +#endif /* GL_AMD_vertex_shader_viewport_index */ + +/* -------------------- GL_ANDROID_extension_pack_es31a -------------------- */ + +#ifndef GL_ANDROID_extension_pack_es31a +#define GL_ANDROID_extension_pack_es31a 1 + +#define GLEW_ANDROID_extension_pack_es31a GLEW_GET_VAR(__GLEW_ANDROID_extension_pack_es31a) + +#endif /* GL_ANDROID_extension_pack_es31a */ + +/* ------------------------- GL_ANGLE_depth_texture ------------------------ */ + +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 + +#define GLEW_ANGLE_depth_texture GLEW_GET_VAR(__GLEW_ANGLE_depth_texture) + +#endif /* GL_ANGLE_depth_texture */ + +/* ----------------------- GL_ANGLE_framebuffer_blit ----------------------- */ + +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferANGLE GLEW_GET_FUN(__glewBlitFramebufferANGLE) + +#define GLEW_ANGLE_framebuffer_blit GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_blit) + +#endif /* GL_ANGLE_framebuffer_blit */ + +/* -------------------- GL_ANGLE_framebuffer_multisample ------------------- */ + +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleANGLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleANGLE) + +#define GLEW_ANGLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_multisample) + +#endif /* GL_ANGLE_framebuffer_multisample */ + +/* ----------------------- GL_ANGLE_instanced_arrays ----------------------- */ + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); + +#define glDrawArraysInstancedANGLE GLEW_GET_FUN(__glewDrawArraysInstancedANGLE) +#define glDrawElementsInstancedANGLE GLEW_GET_FUN(__glewDrawElementsInstancedANGLE) +#define glVertexAttribDivisorANGLE GLEW_GET_FUN(__glewVertexAttribDivisorANGLE) + +#define GLEW_ANGLE_instanced_arrays GLEW_GET_VAR(__GLEW_ANGLE_instanced_arrays) + +#endif /* GL_ANGLE_instanced_arrays */ + +/* -------------------- GL_ANGLE_pack_reverse_row_order -------------------- */ + +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 + +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 + +#define GLEW_ANGLE_pack_reverse_row_order GLEW_GET_VAR(__GLEW_ANGLE_pack_reverse_row_order) + +#endif /* GL_ANGLE_pack_reverse_row_order */ + +/* ------------------------ GL_ANGLE_program_binary ------------------------ */ + +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 + +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 + +#define GLEW_ANGLE_program_binary GLEW_GET_VAR(__GLEW_ANGLE_program_binary) + +#endif /* GL_ANGLE_program_binary */ + +/* ------------------- GL_ANGLE_texture_compression_dxt1 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt1 +#define GL_ANGLE_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt1) + +#endif /* GL_ANGLE_texture_compression_dxt1 */ + +/* ------------------- GL_ANGLE_texture_compression_dxt3 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt3 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt3) + +#endif /* GL_ANGLE_texture_compression_dxt3 */ + +/* ------------------- GL_ANGLE_texture_compression_dxt5 ------------------- */ + +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 + +#define GLEW_ANGLE_texture_compression_dxt5 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt5) + +#endif /* GL_ANGLE_texture_compression_dxt5 */ + +/* ------------------------- GL_ANGLE_texture_usage ------------------------ */ + +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 + +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 + +#define GLEW_ANGLE_texture_usage GLEW_GET_VAR(__GLEW_ANGLE_texture_usage) + +#endif /* GL_ANGLE_texture_usage */ + +/* -------------------------- GL_ANGLE_timer_query ------------------------- */ + +#ifndef GL_ANGLE_timer_query +#define GL_ANGLE_timer_query 1 + +#define GL_QUERY_COUNTER_BITS_ANGLE 0x8864 +#define GL_CURRENT_QUERY_ANGLE 0x8865 +#define GL_QUERY_RESULT_ANGLE 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ANGLE 0x8867 +#define GL_TIME_ELAPSED_ANGLE 0x88BF +#define GL_TIMESTAMP_ANGLE 0x8E28 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYANGLEPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESANGLEPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYANGLEPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESANGLEPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VANGLEPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVANGLEPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VANGLEPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVANGLEPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVANGLEPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYANGLEPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERANGLEPROC) (GLuint id, GLenum target); + +#define glBeginQueryANGLE GLEW_GET_FUN(__glewBeginQueryANGLE) +#define glDeleteQueriesANGLE GLEW_GET_FUN(__glewDeleteQueriesANGLE) +#define glEndQueryANGLE GLEW_GET_FUN(__glewEndQueryANGLE) +#define glGenQueriesANGLE GLEW_GET_FUN(__glewGenQueriesANGLE) +#define glGetQueryObjecti64vANGLE GLEW_GET_FUN(__glewGetQueryObjecti64vANGLE) +#define glGetQueryObjectivANGLE GLEW_GET_FUN(__glewGetQueryObjectivANGLE) +#define glGetQueryObjectui64vANGLE GLEW_GET_FUN(__glewGetQueryObjectui64vANGLE) +#define glGetQueryObjectuivANGLE GLEW_GET_FUN(__glewGetQueryObjectuivANGLE) +#define glGetQueryivANGLE GLEW_GET_FUN(__glewGetQueryivANGLE) +#define glIsQueryANGLE GLEW_GET_FUN(__glewIsQueryANGLE) +#define glQueryCounterANGLE GLEW_GET_FUN(__glewQueryCounterANGLE) + +#define GLEW_ANGLE_timer_query GLEW_GET_VAR(__GLEW_ANGLE_timer_query) + +#endif /* GL_ANGLE_timer_query */ + +/* ------------------- GL_ANGLE_translated_shader_source ------------------- */ + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 + +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 + +typedef void (GLAPIENTRY * PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); + +#define glGetTranslatedShaderSourceANGLE GLEW_GET_FUN(__glewGetTranslatedShaderSourceANGLE) + +#define GLEW_ANGLE_translated_shader_source GLEW_GET_VAR(__GLEW_ANGLE_translated_shader_source) + +#endif /* GL_ANGLE_translated_shader_source */ + +/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 + +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 + +#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil) + +#endif /* GL_APPLE_aux_depth_stencil */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_clip_distance ------------------------ */ + +#ifndef GL_APPLE_clip_distance +#define GL_APPLE_clip_distance 1 + +#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 +#define GL_CLIP_DISTANCE0_APPLE 0x3000 +#define GL_CLIP_DISTANCE1_APPLE 0x3001 +#define GL_CLIP_DISTANCE2_APPLE 0x3002 +#define GL_CLIP_DISTANCE3_APPLE 0x3003 +#define GL_CLIP_DISTANCE4_APPLE 0x3004 +#define GL_CLIP_DISTANCE5_APPLE 0x3005 +#define GL_CLIP_DISTANCE6_APPLE 0x3006 +#define GL_CLIP_DISTANCE7_APPLE 0x3007 + +#define GLEW_APPLE_clip_distance GLEW_GET_VAR(__GLEW_APPLE_clip_distance) + +#endif /* GL_APPLE_clip_distance */ + +/* ------------------- GL_APPLE_color_buffer_packed_float ------------------ */ + +#ifndef GL_APPLE_color_buffer_packed_float +#define GL_APPLE_color_buffer_packed_float 1 + +#define GLEW_APPLE_color_buffer_packed_float GLEW_GET_VAR(__GLEW_APPLE_color_buffer_packed_float) + +#endif /* GL_APPLE_color_buffer_packed_float */ + +/* ---------------------- GL_APPLE_copy_texture_levels --------------------- */ + +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); + +#define glCopyTextureLevelsAPPLE GLEW_GET_FUN(__glewCopyTextureLevelsAPPLE) + +#define GLEW_APPLE_copy_texture_levels GLEW_GET_VAR(__GLEW_APPLE_copy_texture_levels) + +#endif /* GL_APPLE_copy_texture_levels */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#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 (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#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 + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */ + +#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 (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + +#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE) +#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE) + +#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range) + +#endif /* GL_APPLE_flush_buffer_range */ + +/* -------------------- GL_APPLE_framebuffer_multisample ------------------- */ + +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); + +#define glRenderbufferStorageMultisampleAPPLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleAPPLE) +#define glResolveMultisampleFramebufferAPPLE GLEW_GET_FUN(__glewResolveMultisampleFramebufferAPPLE) + +#define GLEW_APPLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_APPLE_framebuffer_multisample) + +#endif /* GL_APPLE_framebuffer_multisample */ + +/* ----------------------- GL_APPLE_object_purgeable ----------------------- */ + +#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 void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + +#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE) +#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE) + +#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable) + +#endif /* GL_APPLE_object_purgeable */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 + +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_422_APPLE 0x8A1F +#define GL_RGB_RAW_422_APPLE 0x8A51 + +#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422) + +#endif /* GL_APPLE_rgb_422 */ + +/* --------------------------- GL_APPLE_row_bytes -------------------------- */ + +#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 + +#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes) + +#endif /* GL_APPLE_row_bytes */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ----------------------------- GL_APPLE_sync ----------------------------- */ + +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 + +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull + +typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout); +typedef void (GLAPIENTRY * PFNGLDELETESYNCAPPLEPROC) (GLsync GLsync); +typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETSYNCIVAPPLEPROC) (GLsync GLsync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); +typedef GLboolean (GLAPIENTRY * PFNGLISSYNCAPPLEPROC) (GLsync GLsync); +typedef void (GLAPIENTRY * PFNGLWAITSYNCAPPLEPROC) (GLsync GLsync, GLbitfield flags, GLuint64 timeout); + +#define glClientWaitSyncAPPLE GLEW_GET_FUN(__glewClientWaitSyncAPPLE) +#define glDeleteSyncAPPLE GLEW_GET_FUN(__glewDeleteSyncAPPLE) +#define glFenceSyncAPPLE GLEW_GET_FUN(__glewFenceSyncAPPLE) +#define glGetInteger64vAPPLE GLEW_GET_FUN(__glewGetInteger64vAPPLE) +#define glGetSyncivAPPLE GLEW_GET_FUN(__glewGetSyncivAPPLE) +#define glIsSyncAPPLE GLEW_GET_FUN(__glewIsSyncAPPLE) +#define glWaitSyncAPPLE GLEW_GET_FUN(__glewWaitSyncAPPLE) + +#define GLEW_APPLE_sync GLEW_GET_VAR(__GLEW_APPLE_sync) + +#endif /* GL_APPLE_sync */ + +/* -------------------- GL_APPLE_texture_2D_limited_npot ------------------- */ + +#ifndef GL_APPLE_texture_2D_limited_npot +#define GL_APPLE_texture_2D_limited_npot 1 + +#define GLEW_APPLE_texture_2D_limited_npot GLEW_GET_VAR(__GLEW_APPLE_texture_2D_limited_npot) + +#endif /* GL_APPLE_texture_2D_limited_npot */ + +/* -------------------- GL_APPLE_texture_format_BGRA8888 ------------------- */ + +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 + +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA8_EXT 0x93A1 + +#define GLEW_APPLE_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_APPLE_texture_format_BGRA8888) + +#endif /* GL_APPLE_texture_format_BGRA8888 */ + +/* ----------------------- GL_APPLE_texture_max_level ---------------------- */ + +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 + +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D + +#define GLEW_APPLE_texture_max_level GLEW_GET_VAR(__GLEW_APPLE_texture_max_level) + +#endif /* GL_APPLE_texture_max_level */ + +/* --------------------- GL_APPLE_texture_packed_float --------------------- */ + +#ifndef GL_APPLE_texture_packed_float +#define GL_APPLE_texture_packed_float 1 + +#define GL_R11F_G11F_B10F_APPLE 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B +#define GL_RGB9_E5_APPLE 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E + +#define GLEW_APPLE_texture_packed_float GLEW_GET_VAR(__GLEW_APPLE_texture_packed_float) + +#endif /* GL_APPLE_texture_packed_float */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#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 (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, void *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#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_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */ + +#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 (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); + +#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE) +#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE) +#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE) +#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE) + +#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators) + +#endif /* GL_APPLE_vertex_program_evaluators */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 + +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_RGB565 0x8D62 +#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_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD + +typedef int GLfixed; + +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); +typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); +typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length); + +#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf) +#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef) +#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat) +#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler) +#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary) + +#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility) + +#endif /* GL_ARB_ES2_compatibility */ + +/* ----------------------- GL_ARB_ES3_1_compatibility ---------------------- */ + +#ifndef GL_ARB_ES3_1_compatibility +#define GL_ARB_ES3_1_compatibility 1 + +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); + +#define glMemoryBarrierByRegion GLEW_GET_FUN(__glewMemoryBarrierByRegion) + +#define GLEW_ARB_ES3_1_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_1_compatibility) + +#endif /* GL_ARB_ES3_1_compatibility */ + +/* ----------------------- GL_ARB_ES3_2_compatibility ---------------------- */ + +#ifndef GL_ARB_ES3_2_compatibility +#define GL_ARB_ES3_2_compatibility 1 + +#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); + +#define glPrimitiveBoundingBoxARB GLEW_GET_FUN(__glewPrimitiveBoundingBoxARB) + +#define GLEW_ARB_ES3_2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_2_compatibility) + +#endif /* GL_ARB_ES3_2_compatibility */ + +/* ------------------------ GL_ARB_ES3_compatibility ----------------------- */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 + +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#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_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 GLEW_ARB_ES3_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_compatibility) + +#endif /* GL_ARB_ES3_compatibility */ + +/* ------------------------ GL_ARB_arrays_of_arrays ------------------------ */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 + +#define GLEW_ARB_arrays_of_arrays GLEW_GET_VAR(__GLEW_ARB_arrays_of_arrays) + +#endif /* GL_ARB_arrays_of_arrays */ + +/* -------------------------- GL_ARB_base_instance ------------------------- */ + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance); + +#define glDrawArraysInstancedBaseInstance GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstance) +#define glDrawElementsInstancedBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstance) +#define glDrawElementsInstancedBaseVertexBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstance) + +#define GLEW_ARB_base_instance GLEW_GET_VAR(__GLEW_ARB_base_instance) + +#endif /* GL_ARB_base_instance */ + +/* ------------------------ GL_ARB_bindless_texture ------------------------ */ + +#ifndef GL_ARB_bindless_texture +#define GL_ARB_bindless_texture 1 + +#define GL_UNSIGNED_INT64_ARB 0x140F + +typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT* v); + +#define glGetImageHandleARB GLEW_GET_FUN(__glewGetImageHandleARB) +#define glGetTextureHandleARB GLEW_GET_FUN(__glewGetTextureHandleARB) +#define glGetTextureSamplerHandleARB GLEW_GET_FUN(__glewGetTextureSamplerHandleARB) +#define glGetVertexAttribLui64vARB GLEW_GET_FUN(__glewGetVertexAttribLui64vARB) +#define glIsImageHandleResidentARB GLEW_GET_FUN(__glewIsImageHandleResidentARB) +#define glIsTextureHandleResidentARB GLEW_GET_FUN(__glewIsTextureHandleResidentARB) +#define glMakeImageHandleNonResidentARB GLEW_GET_FUN(__glewMakeImageHandleNonResidentARB) +#define glMakeImageHandleResidentARB GLEW_GET_FUN(__glewMakeImageHandleResidentARB) +#define glMakeTextureHandleNonResidentARB GLEW_GET_FUN(__glewMakeTextureHandleNonResidentARB) +#define glMakeTextureHandleResidentARB GLEW_GET_FUN(__glewMakeTextureHandleResidentARB) +#define glProgramUniformHandleui64ARB GLEW_GET_FUN(__glewProgramUniformHandleui64ARB) +#define glProgramUniformHandleui64vARB GLEW_GET_FUN(__glewProgramUniformHandleui64vARB) +#define glUniformHandleui64ARB GLEW_GET_FUN(__glewUniformHandleui64ARB) +#define glUniformHandleui64vARB GLEW_GET_FUN(__glewUniformHandleui64vARB) +#define glVertexAttribL1ui64ARB GLEW_GET_FUN(__glewVertexAttribL1ui64ARB) +#define glVertexAttribL1ui64vARB GLEW_GET_FUN(__glewVertexAttribL1ui64vARB) + +#define GLEW_ARB_bindless_texture GLEW_GET_VAR(__GLEW_ARB_bindless_texture) + +#endif /* GL_ARB_bindless_texture */ + +/* ----------------------- GL_ARB_blend_func_extended ---------------------- */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar * name); + +#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed) +#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex) + +#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended) + +#endif /* GL_ARB_blend_func_extended */ + +/* ------------------------- GL_ARB_buffer_storage ------------------------- */ + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_PERSISTENT_BIT 0x00000040 +#define GL_MAP_COHERENT_BIT 0x00000080 +#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 + +typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); + +#define glBufferStorage GLEW_GET_FUN(__glewBufferStorage) + +#define GLEW_ARB_buffer_storage GLEW_GET_VAR(__GLEW_ARB_buffer_storage) + +#endif /* GL_ARB_buffer_storage */ + +/* ---------------------------- GL_ARB_cl_event ---------------------------- */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 + +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 + +typedef struct _cl_context *cl_context; +typedef struct _cl_event *cl_event; + +typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags); + +#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB) + +#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event) + +#endif /* GL_ARB_cl_event */ + +/* ----------------------- GL_ARB_clear_buffer_object ---------------------- */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 + +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + +#define glClearBufferData GLEW_GET_FUN(__glewClearBufferData) +#define glClearBufferSubData GLEW_GET_FUN(__glewClearBufferSubData) +#define glClearNamedBufferDataEXT GLEW_GET_FUN(__glewClearNamedBufferDataEXT) +#define glClearNamedBufferSubDataEXT GLEW_GET_FUN(__glewClearNamedBufferSubDataEXT) + +#define GLEW_ARB_clear_buffer_object GLEW_GET_VAR(__GLEW_ARB_clear_buffer_object) + +#endif /* GL_ARB_clear_buffer_object */ + +/* -------------------------- GL_ARB_clear_texture ------------------------- */ + +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 + +#define GL_CLEAR_TEXTURE 0x9365 + +typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); + +#define glClearTexImage GLEW_GET_FUN(__glewClearTexImage) +#define glClearTexSubImage GLEW_GET_FUN(__glewClearTexSubImage) + +#define GLEW_ARB_clear_texture GLEW_GET_VAR(__GLEW_ARB_clear_texture) + +#endif /* GL_ARB_clear_texture */ + +/* -------------------------- GL_ARB_clip_control -------------------------- */ + +#ifndef GL_ARB_clip_control +#define GL_ARB_clip_control 1 + +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_ZERO_TO_ONE 0x935F + +typedef void (GLAPIENTRY * PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); + +#define glClipControl GLEW_GET_FUN(__glewClipControl) + +#define GLEW_ARB_clip_control GLEW_GET_VAR(__GLEW_ARB_clip_control) + +#endif /* GL_ARB_clip_control */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#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 (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* -------------------------- GL_ARB_compatibility ------------------------- */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 + +#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility) + +#endif /* GL_ARB_compatibility */ + +/* ---------------- GL_ARB_compressed_texture_pixel_storage ---------------- */ + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 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 GLEW_ARB_compressed_texture_pixel_storage GLEW_GET_VAR(__GLEW_ARB_compressed_texture_pixel_storage) + +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +/* ------------------------- GL_ARB_compute_shader ------------------------- */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 + +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#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_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#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 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_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF + +typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); + +#define glDispatchCompute GLEW_GET_FUN(__glewDispatchCompute) +#define glDispatchComputeIndirect GLEW_GET_FUN(__glewDispatchComputeIndirect) + +#define GLEW_ARB_compute_shader GLEW_GET_VAR(__GLEW_ARB_compute_shader) + +#endif /* GL_ARB_compute_shader */ + +/* ------------------- GL_ARB_compute_variable_group_size ------------------ */ + +#ifndef GL_ARB_compute_variable_group_size +#define GL_ARB_compute_variable_group_size 1 + +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 + +typedef void (GLAPIENTRY * 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); + +#define glDispatchComputeGroupSizeARB GLEW_GET_FUN(__glewDispatchComputeGroupSizeARB) + +#define GLEW_ARB_compute_variable_group_size GLEW_GET_VAR(__GLEW_ARB_compute_variable_group_size) + +#endif /* GL_ARB_compute_variable_group_size */ + +/* ------------------- GL_ARB_conditional_render_inverted ------------------ */ + +#ifndef GL_ARB_conditional_render_inverted +#define GL_ARB_conditional_render_inverted 1 + +#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 GLEW_ARB_conditional_render_inverted GLEW_GET_VAR(__GLEW_ARB_conditional_render_inverted) + +#endif /* GL_ARB_conditional_render_inverted */ + +/* ----------------------- GL_ARB_conservative_depth ----------------------- */ + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 + +#define GLEW_ARB_conservative_depth GLEW_GET_VAR(__GLEW_ARB_conservative_depth) + +#endif /* GL_ARB_conservative_depth */ + +/* --------------------------- GL_ARB_copy_buffer -------------------------- */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 + +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 + +typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + +#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData) + +#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer) + +#endif /* GL_ARB_copy_buffer */ + +/* --------------------------- GL_ARB_copy_image --------------------------- */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 + +typedef void (GLAPIENTRY * 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); + +#define glCopyImageSubData GLEW_GET_FUN(__glewCopyImageSubData) + +#define GLEW_ARB_copy_image GLEW_GET_VAR(__GLEW_ARB_copy_image) + +#endif /* GL_ARB_copy_image */ + +/* -------------------------- GL_ARB_cull_distance ------------------------- */ + +#ifndef GL_ARB_cull_distance +#define GL_ARB_cull_distance 1 + +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA + +#define GLEW_ARB_cull_distance GLEW_GET_VAR(__GLEW_ARB_cull_distance) + +#endif /* GL_ARB_cull_distance */ + +/* -------------------------- GL_ARB_debug_output -------------------------- */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 + +#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 (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); + +#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB) +#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB) +#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB) +#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB) + +#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output) + +#endif /* GL_ARB_debug_output */ + +/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 + +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + +#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float) + +#endif /* GL_ARB_depth_buffer_float */ + +/* --------------------------- GL_ARB_depth_clamp -------------------------- */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 + +#define GL_DEPTH_CLAMP 0x864F + +#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp) + +#endif /* GL_ARB_depth_clamp */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#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 + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* ----------------------- GL_ARB_derivative_control ----------------------- */ + +#ifndef GL_ARB_derivative_control +#define GL_ARB_derivative_control 1 + +#define GLEW_ARB_derivative_control GLEW_GET_VAR(__GLEW_ARB_derivative_control) + +#endif /* GL_ARB_derivative_control */ + +/* ----------------------- GL_ARB_direct_state_access ---------------------- */ + +#ifndef GL_ARB_direct_state_access +#define GL_ARB_direct_state_access 1 + +#define GL_TEXTURE_TARGET 0x1006 +#define GL_QUERY_TARGET 0x82EA + +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value); +typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* textures); +typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64* param); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments); +typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); + +#define glBindTextureUnit GLEW_GET_FUN(__glewBindTextureUnit) +#define glBlitNamedFramebuffer GLEW_GET_FUN(__glewBlitNamedFramebuffer) +#define glCheckNamedFramebufferStatus GLEW_GET_FUN(__glewCheckNamedFramebufferStatus) +#define glClearNamedBufferData GLEW_GET_FUN(__glewClearNamedBufferData) +#define glClearNamedBufferSubData GLEW_GET_FUN(__glewClearNamedBufferSubData) +#define glClearNamedFramebufferfi GLEW_GET_FUN(__glewClearNamedFramebufferfi) +#define glClearNamedFramebufferfv GLEW_GET_FUN(__glewClearNamedFramebufferfv) +#define glClearNamedFramebufferiv GLEW_GET_FUN(__glewClearNamedFramebufferiv) +#define glClearNamedFramebufferuiv GLEW_GET_FUN(__glewClearNamedFramebufferuiv) +#define glCompressedTextureSubImage1D GLEW_GET_FUN(__glewCompressedTextureSubImage1D) +#define glCompressedTextureSubImage2D GLEW_GET_FUN(__glewCompressedTextureSubImage2D) +#define glCompressedTextureSubImage3D GLEW_GET_FUN(__glewCompressedTextureSubImage3D) +#define glCopyNamedBufferSubData GLEW_GET_FUN(__glewCopyNamedBufferSubData) +#define glCopyTextureSubImage1D GLEW_GET_FUN(__glewCopyTextureSubImage1D) +#define glCopyTextureSubImage2D GLEW_GET_FUN(__glewCopyTextureSubImage2D) +#define glCopyTextureSubImage3D GLEW_GET_FUN(__glewCopyTextureSubImage3D) +#define glCreateBuffers GLEW_GET_FUN(__glewCreateBuffers) +#define glCreateFramebuffers GLEW_GET_FUN(__glewCreateFramebuffers) +#define glCreateProgramPipelines GLEW_GET_FUN(__glewCreateProgramPipelines) +#define glCreateQueries GLEW_GET_FUN(__glewCreateQueries) +#define glCreateRenderbuffers GLEW_GET_FUN(__glewCreateRenderbuffers) +#define glCreateSamplers GLEW_GET_FUN(__glewCreateSamplers) +#define glCreateTextures GLEW_GET_FUN(__glewCreateTextures) +#define glCreateTransformFeedbacks GLEW_GET_FUN(__glewCreateTransformFeedbacks) +#define glCreateVertexArrays GLEW_GET_FUN(__glewCreateVertexArrays) +#define glDisableVertexArrayAttrib GLEW_GET_FUN(__glewDisableVertexArrayAttrib) +#define glEnableVertexArrayAttrib GLEW_GET_FUN(__glewEnableVertexArrayAttrib) +#define glFlushMappedNamedBufferRange GLEW_GET_FUN(__glewFlushMappedNamedBufferRange) +#define glGenerateTextureMipmap GLEW_GET_FUN(__glewGenerateTextureMipmap) +#define glGetCompressedTextureImage GLEW_GET_FUN(__glewGetCompressedTextureImage) +#define glGetNamedBufferParameteri64v GLEW_GET_FUN(__glewGetNamedBufferParameteri64v) +#define glGetNamedBufferParameteriv GLEW_GET_FUN(__glewGetNamedBufferParameteriv) +#define glGetNamedBufferPointerv GLEW_GET_FUN(__glewGetNamedBufferPointerv) +#define glGetNamedBufferSubData GLEW_GET_FUN(__glewGetNamedBufferSubData) +#define glGetNamedFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameteriv) +#define glGetNamedFramebufferParameteriv GLEW_GET_FUN(__glewGetNamedFramebufferParameteriv) +#define glGetNamedRenderbufferParameteriv GLEW_GET_FUN(__glewGetNamedRenderbufferParameteriv) +#define glGetQueryBufferObjecti64v GLEW_GET_FUN(__glewGetQueryBufferObjecti64v) +#define glGetQueryBufferObjectiv GLEW_GET_FUN(__glewGetQueryBufferObjectiv) +#define glGetQueryBufferObjectui64v GLEW_GET_FUN(__glewGetQueryBufferObjectui64v) +#define glGetQueryBufferObjectuiv GLEW_GET_FUN(__glewGetQueryBufferObjectuiv) +#define glGetTextureImage GLEW_GET_FUN(__glewGetTextureImage) +#define glGetTextureLevelParameterfv GLEW_GET_FUN(__glewGetTextureLevelParameterfv) +#define glGetTextureLevelParameteriv GLEW_GET_FUN(__glewGetTextureLevelParameteriv) +#define glGetTextureParameterIiv GLEW_GET_FUN(__glewGetTextureParameterIiv) +#define glGetTextureParameterIuiv GLEW_GET_FUN(__glewGetTextureParameterIuiv) +#define glGetTextureParameterfv GLEW_GET_FUN(__glewGetTextureParameterfv) +#define glGetTextureParameteriv GLEW_GET_FUN(__glewGetTextureParameteriv) +#define glGetTransformFeedbacki64_v GLEW_GET_FUN(__glewGetTransformFeedbacki64_v) +#define glGetTransformFeedbacki_v GLEW_GET_FUN(__glewGetTransformFeedbacki_v) +#define glGetTransformFeedbackiv GLEW_GET_FUN(__glewGetTransformFeedbackiv) +#define glGetVertexArrayIndexed64iv GLEW_GET_FUN(__glewGetVertexArrayIndexed64iv) +#define glGetVertexArrayIndexediv GLEW_GET_FUN(__glewGetVertexArrayIndexediv) +#define glGetVertexArrayiv GLEW_GET_FUN(__glewGetVertexArrayiv) +#define glInvalidateNamedFramebufferData GLEW_GET_FUN(__glewInvalidateNamedFramebufferData) +#define glInvalidateNamedFramebufferSubData GLEW_GET_FUN(__glewInvalidateNamedFramebufferSubData) +#define glMapNamedBuffer GLEW_GET_FUN(__glewMapNamedBuffer) +#define glMapNamedBufferRange GLEW_GET_FUN(__glewMapNamedBufferRange) +#define glNamedBufferData GLEW_GET_FUN(__glewNamedBufferData) +#define glNamedBufferStorage GLEW_GET_FUN(__glewNamedBufferStorage) +#define glNamedBufferSubData GLEW_GET_FUN(__glewNamedBufferSubData) +#define glNamedFramebufferDrawBuffer GLEW_GET_FUN(__glewNamedFramebufferDrawBuffer) +#define glNamedFramebufferDrawBuffers GLEW_GET_FUN(__glewNamedFramebufferDrawBuffers) +#define glNamedFramebufferParameteri GLEW_GET_FUN(__glewNamedFramebufferParameteri) +#define glNamedFramebufferReadBuffer GLEW_GET_FUN(__glewNamedFramebufferReadBuffer) +#define glNamedFramebufferRenderbuffer GLEW_GET_FUN(__glewNamedFramebufferRenderbuffer) +#define glNamedFramebufferTexture GLEW_GET_FUN(__glewNamedFramebufferTexture) +#define glNamedFramebufferTextureLayer GLEW_GET_FUN(__glewNamedFramebufferTextureLayer) +#define glNamedRenderbufferStorage GLEW_GET_FUN(__glewNamedRenderbufferStorage) +#define glNamedRenderbufferStorageMultisample GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisample) +#define glTextureBuffer GLEW_GET_FUN(__glewTextureBuffer) +#define glTextureBufferRange GLEW_GET_FUN(__glewTextureBufferRange) +#define glTextureParameterIiv GLEW_GET_FUN(__glewTextureParameterIiv) +#define glTextureParameterIuiv GLEW_GET_FUN(__glewTextureParameterIuiv) +#define glTextureParameterf GLEW_GET_FUN(__glewTextureParameterf) +#define glTextureParameterfv GLEW_GET_FUN(__glewTextureParameterfv) +#define glTextureParameteri GLEW_GET_FUN(__glewTextureParameteri) +#define glTextureParameteriv GLEW_GET_FUN(__glewTextureParameteriv) +#define glTextureStorage1D GLEW_GET_FUN(__glewTextureStorage1D) +#define glTextureStorage2D GLEW_GET_FUN(__glewTextureStorage2D) +#define glTextureStorage2DMultisample GLEW_GET_FUN(__glewTextureStorage2DMultisample) +#define glTextureStorage3D GLEW_GET_FUN(__glewTextureStorage3D) +#define glTextureStorage3DMultisample GLEW_GET_FUN(__glewTextureStorage3DMultisample) +#define glTextureSubImage1D GLEW_GET_FUN(__glewTextureSubImage1D) +#define glTextureSubImage2D GLEW_GET_FUN(__glewTextureSubImage2D) +#define glTextureSubImage3D GLEW_GET_FUN(__glewTextureSubImage3D) +#define glTransformFeedbackBufferBase GLEW_GET_FUN(__glewTransformFeedbackBufferBase) +#define glTransformFeedbackBufferRange GLEW_GET_FUN(__glewTransformFeedbackBufferRange) +#define glUnmapNamedBuffer GLEW_GET_FUN(__glewUnmapNamedBuffer) +#define glVertexArrayAttribBinding GLEW_GET_FUN(__glewVertexArrayAttribBinding) +#define glVertexArrayAttribFormat GLEW_GET_FUN(__glewVertexArrayAttribFormat) +#define glVertexArrayAttribIFormat GLEW_GET_FUN(__glewVertexArrayAttribIFormat) +#define glVertexArrayAttribLFormat GLEW_GET_FUN(__glewVertexArrayAttribLFormat) +#define glVertexArrayBindingDivisor GLEW_GET_FUN(__glewVertexArrayBindingDivisor) +#define glVertexArrayElementBuffer GLEW_GET_FUN(__glewVertexArrayElementBuffer) +#define glVertexArrayVertexBuffer GLEW_GET_FUN(__glewVertexArrayVertexBuffer) +#define glVertexArrayVertexBuffers GLEW_GET_FUN(__glewVertexArrayVertexBuffers) + +#define GLEW_ARB_direct_state_access GLEW_GET_VAR(__GLEW_ARB_direct_state_access) + +#endif /* GL_ARB_direct_state_access */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#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 (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); + +#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB) +#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB) +#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB) +#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB) + +#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend) + +#endif /* GL_ARB_draw_buffers_blend */ + +/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei* count, GLenum type, void**indices, GLsizei primcount, GLint *basevertex); + +#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex) +#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex) +#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex) +#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex) + +#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex) + +#endif /* GL_ARB_draw_elements_base_vertex */ + +/* -------------------------- GL_ARB_draw_indirect ------------------------- */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 + +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); + +#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect) +#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect) + +#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect) + +#endif /* GL_ARB_draw_indirect */ + +/* ------------------------- GL_ARB_draw_instanced ------------------------- */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 + +#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced) + +#endif /* GL_ARB_draw_instanced */ + +/* ------------------------ GL_ARB_enhanced_layouts ------------------------ */ + +#ifndef GL_ARB_enhanced_layouts +#define GL_ARB_enhanced_layouts 1 + +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C + +#define GLEW_ARB_enhanced_layouts GLEW_GET_VAR(__GLEW_ARB_enhanced_layouts) + +#endif /* GL_ARB_enhanced_layouts */ + +/* -------------------- GL_ARB_explicit_attrib_location -------------------- */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 + +#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location) + +#endif /* GL_ARB_explicit_attrib_location */ + +/* -------------------- GL_ARB_explicit_uniform_location ------------------- */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 + +#define GL_MAX_UNIFORM_LOCATIONS 0x826E + +#define GLEW_ARB_explicit_uniform_location GLEW_GET_VAR(__GLEW_ARB_explicit_uniform_location) + +#endif /* GL_ARB_explicit_uniform_location */ + +/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 + +#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions) + +#endif /* GL_ARB_fragment_coord_conventions */ + +/* --------------------- GL_ARB_fragment_layer_viewport -------------------- */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 + +#define GLEW_ARB_fragment_layer_viewport GLEW_GET_VAR(__GLEW_ARB_fragment_layer_viewport) + +#endif /* GL_ARB_fragment_layer_viewport */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#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_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#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 + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* -------------------- GL_ARB_fragment_shader_interlock ------------------- */ + +#ifndef GL_ARB_fragment_shader_interlock +#define GL_ARB_fragment_shader_interlock 1 + +#define GLEW_ARB_fragment_shader_interlock GLEW_GET_VAR(__GLEW_ARB_fragment_shader_interlock) + +#endif /* GL_ARB_fragment_shader_interlock */ + +/* ------------------- GL_ARB_framebuffer_no_attachments ------------------- */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); + +#define glFramebufferParameteri GLEW_GET_FUN(__glewFramebufferParameteri) +#define glGetFramebufferParameteriv GLEW_GET_FUN(__glewGetFramebufferParameteriv) +#define glGetNamedFramebufferParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferParameterivEXT) +#define glNamedFramebufferParameteriEXT GLEW_GET_FUN(__glewNamedFramebufferParameteriEXT) + +#define GLEW_ARB_framebuffer_no_attachments GLEW_GET_VAR(__GLEW_ARB_framebuffer_no_attachments) + +#endif /* GL_ARB_framebuffer_no_attachments */ + +/* ----------------------- GL_ARB_framebuffer_object ----------------------- */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 + +#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_INDEX 0x8222 +#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_UNSIGNED_NORMALIZED 0x8C17 +#define GL_SRGB 0x8C40 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_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 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer) +#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer) +#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer) +#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus) +#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers) +#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers) +#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer) +#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D) +#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D) +#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D) +#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer) +#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers) +#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers) +#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap) +#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv) +#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv) +#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer) +#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer) +#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage) +#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample) + +#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object) + +#endif /* GL_ARB_framebuffer_object */ + +/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB 0x8DB9 + +#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB) + +#endif /* GL_ARB_framebuffer_sRGB */ + +/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_ARB 0xA +#define GL_LINE_STRIP_ADJACENCY_ARB 0xB +#define GL_TRIANGLES_ADJACENCY_ARB 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#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 (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB) +#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB) +#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB) +#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB) + +#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4) + +#endif /* GL_ARB_geometry_shader4 */ + +/* ----------------------- GL_ARB_get_program_binary ----------------------- */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, void*binary); +typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); + +#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary) +#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary) +#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri) + +#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary) + +#endif /* GL_ARB_get_program_binary */ + +/* ---------------------- GL_ARB_get_texture_sub_image --------------------- */ + +#ifndef GL_ARB_get_texture_sub_image +#define GL_ARB_get_texture_sub_image 1 + +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); +typedef void (GLAPIENTRY * 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); + +#define glGetCompressedTextureSubImage GLEW_GET_FUN(__glewGetCompressedTextureSubImage) +#define glGetTextureSubImage GLEW_GET_FUN(__glewGetTextureSubImage) + +#define GLEW_ARB_get_texture_sub_image GLEW_GET_VAR(__GLEW_ARB_get_texture_sub_image) + +#endif /* GL_ARB_get_texture_sub_image */ + +/* ---------------------------- GL_ARB_gl_spirv ---------------------------- */ + +#ifndef GL_ARB_gl_spirv +#define GL_ARB_gl_spirv 1 + +#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551 +#define GL_SPIR_V_BINARY_ARB 0x9552 + +typedef void (GLAPIENTRY * PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue); + +#define glSpecializeShaderARB GLEW_GET_FUN(__glewSpecializeShaderARB) + +#define GLEW_ARB_gl_spirv GLEW_GET_VAR(__GLEW_ARB_gl_spirv) + +#endif /* GL_ARB_gl_spirv */ + +/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 + +#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 GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5) + +#endif /* GL_ARB_gpu_shader5 */ + +/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 + +#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_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); + +#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv) +#define glUniform1d GLEW_GET_FUN(__glewUniform1d) +#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv) +#define glUniform2d GLEW_GET_FUN(__glewUniform2d) +#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv) +#define glUniform3d GLEW_GET_FUN(__glewUniform3d) +#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv) +#define glUniform4d GLEW_GET_FUN(__glewUniform4d) +#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv) +#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv) +#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv) +#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv) +#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv) +#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv) +#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv) +#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv) +#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv) +#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv) + +#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64) + +#endif /* GL_ARB_gpu_shader_fp64 */ + +/* ------------------------ GL_ARB_gpu_shader_int64 ------------------------ */ + +#ifndef GL_ARB_gpu_shader_int64 +#define GL_ARB_gpu_shader_int64 1 + +#define GL_INT64_ARB 0x140E +#define GL_UNSIGNED_INT64_ARB 0x140F +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 + +typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value); + +#define glGetUniformi64vARB GLEW_GET_FUN(__glewGetUniformi64vARB) +#define glGetUniformui64vARB GLEW_GET_FUN(__glewGetUniformui64vARB) +#define glGetnUniformi64vARB GLEW_GET_FUN(__glewGetnUniformi64vARB) +#define glGetnUniformui64vARB GLEW_GET_FUN(__glewGetnUniformui64vARB) +#define glProgramUniform1i64ARB GLEW_GET_FUN(__glewProgramUniform1i64ARB) +#define glProgramUniform1i64vARB GLEW_GET_FUN(__glewProgramUniform1i64vARB) +#define glProgramUniform1ui64ARB GLEW_GET_FUN(__glewProgramUniform1ui64ARB) +#define glProgramUniform1ui64vARB GLEW_GET_FUN(__glewProgramUniform1ui64vARB) +#define glProgramUniform2i64ARB GLEW_GET_FUN(__glewProgramUniform2i64ARB) +#define glProgramUniform2i64vARB GLEW_GET_FUN(__glewProgramUniform2i64vARB) +#define glProgramUniform2ui64ARB GLEW_GET_FUN(__glewProgramUniform2ui64ARB) +#define glProgramUniform2ui64vARB GLEW_GET_FUN(__glewProgramUniform2ui64vARB) +#define glProgramUniform3i64ARB GLEW_GET_FUN(__glewProgramUniform3i64ARB) +#define glProgramUniform3i64vARB GLEW_GET_FUN(__glewProgramUniform3i64vARB) +#define glProgramUniform3ui64ARB GLEW_GET_FUN(__glewProgramUniform3ui64ARB) +#define glProgramUniform3ui64vARB GLEW_GET_FUN(__glewProgramUniform3ui64vARB) +#define glProgramUniform4i64ARB GLEW_GET_FUN(__glewProgramUniform4i64ARB) +#define glProgramUniform4i64vARB GLEW_GET_FUN(__glewProgramUniform4i64vARB) +#define glProgramUniform4ui64ARB GLEW_GET_FUN(__glewProgramUniform4ui64ARB) +#define glProgramUniform4ui64vARB GLEW_GET_FUN(__glewProgramUniform4ui64vARB) +#define glUniform1i64ARB GLEW_GET_FUN(__glewUniform1i64ARB) +#define glUniform1i64vARB GLEW_GET_FUN(__glewUniform1i64vARB) +#define glUniform1ui64ARB GLEW_GET_FUN(__glewUniform1ui64ARB) +#define glUniform1ui64vARB GLEW_GET_FUN(__glewUniform1ui64vARB) +#define glUniform2i64ARB GLEW_GET_FUN(__glewUniform2i64ARB) +#define glUniform2i64vARB GLEW_GET_FUN(__glewUniform2i64vARB) +#define glUniform2ui64ARB GLEW_GET_FUN(__glewUniform2ui64ARB) +#define glUniform2ui64vARB GLEW_GET_FUN(__glewUniform2ui64vARB) +#define glUniform3i64ARB GLEW_GET_FUN(__glewUniform3i64ARB) +#define glUniform3i64vARB GLEW_GET_FUN(__glewUniform3i64vARB) +#define glUniform3ui64ARB GLEW_GET_FUN(__glewUniform3ui64ARB) +#define glUniform3ui64vARB GLEW_GET_FUN(__glewUniform3ui64vARB) +#define glUniform4i64ARB GLEW_GET_FUN(__glewUniform4i64ARB) +#define glUniform4i64vARB GLEW_GET_FUN(__glewUniform4i64vARB) +#define glUniform4ui64ARB GLEW_GET_FUN(__glewUniform4ui64ARB) +#define glUniform4ui64vARB GLEW_GET_FUN(__glewUniform4ui64vARB) + +#define GLEW_ARB_gpu_shader_int64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_int64) + +#endif /* GL_ARB_gpu_shader_int64 */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ------------------------ GL_ARB_half_float_vertex ----------------------- */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 + +#define GL_HALF_FLOAT 0x140B + +#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex) + +#endif /* GL_ARB_half_float_vertex */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#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_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#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_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, void *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ----------------------- GL_ARB_indirect_parameters ---------------------- */ + +#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 (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); + +#define glMultiDrawArraysIndirectCountARB GLEW_GET_FUN(__glewMultiDrawArraysIndirectCountARB) +#define glMultiDrawElementsIndirectCountARB GLEW_GET_FUN(__glewMultiDrawElementsIndirectCountARB) + +#define GLEW_ARB_indirect_parameters GLEW_GET_VAR(__GLEW_ARB_indirect_parameters) + +#endif /* GL_ARB_indirect_parameters */ + +/* ------------------------ GL_ARB_instanced_arrays ------------------------ */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + +#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB) +#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB) +#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB) + +#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays) + +#endif /* GL_ARB_instanced_arrays */ + +/* ---------------------- GL_ARB_internalformat_query ---------------------- */ + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 + +#define GL_NUM_SAMPLE_COUNTS 0x9380 + +typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); + +#define glGetInternalformativ GLEW_GET_FUN(__glewGetInternalformativ) + +#define GLEW_ARB_internalformat_query GLEW_GET_VAR(__GLEW_ARB_internalformat_query) + +#endif /* GL_ARB_internalformat_query */ + +/* ---------------------- GL_ARB_internalformat_query2 --------------------- */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 + +#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_SRGB_DECODE_ARB 0x8299 +#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 + +typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params); + +#define glGetInternalformati64v GLEW_GET_FUN(__glewGetInternalformati64v) + +#define GLEW_ARB_internalformat_query2 GLEW_GET_VAR(__GLEW_ARB_internalformat_query2) + +#endif /* GL_ARB_internalformat_query2 */ + +/* ----------------------- GL_ARB_invalidate_subdata ----------------------- */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 + +typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments); +typedef void (GLAPIENTRY * PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + +#define glInvalidateBufferData GLEW_GET_FUN(__glewInvalidateBufferData) +#define glInvalidateBufferSubData GLEW_GET_FUN(__glewInvalidateBufferSubData) +#define glInvalidateFramebuffer GLEW_GET_FUN(__glewInvalidateFramebuffer) +#define glInvalidateSubFramebuffer GLEW_GET_FUN(__glewInvalidateSubFramebuffer) +#define glInvalidateTexImage GLEW_GET_FUN(__glewInvalidateTexImage) +#define glInvalidateTexSubImage GLEW_GET_FUN(__glewInvalidateTexSubImage) + +#define GLEW_ARB_invalidate_subdata GLEW_GET_VAR(__GLEW_ARB_invalidate_subdata) + +#endif /* GL_ARB_invalidate_subdata */ + +/* ---------------------- GL_ARB_map_buffer_alignment ---------------------- */ + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 + +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC + +#define GLEW_ARB_map_buffer_alignment GLEW_GET_VAR(__GLEW_ARB_map_buffer_alignment) + +#endif /* GL_ARB_map_buffer_alignment */ + +/* ------------------------ GL_ARB_map_buffer_range ------------------------ */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange) +#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange) + +#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range) + +#endif /* GL_ARB_map_buffer_range */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#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 (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multi_bind --------------------------- */ + +#ifndef GL_ARB_multi_bind +#define GL_ARB_multi_bind 1 + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); + +#define glBindBuffersBase GLEW_GET_FUN(__glewBindBuffersBase) +#define glBindBuffersRange GLEW_GET_FUN(__glewBindBuffersRange) +#define glBindImageTextures GLEW_GET_FUN(__glewBindImageTextures) +#define glBindSamplers GLEW_GET_FUN(__glewBindSamplers) +#define glBindTextures GLEW_GET_FUN(__glewBindTextures) +#define glBindVertexBuffers GLEW_GET_FUN(__glewBindVertexBuffers) + +#define GLEW_ARB_multi_bind GLEW_GET_VAR(__GLEW_ARB_multi_bind) + +#endif /* GL_ARB_multi_bind */ + +/* ----------------------- GL_ARB_multi_draw_indirect ---------------------- */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); + +#define glMultiDrawArraysIndirect GLEW_GET_FUN(__glewMultiDrawArraysIndirect) +#define glMultiDrawElementsIndirect GLEW_GET_FUN(__glewMultiDrawElementsIndirect) + +#define GLEW_ARB_multi_draw_indirect GLEW_GET_VAR(__GLEW_ARB_multi_draw_indirect) + +#endif /* GL_ARB_multi_draw_indirect */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#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 (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#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 (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#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 (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 + +#define GL_ANY_SAMPLES_PASSED 0x8C2F + +#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2) + +#endif /* GL_ARB_occlusion_query2 */ + +/* --------------------- GL_ARB_parallel_shader_compile -------------------- */ + +#ifndef GL_ARB_parallel_shader_compile +#define GL_ARB_parallel_shader_compile 1 + +#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 +#define GL_COMPLETION_STATUS_ARB 0x91B1 + +typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count); + +#define glMaxShaderCompilerThreadsARB GLEW_GET_FUN(__glewMaxShaderCompilerThreadsARB) + +#define GLEW_ARB_parallel_shader_compile GLEW_GET_VAR(__GLEW_ARB_parallel_shader_compile) + +#endif /* GL_ARB_parallel_shader_compile */ + +/* -------------------- GL_ARB_pipeline_statistics_query ------------------- */ + +#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 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F + +#define GLEW_ARB_pipeline_statistics_query GLEW_GET_VAR(__GLEW_ARB_pipeline_statistics_query) + +#endif /* GL_ARB_pipeline_statistics_query */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#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 + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#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 (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ---------------------- GL_ARB_polygon_offset_clamp ---------------------- */ + +#ifndef GL_ARB_polygon_offset_clamp +#define GL_ARB_polygon_offset_clamp 1 + +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp); + +#define glPolygonOffsetClamp GLEW_GET_FUN(__glewPolygonOffsetClamp) + +#define GLEW_ARB_polygon_offset_clamp GLEW_GET_VAR(__GLEW_ARB_polygon_offset_clamp) + +#endif /* GL_ARB_polygon_offset_clamp */ + +/* ----------------------- GL_ARB_post_depth_coverage ---------------------- */ + +#ifndef GL_ARB_post_depth_coverage +#define GL_ARB_post_depth_coverage 1 + +#define GLEW_ARB_post_depth_coverage GLEW_GET_VAR(__GLEW_ARB_post_depth_coverage) + +#endif /* GL_ARB_post_depth_coverage */ + +/* --------------------- GL_ARB_program_interface_query -------------------- */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 + +#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_IS_PER_PATCH 0x92E7 +#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 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params); +typedef GLuint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params); + +#define glGetProgramInterfaceiv GLEW_GET_FUN(__glewGetProgramInterfaceiv) +#define glGetProgramResourceIndex GLEW_GET_FUN(__glewGetProgramResourceIndex) +#define glGetProgramResourceLocation GLEW_GET_FUN(__glewGetProgramResourceLocation) +#define glGetProgramResourceLocationIndex GLEW_GET_FUN(__glewGetProgramResourceLocationIndex) +#define glGetProgramResourceName GLEW_GET_FUN(__glewGetProgramResourceName) +#define glGetProgramResourceiv GLEW_GET_FUN(__glewGetProgramResourceiv) + +#define GLEW_ARB_program_interface_query GLEW_GET_VAR(__GLEW_ARB_program_interface_query) + +#endif /* GL_ARB_program_interface_query */ + +/* ------------------------ GL_ARB_provoking_vertex ------------------------ */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode); + +#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex) + +#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex) + +#endif /* GL_ARB_provoking_vertex */ + +/* ----------------------- GL_ARB_query_buffer_object ---------------------- */ + +#ifndef GL_ARB_query_buffer_object +#define GL_ARB_query_buffer_object 1 + +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 + +#define GLEW_ARB_query_buffer_object GLEW_GET_VAR(__GLEW_ARB_query_buffer_object) + +#endif /* GL_ARB_query_buffer_object */ + +/* ------------------ GL_ARB_robust_buffer_access_behavior ----------------- */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 + +#define GLEW_ARB_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_ARB_robust_buffer_access_behavior) + +#endif /* GL_ARB_robust_buffer_access_behavior */ + +/* --------------------------- GL_ARB_robustness --------------------------- */ + +#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 (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table); +typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image); +typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v); +typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v); +typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values); +typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values); +typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern); +typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void*column, void*span); +typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); +typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data); + +#define glGetGraphicsResetStatusARB GLEW_GET_FUN(__glewGetGraphicsResetStatusARB) +#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB) +#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB) +#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB) +#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB) +#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB) +#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB) +#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB) +#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB) +#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB) +#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB) +#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB) +#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB) +#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB) +#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB) +#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB) +#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB) +#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB) +#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB) +#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB) + +#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness) + +#endif /* GL_ARB_robustness */ + +/* ---------------- GL_ARB_robustness_application_isolation ---------------- */ + +#ifndef GL_ARB_robustness_application_isolation +#define GL_ARB_robustness_application_isolation 1 + +#define GLEW_ARB_robustness_application_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_application_isolation) + +#endif /* GL_ARB_robustness_application_isolation */ + +/* ---------------- GL_ARB_robustness_share_group_isolation ---------------- */ + +#ifndef GL_ARB_robustness_share_group_isolation +#define GL_ARB_robustness_share_group_isolation 1 + +#define GLEW_ARB_robustness_share_group_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_share_group_isolation) + +#endif /* GL_ARB_robustness_share_group_isolation */ + +/* ------------------------ GL_ARB_sample_locations ------------------------ */ + +#ifndef GL_ARB_sample_locations +#define GL_ARB_sample_locations 1 + +#define GL_SAMPLE_LOCATION_ARB 0x8E50 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); + +#define glFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewFramebufferSampleLocationsfvARB) +#define glNamedFramebufferSampleLocationsfvARB GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvARB) + +#define GLEW_ARB_sample_locations GLEW_GET_VAR(__GLEW_ARB_sample_locations) + +#endif /* GL_ARB_sample_locations */ + +/* ------------------------- GL_ARB_sample_shading ------------------------- */ + +#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 (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); + +#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB) + +#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading) + +#endif /* GL_ARB_sample_shading */ + +/* ------------------------- GL_ARB_sampler_objects ------------------------ */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 + +#define GL_SAMPLER_BINDING 0x8919 + +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers); +typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params); + +#define glBindSampler GLEW_GET_FUN(__glewBindSampler) +#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers) +#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers) +#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv) +#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv) +#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv) +#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv) +#define glIsSampler GLEW_GET_FUN(__glewIsSampler) +#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv) +#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv) +#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf) +#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv) +#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri) +#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv) + +#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects) + +#endif /* GL_ARB_sampler_objects */ + +/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map) + +#endif /* GL_ARB_seamless_cube_map */ + +/* ------------------ GL_ARB_seamless_cubemap_per_texture ------------------ */ + +#ifndef GL_ARB_seamless_cubemap_per_texture +#define GL_ARB_seamless_cubemap_per_texture 1 + +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F + +#define GLEW_ARB_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_ARB_seamless_cubemap_per_texture) + +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +/* --------------------- GL_ARB_separate_shader_objects -------------------- */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 + +#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_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ALL_SHADER_BITS 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar * const * strings); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar *infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); + +#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram) +#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline) +#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv) +#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines) +#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines) +#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog) +#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv) +#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline) +#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d) +#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv) +#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f) +#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv) +#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i) +#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv) +#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui) +#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv) +#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d) +#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv) +#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f) +#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv) +#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i) +#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv) +#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui) +#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv) +#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d) +#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv) +#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f) +#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv) +#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i) +#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv) +#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui) +#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv) +#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d) +#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv) +#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f) +#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv) +#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i) +#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv) +#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui) +#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv) +#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv) +#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv) +#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv) +#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv) +#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv) +#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv) +#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv) +#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv) +#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv) +#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv) +#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv) +#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv) +#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv) +#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv) +#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv) +#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv) +#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv) +#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv) +#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages) +#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline) + +#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects) + +#endif /* GL_ARB_separate_shader_objects */ + +/* -------------------- GL_ARB_shader_atomic_counter_ops ------------------- */ + +#ifndef GL_ARB_shader_atomic_counter_ops +#define GL_ARB_shader_atomic_counter_ops 1 + +#define GLEW_ARB_shader_atomic_counter_ops GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counter_ops) + +#endif /* GL_ARB_shader_atomic_counter_ops */ + +/* --------------------- GL_ARB_shader_atomic_counters --------------------- */ + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 + +#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_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC + +typedef void (GLAPIENTRY * PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint* params); + +#define glGetActiveAtomicCounterBufferiv GLEW_GET_FUN(__glewGetActiveAtomicCounterBufferiv) + +#define GLEW_ARB_shader_atomic_counters GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counters) + +#endif /* GL_ARB_shader_atomic_counters */ + +/* -------------------------- GL_ARB_shader_ballot ------------------------- */ + +#ifndef GL_ARB_shader_ballot +#define GL_ARB_shader_ballot 1 + +#define GLEW_ARB_shader_ballot GLEW_GET_VAR(__GLEW_ARB_shader_ballot) + +#endif /* GL_ARB_shader_ballot */ + +/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 + +#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding) + +#endif /* GL_ARB_shader_bit_encoding */ + +/* -------------------------- GL_ARB_shader_clock -------------------------- */ + +#ifndef GL_ARB_shader_clock +#define GL_ARB_shader_clock 1 + +#define GLEW_ARB_shader_clock GLEW_GET_VAR(__GLEW_ARB_shader_clock) + +#endif /* GL_ARB_shader_clock */ + +/* --------------------- GL_ARB_shader_draw_parameters --------------------- */ + +#ifndef GL_ARB_shader_draw_parameters +#define GL_ARB_shader_draw_parameters 1 + +#define GLEW_ARB_shader_draw_parameters GLEW_GET_VAR(__GLEW_ARB_shader_draw_parameters) + +#endif /* GL_ARB_shader_draw_parameters */ + +/* ------------------------ GL_ARB_shader_group_vote ----------------------- */ + +#ifndef GL_ARB_shader_group_vote +#define GL_ARB_shader_group_vote 1 + +#define GLEW_ARB_shader_group_vote GLEW_GET_VAR(__GLEW_ARB_shader_group_vote) + +#endif /* GL_ARB_shader_group_vote */ + +/* --------------------- GL_ARB_shader_image_load_store -------------------- */ + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 + +#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_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_ALL_BARRIER_BITS 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); + +#define glBindImageTexture GLEW_GET_FUN(__glewBindImageTexture) +#define glMemoryBarrier GLEW_GET_FUN(__glewMemoryBarrier) + +#define GLEW_ARB_shader_image_load_store GLEW_GET_VAR(__GLEW_ARB_shader_image_load_store) + +#endif /* GL_ARB_shader_image_load_store */ + +/* ------------------------ GL_ARB_shader_image_size ----------------------- */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 + +#define GLEW_ARB_shader_image_size GLEW_GET_VAR(__GLEW_ARB_shader_image_size) + +#endif /* GL_ARB_shader_image_size */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#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 char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ------------------------ GL_ARB_shader_precision ------------------------ */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 + +#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision) + +#endif /* GL_ARB_shader_precision */ + +/* ---------------------- GL_ARB_shader_stencil_export --------------------- */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 + +#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export) + +#endif /* GL_ARB_shader_stencil_export */ + +/* ------------------ GL_ARB_shader_storage_buffer_object ------------------ */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 + +#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#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 + +typedef void (GLAPIENTRY * PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); + +#define glShaderStorageBlockBinding GLEW_GET_FUN(__glewShaderStorageBlockBinding) + +#define GLEW_ARB_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_ARB_shader_storage_buffer_object) + +#endif /* GL_ARB_shader_storage_buffer_object */ + +/* ------------------------ GL_ARB_shader_subroutine ----------------------- */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 + +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B + +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values); +typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar* name); +typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params); +typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices); + +#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName) +#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName) +#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv) +#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv) +#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex) +#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation) +#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv) +#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv) + +#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine) + +#endif /* GL_ARB_shader_subroutine */ + +/* ------------------ GL_ARB_shader_texture_image_samples ------------------ */ + +#ifndef GL_ARB_shader_texture_image_samples +#define GL_ARB_shader_texture_image_samples 1 + +#define GLEW_ARB_shader_texture_image_samples GLEW_GET_VAR(__GLEW_ARB_shader_texture_image_samples) + +#endif /* GL_ARB_shader_texture_image_samples */ + +/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 + +#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod) + +#endif /* GL_ARB_shader_texture_lod */ + +/* ------------------- GL_ARB_shader_viewport_layer_array ------------------ */ + +#ifndef GL_ARB_shader_viewport_layer_array +#define GL_ARB_shader_viewport_layer_array 1 + +#define GLEW_ARB_shader_viewport_layer_array GLEW_GET_VAR(__GLEW_ARB_shader_viewport_layer_array) + +#endif /* GL_ARB_shader_viewport_layer_array */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* -------------------- GL_ARB_shading_language_420pack -------------------- */ + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 + +#define GLEW_ARB_shading_language_420pack GLEW_GET_VAR(__GLEW_ARB_shading_language_420pack) + +#endif /* GL_ARB_shading_language_420pack */ + +/* -------------------- GL_ARB_shading_language_include -------------------- */ + +#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 (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* const *path, const GLint *length); +typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar* name, GLenum pname, GLint *params); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar* name, GLint stringlen, const GLchar *string); + +#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB) +#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB) +#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB) +#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB) +#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB) +#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB) + +#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include) + +#endif /* GL_ARB_shading_language_include */ + +/* -------------------- GL_ARB_shading_language_packing -------------------- */ + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 + +#define GLEW_ARB_shading_language_packing GLEW_GET_VAR(__GLEW_ARB_shading_language_packing) + +#endif /* GL_ARB_shading_language_packing */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#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 + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* -------------------------- GL_ARB_sparse_buffer ------------------------- */ + +#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 (GLAPIENTRY * PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); + +#define glBufferPageCommitmentARB GLEW_GET_FUN(__glewBufferPageCommitmentARB) + +#define GLEW_ARB_sparse_buffer GLEW_GET_VAR(__GLEW_ARB_sparse_buffer) + +#endif /* GL_ARB_sparse_buffer */ + +/* ------------------------- GL_ARB_sparse_texture ------------------------- */ + +#ifndef GL_ARB_sparse_texture +#define GL_ARB_sparse_texture 1 + +#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_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA + +typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); + +#define glTexPageCommitmentARB GLEW_GET_FUN(__glewTexPageCommitmentARB) + +#define GLEW_ARB_sparse_texture GLEW_GET_VAR(__GLEW_ARB_sparse_texture) + +#endif /* GL_ARB_sparse_texture */ + +/* ------------------------- GL_ARB_sparse_texture2 ------------------------ */ + +#ifndef GL_ARB_sparse_texture2 +#define GL_ARB_sparse_texture2 1 + +#define GLEW_ARB_sparse_texture2 GLEW_GET_VAR(__GLEW_ARB_sparse_texture2) + +#endif /* GL_ARB_sparse_texture2 */ + +/* ---------------------- GL_ARB_sparse_texture_clamp ---------------------- */ + +#ifndef GL_ARB_sparse_texture_clamp +#define GL_ARB_sparse_texture_clamp 1 + +#define GLEW_ARB_sparse_texture_clamp GLEW_GET_VAR(__GLEW_ARB_sparse_texture_clamp) + +#endif /* GL_ARB_sparse_texture_clamp */ + +/* ------------------------ GL_ARB_spirv_extensions ------------------------ */ + +#ifndef GL_ARB_spirv_extensions +#define GL_ARB_spirv_extensions 1 + +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 + +#define GLEW_ARB_spirv_extensions GLEW_GET_VAR(__GLEW_ARB_spirv_extensions) + +#endif /* GL_ARB_spirv_extensions */ + +/* ------------------------ GL_ARB_stencil_texturing ----------------------- */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 + +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA + +#define GLEW_ARB_stencil_texturing GLEW_GET_VAR(__GLEW_ARB_stencil_texturing) + +#endif /* GL_ARB_stencil_texturing */ + +/* ------------------------------ GL_ARB_sync ------------------------------ */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 + +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#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 + +typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); +typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync); +typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values); +typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync); +typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout); + +#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync) +#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync) +#define glFenceSync GLEW_GET_FUN(__glewFenceSync) +#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v) +#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv) +#define glIsSync GLEW_GET_FUN(__glewIsSync) +#define glWaitSync GLEW_GET_FUN(__glewWaitSync) + +#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync) + +#endif /* GL_ARB_sync */ + +/* ----------------------- GL_ARB_tessellation_shader ---------------------- */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 + +#define GL_PATCHES 0xE +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#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_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_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A + +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values); +typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); + +#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv) +#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri) + +#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader) + +#endif /* GL_ARB_tessellation_shader */ + +/* ------------------------- GL_ARB_texture_barrier ------------------------ */ + +#ifndef GL_ARB_texture_barrier +#define GL_ARB_texture_barrier 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERPROC) (void); + +#define glTextureBarrier GLEW_GET_FUN(__glewTextureBarrier) + +#define GLEW_ARB_texture_barrier GLEW_GET_VAR(__GLEW_ARB_texture_barrier) + +#endif /* GL_ARB_texture_barrier */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ---------------------- GL_ARB_texture_buffer_object --------------------- */ + +#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 (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB) + +#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object) + +#endif /* GL_ARB_texture_buffer_object */ + +/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 + +#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32) + +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +/* ---------------------- GL_ARB_texture_buffer_range ---------------------- */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 + +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F + +typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + +#define glTexBufferRange GLEW_GET_FUN(__glewTexBufferRange) +#define glTextureBufferRangeEXT GLEW_GET_FUN(__glewTextureBufferRangeEXT) + +#define GLEW_ARB_texture_buffer_range GLEW_GET_VAR(__GLEW_ARB_texture_buffer_range) + +#endif /* GL_ARB_texture_buffer_range */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#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 (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void *img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* -------------------- GL_ARB_texture_compression_bptc -------------------- */ + +#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 + +#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc) + +#endif /* GL_ARB_texture_compression_bptc */ + +/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 + +#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 GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc) + +#endif /* GL_ARB_texture_compression_rgtc */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#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 + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* --------------------- GL_ARB_texture_cube_map_array --------------------- */ + +#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 + +#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array) + +#endif /* GL_ARB_texture_cube_map_array */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#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 GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#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 + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* ------------------- GL_ARB_texture_filter_anisotropic ------------------- */ + +#ifndef GL_ARB_texture_filter_anisotropic +#define GL_ARB_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF + +#define GLEW_ARB_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_ARB_texture_filter_anisotropic) + +#endif /* GL_ARB_texture_filter_anisotropic */ + +/* ---------------------- GL_ARB_texture_filter_minmax --------------------- */ + +#ifndef GL_ARB_texture_filter_minmax +#define GL_ARB_texture_filter_minmax 1 + +#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 +#define GL_WEIGHTED_AVERAGE_ARB 0x9367 + +#define GLEW_ARB_texture_filter_minmax GLEW_GET_VAR(__GLEW_ARB_texture_filter_minmax) + +#endif /* GL_ARB_texture_filter_minmax */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#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 +#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 GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* ------------------------- GL_ARB_texture_gather ------------------------- */ + +#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 + +#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather) + +#endif /* GL_ARB_texture_gather */ + +/* ------------------ GL_ARB_texture_mirror_clamp_to_edge ------------------ */ + +#ifndef GL_ARB_texture_mirror_clamp_to_edge +#define GL_ARB_texture_mirror_clamp_to_edge 1 + +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 + +#define GLEW_ARB_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_ARB_texture_mirror_clamp_to_edge) + +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* ----------------------- GL_ARB_texture_multisample ---------------------- */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 + +#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 (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv) +#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski) +#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample) +#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample) + +#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample) + +#endif /* GL_ARB_texture_multisample */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ---------------------- GL_ARB_texture_query_levels ---------------------- */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 + +#define GLEW_ARB_texture_query_levels GLEW_GET_VAR(__GLEW_ARB_texture_query_levels) + +#endif /* GL_ARB_texture_query_levels */ + +/* ------------------------ GL_ARB_texture_query_lod ----------------------- */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 + +#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod) + +#endif /* GL_ARB_texture_query_lod */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#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 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* --------------------------- GL_ARB_texture_rg --------------------------- */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 + +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#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 GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg) + +#endif /* GL_ARB_texture_rg */ + +/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 + +#define GL_RGB10_A2UI 0x906F + +#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui) + +#endif /* GL_ARB_texture_rgb10_a2ui */ + +/* ------------------------ GL_ARB_texture_stencil8 ------------------------ */ + +#ifndef GL_ARB_texture_stencil8 +#define GL_ARB_texture_stencil8 1 + +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GLEW_ARB_texture_stencil8 GLEW_GET_VAR(__GLEW_ARB_texture_stencil8) + +#endif /* GL_ARB_texture_stencil8 */ + +/* ------------------------- GL_ARB_texture_storage ------------------------ */ + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 + +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + +#define glTexStorage1D GLEW_GET_FUN(__glewTexStorage1D) +#define glTexStorage2D GLEW_GET_FUN(__glewTexStorage2D) +#define glTexStorage3D GLEW_GET_FUN(__glewTexStorage3D) + +#define GLEW_ARB_texture_storage GLEW_GET_VAR(__GLEW_ARB_texture_storage) + +#endif /* GL_ARB_texture_storage */ + +/* ------------------- GL_ARB_texture_storage_multisample ------------------ */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + +#define glTexStorage2DMultisample GLEW_GET_FUN(__glewTexStorage2DMultisample) +#define glTexStorage3DMultisample GLEW_GET_FUN(__glewTexStorage3DMultisample) +#define glTextureStorage2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage2DMultisampleEXT) +#define glTextureStorage3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage3DMultisampleEXT) + +#define GLEW_ARB_texture_storage_multisample GLEW_GET_VAR(__GLEW_ARB_texture_storage_multisample) + +#endif /* GL_ARB_texture_storage_multisample */ + +/* ------------------------- GL_ARB_texture_swizzle ------------------------ */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 + +#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 GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle) + +#endif /* GL_ARB_texture_swizzle */ + +/* -------------------------- GL_ARB_texture_view -------------------------- */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); + +#define glTextureView GLEW_GET_FUN(__glewTextureView) + +#define GLEW_ARB_texture_view GLEW_GET_VAR(__GLEW_ARB_texture_view) + +#endif /* GL_ARB_texture_view */ + +/* --------------------------- GL_ARB_timer_query -------------------------- */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 + +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); + +#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v) +#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v) +#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter) + +#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query) + +#endif /* GL_ARB_timer_query */ + +/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); + +#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback) +#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks) +#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback) +#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks) +#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback) +#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback) +#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback) + +#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2) + +#endif /* GL_ARB_transform_feedback2 */ + +/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 + +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); + +#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed) +#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream) +#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed) +#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv) + +#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3) + +#endif /* GL_ARB_transform_feedback3 */ + +/* ------------------ GL_ARB_transform_feedback_instanced ------------------ */ + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount); + +#define glDrawTransformFeedbackInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackInstanced) +#define glDrawTransformFeedbackStreamInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackStreamInstanced) + +#define GLEW_ARB_transform_feedback_instanced GLEW_GET_VAR(__GLEW_ARB_transform_feedback_instanced) + +#endif /* GL_ARB_transform_feedback_instanced */ + +/* ---------------- GL_ARB_transform_feedback_overflow_query --------------- */ + +#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 + +#define GLEW_ARB_transform_feedback_overflow_query GLEW_GET_VAR(__GLEW_ARB_transform_feedback_overflow_query) + +#endif /* GL_ARB_transform_feedback_overflow_query */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#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 (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 + +#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 (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); +typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const * uniformNames, GLuint* uniformIndices); +typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + +#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase) +#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange) +#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName) +#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv) +#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName) +#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv) +#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v) +#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex) +#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices) +#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding) + +#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object) + +#endif /* GL_ARB_uniform_buffer_object */ + +/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra) + +#endif /* GL_ARB_vertex_array_bgra */ + +/* ----------------------- GL_ARB_vertex_array_object ---------------------- */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + +#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray) +#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays) +#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays) +#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray) + +#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object) + +#endif /* GL_ARB_vertex_array_object */ + +/* ----------------------- GL_ARB_vertex_attrib_64bit ---------------------- */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); + +#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv) +#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d) +#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv) +#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d) +#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv) +#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d) +#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv) +#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d) +#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv) +#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer) + +#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit) + +#endif /* GL_ARB_vertex_attrib_64bit */ + +/* ---------------------- GL_ARB_vertex_attrib_binding --------------------- */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 + +#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 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); + +#define glBindVertexBuffer GLEW_GET_FUN(__glewBindVertexBuffer) +#define glVertexArrayBindVertexBufferEXT GLEW_GET_FUN(__glewVertexArrayBindVertexBufferEXT) +#define glVertexArrayVertexAttribBindingEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribBindingEXT) +#define glVertexArrayVertexAttribFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribFormatEXT) +#define glVertexArrayVertexAttribIFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIFormatEXT) +#define glVertexArrayVertexAttribLFormatEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLFormatEXT) +#define glVertexArrayVertexBindingDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexBindingDivisorEXT) +#define glVertexAttribBinding GLEW_GET_FUN(__glewVertexAttribBinding) +#define glVertexAttribFormat GLEW_GET_FUN(__glewVertexAttribFormat) +#define glVertexAttribIFormat GLEW_GET_FUN(__glewVertexAttribIFormat) +#define glVertexAttribLFormat GLEW_GET_FUN(__glewVertexAttribLFormat) +#define glVertexBindingDivisor GLEW_GET_FUN(__glewVertexBindingDivisor) + +#define GLEW_ARB_vertex_attrib_binding GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_binding) + +#endif /* GL_ARB_vertex_attrib_binding */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#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_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 (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#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 ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#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_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#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_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#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_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 +#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_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#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 (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#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 (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* ------------------- GL_ARB_vertex_type_10f_11f_11f_rev ------------------ */ + +#ifndef GL_ARB_vertex_type_10f_11f_11f_rev +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 + +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B + +#define GLEW_ARB_vertex_type_10f_11f_11f_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_10f_11f_11f_rev) + +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 + +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_INT_2_10_10_10_REV 0x8D9F + +typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value); + +#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui) +#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv) +#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui) +#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv) +#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui) +#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv) +#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui) +#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv) +#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui) +#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv) +#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui) +#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv) +#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui) +#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv) +#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui) +#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv) +#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui) +#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv) +#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui) +#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv) +#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui) +#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv) +#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui) +#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv) +#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui) +#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv) +#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui) +#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv) +#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui) +#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv) +#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui) +#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv) +#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui) +#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv) +#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui) +#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv) +#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui) +#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv) + +#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev) + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +/* ------------------------- GL_ARB_viewport_array ------------------------- */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 + +#define GL_DEPTH_RANGE 0x0B70 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#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 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F + +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v); + +#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv) +#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed) +#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v) +#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v) +#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv) +#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed) +#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv) +#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv) +#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf) +#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv) + +#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array) + +#endif /* GL_ARB_viewport_array */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ----------------------- GL_ARM_mali_program_binary ---------------------- */ + +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 + +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 + +#define GLEW_ARM_mali_program_binary GLEW_GET_VAR(__GLEW_ARM_mali_program_binary) + +#endif /* GL_ARM_mali_program_binary */ + +/* ----------------------- GL_ARM_mali_shader_binary ----------------------- */ + +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 + +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 + +#define GLEW_ARM_mali_shader_binary GLEW_GET_VAR(__GLEW_ARM_mali_shader_binary) + +#endif /* GL_ARM_mali_shader_binary */ + +/* ------------------------------ GL_ARM_rgba8 ----------------------------- */ + +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 + +#define GL_RGBA8_OES 0x8058 + +#define GLEW_ARM_rgba8 GLEW_GET_VAR(__GLEW_ARM_rgba8) + +#endif /* GL_ARM_rgba8 */ + +/* -------------------- GL_ARM_shader_framebuffer_fetch -------------------- */ + +#ifndef GL_ARM_shader_framebuffer_fetch +#define GL_ARM_shader_framebuffer_fetch 1 + +#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 +#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 + +#define GLEW_ARM_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch) + +#endif /* GL_ARM_shader_framebuffer_fetch */ + +/* ------------- GL_ARM_shader_framebuffer_fetch_depth_stencil ------------- */ + +#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil +#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 + +#define GLEW_ARM_shader_framebuffer_fetch_depth_stencil GLEW_GET_VAR(__GLEW_ARM_shader_framebuffer_fetch_depth_stencil) + +#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0 +#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1 +#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2 +#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3 +#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4 +#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#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 (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#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 (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#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 (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_2X_BIT_ATI 0x00000001 +#define GL_RED_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#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_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_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_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 + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void * (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* ----------------------------- GL_ATI_meminfo ---------------------------- */ + +#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 + +#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo) + +#endif /* GL_ATI_meminfo */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#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 (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glewPNTrianglesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#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 (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */ + +#ifndef GL_ATI_shader_texture_lod +#define GL_ATI_shader_texture_lod 1 + +#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod) + +#endif /* GL_ATI_shader_texture_lod */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#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 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#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 + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#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 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#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 void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream1dATI GLEW_GET_FUN(__glewVertexStream1dATI) +#define glVertexStream1dvATI GLEW_GET_FUN(__glewVertexStream1dvATI) +#define glVertexStream1fATI GLEW_GET_FUN(__glewVertexStream1fATI) +#define glVertexStream1fvATI GLEW_GET_FUN(__glewVertexStream1fvATI) +#define glVertexStream1iATI GLEW_GET_FUN(__glewVertexStream1iATI) +#define glVertexStream1ivATI GLEW_GET_FUN(__glewVertexStream1ivATI) +#define glVertexStream1sATI GLEW_GET_FUN(__glewVertexStream1sATI) +#define glVertexStream1svATI GLEW_GET_FUN(__glewVertexStream1svATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* -------------------- GL_EGL_KHR_context_flush_control ------------------- */ + +#ifndef GL_EGL_KHR_context_flush_control +#define GL_EGL_KHR_context_flush_control 1 + +#define GLEW_EGL_KHR_context_flush_control GLEW_GET_VAR(__GLEW_EGL_KHR_context_flush_control) + +#endif /* GL_EGL_KHR_context_flush_control */ + +/* ---------------- GL_EGL_NV_robustness_video_memory_purge ---------------- */ + +#ifndef GL_EGL_NV_robustness_video_memory_purge +#define GL_EGL_NV_robustness_video_memory_purge 1 + +#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB + +#define GLEW_EGL_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_EGL_NV_robustness_video_memory_purge) + +#endif /* GL_EGL_NV_robustness_video_memory_purge */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#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 + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------- GL_EXT_EGL_image_array ------------------------ */ + +#ifndef GL_EXT_EGL_image_array +#define GL_EXT_EGL_image_array 1 + +#define GLEW_EXT_EGL_image_array GLEW_GET_VAR(__GLEW_EXT_EGL_image_array) + +#endif /* GL_EXT_EGL_image_array */ + +/* --------------------------- GL_EXT_YUV_target --------------------------- */ + +#ifndef GL_EXT_YUV_target +#define GL_EXT_YUV_target 1 + +#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 + +#define GLEW_EXT_YUV_target GLEW_GET_VAR(__GLEW_EXT_YUV_target) + +#endif /* GL_EXT_YUV_target */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* -------------------------- GL_EXT_base_instance ------------------------- */ + +#ifndef GL_EXT_base_instance +#define GL_EXT_base_instance 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); + +#define glDrawArraysInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstanceEXT) +#define glDrawElementsInstancedBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstanceEXT) +#define glDrawElementsInstancedBaseVertexBaseInstanceEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstanceEXT) + +#define GLEW_EXT_base_instance GLEW_GET_VAR(__GLEW_EXT_base_instance) + +#endif /* GL_EXT_base_instance */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* ------------------------ GL_EXT_bindable_uniform ------------------------ */ + +#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 GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); + +#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT) +#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT) +#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT) + +#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform) + +#endif /* GL_EXT_bindable_uniform */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#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 (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#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 (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_extended ---------------------- */ + +#ifndef GL_EXT_blend_func_extended +#define GL_EXT_blend_func_extended 1 + +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_SRC1_ALPHA_EXT 0x8589 +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +#define GL_LOCATION_INDEX_EXT 0x930F + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar * name); +typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar* name); + +#define glBindFragDataLocationIndexedEXT GLEW_GET_FUN(__glewBindFragDataLocationIndexedEXT) +#define glGetFragDataIndexEXT GLEW_GET_FUN(__glewGetFragDataIndexEXT) +#define glGetProgramResourceLocationIndexEXT GLEW_GET_FUN(__glewGetProgramResourceLocationIndexEXT) + +#define GLEW_EXT_blend_func_extended GLEW_GET_VAR(__GLEW_EXT_blend_func_extended) + +#endif /* GL_EXT_blend_func_extended */ + +/* ----------------------- GL_EXT_blend_func_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 (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------- GL_EXT_buffer_storage ------------------------- */ + +#ifndef GL_EXT_buffer_storage +#define GL_EXT_buffer_storage 1 + +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 + +typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); + +#define glBufferStorageEXT GLEW_GET_FUN(__glewBufferStorageEXT) +#define glNamedBufferStorageEXT GLEW_GET_FUN(__glewNamedBufferStorageEXT) + +#define GLEW_EXT_buffer_storage GLEW_GET_VAR(__GLEW_EXT_buffer_storage) + +#endif /* GL_EXT_buffer_storage */ + +/* -------------------------- GL_EXT_clear_texture ------------------------- */ + +#ifndef GL_EXT_clear_texture +#define GL_EXT_clear_texture 1 + +typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); + +#define glClearTexImageEXT GLEW_GET_FUN(__glewClearTexImageEXT) +#define glClearTexSubImageEXT GLEW_GET_FUN(__glewClearTexSubImageEXT) + +#define GLEW_EXT_clear_texture GLEW_GET_VAR(__GLEW_EXT_clear_texture) + +#endif /* GL_EXT_clear_texture */ + +/* ----------------------- GL_EXT_clip_cull_distance ----------------------- */ + +#ifndef GL_EXT_clip_cull_distance +#define GL_EXT_clip_cull_distance 1 + +#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 +#define GL_CLIP_DISTANCE0_EXT 0x3000 +#define GL_CLIP_DISTANCE1_EXT 0x3001 +#define GL_CLIP_DISTANCE2_EXT 0x3002 +#define GL_CLIP_DISTANCE3_EXT 0x3003 +#define GL_CLIP_DISTANCE4_EXT 0x3004 +#define GL_CLIP_DISTANCE5_EXT 0x3005 +#define GL_CLIP_DISTANCE6_EXT 0x3006 +#define GL_CLIP_DISTANCE7_EXT 0x3007 +#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA + +#define GLEW_EXT_clip_cull_distance GLEW_GET_VAR(__GLEW_EXT_clip_cull_distance) + +#endif /* GL_EXT_clip_cull_distance */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#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 + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ----------------------- GL_EXT_color_buffer_float ----------------------- */ + +#ifndef GL_EXT_color_buffer_float +#define GL_EXT_color_buffer_float 1 + +#define GLEW_EXT_color_buffer_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_float) + +#endif /* GL_EXT_color_buffer_float */ + +/* --------------------- GL_EXT_color_buffer_half_float -------------------- */ + +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 + +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 + +#define GLEW_EXT_color_buffer_half_float GLEW_GET_VAR(__GLEW_EXT_color_buffer_half_float) + +#endif /* GL_EXT_color_buffer_half_float */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#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 (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* ---------------- GL_EXT_compressed_ETC1_RGB8_sub_texture ---------------- */ + +#ifndef GL_EXT_compressed_ETC1_RGB8_sub_texture +#define GL_EXT_compressed_ETC1_RGB8_sub_texture 1 + +#define GLEW_EXT_compressed_ETC1_RGB8_sub_texture GLEW_GET_VAR(__GLEW_EXT_compressed_ETC1_RGB8_sub_texture) + +#endif /* GL_EXT_compressed_ETC1_RGB8_sub_texture */ + +/* ----------------------- GL_EXT_conservative_depth ----------------------- */ + +#ifndef GL_EXT_conservative_depth +#define GL_EXT_conservative_depth 1 + +#define GLEW_EXT_conservative_depth GLEW_GET_VAR(__GLEW_EXT_conservative_depth) + +#endif /* GL_EXT_conservative_depth */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#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 (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#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 (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void *pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* --------------------------- GL_EXT_copy_image --------------------------- */ + +#ifndef GL_EXT_copy_image +#define GL_EXT_copy_image 1 + +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAEXTPROC) (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); + +#define glCopyImageSubDataEXT GLEW_GET_FUN(__glewCopyImageSubDataEXT) + +#define GLEW_EXT_copy_image GLEW_GET_VAR(__GLEW_EXT_copy_image) + +#endif /* GL_EXT_copy_image */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#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 (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* --------------------------- GL_EXT_debug_label -------------------------- */ + +#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 (GLAPIENTRY * PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar* label); + +#define glGetObjectLabelEXT GLEW_GET_FUN(__glewGetObjectLabelEXT) +#define glLabelObjectEXT GLEW_GET_FUN(__glewLabelObjectEXT) + +#define GLEW_EXT_debug_label GLEW_GET_VAR(__GLEW_EXT_debug_label) + +#endif /* GL_EXT_debug_label */ + +/* -------------------------- GL_EXT_debug_marker -------------------------- */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 + +typedef void (GLAPIENTRY * PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar* marker); +typedef void (GLAPIENTRY * PFNGLPOPGROUPMARKEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar* marker); + +#define glInsertEventMarkerEXT GLEW_GET_FUN(__glewInsertEventMarkerEXT) +#define glPopGroupMarkerEXT GLEW_GET_FUN(__glewPopGroupMarkerEXT) +#define glPushGroupMarkerEXT GLEW_GET_FUN(__glewPushGroupMarkerEXT) + +#define GLEW_EXT_debug_marker GLEW_GET_VAR(__GLEW_EXT_debug_marker) + +#endif /* GL_EXT_debug_marker */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#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 (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_direct_state_access ---------------------- */ + +#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 (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * 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 *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * 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 *data); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void *img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void *img); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void** params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void** params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void** param); +typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void** param); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * 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 GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); + +#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT) +#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT) +#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT) +#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT) +#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT) +#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT) +#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT) +#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT) +#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT) +#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT) +#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT) +#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT) +#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT) +#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT) +#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT) +#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT) +#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT) +#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT) +#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT) +#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT) +#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT) +#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT) +#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT) +#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT) +#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT) +#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT) +#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT) +#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT) +#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT) +#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT) +#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT) +#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT) +#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT) +#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT) +#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT) +#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT) +#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT) +#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT) +#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT) +#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT) +#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT) +#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT) +#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT) +#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT) +#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT) +#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT) +#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT) +#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT) +#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT) +#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT) +#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT) +#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT) +#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT) +#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT) +#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT) +#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT) +#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT) +#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT) +#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT) +#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT) +#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT) +#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT) +#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT) +#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT) +#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT) +#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT) +#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT) +#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT) +#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT) +#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT) +#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT) +#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT) +#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT) +#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT) +#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT) +#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT) +#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT) +#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT) +#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT) +#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT) +#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT) +#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT) +#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT) +#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT) +#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT) +#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT) +#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT) +#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT) +#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT) +#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT) +#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT) +#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT) +#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT) +#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT) +#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT) +#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT) +#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT) +#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT) +#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT) +#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT) +#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT) +#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT) +#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT) +#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT) +#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT) +#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT) +#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT) +#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT) +#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT) +#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT) +#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT) +#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT) +#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT) +#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT) +#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT) +#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT) +#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT) +#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT) +#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT) +#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT) +#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT) +#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT) +#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT) +#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT) +#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT) +#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT) +#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT) +#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT) +#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT) +#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT) +#define glVertexArrayVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribDivisorEXT) +#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT) +#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT) +#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT) + +#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access) + +#endif /* GL_EXT_direct_state_access */ + +/* ----------------------- GL_EXT_discard_framebuffer ---------------------- */ + +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 + +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 + +typedef void (GLAPIENTRY * PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments); + +#define glDiscardFramebufferEXT GLEW_GET_FUN(__glewDiscardFramebufferEXT) + +#define GLEW_EXT_discard_framebuffer GLEW_GET_VAR(__GLEW_EXT_discard_framebuffer) + +#endif /* GL_EXT_discard_framebuffer */ + +/* -------------------------- GL_EXT_draw_buffers -------------------------- */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#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 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersEXT GLEW_GET_FUN(__glewDrawBuffersEXT) + +#define GLEW_EXT_draw_buffers GLEW_GET_VAR(__GLEW_EXT_draw_buffers) + +#endif /* GL_EXT_draw_buffers */ + +/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 + +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + +#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT) +#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT) +#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT) +#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT) +#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT) +#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT) + +#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2) + +#endif /* GL_EXT_draw_buffers2 */ + +/* ---------------------- GL_EXT_draw_buffers_indexed ---------------------- */ + +#ifndef GL_EXT_draw_buffers_indexed +#define GL_EXT_draw_buffers_indexed 1 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEIEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index); + +#define glBlendEquationSeparateiEXT GLEW_GET_FUN(__glewBlendEquationSeparateiEXT) +#define glBlendEquationiEXT GLEW_GET_FUN(__glewBlendEquationiEXT) +#define glBlendFuncSeparateiEXT GLEW_GET_FUN(__glewBlendFuncSeparateiEXT) +#define glBlendFunciEXT GLEW_GET_FUN(__glewBlendFunciEXT) +#define glColorMaskiEXT GLEW_GET_FUN(__glewColorMaskiEXT) +#define glDisableiEXT GLEW_GET_FUN(__glewDisableiEXT) +#define glEnableiEXT GLEW_GET_FUN(__glewEnableiEXT) +#define glIsEnablediEXT GLEW_GET_FUN(__glewIsEnablediEXT) + +#define GLEW_EXT_draw_buffers_indexed GLEW_GET_VAR(__GLEW_EXT_draw_buffers_indexed) + +#endif /* GL_EXT_draw_buffers_indexed */ + +/* -------------------- GL_EXT_draw_elements_base_vertex ------------------- */ + +#ifndef GL_EXT_draw_elements_base_vertex +#define GL_EXT_draw_elements_base_vertex 1 + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount, const GLint *basevertex); + +#define glDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsBaseVertexEXT) +#define glDrawElementsInstancedBaseVertexEXT GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexEXT) +#define glDrawRangeElementsBaseVertexEXT GLEW_GET_FUN(__glewDrawRangeElementsBaseVertexEXT) +#define glMultiDrawElementsBaseVertexEXT GLEW_GET_FUN(__glewMultiDrawElementsBaseVertexEXT) + +#define GLEW_EXT_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_EXT_draw_elements_base_vertex) + +#endif /* GL_EXT_draw_elements_base_vertex */ + +/* ------------------------- GL_EXT_draw_instanced ------------------------- */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); + +#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT) +#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT) + +#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced) + +#endif /* GL_EXT_draw_instanced */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#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 (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ------------------------- GL_EXT_external_buffer ------------------------ */ + +#ifndef GL_EXT_external_buffer +#define GL_EXT_external_buffer 1 + +typedef void* GLeglClientBufferEXT; + +typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); + +#define glBufferStorageExternalEXT GLEW_GET_FUN(__glewBufferStorageExternalEXT) +#define glNamedBufferStorageExternalEXT GLEW_GET_FUN(__glewNamedBufferStorageExternalEXT) + +#define GLEW_EXT_external_buffer GLEW_GET_VAR(__GLEW_EXT_external_buffer) + +#endif /* GL_EXT_external_buffer */ + +/* --------------------------- GL_EXT_float_blend -------------------------- */ + +#ifndef GL_EXT_float_blend +#define GL_EXT_float_blend 1 + +#define GLEW_EXT_float_blend GLEW_GET_VAR(__GLEW_EXT_float_blend) + +#endif /* GL_EXT_float_blend */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#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 (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* --------------------------- GL_EXT_frag_depth --------------------------- */ + +#ifndef GL_EXT_frag_depth +#define GL_EXT_frag_depth 1 + +#define GLEW_EXT_frag_depth GLEW_GET_VAR(__GLEW_EXT_frag_depth) + +#endif /* GL_EXT_frag_depth */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#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 (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* --------------- GL_EXT_framebuffer_multisample_blit_scaled -------------- */ + +#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 + +#define GLEW_EXT_framebuffer_multisample_blit_scaled GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample_blit_scaled) + +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#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 void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA + +#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB) + +#endif /* GL_EXT_framebuffer_sRGB */ + +/* ----------------------- GL_EXT_geometry_point_size ---------------------- */ + +#ifndef GL_EXT_geometry_point_size +#define GL_EXT_geometry_point_size 1 + +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#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_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 + +#define GLEW_EXT_geometry_point_size GLEW_GET_VAR(__GLEW_EXT_geometry_point_size) + +#endif /* GL_EXT_geometry_point_size */ + +/* ------------------------- GL_EXT_geometry_shader ------------------------ */ + +#ifndef GL_EXT_geometry_shader +#define GL_EXT_geometry_shader 1 + +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#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_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 + +#define GLEW_EXT_geometry_shader GLEW_GET_VAR(__GLEW_EXT_geometry_shader) + +#endif /* GL_EXT_geometry_shader */ + +/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 + +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#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_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#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 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); + +#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT) +#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT) +#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT) + +#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4) + +#endif /* GL_EXT_geometry_shader4 */ + +/* --------------------- GL_EXT_gpu_program_parameters --------------------- */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 + +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params); + +#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT) +#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT) + +#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters) + +#endif /* GL_EXT_gpu_program_parameters */ + +/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */ + +#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 + +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + +#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT) +#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT) +#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT) +#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT) +#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT) +#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT) +#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT) +#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT) +#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT) +#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT) +#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT) +#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT) +#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT) +#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT) +#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT) +#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT) +#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT) +#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT) +#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT) +#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT) +#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT) +#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT) +#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT) +#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT) +#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT) +#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT) +#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT) +#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT) +#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT) +#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT) +#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT) +#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT) +#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT) +#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT) + +#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4) + +#endif /* GL_EXT_gpu_shader4 */ + +/* --------------------------- GL_EXT_gpu_shader5 -------------------------- */ + +#ifndef GL_EXT_gpu_shader5 +#define GL_EXT_gpu_shader5 1 + +#define GLEW_EXT_gpu_shader5 GLEW_GET_VAR(__GLEW_EXT_gpu_shader5) + +#endif /* GL_EXT_gpu_shader5 */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#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 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* ------------------------ GL_EXT_instanced_arrays ------------------------ */ + +#ifndef GL_EXT_instanced_arrays +#define GL_EXT_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisorEXT GLEW_GET_FUN(__glewVertexAttribDivisorEXT) + +#define GLEW_EXT_instanced_arrays GLEW_GET_VAR(__GLEW_EXT_instanced_arrays) + +#endif /* GL_EXT_instanced_arrays */ + +/* -------------------------- GL_EXT_light_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 (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------ GL_EXT_map_buffer_range ------------------------ */ + +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 + +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 + +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + +#define glFlushMappedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedBufferRangeEXT) +#define glMapBufferRangeEXT GLEW_GET_FUN(__glewMapBufferRangeEXT) + +#define GLEW_EXT_map_buffer_range GLEW_GET_VAR(__GLEW_EXT_map_buffer_range) + +#endif /* GL_EXT_map_buffer_range */ + +/* -------------------------- GL_EXT_memory_object ------------------------- */ + +#ifndef GL_EXT_memory_object +#define GL_EXT_memory_object 1 + +#define GL_UUID_SIZE_EXT 16 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B + +typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint* memoryObjects); +typedef void (GLAPIENTRY * PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint* memoryObjects); +typedef void (GLAPIENTRY * PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte* data); +typedef void (GLAPIENTRY * PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte* data); +typedef GLboolean (GLAPIENTRY * PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); +typedef void (GLAPIENTRY * PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); + +#define glBufferStorageMemEXT GLEW_GET_FUN(__glewBufferStorageMemEXT) +#define glCreateMemoryObjectsEXT GLEW_GET_FUN(__glewCreateMemoryObjectsEXT) +#define glDeleteMemoryObjectsEXT GLEW_GET_FUN(__glewDeleteMemoryObjectsEXT) +#define glGetMemoryObjectParameterivEXT GLEW_GET_FUN(__glewGetMemoryObjectParameterivEXT) +#define glGetUnsignedBytei_vEXT GLEW_GET_FUN(__glewGetUnsignedBytei_vEXT) +#define glGetUnsignedBytevEXT GLEW_GET_FUN(__glewGetUnsignedBytevEXT) +#define glIsMemoryObjectEXT GLEW_GET_FUN(__glewIsMemoryObjectEXT) +#define glMemoryObjectParameterivEXT GLEW_GET_FUN(__glewMemoryObjectParameterivEXT) +#define glNamedBufferStorageMemEXT GLEW_GET_FUN(__glewNamedBufferStorageMemEXT) +#define glTexStorageMem1DEXT GLEW_GET_FUN(__glewTexStorageMem1DEXT) +#define glTexStorageMem2DEXT GLEW_GET_FUN(__glewTexStorageMem2DEXT) +#define glTexStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem2DMultisampleEXT) +#define glTexStorageMem3DEXT GLEW_GET_FUN(__glewTexStorageMem3DEXT) +#define glTexStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTexStorageMem3DMultisampleEXT) +#define glTextureStorageMem1DEXT GLEW_GET_FUN(__glewTextureStorageMem1DEXT) +#define glTextureStorageMem2DEXT GLEW_GET_FUN(__glewTextureStorageMem2DEXT) +#define glTextureStorageMem2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem2DMultisampleEXT) +#define glTextureStorageMem3DEXT GLEW_GET_FUN(__glewTextureStorageMem3DEXT) +#define glTextureStorageMem3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorageMem3DMultisampleEXT) + +#define GLEW_EXT_memory_object GLEW_GET_VAR(__GLEW_EXT_memory_object) + +#endif /* GL_EXT_memory_object */ + +/* ------------------------ GL_EXT_memory_object_fd ------------------------ */ + +#ifndef GL_EXT_memory_object_fd +#define GL_EXT_memory_object_fd 1 + +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 + +typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); + +#define glImportMemoryFdEXT GLEW_GET_FUN(__glewImportMemoryFdEXT) + +#define GLEW_EXT_memory_object_fd GLEW_GET_VAR(__GLEW_EXT_memory_object_fd) + +#endif /* GL_EXT_memory_object_fd */ + +/* ----------------------- GL_EXT_memory_object_win32 ---------------------- */ + +#ifndef GL_EXT_memory_object_win32 +#define GL_EXT_memory_object_win32 1 + +#define GL_LUID_SIZE_EXT 8 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A + +typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +typedef void (GLAPIENTRY * PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); + +#define glImportMemoryWin32HandleEXT GLEW_GET_FUN(__glewImportMemoryWin32HandleEXT) +#define glImportMemoryWin32NameEXT GLEW_GET_FUN(__glewImportMemoryWin32NameEXT) + +#define GLEW_EXT_memory_object_win32 GLEW_GET_VAR(__GLEW_EXT_memory_object_win32) + +#endif /* GL_EXT_memory_object_win32 */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const void *const *indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* ----------------------- GL_EXT_multi_draw_indirect ---------------------- */ + +#ifndef GL_EXT_multi_draw_indirect +#define GL_EXT_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); + +#define glMultiDrawArraysIndirectEXT GLEW_GET_FUN(__glewMultiDrawArraysIndirectEXT) +#define glMultiDrawElementsIndirectEXT GLEW_GET_FUN(__glewMultiDrawElementsIndirectEXT) + +#define GLEW_EXT_multi_draw_indirect GLEW_GET_VAR(__GLEW_EXT_multi_draw_indirect) + +#endif /* GL_EXT_multi_draw_indirect */ + +/* ------------------------ GL_EXT_multiple_textures ----------------------- */ + +#ifndef GL_EXT_multiple_textures +#define GL_EXT_multiple_textures 1 + +#define GLEW_EXT_multiple_textures GLEW_GET_VAR(__GLEW_EXT_multiple_textures) + +#endif /* GL_EXT_multiple_textures */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#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 (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* -------------------- GL_EXT_multisample_compatibility ------------------- */ + +#ifndef GL_EXT_multisample_compatibility +#define GL_EXT_multisample_compatibility 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F + +#define GLEW_EXT_multisample_compatibility GLEW_GET_VAR(__GLEW_EXT_multisample_compatibility) + +#endif /* GL_EXT_multisample_compatibility */ + +/* ----------------- GL_EXT_multisampled_render_to_texture ----------------- */ + +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); + +#define glFramebufferTexture2DMultisampleEXT GLEW_GET_FUN(__glewFramebufferTexture2DMultisampleEXT) + +#define GLEW_EXT_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture) + +#endif /* GL_EXT_multisampled_render_to_texture */ + +/* ----------------- GL_EXT_multisampled_render_to_texture2 ---------------- */ + +#ifndef GL_EXT_multisampled_render_to_texture2 +#define GL_EXT_multisampled_render_to_texture2 1 + +#define GLEW_EXT_multisampled_render_to_texture2 GLEW_GET_VAR(__GLEW_EXT_multisampled_render_to_texture2) + +#endif /* GL_EXT_multisampled_render_to_texture2 */ + +/* --------------------- GL_EXT_multiview_draw_buffers --------------------- */ + +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 + +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum* location, const GLint *indices); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint* data); +typedef void (GLAPIENTRY * PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); + +#define glDrawBuffersIndexedEXT GLEW_GET_FUN(__glewDrawBuffersIndexedEXT) +#define glGetIntegeri_vEXT GLEW_GET_FUN(__glewGetIntegeri_vEXT) +#define glReadBufferIndexedEXT GLEW_GET_FUN(__glewReadBufferIndexedEXT) + +#define GLEW_EXT_multiview_draw_buffers GLEW_GET_VAR(__GLEW_EXT_multiview_draw_buffers) + +#endif /* GL_EXT_multiview_draw_buffers */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#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 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_float -------------------------- */ + +#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 + +#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float) + +#endif /* GL_EXT_packed_float */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#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 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#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 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#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 + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#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 (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#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 (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#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 (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ---------------------- GL_EXT_polygon_offset_clamp ---------------------- */ + +#ifndef GL_EXT_polygon_offset_clamp +#define GL_EXT_polygon_offset_clamp 1 + +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); + +#define glPolygonOffsetClampEXT GLEW_GET_FUN(__glewPolygonOffsetClampEXT) + +#define GLEW_EXT_polygon_offset_clamp GLEW_GET_VAR(__GLEW_EXT_polygon_offset_clamp) + +#endif /* GL_EXT_polygon_offset_clamp */ + +/* ----------------------- GL_EXT_post_depth_coverage ---------------------- */ + +#ifndef GL_EXT_post_depth_coverage +#define GL_EXT_post_depth_coverage 1 + +#define GLEW_EXT_post_depth_coverage GLEW_GET_VAR(__GLEW_EXT_post_depth_coverage) + +#endif /* GL_EXT_post_depth_coverage */ + +/* ------------------------ GL_EXT_provoking_vertex ------------------------ */ + +#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 (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); + +#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT) + +#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex) + +#endif /* GL_EXT_provoking_vertex */ + +/* --------------------------- GL_EXT_pvrtc_sRGB --------------------------- */ + +#ifndef GL_EXT_pvrtc_sRGB +#define GL_EXT_pvrtc_sRGB 1 + +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 + +#define GLEW_EXT_pvrtc_sRGB GLEW_GET_VAR(__GLEW_EXT_pvrtc_sRGB) + +#endif /* GL_EXT_pvrtc_sRGB */ + +/* ----------------------- GL_EXT_raster_multisample ----------------------- */ + +#ifndef GL_EXT_raster_multisample +#define GL_EXT_raster_multisample 1 + +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 + +typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); +typedef void (GLAPIENTRY * PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat* v); +typedef void (GLAPIENTRY * PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); + +#define glCoverageModulationNV GLEW_GET_FUN(__glewCoverageModulationNV) +#define glCoverageModulationTableNV GLEW_GET_FUN(__glewCoverageModulationTableNV) +#define glGetCoverageModulationTableNV GLEW_GET_FUN(__glewGetCoverageModulationTableNV) +#define glRasterSamplesEXT GLEW_GET_FUN(__glewRasterSamplesEXT) + +#define GLEW_EXT_raster_multisample GLEW_GET_VAR(__GLEW_EXT_raster_multisample) + +#endif /* GL_EXT_raster_multisample */ + +/* ------------------------ GL_EXT_read_format_bgra ------------------------ */ + +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 + +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 + +#define GLEW_EXT_read_format_bgra GLEW_GET_VAR(__GLEW_EXT_read_format_bgra) + +#endif /* GL_EXT_read_format_bgra */ + +/* -------------------------- GL_EXT_render_snorm -------------------------- */ + +#ifndef GL_EXT_render_snorm +#define GL_EXT_render_snorm 1 + +#define GL_BYTE 0x1400 +#define GL_SHORT 0x1402 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RGBA16_SNORM_EXT 0x8F9B + +#define GLEW_EXT_render_snorm GLEW_GET_VAR(__GLEW_EXT_render_snorm) + +#endif /* GL_EXT_render_snorm */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GL_RESCALE_NORMAL_EXT 0x803A + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* ------------------------------ GL_EXT_sRGB ------------------------------ */ + +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 + +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 + +#define GLEW_EXT_sRGB GLEW_GET_VAR(__GLEW_EXT_sRGB) + +#endif /* GL_EXT_sRGB */ + +/* ----------------------- GL_EXT_sRGB_write_control ----------------------- */ + +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 + +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 + +#define GLEW_EXT_sRGB_write_control GLEW_GET_VAR(__GLEW_EXT_sRGB_write_control) + +#endif /* GL_EXT_sRGB_write_control */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#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 (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* ---------------------------- GL_EXT_semaphore --------------------------- */ + +#ifndef GL_EXT_semaphore +#define GL_EXT_semaphore 1 + +typedef void (GLAPIENTRY * PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint* semaphores); +typedef void (GLAPIENTRY * PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint* semaphores); +typedef void (GLAPIENTRY * PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64* params); +typedef GLboolean (GLAPIENTRY * PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); +typedef void (GLAPIENTRY * PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64* params); +typedef void (GLAPIENTRY * PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +typedef void (GLAPIENTRY * PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint* buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); + +#define glDeleteSemaphoresEXT GLEW_GET_FUN(__glewDeleteSemaphoresEXT) +#define glGenSemaphoresEXT GLEW_GET_FUN(__glewGenSemaphoresEXT) +#define glGetSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewGetSemaphoreParameterui64vEXT) +#define glIsSemaphoreEXT GLEW_GET_FUN(__glewIsSemaphoreEXT) +#define glSemaphoreParameterui64vEXT GLEW_GET_FUN(__glewSemaphoreParameterui64vEXT) +#define glSignalSemaphoreEXT GLEW_GET_FUN(__glewSignalSemaphoreEXT) +#define glWaitSemaphoreEXT GLEW_GET_FUN(__glewWaitSemaphoreEXT) + +#define GLEW_EXT_semaphore GLEW_GET_VAR(__GLEW_EXT_semaphore) + +#endif /* GL_EXT_semaphore */ + +/* -------------------------- GL_EXT_semaphore_fd -------------------------- */ + +#ifndef GL_EXT_semaphore_fd +#define GL_EXT_semaphore_fd 1 + +typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); + +#define glImportSemaphoreFdEXT GLEW_GET_FUN(__glewImportSemaphoreFdEXT) + +#define GLEW_EXT_semaphore_fd GLEW_GET_VAR(__GLEW_EXT_semaphore_fd) + +#endif /* GL_EXT_semaphore_fd */ + +/* ------------------------- GL_EXT_semaphore_win32 ------------------------ */ + +#ifndef GL_EXT_semaphore_win32 +#define GL_EXT_semaphore_win32 1 + +typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); +typedef void (GLAPIENTRY * PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); + +#define glImportSemaphoreWin32HandleEXT GLEW_GET_FUN(__glewImportSemaphoreWin32HandleEXT) +#define glImportSemaphoreWin32NameEXT GLEW_GET_FUN(__glewImportSemaphoreWin32NameEXT) + +#define GLEW_EXT_semaphore_win32 GLEW_GET_VAR(__GLEW_EXT_semaphore_win32) + +#endif /* GL_EXT_semaphore_win32 */ + +/* --------------------- GL_EXT_separate_shader_objects -------------------- */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 + +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D + +typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar* string); +typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); + +#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT) +#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT) +#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT) + +#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects) + +#endif /* GL_EXT_separate_shader_objects */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#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 + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* -------------------- GL_EXT_shader_framebuffer_fetch -------------------- */ + +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 + +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 + +#define GLEW_EXT_shader_framebuffer_fetch GLEW_GET_VAR(__GLEW_EXT_shader_framebuffer_fetch) + +#endif /* GL_EXT_shader_framebuffer_fetch */ + +/* ------------------------ GL_EXT_shader_group_vote ----------------------- */ + +#ifndef GL_EXT_shader_group_vote +#define GL_EXT_shader_group_vote 1 + +#define GLEW_EXT_shader_group_vote GLEW_GET_VAR(__GLEW_EXT_shader_group_vote) + +#endif /* GL_EXT_shader_group_vote */ + +/* ------------------- GL_EXT_shader_image_load_formatted ------------------ */ + +#ifndef GL_EXT_shader_image_load_formatted +#define GL_EXT_shader_image_load_formatted 1 + +#define GLEW_EXT_shader_image_load_formatted GLEW_GET_VAR(__GLEW_EXT_shader_image_load_formatted) + +#endif /* GL_EXT_shader_image_load_formatted */ + +/* --------------------- GL_EXT_shader_image_load_store -------------------- */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 + +#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_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_ALL_BARRIER_BITS_EXT 0xFFFFFFFF + +typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); + +#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT) +#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT) + +#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store) + +#endif /* GL_EXT_shader_image_load_store */ + +/* ------------------- GL_EXT_shader_implicit_conversions ------------------ */ + +#ifndef GL_EXT_shader_implicit_conversions +#define GL_EXT_shader_implicit_conversions 1 + +#define GLEW_EXT_shader_implicit_conversions GLEW_GET_VAR(__GLEW_EXT_shader_implicit_conversions) + +#endif /* GL_EXT_shader_implicit_conversions */ + +/* ----------------------- GL_EXT_shader_integer_mix ----------------------- */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 + +#define GLEW_EXT_shader_integer_mix GLEW_GET_VAR(__GLEW_EXT_shader_integer_mix) + +#endif /* GL_EXT_shader_integer_mix */ + +/* ------------------------ GL_EXT_shader_io_blocks ------------------------ */ + +#ifndef GL_EXT_shader_io_blocks +#define GL_EXT_shader_io_blocks 1 + +#define GLEW_EXT_shader_io_blocks GLEW_GET_VAR(__GLEW_EXT_shader_io_blocks) + +#endif /* GL_EXT_shader_io_blocks */ + +/* ------------- GL_EXT_shader_non_constant_global_initializers ------------ */ + +#ifndef GL_EXT_shader_non_constant_global_initializers +#define GL_EXT_shader_non_constant_global_initializers 1 + +#define GLEW_EXT_shader_non_constant_global_initializers GLEW_GET_VAR(__GLEW_EXT_shader_non_constant_global_initializers) + +#endif /* GL_EXT_shader_non_constant_global_initializers */ + +/* ------------------- GL_EXT_shader_pixel_local_storage ------------------- */ + +#ifndef GL_EXT_shader_pixel_local_storage +#define GL_EXT_shader_pixel_local_storage 1 + +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 +#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 + +#define GLEW_EXT_shader_pixel_local_storage GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage) + +#endif /* GL_EXT_shader_pixel_local_storage */ + +/* ------------------- GL_EXT_shader_pixel_local_storage2 ------------------ */ + +#ifndef GL_EXT_shader_pixel_local_storage2 +#define GL_EXT_shader_pixel_local_storage2 1 + +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 +#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 + +typedef void (GLAPIENTRY * PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint* values); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size); +typedef GLsizei (GLAPIENTRY * PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target); + +#define glClearPixelLocalStorageuiEXT GLEW_GET_FUN(__glewClearPixelLocalStorageuiEXT) +#define glFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewFramebufferPixelLocalStorageSizeEXT) +#define glGetFramebufferPixelLocalStorageSizeEXT GLEW_GET_FUN(__glewGetFramebufferPixelLocalStorageSizeEXT) + +#define GLEW_EXT_shader_pixel_local_storage2 GLEW_GET_VAR(__GLEW_EXT_shader_pixel_local_storage2) + +#endif /* GL_EXT_shader_pixel_local_storage2 */ + +/* ----------------------- GL_EXT_shader_texture_lod ----------------------- */ + +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 + +#define GLEW_EXT_shader_texture_lod GLEW_GET_VAR(__GLEW_EXT_shader_texture_lod) + +#endif /* GL_EXT_shader_texture_lod */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* ------------------------- GL_EXT_shadow_samplers ------------------------ */ + +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 + +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 + +#define GLEW_EXT_shadow_samplers GLEW_GET_VAR(__GLEW_EXT_shadow_samplers) + +#endif /* GL_EXT_shadow_samplers */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------- GL_EXT_sparse_texture ------------------------- */ + +#ifndef GL_EXT_sparse_texture +#define GL_EXT_sparse_texture 1 + +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 +#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A +#define GL_TEXTURE_SPARSE_EXT 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 +#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 +#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA + +typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); + +#define glTexPageCommitmentEXT GLEW_GET_FUN(__glewTexPageCommitmentEXT) +#define glTexturePageCommitmentEXT GLEW_GET_FUN(__glewTexturePageCommitmentEXT) + +#define GLEW_EXT_sparse_texture GLEW_GET_VAR(__GLEW_EXT_sparse_texture) + +#endif /* GL_EXT_sparse_texture */ + +/* ------------------------- GL_EXT_sparse_texture2 ------------------------ */ + +#ifndef GL_EXT_sparse_texture2 +#define GL_EXT_sparse_texture2 1 + +#define GLEW_EXT_sparse_texture2 GLEW_GET_VAR(__GLEW_EXT_sparse_texture2) + +#endif /* GL_EXT_sparse_texture2 */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#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 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#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 (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#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 GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#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 (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------------- GL_EXT_texture_array ------------------------- */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 + +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#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 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + +#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT) + +#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array) + +#endif /* GL_EXT_texture_array */ + +/* ---------------------- GL_EXT_texture_buffer_object --------------------- */ + +#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 (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); + +#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT) + +#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object) + +#endif /* GL_EXT_texture_buffer_object */ + +/* -------------- GL_EXT_texture_compression_astc_decode_mode -------------- */ + +#ifndef GL_EXT_texture_compression_astc_decode_mode +#define GL_EXT_texture_compression_astc_decode_mode 1 + +#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 + +#define GLEW_EXT_texture_compression_astc_decode_mode GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode) + +#endif /* GL_EXT_texture_compression_astc_decode_mode */ + +/* ----------- GL_EXT_texture_compression_astc_decode_mode_rgb9e5 ---------- */ + +#ifndef GL_EXT_texture_compression_astc_decode_mode_rgb9e5 +#define GL_EXT_texture_compression_astc_decode_mode_rgb9e5 1 + +#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 + +#define GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5 GLEW_GET_VAR(__GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5) + +#endif /* GL_EXT_texture_compression_astc_decode_mode_rgb9e5 */ + +/* -------------------- GL_EXT_texture_compression_bptc -------------------- */ + +#ifndef GL_EXT_texture_compression_bptc +#define GL_EXT_texture_compression_bptc 1 + +#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F + +#define GLEW_EXT_texture_compression_bptc GLEW_GET_VAR(__GLEW_EXT_texture_compression_bptc) + +#endif /* GL_EXT_texture_compression_bptc */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_latc -------------------- */ + +#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 + +#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc) + +#endif /* GL_EXT_texture_compression_latc */ + +/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */ + +#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 + +#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc) + +#endif /* GL_EXT_texture_compression_rgtc */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#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 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#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 + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* --------------------- GL_EXT_texture_cube_map_array --------------------- */ + +#ifndef GL_EXT_texture_cube_map_array +#define GL_EXT_texture_cube_map_array 1 + +#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A + +#define GLEW_EXT_texture_cube_map_array GLEW_GET_VAR(__GLEW_EXT_texture_cube_map_array) + +#endif /* GL_EXT_texture_cube_map_array */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#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 + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#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 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#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 + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ---------------------- GL_EXT_texture_filter_minmax --------------------- */ + +#ifndef GL_EXT_texture_filter_minmax +#define GL_EXT_texture_filter_minmax 1 + +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 + +#define GLEW_EXT_texture_filter_minmax GLEW_GET_VAR(__GLEW_EXT_texture_filter_minmax) + +#endif /* GL_EXT_texture_filter_minmax */ + +/* --------------------- GL_EXT_texture_format_BGRA8888 -------------------- */ + +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 + +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_texture_format_BGRA8888 GLEW_GET_VAR(__GLEW_EXT_texture_format_BGRA8888) + +#endif /* GL_EXT_texture_format_BGRA8888 */ + +/* ------------------------- GL_EXT_texture_integer ------------------------ */ + +#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 (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); + +#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT) +#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT) +#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT) +#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT) +#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT) +#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT) + +#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer) + +#endif /* GL_EXT_texture_integer */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#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 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#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 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_norm16 ------------------------- */ + +#ifndef GL_EXT_texture_norm16 +#define GL_EXT_texture_norm16 1 + +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA16_EXT 0x805B +#define GL_R16_EXT 0x822A +#define GL_RG16_EXT 0x822C +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RGB16_SNORM_EXT 0x8F9A +#define GL_RGBA16_SNORM_EXT 0x8F9B + +#define GLEW_EXT_texture_norm16 GLEW_GET_VAR(__GLEW_EXT_texture_norm16) + +#endif /* GL_EXT_texture_norm16 */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#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 (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#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 (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* --------------------------- GL_EXT_texture_rg --------------------------- */ + +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 + +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B + +#define GLEW_EXT_texture_rg GLEW_GET_VAR(__GLEW_EXT_texture_rg) + +#endif /* GL_EXT_texture_rg */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#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 + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* ------------------------- GL_EXT_texture_sRGB_R8 ------------------------ */ + +#ifndef GL_EXT_texture_sRGB_R8 +#define GL_EXT_texture_sRGB_R8 1 + +#define GL_SR8_EXT 0x8FBD + +#define GLEW_EXT_texture_sRGB_R8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_R8) + +#endif /* GL_EXT_texture_sRGB_R8 */ + +/* ------------------------ GL_EXT_texture_sRGB_RG8 ------------------------ */ + +#ifndef GL_EXT_texture_sRGB_RG8 +#define GL_EXT_texture_sRGB_RG8 1 + +#define GL_SRG8_EXT 0x8FBE + +#define GLEW_EXT_texture_sRGB_RG8 GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_RG8) + +#endif /* GL_EXT_texture_sRGB_RG8 */ + +/* ----------------------- GL_EXT_texture_sRGB_decode ---------------------- */ + +#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 + +#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode) + +#endif /* GL_EXT_texture_sRGB_decode */ + +/* --------------------- GL_EXT_texture_shared_exponent -------------------- */ + +#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 + +#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent) + +#endif /* GL_EXT_texture_shared_exponent */ + +/* -------------------------- GL_EXT_texture_snorm ------------------------- */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 + +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#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_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 GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm) + +#endif /* GL_EXT_texture_snorm */ + +/* ------------------------- GL_EXT_texture_storage ------------------------ */ + +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 + +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R16F_EXT 0x822D +#define GL_R32F_EXT 0x822E +#define GL_RG16F_EXT 0x822F +#define GL_RG32F_EXT 0x8230 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB_RAW_422_APPLE 0x8A51 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_BGRA8_EXT 0x93A1 + +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + +#define glTexStorage1DEXT GLEW_GET_FUN(__glewTexStorage1DEXT) +#define glTexStorage2DEXT GLEW_GET_FUN(__glewTexStorage2DEXT) +#define glTexStorage3DEXT GLEW_GET_FUN(__glewTexStorage3DEXT) +#define glTextureStorage1DEXT GLEW_GET_FUN(__glewTextureStorage1DEXT) +#define glTextureStorage2DEXT GLEW_GET_FUN(__glewTextureStorage2DEXT) +#define glTextureStorage3DEXT GLEW_GET_FUN(__glewTextureStorage3DEXT) + +#define GLEW_EXT_texture_storage GLEW_GET_VAR(__GLEW_EXT_texture_storage) + +#endif /* GL_EXT_texture_storage */ + +/* ------------------------- GL_EXT_texture_swizzle ------------------------ */ + +#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 + +#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle) + +#endif /* GL_EXT_texture_swizzle */ + +/* ------------------- GL_EXT_texture_type_2_10_10_10_REV ------------------ */ + +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 + +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 + +#define GLEW_EXT_texture_type_2_10_10_10_REV GLEW_GET_VAR(__GLEW_EXT_texture_type_2_10_10_10_REV) + +#endif /* GL_EXT_texture_type_2_10_10_10_REV */ + +/* -------------------------- GL_EXT_texture_view -------------------------- */ + +#ifndef GL_EXT_texture_view +#define GL_EXT_texture_view 1 + +#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF + +typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); + +#define glTextureViewEXT GLEW_GET_FUN(__glewTextureViewEXT) + +#define GLEW_EXT_texture_view GLEW_GET_VAR(__GLEW_EXT_texture_view) + +#endif /* GL_EXT_texture_view */ + +/* --------------------------- GL_EXT_timer_query -------------------------- */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 + +#define GL_TIME_ELAPSED_EXT 0x88BF + +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); + +#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT) +#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT) + +#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query) + +#endif /* GL_EXT_timer_query */ + +/* ----------------------- GL_EXT_transform_feedback ----------------------- */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 + +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#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_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F + +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar * const* varyings, GLenum bufferMode); + +#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT) +#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT) +#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT) +#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT) +#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT) +#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT) +#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT) + +#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback) + +#endif /* GL_EXT_transform_feedback */ + +/* ------------------------- GL_EXT_unpack_subimage ------------------------ */ + +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 + +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 + +#define GLEW_EXT_unpack_subimage GLEW_GET_VAR(__GLEW_EXT_unpack_subimage) + +#endif /* GL_EXT_unpack_subimage */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#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 (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 + +#define GL_BGRA 0x80E1 + +#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra) + +#endif /* GL_EXT_vertex_array_bgra */ + +/* ----------------------- GL_EXT_vertex_array_setXXX ---------------------- */ + +#ifndef GL_EXT_vertex_array_setXXX +#define GL_EXT_vertex_array_setXXX 1 + +typedef void (GLAPIENTRY * PFNGLBINDARRAYSETEXTPROC) (const void *arrayset); +typedef const void * (GLAPIENTRY * PFNGLCREATEARRAYSETEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEARRAYSETSEXTPROC) (GLsizei n, const void *arrayset[]); + +#define glBindArraySetEXT GLEW_GET_FUN(__glewBindArraySetEXT) +#define glCreateArraySetExt GLEW_GET_FUN(__glewCreateArraySetExt) +#define glDeleteArraySetsEXT GLEW_GET_FUN(__glewDeleteArraySetsEXT) + +#define GLEW_EXT_vertex_array_setXXX GLEW_GET_VAR(__GLEW_EXT_vertex_array_setXXX) + +#endif /* GL_EXT_vertex_array_setXXX */ + +/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 + +#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 +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + +#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT) +#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT) +#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT) +#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT) +#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT) +#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT) +#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT) +#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT) +#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT) +#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT) +#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT) + +#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit) + +#endif /* GL_EXT_vertex_attrib_64bit */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#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_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_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 (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, void *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, void *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, void *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#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 (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void *pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ------------------------ GL_EXT_win32_keyed_mutex ----------------------- */ + +#ifndef GL_EXT_win32_keyed_mutex +#define GL_EXT_win32_keyed_mutex 1 + +typedef GLboolean (GLAPIENTRY * PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); +typedef GLboolean (GLAPIENTRY * PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); + +#define glAcquireKeyedMutexWin32EXT GLEW_GET_FUN(__glewAcquireKeyedMutexWin32EXT) +#define glReleaseKeyedMutexWin32EXT GLEW_GET_FUN(__glewReleaseKeyedMutexWin32EXT) + +#define GLEW_EXT_win32_keyed_mutex GLEW_GET_VAR(__GLEW_EXT_win32_keyed_mutex) + +#endif /* GL_EXT_win32_keyed_mutex */ + +/* ------------------------ GL_EXT_window_rectangles ----------------------- */ + +#ifndef GL_EXT_window_rectangles +#define GL_EXT_window_rectangles 1 + +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 + +typedef void (GLAPIENTRY * PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint box[]); + +#define glWindowRectanglesEXT GLEW_GET_FUN(__glewWindowRectanglesEXT) + +#define GLEW_EXT_window_rectangles GLEW_GET_VAR(__GLEW_EXT_window_rectangles) + +#endif /* GL_EXT_window_rectangles */ + +/* ------------------------- GL_EXT_x11_sync_object ------------------------ */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 + +#define GL_SYNC_X11_FENCE_EXT 0x90E1 + +typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); + +#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT) + +#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object) + +#endif /* GL_EXT_x11_sync_object */ + +/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 + +typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void); + +#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY) + +#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator) + +#endif /* GL_GREMEDY_frame_terminator */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#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 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#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 (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#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 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------ GL_INTEL_conservative_rasterization ------------------ */ + +#ifndef GL_INTEL_conservative_rasterization +#define GL_INTEL_conservative_rasterization 1 + +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE + +#define GLEW_INTEL_conservative_rasterization GLEW_GET_VAR(__GLEW_INTEL_conservative_rasterization) + +#endif /* GL_INTEL_conservative_rasterization */ + +/* ------------------- GL_INTEL_fragment_shader_ordering ------------------- */ + +#ifndef GL_INTEL_fragment_shader_ordering +#define GL_INTEL_fragment_shader_ordering 1 + +#define GLEW_INTEL_fragment_shader_ordering GLEW_GET_VAR(__GLEW_INTEL_fragment_shader_ordering) + +#endif /* GL_INTEL_fragment_shader_ordering */ + +/* ----------------------- GL_INTEL_framebuffer_CMAA ----------------------- */ + +#ifndef GL_INTEL_framebuffer_CMAA +#define GL_INTEL_framebuffer_CMAA 1 + +#define GLEW_INTEL_framebuffer_CMAA GLEW_GET_VAR(__GLEW_INTEL_framebuffer_CMAA) + +#endif /* GL_INTEL_framebuffer_CMAA */ + +/* -------------------------- GL_INTEL_map_texture ------------------------- */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 + +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF + +typedef void * (GLAPIENTRY * PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint* stride, GLenum *layout); +typedef void (GLAPIENTRY * PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); + +#define glMapTexture2DINTEL GLEW_GET_FUN(__glewMapTexture2DINTEL) +#define glSyncTextureINTEL GLEW_GET_FUN(__glewSyncTextureINTEL) +#define glUnmapTexture2DINTEL GLEW_GET_FUN(__glewUnmapTexture2DINTEL) + +#define GLEW_INTEL_map_texture GLEW_GET_VAR(__GLEW_INTEL_map_texture) + +#endif /* GL_INTEL_map_texture */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#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 (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ----------------------- GL_INTEL_performance_query ---------------------- */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 + +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x0000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x0001 +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#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 (GLAPIENTRY * PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint* queryHandle); +typedef void (GLAPIENTRY * PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GLAPIENTRY * PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint* queryId); +typedef void (GLAPIENTRY * PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint* nextQueryId); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); +typedef void (GLAPIENTRY * PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar* queryName, GLuint *queryId); +typedef void (GLAPIENTRY * PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar* queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); + +#define glBeginPerfQueryINTEL GLEW_GET_FUN(__glewBeginPerfQueryINTEL) +#define glCreatePerfQueryINTEL GLEW_GET_FUN(__glewCreatePerfQueryINTEL) +#define glDeletePerfQueryINTEL GLEW_GET_FUN(__glewDeletePerfQueryINTEL) +#define glEndPerfQueryINTEL GLEW_GET_FUN(__glewEndPerfQueryINTEL) +#define glGetFirstPerfQueryIdINTEL GLEW_GET_FUN(__glewGetFirstPerfQueryIdINTEL) +#define glGetNextPerfQueryIdINTEL GLEW_GET_FUN(__glewGetNextPerfQueryIdINTEL) +#define glGetPerfCounterInfoINTEL GLEW_GET_FUN(__glewGetPerfCounterInfoINTEL) +#define glGetPerfQueryDataINTEL GLEW_GET_FUN(__glewGetPerfQueryDataINTEL) +#define glGetPerfQueryIdByNameINTEL GLEW_GET_FUN(__glewGetPerfQueryIdByNameINTEL) +#define glGetPerfQueryInfoINTEL GLEW_GET_FUN(__glewGetPerfQueryInfoINTEL) + +#define GLEW_INTEL_performance_query GLEW_GET_VAR(__GLEW_INTEL_performance_query) + +#endif /* GL_INTEL_performance_query */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* --------------------- GL_KHR_blend_equation_advanced -------------------- */ + +#ifndef GL_KHR_blend_equation_advanced +#define GL_KHR_blend_equation_advanced 1 + +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#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 (GLAPIENTRY * PFNGLBLENDBARRIERKHRPROC) (void); + +#define glBlendBarrierKHR GLEW_GET_FUN(__glewBlendBarrierKHR) + +#define GLEW_KHR_blend_equation_advanced GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced) + +#endif /* GL_KHR_blend_equation_advanced */ + +/* ---------------- GL_KHR_blend_equation_advanced_coherent ---------------- */ + +#ifndef GL_KHR_blend_equation_advanced_coherent +#define GL_KHR_blend_equation_advanced_coherent 1 + +#define GLEW_KHR_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_KHR_blend_equation_advanced_coherent) + +#endif /* GL_KHR_blend_equation_advanced_coherent */ + +/* ---------------------- GL_KHR_context_flush_control --------------------- */ + +#ifndef GL_KHR_context_flush_control +#define GL_KHR_context_flush_control 1 + +#define GLEW_KHR_context_flush_control GLEW_GET_VAR(__GLEW_KHR_context_flush_control) + +#endif /* GL_KHR_context_flush_control */ + +/* ------------------------------ GL_KHR_debug ----------------------------- */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 + +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#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_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_DISPLAY_LIST 0x82E7 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#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_OUTPUT 0x92E0 + +typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); +typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); +typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (void* ptr, GLsizei bufSize, GLsizei* length, GLchar *label); +typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label); +typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (void* ptr, GLsizei length, const GLchar* label); +typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); + +#define glDebugMessageCallback GLEW_GET_FUN(__glewDebugMessageCallback) +#define glDebugMessageControl GLEW_GET_FUN(__glewDebugMessageControl) +#define glDebugMessageInsert GLEW_GET_FUN(__glewDebugMessageInsert) +#define glGetDebugMessageLog GLEW_GET_FUN(__glewGetDebugMessageLog) +#define glGetObjectLabel GLEW_GET_FUN(__glewGetObjectLabel) +#define glGetObjectPtrLabel GLEW_GET_FUN(__glewGetObjectPtrLabel) +#define glObjectLabel GLEW_GET_FUN(__glewObjectLabel) +#define glObjectPtrLabel GLEW_GET_FUN(__glewObjectPtrLabel) +#define glPopDebugGroup GLEW_GET_FUN(__glewPopDebugGroup) +#define glPushDebugGroup GLEW_GET_FUN(__glewPushDebugGroup) + +#define GLEW_KHR_debug GLEW_GET_VAR(__GLEW_KHR_debug) + +#endif /* GL_KHR_debug */ + +/* ---------------------------- GL_KHR_no_error ---------------------------- */ + +#ifndef GL_KHR_no_error +#define GL_KHR_no_error 1 + +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 + +#define GLEW_KHR_no_error GLEW_GET_VAR(__GLEW_KHR_no_error) + +#endif /* GL_KHR_no_error */ + +/* --------------------- GL_KHR_parallel_shader_compile -------------------- */ + +#ifndef GL_KHR_parallel_shader_compile +#define GL_KHR_parallel_shader_compile 1 + +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_COMPLETION_STATUS_KHR 0x91B1 + +typedef void (GLAPIENTRY * PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count); + +#define glMaxShaderCompilerThreadsKHR GLEW_GET_FUN(__glewMaxShaderCompilerThreadsKHR) + +#define GLEW_KHR_parallel_shader_compile GLEW_GET_VAR(__GLEW_KHR_parallel_shader_compile) + +#endif /* GL_KHR_parallel_shader_compile */ + +/* ------------------ GL_KHR_robust_buffer_access_behavior ----------------- */ + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 + +#define GLEW_KHR_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_KHR_robust_buffer_access_behavior) + +#endif /* GL_KHR_robust_buffer_access_behavior */ + +/* --------------------------- GL_KHR_robustness --------------------------- */ + +#ifndef GL_KHR_robustness +#define GL_KHR_robustness 1 + +#define GL_CONTEXT_LOST 0x0507 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#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_NO_RESET_NOTIFICATION 0x8261 +#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 + +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); +typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); + +#define glGetnUniformfv GLEW_GET_FUN(__glewGetnUniformfv) +#define glGetnUniformiv GLEW_GET_FUN(__glewGetnUniformiv) +#define glGetnUniformuiv GLEW_GET_FUN(__glewGetnUniformuiv) +#define glReadnPixels GLEW_GET_FUN(__glewReadnPixels) + +#define GLEW_KHR_robustness GLEW_GET_VAR(__GLEW_KHR_robustness) + +#endif /* GL_KHR_robustness */ + +/* ------------------ GL_KHR_texture_compression_astc_hdr ------------------ */ + +#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 + +#define GLEW_KHR_texture_compression_astc_hdr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_hdr) + +#endif /* GL_KHR_texture_compression_astc_hdr */ + +/* ------------------ GL_KHR_texture_compression_astc_ldr ------------------ */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 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 + +#define GLEW_KHR_texture_compression_astc_ldr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_ldr) + +#endif /* GL_KHR_texture_compression_astc_ldr */ + +/* --------------- GL_KHR_texture_compression_astc_sliced_3d --------------- */ + +#ifndef GL_KHR_texture_compression_astc_sliced_3d +#define GL_KHR_texture_compression_astc_sliced_3d 1 + +#define GLEW_KHR_texture_compression_astc_sliced_3d GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_sliced_3d) + +#endif /* GL_KHR_texture_compression_astc_sliced_3d */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabled GLEW_GET_FUN(__glewBufferRegionEnabled) +#define glDeleteBufferRegion GLEW_GET_FUN(__glewDeleteBufferRegion) +#define glDrawBufferRegion GLEW_GET_FUN(__glewDrawBufferRegion) +#define glNewBufferRegion GLEW_GET_FUN(__glewNewBufferRegion) +#define glReadBufferRegion GLEW_GET_FUN(__glewReadBufferRegion) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#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 + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* -------------------- GL_MESA_shader_integer_functions ------------------- */ + +#ifndef GL_MESA_shader_integer_functions +#define GL_MESA_shader_integer_functions 1 + +#define GLEW_MESA_shader_integer_functions GLEW_GET_VAR(__GLEW_MESA_shader_integer_functions) + +#endif /* GL_MESA_shader_integer_functions */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#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 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* ----------- GL_NVX_blend_equation_advanced_multi_draw_buffers ----------- */ + +#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 + +#define GLEW_NVX_blend_equation_advanced_multi_draw_buffers GLEW_GET_VAR(__GLEW_NVX_blend_equation_advanced_multi_draw_buffers) + +#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ + +/* ----------------------- GL_NVX_conditional_render ----------------------- */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 + +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void); + +#define glBeginConditionalRenderNVX GLEW_GET_FUN(__glewBeginConditionalRenderNVX) +#define glEndConditionalRenderNVX GLEW_GET_FUN(__glewEndConditionalRenderNVX) + +#define GLEW_NVX_conditional_render GLEW_GET_VAR(__GLEW_NVX_conditional_render) + +#endif /* GL_NVX_conditional_render */ + +/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */ + +#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 + +#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info) + +#endif /* GL_NVX_gpu_memory_info */ + +/* ---------------------- GL_NVX_linked_gpu_multicast ---------------------- */ + +#ifndef GL_NVX_linked_gpu_multicast +#define GL_NVX_linked_gpu_multicast 1 + +#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 +#define GL_MAX_LGPU_GPUS_NVX 0x92BA + +typedef void (GLAPIENTRY * PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GLAPIENTRY * PFNGLLGPUINTERLOCKNVXPROC) (void); +typedef void (GLAPIENTRY * PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); + +#define glLGPUCopyImageSubDataNVX GLEW_GET_FUN(__glewLGPUCopyImageSubDataNVX) +#define glLGPUInterlockNVX GLEW_GET_FUN(__glewLGPUInterlockNVX) +#define glLGPUNamedBufferSubDataNVX GLEW_GET_FUN(__glewLGPUNamedBufferSubDataNVX) + +#define GLEW_NVX_linked_gpu_multicast GLEW_GET_VAR(__GLEW_NVX_linked_gpu_multicast) + +#endif /* GL_NVX_linked_gpu_multicast */ + +/* ------------------------ GL_NV_3dvision_settings ------------------------ */ + +#ifndef GL_NV_3dvision_settings +#define GL_NV_3dvision_settings 1 + +#define GL_3DVISION_STEREO_NV 0x90F4 +#define GL_STEREO_SEPARATION_NV 0x90F5 +#define GL_STEREO_CONVERGENCE_NV 0x90F6 +#define GL_STEREO_CUTOFF_NV 0x90F7 +#define GL_STEREO_PROJECTION_NV 0x90F8 +#define GL_STEREO_PROJECTION_PERSPECTIVE_NV 0x90F9 +#define GL_STEREO_PROJECTION_ORTHO_NV 0x90FA + +typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSTEREOPARAMETERINVPROC) (GLenum pname, GLint param); + +#define glStereoParameterfNV GLEW_GET_FUN(__glewStereoParameterfNV) +#define glStereoParameteriNV GLEW_GET_FUN(__glewStereoParameteriNV) + +#define GLEW_NV_3dvision_settings GLEW_GET_VAR(__GLEW_NV_3dvision_settings) + +#endif /* GL_NV_3dvision_settings */ + +/* ------------------- GL_NV_EGL_stream_consumer_external ------------------ */ + +#ifndef GL_NV_EGL_stream_consumer_external +#define GL_NV_EGL_stream_consumer_external 1 + +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 + +#define GLEW_NV_EGL_stream_consumer_external GLEW_GET_VAR(__GLEW_NV_EGL_stream_consumer_external) + +#endif /* GL_NV_EGL_stream_consumer_external */ + +/* ----------------- GL_NV_alpha_to_coverage_dither_control ---------------- */ + +#ifndef GL_NV_alpha_to_coverage_dither_control +#define GL_NV_alpha_to_coverage_dither_control 1 + +#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF +#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D +#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E +#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F + +#define GLEW_NV_alpha_to_coverage_dither_control GLEW_GET_VAR(__GLEW_NV_alpha_to_coverage_dither_control) + +#endif /* GL_NV_alpha_to_coverage_dither_control */ + +/* ------------------------------- GL_NV_bgr ------------------------------- */ + +#ifndef GL_NV_bgr +#define GL_NV_bgr 1 + +#define GL_BGR_NV 0x80E0 + +#define GLEW_NV_bgr GLEW_GET_VAR(__GLEW_NV_bgr) + +#endif /* GL_NV_bgr */ + +/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */ + +#ifndef GL_NV_bindless_multi_draw_indirect +#define GL_NV_bindless_multi_draw_indirect 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); + +#define glMultiDrawArraysIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessNV) +#define glMultiDrawElementsIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessNV) + +#define GLEW_NV_bindless_multi_draw_indirect GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect) + +#endif /* GL_NV_bindless_multi_draw_indirect */ + +/* ---------------- GL_NV_bindless_multi_draw_indirect_count --------------- */ + +#ifndef GL_NV_bindless_multi_draw_indirect_count +#define GL_NV_bindless_multi_draw_indirect_count 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); + +#define glMultiDrawArraysIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessCountNV) +#define glMultiDrawElementsIndirectBindlessCountNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessCountNV) + +#define GLEW_NV_bindless_multi_draw_indirect_count GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect_count) + +#endif /* GL_NV_bindless_multi_draw_indirect_count */ + +/* ------------------------- GL_NV_bindless_texture ------------------------ */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 + +typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64* value); + +#define glGetImageHandleNV GLEW_GET_FUN(__glewGetImageHandleNV) +#define glGetTextureHandleNV GLEW_GET_FUN(__glewGetTextureHandleNV) +#define glGetTextureSamplerHandleNV GLEW_GET_FUN(__glewGetTextureSamplerHandleNV) +#define glIsImageHandleResidentNV GLEW_GET_FUN(__glewIsImageHandleResidentNV) +#define glIsTextureHandleResidentNV GLEW_GET_FUN(__glewIsTextureHandleResidentNV) +#define glMakeImageHandleNonResidentNV GLEW_GET_FUN(__glewMakeImageHandleNonResidentNV) +#define glMakeImageHandleResidentNV GLEW_GET_FUN(__glewMakeImageHandleResidentNV) +#define glMakeTextureHandleNonResidentNV GLEW_GET_FUN(__glewMakeTextureHandleNonResidentNV) +#define glMakeTextureHandleResidentNV GLEW_GET_FUN(__glewMakeTextureHandleResidentNV) +#define glProgramUniformHandleui64NV GLEW_GET_FUN(__glewProgramUniformHandleui64NV) +#define glProgramUniformHandleui64vNV GLEW_GET_FUN(__glewProgramUniformHandleui64vNV) +#define glUniformHandleui64NV GLEW_GET_FUN(__glewUniformHandleui64NV) +#define glUniformHandleui64vNV GLEW_GET_FUN(__glewUniformHandleui64vNV) + +#define GLEW_NV_bindless_texture GLEW_GET_VAR(__GLEW_NV_bindless_texture) + +#endif /* GL_NV_bindless_texture */ + +/* --------------------- GL_NV_blend_equation_advanced --------------------- */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 + +#define GL_XOR_NV 0x1506 +#define GL_RED_NV 0x1903 +#define GL_GREEN_NV 0x1904 +#define GL_BLUE_NV 0x1905 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_DISJOINT_NV 0x9283 +#define GL_CONJOINT_NV 0x9284 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#define GL_SRC_NV 0x9286 +#define GL_DST_NV 0x9287 +#define GL_SRC_OVER_NV 0x9288 +#define GL_DST_OVER_NV 0x9289 +#define GL_SRC_IN_NV 0x928A +#define GL_DST_IN_NV 0x928B +#define GL_SRC_OUT_NV 0x928C +#define GL_DST_OUT_NV 0x928D +#define GL_SRC_ATOP_NV 0x928E +#define GL_DST_ATOP_NV 0x928F +#define GL_PLUS_NV 0x9291 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_MULTIPLY_NV 0x9294 +#define GL_SCREEN_NV 0x9295 +#define GL_OVERLAY_NV 0x9296 +#define GL_DARKEN_NV 0x9297 +#define GL_LIGHTEN_NV 0x9298 +#define GL_COLORDODGE_NV 0x9299 +#define GL_COLORBURN_NV 0x929A +#define GL_HARDLIGHT_NV 0x929B +#define GL_SOFTLIGHT_NV 0x929C +#define GL_DIFFERENCE_NV 0x929E +#define GL_MINUS_NV 0x929F +#define GL_EXCLUSION_NV 0x92A0 +#define GL_CONTRAST_NV 0x92A1 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_INVERT_OVG_NV 0x92B4 + +typedef void (GLAPIENTRY * PFNGLBLENDBARRIERNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); + +#define glBlendBarrierNV GLEW_GET_FUN(__glewBlendBarrierNV) +#define glBlendParameteriNV GLEW_GET_FUN(__glewBlendParameteriNV) + +#define GLEW_NV_blend_equation_advanced GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced) + +#endif /* GL_NV_blend_equation_advanced */ + +/* ----------------- GL_NV_blend_equation_advanced_coherent ---------------- */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 + +#define GLEW_NV_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced_coherent) + +#endif /* GL_NV_blend_equation_advanced_coherent */ + +/* ----------------------- GL_NV_blend_minmax_factor ----------------------- */ + +#ifndef GL_NV_blend_minmax_factor +#define GL_NV_blend_minmax_factor 1 + +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D + +#define GLEW_NV_blend_minmax_factor GLEW_GET_VAR(__GLEW_NV_blend_minmax_factor) + +#endif /* GL_NV_blend_minmax_factor */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ----------------------- GL_NV_clip_space_w_scaling ---------------------- */ + +#ifndef GL_NV_clip_space_w_scaling +#define GL_NV_clip_space_w_scaling 1 + +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E + +typedef void (GLAPIENTRY * PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); + +#define glViewportPositionWScaleNV GLEW_GET_FUN(__glewViewportPositionWScaleNV) + +#define GLEW_NV_clip_space_w_scaling GLEW_GET_VAR(__GLEW_NV_clip_space_w_scaling) + +#endif /* GL_NV_clip_space_w_scaling */ + +/* --------------------------- GL_NV_command_list -------------------------- */ + +#ifndef GL_NV_command_list +#define GL_NV_command_list 1 + +#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 +#define GL_NOP_COMMAND_NV 0x0001 +#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 +#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 +#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 +#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 +#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 +#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 +#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 +#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 +#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000a +#define GL_BLEND_COLOR_COMMAND_NV 0x000b +#define GL_STENCIL_REF_COMMAND_NV 0x000c +#define GL_LINE_WIDTH_COMMAND_NV 0x000d +#define GL_POLYGON_OFFSET_COMMAND_NV 0x000e +#define GL_ALPHA_REF_COMMAND_NV 0x000f +#define GL_VIEWPORT_COMMAND_NV 0x0010 +#define GL_SCISSOR_COMMAND_NV 0x0011 +#define GL_FRONT_FACE_COMMAND_NV 0x0012 + +typedef void (GLAPIENTRY * PFNGLCALLCOMMANDLISTNVPROC) (GLuint list); +typedef void (GLAPIENTRY * PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments); +typedef void (GLAPIENTRY * PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list); +typedef void (GLAPIENTRY * PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint* lists); +typedef void (GLAPIENTRY * PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint* states); +typedef void (GLAPIENTRY * PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint* lists); +typedef void (GLAPIENTRY * PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint* states); +typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64* indirects, const GLsizei* sizes, GLuint count); +typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, GLuint count); +typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); +typedef void (GLAPIENTRY * PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr* indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); +typedef GLuint (GLAPIENTRY * PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size); +typedef GLushort (GLAPIENTRY * PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype); +typedef GLboolean (GLAPIENTRY * PFNGLISCOMMANDLISTNVPROC) (GLuint list); +typedef GLboolean (GLAPIENTRY * PFNGLISSTATENVPROC) (GLuint state); +typedef void (GLAPIENTRY * PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void** indirects, const GLsizei* sizes, const GLuint* states, const GLuint* fbos, GLuint count); +typedef void (GLAPIENTRY * PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode); + +#define glCallCommandListNV GLEW_GET_FUN(__glewCallCommandListNV) +#define glCommandListSegmentsNV GLEW_GET_FUN(__glewCommandListSegmentsNV) +#define glCompileCommandListNV GLEW_GET_FUN(__glewCompileCommandListNV) +#define glCreateCommandListsNV GLEW_GET_FUN(__glewCreateCommandListsNV) +#define glCreateStatesNV GLEW_GET_FUN(__glewCreateStatesNV) +#define glDeleteCommandListsNV GLEW_GET_FUN(__glewDeleteCommandListsNV) +#define glDeleteStatesNV GLEW_GET_FUN(__glewDeleteStatesNV) +#define glDrawCommandsAddressNV GLEW_GET_FUN(__glewDrawCommandsAddressNV) +#define glDrawCommandsNV GLEW_GET_FUN(__glewDrawCommandsNV) +#define glDrawCommandsStatesAddressNV GLEW_GET_FUN(__glewDrawCommandsStatesAddressNV) +#define glDrawCommandsStatesNV GLEW_GET_FUN(__glewDrawCommandsStatesNV) +#define glGetCommandHeaderNV GLEW_GET_FUN(__glewGetCommandHeaderNV) +#define glGetStageIndexNV GLEW_GET_FUN(__glewGetStageIndexNV) +#define glIsCommandListNV GLEW_GET_FUN(__glewIsCommandListNV) +#define glIsStateNV GLEW_GET_FUN(__glewIsStateNV) +#define glListDrawCommandsStatesClientNV GLEW_GET_FUN(__glewListDrawCommandsStatesClientNV) +#define glStateCaptureNV GLEW_GET_FUN(__glewStateCaptureNV) + +#define GLEW_NV_command_list GLEW_GET_VAR(__GLEW_NV_command_list) + +#endif /* GL_NV_command_list */ + +/* ------------------------- GL_NV_compute_program5 ------------------------ */ + +#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 + +#define GLEW_NV_compute_program5 GLEW_GET_VAR(__GLEW_NV_compute_program5) + +#endif /* GL_NV_compute_program5 */ + +/* ------------------------ GL_NV_conditional_render ----------------------- */ + +#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 (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void); + +#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV) +#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV) + +#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render) + +#endif /* GL_NV_conditional_render */ + +/* ----------------------- GL_NV_conservative_raster ----------------------- */ + +#ifndef GL_NV_conservative_raster +#define GL_NV_conservative_raster 1 + +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 + +typedef void (GLAPIENTRY * PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); + +#define glSubpixelPrecisionBiasNV GLEW_GET_FUN(__glewSubpixelPrecisionBiasNV) + +#define GLEW_NV_conservative_raster GLEW_GET_VAR(__GLEW_NV_conservative_raster) + +#endif /* GL_NV_conservative_raster */ + +/* -------------------- GL_NV_conservative_raster_dilate ------------------- */ + +#ifndef GL_NV_conservative_raster_dilate +#define GL_NV_conservative_raster_dilate 1 + +#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 +#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A +#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B + +typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value); + +#define glConservativeRasterParameterfNV GLEW_GET_FUN(__glewConservativeRasterParameterfNV) + +#define GLEW_NV_conservative_raster_dilate GLEW_GET_VAR(__GLEW_NV_conservative_raster_dilate) + +#endif /* GL_NV_conservative_raster_dilate */ + +/* -------------- GL_NV_conservative_raster_pre_snap_triangles ------------- */ + +#ifndef GL_NV_conservative_raster_pre_snap_triangles +#define GL_NV_conservative_raster_pre_snap_triangles 1 + +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F + +typedef void (GLAPIENTRY * PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); + +#define glConservativeRasterParameteriNV GLEW_GET_FUN(__glewConservativeRasterParameteriNV) + +#define GLEW_NV_conservative_raster_pre_snap_triangles GLEW_GET_VAR(__GLEW_NV_conservative_raster_pre_snap_triangles) + +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + +/* --------------------------- GL_NV_copy_buffer --------------------------- */ + +#ifndef GL_NV_copy_buffer +#define GL_NV_copy_buffer 1 + +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 + +typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + +#define glCopyBufferSubDataNV GLEW_GET_FUN(__glewCopyBufferSubDataNV) + +#define GLEW_NV_copy_buffer GLEW_GET_VAR(__GLEW_NV_copy_buffer) + +#endif /* GL_NV_copy_buffer */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#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 + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* ---------------------------- GL_NV_copy_image --------------------------- */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 + +typedef void (GLAPIENTRY * 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); + +#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV) + +#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image) + +#endif /* GL_NV_copy_image */ + +/* -------------------------- GL_NV_deep_texture3D ------------------------- */ + +#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 + +#define GLEW_NV_deep_texture3D GLEW_GET_VAR(__GLEW_NV_deep_texture3D) + +#endif /* GL_NV_deep_texture3D */ + +/* ------------------------ GL_NV_depth_buffer_float ----------------------- */ + +#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 (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); + +#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV) +#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV) +#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV) + +#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float) + +#endif /* GL_NV_depth_buffer_float */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */ + +#ifndef GL_NV_depth_range_unclamped +#define GL_NV_depth_range_unclamped 1 + +#define GL_SAMPLE_COUNT_BITS_NV 0x8864 +#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865 +#define GL_QUERY_RESULT_NV 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867 +#define GL_SAMPLE_COUNT_NV 0x8914 + +#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped) + +#endif /* GL_NV_depth_range_unclamped */ + +/* --------------------------- GL_NV_draw_buffers -------------------------- */ + +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersNV GLEW_GET_FUN(__glewDrawBuffersNV) + +#define GLEW_NV_draw_buffers GLEW_GET_VAR(__GLEW_NV_draw_buffers) + +#endif /* GL_NV_draw_buffers */ + +/* -------------------------- GL_NV_draw_instanced ------------------------- */ + +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 + +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); + +#define glDrawArraysInstancedNV GLEW_GET_FUN(__glewDrawArraysInstancedNV) +#define glDrawElementsInstancedNV GLEW_GET_FUN(__glewDrawElementsInstancedNV) + +#define GLEW_NV_draw_instanced GLEW_GET_VAR(__GLEW_NV_draw_instanced) + +#endif /* GL_NV_draw_instanced */ + +/* --------------------------- GL_NV_draw_texture -------------------------- */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 + +typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); + +#define glDrawTextureNV GLEW_GET_FUN(__glewDrawTextureNV) + +#define GLEW_NV_draw_texture GLEW_GET_VAR(__GLEW_NV_draw_texture) + +#endif /* GL_NV_draw_texture */ + +/* ------------------------ GL_NV_draw_vulkan_image ------------------------ */ + +#ifndef GL_NV_draw_vulkan_image +#define GL_NV_draw_vulkan_image 1 + +typedef void (APIENTRY *GLVULKANPROCNV)(void); + +typedef void (GLAPIENTRY * PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef GLVULKANPROCNV (GLAPIENTRY * PFNGLGETVKPROCADDRNVPROC) (const GLchar* name); +typedef void (GLAPIENTRY * PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); +typedef void (GLAPIENTRY * PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (GLAPIENTRY * PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); + +#define glDrawVkImageNV GLEW_GET_FUN(__glewDrawVkImageNV) +#define glGetVkProcAddrNV GLEW_GET_FUN(__glewGetVkProcAddrNV) +#define glSignalVkFenceNV GLEW_GET_FUN(__glewSignalVkFenceNV) +#define glSignalVkSemaphoreNV GLEW_GET_FUN(__glewSignalVkSemaphoreNV) +#define glWaitVkSemaphoreNV GLEW_GET_FUN(__glewWaitVkSemaphoreNV) + +#define GLEW_NV_draw_vulkan_image GLEW_GET_VAR(__GLEW_NV_draw_vulkan_image) + +#endif /* GL_NV_draw_vulkan_image */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#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 (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* --------------------- GL_NV_explicit_attrib_location -------------------- */ + +#ifndef GL_NV_explicit_attrib_location +#define GL_NV_explicit_attrib_location 1 + +#define GLEW_NV_explicit_attrib_location GLEW_GET_VAR(__GLEW_NV_explicit_attrib_location) + +#endif /* GL_NV_explicit_attrib_location */ + +/* ----------------------- GL_NV_explicit_multisample ---------------------- */ + +#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 (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); + +#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV) +#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV) +#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV) + +#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample) + +#endif /* GL_NV_explicit_multisample */ + +/* ---------------------- GL_NV_fbo_color_attachments ---------------------- */ + +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 + +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF + +#define GLEW_NV_fbo_color_attachments GLEW_GET_VAR(__GLEW_NV_fbo_color_attachments) + +#endif /* GL_NV_fbo_color_attachments */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#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 (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* -------------------------- GL_NV_fill_rectangle ------------------------- */ + +#ifndef GL_NV_fill_rectangle +#define GL_NV_fill_rectangle 1 + +#define GL_FILL_RECTANGLE_NV 0x933C + +#define GLEW_NV_fill_rectangle GLEW_GET_VAR(__GLEW_NV_fill_rectangle) + +#endif /* GL_NV_fill_rectangle */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#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 + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#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 + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* -------------------- GL_NV_fragment_coverage_to_color ------------------- */ + +#ifndef GL_NV_fragment_coverage_to_color +#define GL_NV_fragment_coverage_to_color 1 + +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); + +#define glFragmentCoverageColorNV GLEW_GET_FUN(__glewFragmentCoverageColorNV) + +#define GLEW_NV_fragment_coverage_to_color GLEW_GET_VAR(__GLEW_NV_fragment_coverage_to_color) + +#endif /* GL_NV_fragment_coverage_to_color */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#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 (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#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 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* ------------------------ GL_NV_fragment_program4 ------------------------ */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 + +#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4) + +#endif /* GL_NV_fragment_program4 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* -------------------- GL_NV_fragment_shader_interlock -------------------- */ + +#ifndef GL_NV_fragment_shader_interlock +#define GL_NV_fragment_shader_interlock 1 + +#define GLEW_NV_fragment_shader_interlock GLEW_GET_VAR(__GLEW_NV_fragment_shader_interlock) + +#endif /* GL_NV_fragment_shader_interlock */ + +/* ------------------------- GL_NV_framebuffer_blit ------------------------ */ + +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferNV GLEW_GET_FUN(__glewBlitFramebufferNV) + +#define GLEW_NV_framebuffer_blit GLEW_GET_VAR(__GLEW_NV_framebuffer_blit) + +#endif /* GL_NV_framebuffer_blit */ + +/* -------------------- GL_NV_framebuffer_mixed_samples -------------------- */ + +#ifndef GL_NV_framebuffer_mixed_samples +#define GL_NV_framebuffer_mixed_samples 1 + +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 + +#define GLEW_NV_framebuffer_mixed_samples GLEW_GET_VAR(__GLEW_NV_framebuffer_mixed_samples) + +#endif /* GL_NV_framebuffer_mixed_samples */ + +/* --------------------- GL_NV_framebuffer_multisample --------------------- */ + +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleNV) + +#define GLEW_NV_framebuffer_multisample GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample) + +#endif /* GL_NV_framebuffer_multisample */ + +/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */ + +#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 (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV) + +#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage) + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +/* ----------------------- GL_NV_generate_mipmap_sRGB ---------------------- */ + +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 + +#define GLEW_NV_generate_mipmap_sRGB GLEW_GET_VAR(__GLEW_NV_generate_mipmap_sRGB) + +#endif /* GL_NV_generate_mipmap_sRGB */ + +/* ------------------------ GL_NV_geometry_program4 ------------------------ */ + +#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 (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); + +#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV) + +#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4) + +#endif /* GL_NV_geometry_program4 */ + +/* ------------------------- GL_NV_geometry_shader4 ------------------------ */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 + +#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4) + +#endif /* GL_NV_geometry_shader4 */ + +/* ------------------- GL_NV_geometry_shader_passthrough ------------------- */ + +#ifndef GL_NV_geometry_shader_passthrough +#define GL_NV_geometry_shader_passthrough 1 + +#define GLEW_NV_geometry_shader_passthrough GLEW_GET_VAR(__GLEW_NV_geometry_shader_passthrough) + +#endif /* GL_NV_geometry_shader_passthrough */ + +/* -------------------------- GL_NV_gpu_multicast -------------------------- */ + +#ifndef GL_NV_gpu_multicast +#define GL_NV_gpu_multicast 1 + +#define GL_PER_GPU_STORAGE_BIT_NV 0x0800 +#define GL_MULTICAST_GPUS_NV 0x92BA +#define GL_PER_GPU_STORAGE_NV 0x9548 +#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 +#define GL_RENDER_GPU_MASK_NV 0x9558 + +typedef void (GLAPIENTRY * PFNGLMULTICASTBARRIERNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAPIENTRY * PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, 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 (GLAPIENTRY * PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64* params); +typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64* params); +typedef void (GLAPIENTRY * PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask); +typedef void (GLAPIENTRY * PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask); + +#define glMulticastBarrierNV GLEW_GET_FUN(__glewMulticastBarrierNV) +#define glMulticastBlitFramebufferNV GLEW_GET_FUN(__glewMulticastBlitFramebufferNV) +#define glMulticastBufferSubDataNV GLEW_GET_FUN(__glewMulticastBufferSubDataNV) +#define glMulticastCopyBufferSubDataNV GLEW_GET_FUN(__glewMulticastCopyBufferSubDataNV) +#define glMulticastCopyImageSubDataNV GLEW_GET_FUN(__glewMulticastCopyImageSubDataNV) +#define glMulticastFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewMulticastFramebufferSampleLocationsfvNV) +#define glMulticastGetQueryObjecti64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjecti64vNV) +#define glMulticastGetQueryObjectivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectivNV) +#define glMulticastGetQueryObjectui64vNV GLEW_GET_FUN(__glewMulticastGetQueryObjectui64vNV) +#define glMulticastGetQueryObjectuivNV GLEW_GET_FUN(__glewMulticastGetQueryObjectuivNV) +#define glMulticastWaitSyncNV GLEW_GET_FUN(__glewMulticastWaitSyncNV) +#define glRenderGpuMaskNV GLEW_GET_FUN(__glewRenderGpuMaskNV) + +#define GLEW_NV_gpu_multicast GLEW_GET_VAR(__GLEW_NV_gpu_multicast) + +#endif /* GL_NV_gpu_multicast */ + +/* --------------------------- GL_NV_gpu_program4 -------------------------- */ + +#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 (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); + +#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV) +#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV) +#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV) +#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV) + +#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4) + +#endif /* GL_NV_gpu_program4 */ + +/* --------------------------- GL_NV_gpu_program5 -------------------------- */ + +#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 GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5) + +#endif /* GL_NV_gpu_program5 */ + +/* -------------------- GL_NV_gpu_program5_mem_extended -------------------- */ + +#ifndef GL_NV_gpu_program5_mem_extended +#define GL_NV_gpu_program5_mem_extended 1 + +#define GLEW_NV_gpu_program5_mem_extended GLEW_GET_VAR(__GLEW_NV_gpu_program5_mem_extended) + +#endif /* GL_NV_gpu_program5_mem_extended */ + +/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */ + +#ifndef GL_NV_gpu_program_fp64 +#define GL_NV_gpu_program_fp64 1 + +#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64) + +#endif /* GL_NV_gpu_program_fp64 */ + +/* --------------------------- GL_NV_gpu_shader5 --------------------------- */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 + +#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 (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV) +#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV) +#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV) +#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV) +#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV) +#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV) +#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV) +#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV) +#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV) +#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV) +#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV) +#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV) +#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV) +#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV) +#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV) +#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV) +#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV) +#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV) +#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV) +#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV) +#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV) +#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV) +#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV) +#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV) +#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV) +#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV) +#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV) +#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV) +#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV) +#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV) +#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV) +#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV) +#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV) +#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV) + +#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5) + +#endif /* GL_NV_gpu_shader5 */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* -------------------------- GL_NV_image_formats -------------------------- */ + +#ifndef GL_NV_image_formats +#define GL_NV_image_formats 1 + +#define GLEW_NV_image_formats GLEW_GET_VAR(__GLEW_NV_image_formats) + +#endif /* GL_NV_image_formats */ + +/* ------------------------- GL_NV_instanced_arrays ------------------------ */ + +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 + +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE + +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); + +#define glVertexAttribDivisorNV GLEW_GET_FUN(__glewVertexAttribDivisorNV) + +#define GLEW_NV_instanced_arrays GLEW_GET_VAR(__GLEW_NV_instanced_arrays) + +#endif /* GL_NV_instanced_arrays */ + +/* ------------------- GL_NV_internalformat_sample_query ------------------- */ + +#ifndef GL_NV_internalformat_sample_query +#define GL_NV_internalformat_sample_query 1 + +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_CONFORMANT_NV 0x9374 + +typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint* params); + +#define glGetInternalformatSampleivNV GLEW_GET_FUN(__glewGetInternalformatSampleivNV) + +#define GLEW_NV_internalformat_sample_query GLEW_GET_VAR(__GLEW_NV_internalformat_sample_query) + +#endif /* GL_NV_internalformat_sample_query */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#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 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* ----------------------- GL_NV_multisample_coverage ---------------------- */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 + +#define GL_COLOR_SAMPLES_NV 0x8E20 + +#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage) + +#endif /* GL_NV_multisample_coverage */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ----------------------- GL_NV_non_square_matrices ----------------------- */ + +#ifndef GL_NV_non_square_matrices +#define GL_NV_non_square_matrices 1 + +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3_NV 0x8B6A + +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + +#define glUniformMatrix2x3fvNV GLEW_GET_FUN(__glewUniformMatrix2x3fvNV) +#define glUniformMatrix2x4fvNV GLEW_GET_FUN(__glewUniformMatrix2x4fvNV) +#define glUniformMatrix3x2fvNV GLEW_GET_FUN(__glewUniformMatrix3x2fvNV) +#define glUniformMatrix3x4fvNV GLEW_GET_FUN(__glewUniformMatrix3x4fvNV) +#define glUniformMatrix4x2fvNV GLEW_GET_FUN(__glewUniformMatrix4x2fvNV) +#define glUniformMatrix4x3fvNV GLEW_GET_FUN(__glewUniformMatrix4x3fvNV) + +#define GLEW_NV_non_square_matrices GLEW_GET_VAR(__GLEW_NV_non_square_matrices) + +#endif /* GL_NV_non_square_matrices */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#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 (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* -------------------------- GL_NV_pack_subimage -------------------------- */ + +#ifndef GL_NV_pack_subimage +#define GL_NV_pack_subimage 1 + +#define GL_PACK_ROW_LENGTH_NV 0x0D02 +#define GL_PACK_SKIP_ROWS_NV 0x0D03 +#define GL_PACK_SKIP_PIXELS_NV 0x0D04 + +#define GLEW_NV_pack_subimage GLEW_GET_VAR(__GLEW_NV_pack_subimage) + +#endif /* GL_NV_pack_subimage */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#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 + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* --------------------------- GL_NV_packed_float -------------------------- */ + +#ifndef GL_NV_packed_float +#define GL_NV_packed_float 1 + +#define GL_R11F_G11F_B10F_NV 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B + +#define GLEW_NV_packed_float GLEW_GET_VAR(__GLEW_NV_packed_float) + +#endif /* GL_NV_packed_float */ + +/* ----------------------- GL_NV_packed_float_linear ----------------------- */ + +#ifndef GL_NV_packed_float_linear +#define GL_NV_packed_float_linear 1 + +#define GL_R11F_G11F_B10F_NV 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_NV 0x8C3B + +#define GLEW_NV_packed_float_linear GLEW_GET_VAR(__GLEW_NV_packed_float_linear) + +#endif /* GL_NV_packed_float_linear */ + +/* --------------------- GL_NV_parameter_buffer_object --------------------- */ + +#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 (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); + +#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV) +#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV) + +#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object) + +#endif /* GL_NV_parameter_buffer_object */ + +/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 + +#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2) + +#endif /* GL_NV_parameter_buffer_object2 */ + +/* -------------------------- GL_NV_path_rendering ------------------------- */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 + +#define GL_CLOSE_PATH_NV 0x00 +#define GL_BOLD_BIT_NV 0x01 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#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_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#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_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#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_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#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_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_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_RELATIVE_RECT_NV 0xF7 +#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_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_PRIMARY_COLOR 0x8577 +#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_PATH_STROKE_BOUND_NV 0x9086 +#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_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#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_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_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_FRAGMENT_INPUT_NV 0x936D +#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_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 + +typedef void (GLAPIENTRY * PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLuint (GLAPIENTRY * PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint* value); +typedef void (GLAPIENTRY * PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte* commands); +typedef void (GLAPIENTRY * PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat* coords); +typedef void (GLAPIENTRY * PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat* dashArray); +typedef GLfloat (GLAPIENTRY * PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef void (GLAPIENTRY * PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat* metrics); +typedef void (GLAPIENTRY * PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint* value); +typedef void (GLAPIENTRY * PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat* value); +typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint* value); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef GLboolean (GLAPIENTRY * PFNGLISPATHNVPROC) (GLuint path); +typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat* m); +typedef void (GLAPIENTRY * PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat* coeffs); +typedef void (GLAPIENTRY * PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); +typedef void (GLAPIENTRY * PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GLAPIENTRY * PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum zfunc); +typedef void (GLAPIENTRY * PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat* dashArray); +typedef void (GLAPIENTRY * PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GLAPIENTRY * PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +typedef void (GLAPIENTRY * PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAPIENTRY * PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void*charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GLAPIENTRY * PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (GLAPIENTRY * PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint* value); +typedef void (GLAPIENTRY * PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (GLAPIENTRY * PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (GLAPIENTRY * PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const void*coords); +typedef void (GLAPIENTRY * PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GLAPIENTRY * PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat* coeffs); +typedef GLboolean (GLAPIENTRY * PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat* x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (GLAPIENTRY * PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat* coeffs); +typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GLAPIENTRY * PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat* transformValues); +typedef void (GLAPIENTRY * PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint paths[], const GLfloat weights[]); + +#define glCopyPathNV GLEW_GET_FUN(__glewCopyPathNV) +#define glCoverFillPathInstancedNV GLEW_GET_FUN(__glewCoverFillPathInstancedNV) +#define glCoverFillPathNV GLEW_GET_FUN(__glewCoverFillPathNV) +#define glCoverStrokePathInstancedNV GLEW_GET_FUN(__glewCoverStrokePathInstancedNV) +#define glCoverStrokePathNV GLEW_GET_FUN(__glewCoverStrokePathNV) +#define glDeletePathsNV GLEW_GET_FUN(__glewDeletePathsNV) +#define glGenPathsNV GLEW_GET_FUN(__glewGenPathsNV) +#define glGetPathColorGenfvNV GLEW_GET_FUN(__glewGetPathColorGenfvNV) +#define glGetPathColorGenivNV GLEW_GET_FUN(__glewGetPathColorGenivNV) +#define glGetPathCommandsNV GLEW_GET_FUN(__glewGetPathCommandsNV) +#define glGetPathCoordsNV GLEW_GET_FUN(__glewGetPathCoordsNV) +#define glGetPathDashArrayNV GLEW_GET_FUN(__glewGetPathDashArrayNV) +#define glGetPathLengthNV GLEW_GET_FUN(__glewGetPathLengthNV) +#define glGetPathMetricRangeNV GLEW_GET_FUN(__glewGetPathMetricRangeNV) +#define glGetPathMetricsNV GLEW_GET_FUN(__glewGetPathMetricsNV) +#define glGetPathParameterfvNV GLEW_GET_FUN(__glewGetPathParameterfvNV) +#define glGetPathParameterivNV GLEW_GET_FUN(__glewGetPathParameterivNV) +#define glGetPathSpacingNV GLEW_GET_FUN(__glewGetPathSpacingNV) +#define glGetPathTexGenfvNV GLEW_GET_FUN(__glewGetPathTexGenfvNV) +#define glGetPathTexGenivNV GLEW_GET_FUN(__glewGetPathTexGenivNV) +#define glGetProgramResourcefvNV GLEW_GET_FUN(__glewGetProgramResourcefvNV) +#define glInterpolatePathsNV GLEW_GET_FUN(__glewInterpolatePathsNV) +#define glIsPathNV GLEW_GET_FUN(__glewIsPathNV) +#define glIsPointInFillPathNV GLEW_GET_FUN(__glewIsPointInFillPathNV) +#define glIsPointInStrokePathNV GLEW_GET_FUN(__glewIsPointInStrokePathNV) +#define glMatrixLoad3x2fNV GLEW_GET_FUN(__glewMatrixLoad3x2fNV) +#define glMatrixLoad3x3fNV GLEW_GET_FUN(__glewMatrixLoad3x3fNV) +#define glMatrixLoadTranspose3x3fNV GLEW_GET_FUN(__glewMatrixLoadTranspose3x3fNV) +#define glMatrixMult3x2fNV GLEW_GET_FUN(__glewMatrixMult3x2fNV) +#define glMatrixMult3x3fNV GLEW_GET_FUN(__glewMatrixMult3x3fNV) +#define glMatrixMultTranspose3x3fNV GLEW_GET_FUN(__glewMatrixMultTranspose3x3fNV) +#define glPathColorGenNV GLEW_GET_FUN(__glewPathColorGenNV) +#define glPathCommandsNV GLEW_GET_FUN(__glewPathCommandsNV) +#define glPathCoordsNV GLEW_GET_FUN(__glewPathCoordsNV) +#define glPathCoverDepthFuncNV GLEW_GET_FUN(__glewPathCoverDepthFuncNV) +#define glPathDashArrayNV GLEW_GET_FUN(__glewPathDashArrayNV) +#define glPathFogGenNV GLEW_GET_FUN(__glewPathFogGenNV) +#define glPathGlyphIndexArrayNV GLEW_GET_FUN(__glewPathGlyphIndexArrayNV) +#define glPathGlyphIndexRangeNV GLEW_GET_FUN(__glewPathGlyphIndexRangeNV) +#define glPathGlyphRangeNV GLEW_GET_FUN(__glewPathGlyphRangeNV) +#define glPathGlyphsNV GLEW_GET_FUN(__glewPathGlyphsNV) +#define glPathMemoryGlyphIndexArrayNV GLEW_GET_FUN(__glewPathMemoryGlyphIndexArrayNV) +#define glPathParameterfNV GLEW_GET_FUN(__glewPathParameterfNV) +#define glPathParameterfvNV GLEW_GET_FUN(__glewPathParameterfvNV) +#define glPathParameteriNV GLEW_GET_FUN(__glewPathParameteriNV) +#define glPathParameterivNV GLEW_GET_FUN(__glewPathParameterivNV) +#define glPathStencilDepthOffsetNV GLEW_GET_FUN(__glewPathStencilDepthOffsetNV) +#define glPathStencilFuncNV GLEW_GET_FUN(__glewPathStencilFuncNV) +#define glPathStringNV GLEW_GET_FUN(__glewPathStringNV) +#define glPathSubCommandsNV GLEW_GET_FUN(__glewPathSubCommandsNV) +#define glPathSubCoordsNV GLEW_GET_FUN(__glewPathSubCoordsNV) +#define glPathTexGenNV GLEW_GET_FUN(__glewPathTexGenNV) +#define glPointAlongPathNV GLEW_GET_FUN(__glewPointAlongPathNV) +#define glProgramPathFragmentInputGenNV GLEW_GET_FUN(__glewProgramPathFragmentInputGenNV) +#define glStencilFillPathInstancedNV GLEW_GET_FUN(__glewStencilFillPathInstancedNV) +#define glStencilFillPathNV GLEW_GET_FUN(__glewStencilFillPathNV) +#define glStencilStrokePathInstancedNV GLEW_GET_FUN(__glewStencilStrokePathInstancedNV) +#define glStencilStrokePathNV GLEW_GET_FUN(__glewStencilStrokePathNV) +#define glStencilThenCoverFillPathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverFillPathInstancedNV) +#define glStencilThenCoverFillPathNV GLEW_GET_FUN(__glewStencilThenCoverFillPathNV) +#define glStencilThenCoverStrokePathInstancedNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathInstancedNV) +#define glStencilThenCoverStrokePathNV GLEW_GET_FUN(__glewStencilThenCoverStrokePathNV) +#define glTransformPathNV GLEW_GET_FUN(__glewTransformPathNV) +#define glWeightPathsNV GLEW_GET_FUN(__glewWeightPathsNV) + +#define GLEW_NV_path_rendering GLEW_GET_VAR(__GLEW_NV_path_rendering) + +#endif /* GL_NV_path_rendering */ + +/* -------------------- GL_NV_path_rendering_shared_edge ------------------- */ + +#ifndef GL_NV_path_rendering_shared_edge +#define GL_NV_path_rendering_shared_edge 1 + +#define GL_SHARED_EDGE_NV 0xC0 + +#define GLEW_NV_path_rendering_shared_edge GLEW_GET_VAR(__GLEW_NV_path_rendering_shared_edge) + +#endif /* GL_NV_path_rendering_shared_edge */ + +/* ----------------------- GL_NV_pixel_buffer_object ----------------------- */ + +#ifndef GL_NV_pixel_buffer_object +#define GL_NV_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_NV 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF + +#define GLEW_NV_pixel_buffer_object GLEW_GET_VAR(__GLEW_NV_pixel_buffer_object) + +#endif /* GL_NV_pixel_buffer_object */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#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 (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void *pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* ------------------------- GL_NV_platform_binary ------------------------- */ + +#ifndef GL_NV_platform_binary +#define GL_NV_platform_binary 1 + +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B + +#define GLEW_NV_platform_binary GLEW_GET_VAR(__GLEW_NV_platform_binary) + +#endif /* GL_NV_platform_binary */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#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 (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* --------------------------- GL_NV_polygon_mode -------------------------- */ + +#ifndef GL_NV_polygon_mode +#define GL_NV_polygon_mode 1 + +#define GL_POLYGON_MODE_NV 0x0B40 +#define GL_POINT_NV 0x1B00 +#define GL_LINE_NV 0x1B01 +#define GL_FILL_NV 0x1B02 +#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 +#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 + +typedef void (GLAPIENTRY * PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode); + +#define glPolygonModeNV GLEW_GET_FUN(__glewPolygonModeNV) + +#define GLEW_NV_polygon_mode GLEW_GET_VAR(__GLEW_NV_polygon_mode) + +#endif /* GL_NV_polygon_mode */ + +/* -------------------------- GL_NV_present_video -------------------------- */ + +#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 (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); + +#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV) +#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV) +#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV) +#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV) +#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV) +#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV) + +#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video) + +#endif /* GL_NV_present_video */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#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 (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ---------------------------- GL_NV_read_depth --------------------------- */ + +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 + +#define GLEW_NV_read_depth GLEW_GET_VAR(__GLEW_NV_read_depth) + +#endif /* GL_NV_read_depth */ + +/* ------------------------ GL_NV_read_depth_stencil ----------------------- */ + +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 + +#define GLEW_NV_read_depth_stencil GLEW_GET_VAR(__GLEW_NV_read_depth_stencil) + +#endif /* GL_NV_read_depth_stencil */ + +/* --------------------------- GL_NV_read_stencil -------------------------- */ + +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 + +#define GLEW_NV_read_stencil GLEW_GET_VAR(__GLEW_NV_read_stencil) + +#endif /* GL_NV_read_stencil */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#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_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#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 (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* ------------------ GL_NV_robustness_video_memory_purge ------------------ */ + +#ifndef GL_NV_robustness_video_memory_purge +#define GL_NV_robustness_video_memory_purge 1 + +#define GL_EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB + +#define GLEW_NV_robustness_video_memory_purge GLEW_GET_VAR(__GLEW_NV_robustness_video_memory_purge) + +#endif /* GL_NV_robustness_video_memory_purge */ + +/* --------------------------- GL_NV_sRGB_formats -------------------------- */ + +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 + +#define GL_ETC1_SRGB8_NV 0x88EE +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F + +#define GLEW_NV_sRGB_formats GLEW_GET_VAR(__GLEW_NV_sRGB_formats) + +#endif /* GL_NV_sRGB_formats */ + +/* ------------------------- GL_NV_sample_locations ------------------------ */ + +#ifndef GL_NV_sample_locations +#define GL_NV_sample_locations 1 + +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat* v); + +#define glFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewFramebufferSampleLocationsfvNV) +#define glNamedFramebufferSampleLocationsfvNV GLEW_GET_FUN(__glewNamedFramebufferSampleLocationsfvNV) + +#define GLEW_NV_sample_locations GLEW_GET_VAR(__GLEW_NV_sample_locations) + +#endif /* GL_NV_sample_locations */ + +/* ------------------ GL_NV_sample_mask_override_coverage ------------------ */ + +#ifndef GL_NV_sample_mask_override_coverage +#define GL_NV_sample_mask_override_coverage 1 + +#define GLEW_NV_sample_mask_override_coverage GLEW_GET_VAR(__GLEW_NV_sample_mask_override_coverage) + +#endif /* GL_NV_sample_mask_override_coverage */ + +/* ---------------------- GL_NV_shader_atomic_counters --------------------- */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 + +#define GLEW_NV_shader_atomic_counters GLEW_GET_VAR(__GLEW_NV_shader_atomic_counters) + +#endif /* GL_NV_shader_atomic_counters */ + +/* ----------------------- GL_NV_shader_atomic_float ----------------------- */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 + +#define GLEW_NV_shader_atomic_float GLEW_GET_VAR(__GLEW_NV_shader_atomic_float) + +#endif /* GL_NV_shader_atomic_float */ + +/* ---------------------- GL_NV_shader_atomic_float64 ---------------------- */ + +#ifndef GL_NV_shader_atomic_float64 +#define GL_NV_shader_atomic_float64 1 + +#define GLEW_NV_shader_atomic_float64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_float64) + +#endif /* GL_NV_shader_atomic_float64 */ + +/* -------------------- GL_NV_shader_atomic_fp16_vector -------------------- */ + +#ifndef GL_NV_shader_atomic_fp16_vector +#define GL_NV_shader_atomic_fp16_vector 1 + +#define GLEW_NV_shader_atomic_fp16_vector GLEW_GET_VAR(__GLEW_NV_shader_atomic_fp16_vector) + +#endif /* GL_NV_shader_atomic_fp16_vector */ + +/* ----------------------- GL_NV_shader_atomic_int64 ----------------------- */ + +#ifndef GL_NV_shader_atomic_int64 +#define GL_NV_shader_atomic_int64 1 + +#define GLEW_NV_shader_atomic_int64 GLEW_GET_VAR(__GLEW_NV_shader_atomic_int64) + +#endif /* GL_NV_shader_atomic_int64 */ + +/* ------------------------ GL_NV_shader_buffer_load ----------------------- */ + +#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 (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value); + +#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV) +#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV) +#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV) +#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV) +#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV) +#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV) +#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV) +#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV) +#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV) +#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV) +#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV) +#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV) +#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV) + +#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load) + +#endif /* GL_NV_shader_buffer_load */ + +/* ---------------- GL_NV_shader_noperspective_interpolation --------------- */ + +#ifndef GL_NV_shader_noperspective_interpolation +#define GL_NV_shader_noperspective_interpolation 1 + +#define GLEW_NV_shader_noperspective_interpolation GLEW_GET_VAR(__GLEW_NV_shader_noperspective_interpolation) + +#endif /* GL_NV_shader_noperspective_interpolation */ + +/* ------------------- GL_NV_shader_storage_buffer_object ------------------ */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 + +#define GLEW_NV_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_NV_shader_storage_buffer_object) + +#endif /* GL_NV_shader_storage_buffer_object */ + +/* ----------------------- GL_NV_shader_thread_group ----------------------- */ + +#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 + +#define GLEW_NV_shader_thread_group GLEW_GET_VAR(__GLEW_NV_shader_thread_group) + +#endif /* GL_NV_shader_thread_group */ + +/* ---------------------- GL_NV_shader_thread_shuffle ---------------------- */ + +#ifndef GL_NV_shader_thread_shuffle +#define GL_NV_shader_thread_shuffle 1 + +#define GLEW_NV_shader_thread_shuffle GLEW_GET_VAR(__GLEW_NV_shader_thread_shuffle) + +#endif /* GL_NV_shader_thread_shuffle */ + +/* ---------------------- GL_NV_shadow_samplers_array ---------------------- */ + +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 + +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 + +#define GLEW_NV_shadow_samplers_array GLEW_GET_VAR(__GLEW_NV_shadow_samplers_array) + +#endif /* GL_NV_shadow_samplers_array */ + +/* ----------------------- GL_NV_shadow_samplers_cube ---------------------- */ + +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 + +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 + +#define GLEW_NV_shadow_samplers_cube GLEW_GET_VAR(__GLEW_NV_shadow_samplers_cube) + +#endif /* GL_NV_shadow_samplers_cube */ + +/* ---------------------- GL_NV_stereo_view_rendering ---------------------- */ + +#ifndef GL_NV_stereo_view_rendering +#define GL_NV_stereo_view_rendering 1 + +#define GLEW_NV_stereo_view_rendering GLEW_GET_VAR(__GLEW_NV_stereo_view_rendering) + +#endif /* GL_NV_stereo_view_rendering */ + +/* ---------------------- GL_NV_tessellation_program5 ---------------------- */ + +#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 + +#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5) + +#endif /* GL_NV_tessellation_program5 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#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 + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* -------------------------- GL_NV_texture_array -------------------------- */ + +#ifndef GL_NV_texture_array +#define GL_NV_texture_array 1 + +#define GL_UNPACK_SKIP_IMAGES_NV 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_NV 0x806E +#define GL_MAX_ARRAY_TEXTURE_LAYERS_NV 0x88FF +#define GL_TEXTURE_2D_ARRAY_NV 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY_NV 0x8C1D +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_NV 0x8CD4 +#define GL_SAMPLER_2D_ARRAY_NV 0x8DC1 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC) (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 (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERNVPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DNVPROC) (GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DNVPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + +#define glCompressedTexImage3DNV GLEW_GET_FUN(__glewCompressedTexImage3DNV) +#define glCompressedTexSubImage3DNV GLEW_GET_FUN(__glewCompressedTexSubImage3DNV) +#define glCopyTexSubImage3DNV GLEW_GET_FUN(__glewCopyTexSubImage3DNV) +#define glFramebufferTextureLayerNV GLEW_GET_FUN(__glewFramebufferTextureLayerNV) +#define glTexImage3DNV GLEW_GET_FUN(__glewTexImage3DNV) +#define glTexSubImage3DNV GLEW_GET_FUN(__glewTexSubImage3DNV) + +#define GLEW_NV_texture_array GLEW_GET_VAR(__GLEW_NV_texture_array) + +#endif /* GL_NV_texture_array */ + +/* ------------------------- GL_NV_texture_barrier ------------------------- */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void); + +#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV) + +#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier) + +#endif /* GL_NV_texture_barrier */ + +/* ----------------------- GL_NV_texture_border_clamp ---------------------- */ + +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 + +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D + +#define GLEW_NV_texture_border_clamp GLEW_GET_VAR(__GLEW_NV_texture_border_clamp) + +#endif /* GL_NV_texture_border_clamp */ + +/* --------------------- GL_NV_texture_compression_latc -------------------- */ + +#ifndef GL_NV_texture_compression_latc +#define GL_NV_texture_compression_latc 1 + +#define GL_COMPRESSED_LUMINANCE_LATC1_NV 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_NV 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_NV 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_NV 0x8C73 + +#define GLEW_NV_texture_compression_latc GLEW_GET_VAR(__GLEW_NV_texture_compression_latc) + +#endif /* GL_NV_texture_compression_latc */ + +/* --------------------- GL_NV_texture_compression_s3tc -------------------- */ + +#ifndef GL_NV_texture_compression_s3tc +#define GL_NV_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_NV 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_NV 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_NV 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_NV 0x83F3 + +#define GLEW_NV_texture_compression_s3tc GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc) + +#endif /* GL_NV_texture_compression_s3tc */ + +/* ----------------- GL_NV_texture_compression_s3tc_update ----------------- */ + +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 + +#define GLEW_NV_texture_compression_s3tc_update GLEW_GET_VAR(__GLEW_NV_texture_compression_s3tc_update) + +#endif /* GL_NV_texture_compression_s3tc_update */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#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 + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ----------------------- GL_NV_texture_multisample ----------------------- */ + +#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 (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); + +#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV) +#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV) +#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV) +#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV) +#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV) +#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV) + +#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample) + +#endif /* GL_NV_texture_multisample */ + +/* ---------------------- GL_NV_texture_npot_2D_mipmap --------------------- */ + +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 + +#define GLEW_NV_texture_npot_2D_mipmap GLEW_GET_VAR(__GLEW_NV_texture_npot_2D_mipmap) + +#endif /* GL_NV_texture_npot_2D_mipmap */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#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 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* ------------------- GL_NV_texture_rectangle_compressed ------------------ */ + +#ifndef GL_NV_texture_rectangle_compressed +#define GL_NV_texture_rectangle_compressed 1 + +#define GLEW_NV_texture_rectangle_compressed GLEW_GET_VAR(__GLEW_NV_texture_rectangle_compressed) + +#endif /* GL_NV_texture_rectangle_compressed */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#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_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_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 + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#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_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#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 GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#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 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_transform_feedback ----------------------- */ + +#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 + +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); + +#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV) +#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV) +#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV) +#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV) +#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV) +#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV) +#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV) +#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV) +#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV) +#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV) +#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV) + +#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback) + +#endif /* GL_NV_transform_feedback */ + +/* ----------------------- GL_NV_transform_feedback2 ----------------------- */ + +#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 (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids); +typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); + +#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV) +#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV) +#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV) +#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV) +#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV) +#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV) +#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV) + +#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2) + +#endif /* GL_NV_transform_feedback2 */ + +/* ------------------ GL_NV_uniform_buffer_unified_memory ------------------ */ + +#ifndef GL_NV_uniform_buffer_unified_memory +#define GL_NV_uniform_buffer_unified_memory 1 + +#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E +#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F +#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 + +#define GLEW_NV_uniform_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_uniform_buffer_unified_memory) + +#endif /* GL_NV_uniform_buffer_unified_memory */ + +/* -------------------------- GL_NV_vdpau_interop -------------------------- */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 + +#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 GLintptr GLvdpauSurfaceNV; + +typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values); +typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const void*getProcAddress); +typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces); +typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); + +#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV) +#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV) +#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV) +#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV) +#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV) +#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV) +#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV) +#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV) +#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV) +#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV) + +#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop) + +#endif /* GL_NV_vdpau_interop */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#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 (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void *pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 + +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); + +#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV) +#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV) +#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV) +#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV) +#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV) +#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV) +#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV) +#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV) +#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV) +#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV) +#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV) +#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV) +#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV) +#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV) +#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV) +#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV) +#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV) +#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV) +#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV) + +#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit) + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */ + +#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 (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]); +typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); + +#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV) +#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV) +#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV) +#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV) +#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV) +#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV) +#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV) +#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV) +#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV) +#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV) +#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV) +#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV) + +#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory) + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#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 (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ------------------------- GL_NV_vertex_program4 ------------------------- */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 + +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD + +#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4) + +#endif /* GL_NV_vertex_program4 */ + +/* -------------------------- GL_NV_video_capture -------------------------- */ + +#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 (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params); +typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params); + +#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV) +#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV) +#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV) +#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV) +#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV) +#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV) +#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV) +#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV) +#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV) +#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV) +#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV) +#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV) + +#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture) + +#endif /* GL_NV_video_capture */ + +/* -------------------------- GL_NV_viewport_array ------------------------- */ + +#ifndef GL_NV_viewport_array +#define GL_NV_viewport_array 1 + +#define GL_DEPTH_RANGE 0x0B70 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_MAX_VIEWPORTS_NV 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F + +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f); +typedef void (GLAPIENTRY * PFNGLDISABLEINVPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINVPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat* data); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINVPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint * v); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat * v); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat * v); + +#define glDepthRangeArrayfvNV GLEW_GET_FUN(__glewDepthRangeArrayfvNV) +#define glDepthRangeIndexedfNV GLEW_GET_FUN(__glewDepthRangeIndexedfNV) +#define glDisableiNV GLEW_GET_FUN(__glewDisableiNV) +#define glEnableiNV GLEW_GET_FUN(__glewEnableiNV) +#define glGetFloati_vNV GLEW_GET_FUN(__glewGetFloati_vNV) +#define glIsEnablediNV GLEW_GET_FUN(__glewIsEnablediNV) +#define glScissorArrayvNV GLEW_GET_FUN(__glewScissorArrayvNV) +#define glScissorIndexedNV GLEW_GET_FUN(__glewScissorIndexedNV) +#define glScissorIndexedvNV GLEW_GET_FUN(__glewScissorIndexedvNV) +#define glViewportArrayvNV GLEW_GET_FUN(__glewViewportArrayvNV) +#define glViewportIndexedfNV GLEW_GET_FUN(__glewViewportIndexedfNV) +#define glViewportIndexedfvNV GLEW_GET_FUN(__glewViewportIndexedfvNV) + +#define GLEW_NV_viewport_array GLEW_GET_VAR(__GLEW_NV_viewport_array) + +#endif /* GL_NV_viewport_array */ + +/* ------------------------- GL_NV_viewport_array2 ------------------------- */ + +#ifndef GL_NV_viewport_array2 +#define GL_NV_viewport_array2 1 + +#define GLEW_NV_viewport_array2 GLEW_GET_VAR(__GLEW_NV_viewport_array2) + +#endif /* GL_NV_viewport_array2 */ + +/* ------------------------- GL_NV_viewport_swizzle ------------------------ */ + +#ifndef GL_NV_viewport_swizzle +#define GL_NV_viewport_swizzle 1 + +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B + +typedef void (GLAPIENTRY * PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); + +#define glViewportSwizzleNV GLEW_GET_FUN(__glewViewportSwizzleNV) + +#define GLEW_NV_viewport_swizzle GLEW_GET_VAR(__GLEW_NV_viewport_swizzle) + +#endif /* GL_NV_viewport_swizzle */ + +/* ------------------------ GL_OES_byte_coordinates ------------------------ */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 + +#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates) + +#endif /* GL_OES_byte_coordinates */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#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 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#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 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* ---------------------------- GL_OVR_multiview --------------------------- */ + +#ifndef GL_OVR_multiview +#define GL_OVR_multiview 1 + +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); + +#define glFramebufferTextureMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultiviewOVR) + +#define GLEW_OVR_multiview GLEW_GET_VAR(__GLEW_OVR_multiview) + +#endif /* GL_OVR_multiview */ + +/* --------------------------- GL_OVR_multiview2 --------------------------- */ + +#ifndef GL_OVR_multiview2 +#define GL_OVR_multiview2 1 + +#define GLEW_OVR_multiview2 GLEW_GET_VAR(__GLEW_OVR_multiview2) + +#endif /* GL_OVR_multiview2 */ + +/* ------------ GL_OVR_multiview_multisampled_render_to_texture ------------ */ + +#ifndef GL_OVR_multiview_multisampled_render_to_texture +#define GL_OVR_multiview_multisampled_render_to_texture 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); + +#define glFramebufferTextureMultisampleMultiviewOVR GLEW_GET_FUN(__glewFramebufferTextureMultisampleMultiviewOVR) + +#define GLEW_OVR_multiview_multisampled_render_to_texture GLEW_GET_VAR(__GLEW_OVR_multiview_multisampled_render_to_texture) + +#endif /* GL_OVR_multiview_multisampled_render_to_texture */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#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_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#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 GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* --------------------------- GL_QCOM_alpha_test -------------------------- */ + +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 + +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 + +typedef void (GLAPIENTRY * PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); + +#define glAlphaFuncQCOM GLEW_GET_FUN(__glewAlphaFuncQCOM) + +#define GLEW_QCOM_alpha_test GLEW_GET_VAR(__GLEW_QCOM_alpha_test) + +#endif /* GL_QCOM_alpha_test */ + +/* ------------------------ GL_QCOM_binning_control ------------------------ */ + +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 + +#define GL_DONT_CARE 0x1100 +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 + +#define GLEW_QCOM_binning_control GLEW_GET_VAR(__GLEW_QCOM_binning_control) + +#endif /* GL_QCOM_binning_control */ + +/* ------------------------- GL_QCOM_driver_control ------------------------ */ + +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 + +typedef void (GLAPIENTRY * PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GLAPIENTRY * PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei* length, GLchar *driverControlString); +typedef void (GLAPIENTRY * PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint* num, GLsizei size, GLuint *driverControls); + +#define glDisableDriverControlQCOM GLEW_GET_FUN(__glewDisableDriverControlQCOM) +#define glEnableDriverControlQCOM GLEW_GET_FUN(__glewEnableDriverControlQCOM) +#define glGetDriverControlStringQCOM GLEW_GET_FUN(__glewGetDriverControlStringQCOM) +#define glGetDriverControlsQCOM GLEW_GET_FUN(__glewGetDriverControlsQCOM) + +#define GLEW_QCOM_driver_control GLEW_GET_VAR(__GLEW_QCOM_driver_control) + +#endif /* GL_QCOM_driver_control */ + +/* -------------------------- GL_QCOM_extended_get ------------------------- */ + +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 + +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC + +typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void** params); +typedef void (GLAPIENTRY * PFNGLEXTGETBUFFERSQCOMPROC) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers); +typedef void (GLAPIENTRY * PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers); +typedef void (GLAPIENTRY * PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers); +typedef void (GLAPIENTRY * PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +typedef void (GLAPIENTRY * PFNGLEXTGETTEXTURESQCOMPROC) (GLuint* textures, GLint maxTextures, GLint* numTextures); +typedef void (GLAPIENTRY * PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); + +#define glExtGetBufferPointervQCOM GLEW_GET_FUN(__glewExtGetBufferPointervQCOM) +#define glExtGetBuffersQCOM GLEW_GET_FUN(__glewExtGetBuffersQCOM) +#define glExtGetFramebuffersQCOM GLEW_GET_FUN(__glewExtGetFramebuffersQCOM) +#define glExtGetRenderbuffersQCOM GLEW_GET_FUN(__glewExtGetRenderbuffersQCOM) +#define glExtGetTexLevelParameterivQCOM GLEW_GET_FUN(__glewExtGetTexLevelParameterivQCOM) +#define glExtGetTexSubImageQCOM GLEW_GET_FUN(__glewExtGetTexSubImageQCOM) +#define glExtGetTexturesQCOM GLEW_GET_FUN(__glewExtGetTexturesQCOM) +#define glExtTexObjectStateOverrideiQCOM GLEW_GET_FUN(__glewExtTexObjectStateOverrideiQCOM) + +#define GLEW_QCOM_extended_get GLEW_GET_VAR(__GLEW_QCOM_extended_get) + +#endif /* GL_QCOM_extended_get */ + +/* ------------------------- GL_QCOM_extended_get2 ------------------------- */ + +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 + +typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar* source, GLint* length); +typedef void (GLAPIENTRY * PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint* programs, GLint maxPrograms, GLint* numPrograms); +typedef void (GLAPIENTRY * PFNGLEXTGETSHADERSQCOMPROC) (GLuint* shaders, GLint maxShaders, GLint* numShaders); +typedef GLboolean (GLAPIENTRY * PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); + +#define glExtGetProgramBinarySourceQCOM GLEW_GET_FUN(__glewExtGetProgramBinarySourceQCOM) +#define glExtGetProgramsQCOM GLEW_GET_FUN(__glewExtGetProgramsQCOM) +#define glExtGetShadersQCOM GLEW_GET_FUN(__glewExtGetShadersQCOM) +#define glExtIsProgramBinaryQCOM GLEW_GET_FUN(__glewExtIsProgramBinaryQCOM) + +#define GLEW_QCOM_extended_get2 GLEW_GET_VAR(__GLEW_QCOM_extended_get2) + +#endif /* GL_QCOM_extended_get2 */ + +/* ---------------------- GL_QCOM_framebuffer_foveated --------------------- */ + +#ifndef GL_QCOM_framebuffer_foveated +#define GL_QCOM_framebuffer_foveated 1 + +#define GL_FOVEATION_ENABLE_BIT_QCOM 0x1 +#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x2 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint fbo, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint* providedFeatures); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint fbo, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); + +#define glFramebufferFoveationConfigQCOM GLEW_GET_FUN(__glewFramebufferFoveationConfigQCOM) +#define glFramebufferFoveationParametersQCOM GLEW_GET_FUN(__glewFramebufferFoveationParametersQCOM) + +#define GLEW_QCOM_framebuffer_foveated GLEW_GET_VAR(__GLEW_QCOM_framebuffer_foveated) + +#endif /* GL_QCOM_framebuffer_foveated */ + +/* ---------------------- GL_QCOM_perfmon_global_mode ---------------------- */ + +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 + +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 + +#define GLEW_QCOM_perfmon_global_mode GLEW_GET_VAR(__GLEW_QCOM_perfmon_global_mode) + +#endif /* GL_QCOM_perfmon_global_mode */ + +/* -------------- GL_QCOM_shader_framebuffer_fetch_noncoherent ------------- */ + +#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent +#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 + +#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 + +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void); + +#define glFramebufferFetchBarrierQCOM GLEW_GET_FUN(__glewFramebufferFetchBarrierQCOM) + +#define GLEW_QCOM_shader_framebuffer_fetch_noncoherent GLEW_GET_VAR(__GLEW_QCOM_shader_framebuffer_fetch_noncoherent) + +#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ + +/* ------------------------ GL_QCOM_tiled_rendering ------------------------ */ + +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 + +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 + +typedef void (GLAPIENTRY * PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +typedef void (GLAPIENTRY * PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); + +#define glEndTilingQCOM GLEW_GET_FUN(__glewEndTilingQCOM) +#define glStartTilingQCOM GLEW_GET_FUN(__glewStartTilingQCOM) + +#define GLEW_QCOM_tiled_rendering GLEW_GET_VAR(__GLEW_QCOM_tiled_rendering) + +#endif /* GL_QCOM_tiled_rendering */ + +/* ---------------------- GL_QCOM_writeonly_rendering ---------------------- */ + +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 + +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 + +#define GLEW_QCOM_writeonly_rendering GLEW_GET_VAR(__GLEW_QCOM_writeonly_rendering) + +#endif /* GL_QCOM_writeonly_rendering */ + +/* ---------------------- GL_REGAL_ES1_0_compatibility --------------------- */ + +#ifndef GL_REGAL_ES1_0_compatibility +#define GL_REGAL_ES1_0_compatibility 1 + +typedef int GLclampx; + +typedef void (GLAPIENTRY * PFNGLALPHAFUNCXPROC) (GLenum func, GLclampx ref); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORXPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha); +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHXPROC) (GLclampx depth); +typedef void (GLAPIENTRY * PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEXPROC) (GLclampx zNear, GLclampx zFar); +typedef void (GLAPIENTRY * PFNGLFOGXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLFOGXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLFRUSTUMFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); +typedef void (GLAPIENTRY * PFNGLFRUSTUMXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +typedef void (GLAPIENTRY * PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLLINEWIDTHXPROC) (GLfixed width); +typedef void (GLAPIENTRY * PFNGLLOADMATRIXXPROC) (const GLfixed* m); +typedef void (GLAPIENTRY * PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLMULTMATRIXXPROC) (const GLfixed* m); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4XPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (GLAPIENTRY * PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (GLAPIENTRY * PFNGLORTHOFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); +typedef void (GLAPIENTRY * PFNGLORTHOXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar); +typedef void (GLAPIENTRY * PFNGLPOINTSIZEXPROC) (GLfixed size); +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units); +typedef void (GLAPIENTRY * PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (GLAPIENTRY * PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z); + +#define glAlphaFuncx GLEW_GET_FUN(__glewAlphaFuncx) +#define glClearColorx GLEW_GET_FUN(__glewClearColorx) +#define glClearDepthx GLEW_GET_FUN(__glewClearDepthx) +#define glColor4x GLEW_GET_FUN(__glewColor4x) +#define glDepthRangex GLEW_GET_FUN(__glewDepthRangex) +#define glFogx GLEW_GET_FUN(__glewFogx) +#define glFogxv GLEW_GET_FUN(__glewFogxv) +#define glFrustumf GLEW_GET_FUN(__glewFrustumf) +#define glFrustumx GLEW_GET_FUN(__glewFrustumx) +#define glLightModelx GLEW_GET_FUN(__glewLightModelx) +#define glLightModelxv GLEW_GET_FUN(__glewLightModelxv) +#define glLightx GLEW_GET_FUN(__glewLightx) +#define glLightxv GLEW_GET_FUN(__glewLightxv) +#define glLineWidthx GLEW_GET_FUN(__glewLineWidthx) +#define glLoadMatrixx GLEW_GET_FUN(__glewLoadMatrixx) +#define glMaterialx GLEW_GET_FUN(__glewMaterialx) +#define glMaterialxv GLEW_GET_FUN(__glewMaterialxv) +#define glMultMatrixx GLEW_GET_FUN(__glewMultMatrixx) +#define glMultiTexCoord4x GLEW_GET_FUN(__glewMultiTexCoord4x) +#define glNormal3x GLEW_GET_FUN(__glewNormal3x) +#define glOrthof GLEW_GET_FUN(__glewOrthof) +#define glOrthox GLEW_GET_FUN(__glewOrthox) +#define glPointSizex GLEW_GET_FUN(__glewPointSizex) +#define glPolygonOffsetx GLEW_GET_FUN(__glewPolygonOffsetx) +#define glRotatex GLEW_GET_FUN(__glewRotatex) +#define glSampleCoveragex GLEW_GET_FUN(__glewSampleCoveragex) +#define glScalex GLEW_GET_FUN(__glewScalex) +#define glTexEnvx GLEW_GET_FUN(__glewTexEnvx) +#define glTexEnvxv GLEW_GET_FUN(__glewTexEnvxv) +#define glTexParameterx GLEW_GET_FUN(__glewTexParameterx) +#define glTranslatex GLEW_GET_FUN(__glewTranslatex) + +#define GLEW_REGAL_ES1_0_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_0_compatibility) + +#endif /* GL_REGAL_ES1_0_compatibility */ + +/* ---------------------- GL_REGAL_ES1_1_compatibility --------------------- */ + +#ifndef GL_REGAL_ES1_1_compatibility +#define GL_REGAL_ES1_1_compatibility 1 + +typedef void (GLAPIENTRY * PFNGLCLIPPLANEFPROC) (GLenum plane, const GLfloat* equation); +typedef void (GLAPIENTRY * PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed* equation); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFPROC) (GLenum pname, GLfloat eqn[4]); +typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEXPROC) (GLenum pname, GLfixed eqn[4]); +typedef void (GLAPIENTRY * PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETTEXENVXVPROC) (GLenum env, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed* params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed* params); +typedef void (GLAPIENTRY * PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed* params); + +#define glClipPlanef GLEW_GET_FUN(__glewClipPlanef) +#define glClipPlanex GLEW_GET_FUN(__glewClipPlanex) +#define glGetClipPlanef GLEW_GET_FUN(__glewGetClipPlanef) +#define glGetClipPlanex GLEW_GET_FUN(__glewGetClipPlanex) +#define glGetFixedv GLEW_GET_FUN(__glewGetFixedv) +#define glGetLightxv GLEW_GET_FUN(__glewGetLightxv) +#define glGetMaterialxv GLEW_GET_FUN(__glewGetMaterialxv) +#define glGetTexEnvxv GLEW_GET_FUN(__glewGetTexEnvxv) +#define glGetTexParameterxv GLEW_GET_FUN(__glewGetTexParameterxv) +#define glPointParameterx GLEW_GET_FUN(__glewPointParameterx) +#define glPointParameterxv GLEW_GET_FUN(__glewPointParameterxv) +#define glPointSizePointerOES GLEW_GET_FUN(__glewPointSizePointerOES) +#define glTexParameterxv GLEW_GET_FUN(__glewTexParameterxv) + +#define GLEW_REGAL_ES1_1_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_1_compatibility) + +#endif /* GL_REGAL_ES1_1_compatibility */ + +/* ---------------------------- GL_REGAL_enable ---------------------------- */ + +#ifndef GL_REGAL_enable +#define GL_REGAL_enable 1 + +#define GL_ERROR_REGAL 0x9322 +#define GL_DEBUG_REGAL 0x9323 +#define GL_LOG_REGAL 0x9324 +#define GL_EMULATION_REGAL 0x9325 +#define GL_DRIVER_REGAL 0x9326 +#define GL_MISSING_REGAL 0x9360 +#define GL_TRACE_REGAL 0x9361 +#define GL_CACHE_REGAL 0x9362 +#define GL_CODE_REGAL 0x9363 +#define GL_STATISTICS_REGAL 0x9364 + +#define GLEW_REGAL_enable GLEW_GET_VAR(__GLEW_REGAL_enable) + +#endif /* GL_REGAL_enable */ + +/* ------------------------- GL_REGAL_error_string ------------------------- */ + +#ifndef GL_REGAL_error_string +#define GL_REGAL_error_string 1 + +typedef const GLchar* (GLAPIENTRY * PFNGLERRORSTRINGREGALPROC) (GLenum error); + +#define glErrorStringREGAL GLEW_GET_FUN(__glewErrorStringREGAL) + +#define GLEW_REGAL_error_string GLEW_GET_VAR(__GLEW_REGAL_error_string) + +#endif /* GL_REGAL_error_string */ + +/* ------------------------ GL_REGAL_extension_query ----------------------- */ + +#ifndef GL_REGAL_extension_query +#define GL_REGAL_extension_query 1 + +typedef GLboolean (GLAPIENTRY * PFNGLGETEXTENSIONREGALPROC) (const GLchar* ext); +typedef GLboolean (GLAPIENTRY * PFNGLISSUPPORTEDREGALPROC) (const GLchar* ext); + +#define glGetExtensionREGAL GLEW_GET_FUN(__glewGetExtensionREGAL) +#define glIsSupportedREGAL GLEW_GET_FUN(__glewIsSupportedREGAL) + +#define GLEW_REGAL_extension_query GLEW_GET_VAR(__GLEW_REGAL_extension_query) + +#endif /* GL_REGAL_extension_query */ + +/* ------------------------------ GL_REGAL_log ----------------------------- */ + +#ifndef GL_REGAL_log +#define GL_REGAL_log 1 + +#define GL_LOG_ERROR_REGAL 0x9319 +#define GL_LOG_WARNING_REGAL 0x931A +#define GL_LOG_INFO_REGAL 0x931B +#define GL_LOG_APP_REGAL 0x931C +#define GL_LOG_DRIVER_REGAL 0x931D +#define GL_LOG_INTERNAL_REGAL 0x931E +#define GL_LOG_DEBUG_REGAL 0x931F +#define GL_LOG_STATUS_REGAL 0x9320 +#define GL_LOG_HTTP_REGAL 0x9321 + +typedef void (APIENTRY *GLLOGPROCREGAL)(GLenum stream, GLsizei length, const GLchar *message, void *context); + +typedef void (GLAPIENTRY * PFNGLLOGMESSAGECALLBACKREGALPROC) (GLLOGPROCREGAL callback); + +#define glLogMessageCallbackREGAL GLEW_GET_FUN(__glewLogMessageCallbackREGAL) + +#define GLEW_REGAL_log GLEW_GET_VAR(__GLEW_REGAL_log) + +#endif /* GL_REGAL_log */ + +/* ------------------------- GL_REGAL_proc_address ------------------------- */ + +#ifndef GL_REGAL_proc_address +#define GL_REGAL_proc_address 1 + +typedef void * (GLAPIENTRY * PFNGLGETPROCADDRESSREGALPROC) (const GLchar *name); + +#define glGetProcAddressREGAL GLEW_GET_FUN(__glewGetProcAddressREGAL) + +#define GLEW_REGAL_proc_address GLEW_GET_VAR(__GLEW_REGAL_proc_address) + +#endif /* GL_REGAL_proc_address */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#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 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* ------------------------- GL_SGIS_clip_band_hint ------------------------ */ + +#ifndef GL_SGIS_clip_band_hint +#define GL_SGIS_clip_band_hint 1 + +#define GLEW_SGIS_clip_band_hint GLEW_GET_VAR(__GLEW_SGIS_clip_band_hint) + +#endif /* GL_SGIS_clip_band_hint */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_line_texgen -------------------------- */ + +#ifndef GL_SGIS_line_texgen +#define GL_SGIS_line_texgen 1 + +#define GLEW_SGIS_line_texgen GLEW_GET_VAR(__GLEW_SGIS_line_texgen) + +#endif /* GL_SGIS_line_texgen */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#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 (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* -------------------------- GL_SGIS_multitexture ------------------------- */ + +#ifndef GL_SGIS_multitexture +#define GL_SGIS_multitexture 1 + +#define GL_SELECTED_TEXTURE_SGIS 0x83C0 +#define GL_SELECTED_TEXTURE_COORD_SET_SGIS 0x83C1 +#define GL_SELECTED_TEXTURE_TRANSFORM_SGIS 0x83C2 +#define GL_MAX_TEXTURES_SGIS 0x83C3 +#define GL_MAX_TEXTURE_COORD_SETS_SGIS 0x83C4 +#define GL_TEXTURE_COORD_SET_INTERLEAVE_FACTOR_SGIS 0x83C5 +#define GL_TEXTURE_ENV_COORD_SET_SGIS 0x83C6 +#define GL_TEXTURE0_SGIS 0x83C7 +#define GL_TEXTURE1_SGIS 0x83C8 +#define GL_TEXTURE2_SGIS 0x83C9 +#define GL_TEXTURE3_SGIS 0x83CA + +typedef void (GLAPIENTRY * PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLSELECTTEXTURECOORDSETSGISPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSELECTTEXTURESGISPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSELECTTEXTURETRANSFORMSGISPROC) (GLenum target); + +#define glInterleavedTextureCoordSetsSGIS GLEW_GET_FUN(__glewInterleavedTextureCoordSetsSGIS) +#define glSelectTextureCoordSetSGIS GLEW_GET_FUN(__glewSelectTextureCoordSetSGIS) +#define glSelectTextureSGIS GLEW_GET_FUN(__glewSelectTextureSGIS) +#define glSelectTextureTransformSGIS GLEW_GET_FUN(__glewSelectTextureTransformSGIS) + +#define GLEW_SGIS_multitexture GLEW_GET_VAR(__GLEW_SGIS_multitexture) + +#endif /* GL_SGIS_multitexture */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */ + +#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 + +#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen) + +#endif /* GL_SGIS_point_line_texgen */ + +/* ----------------------- GL_SGIS_shared_multisample ---------------------- */ + +#ifndef GL_SGIS_shared_multisample +#define GL_SGIS_shared_multisample 1 + +typedef void (GLAPIENTRY * PFNGLMULTISAMPLESUBRECTPOSSGISPROC) (GLint x, GLint y); + +#define glMultisampleSubRectPosSGIS GLEW_GET_FUN(__glewMultisampleSubRectPosSGIS) + +#define GLEW_SGIS_shared_multisample GLEW_GET_VAR(__GLEW_SGIS_shared_multisample) + +#endif /* GL_SGIS_shared_multisample */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void *pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#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 + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#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 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_bali_g_instruments ---------------------- */ + +#ifndef GL_SGIX_bali_g_instruments +#define GL_SGIX_bali_g_instruments 1 + +#define GL_BALI_NUM_TRIS_CULLED_INSTRUMENT 0x6080 +#define GL_BALI_NUM_PRIMS_CLIPPED_INSTRUMENT 0x6081 +#define GL_BALI_NUM_PRIMS_REJECT_INSTRUMENT 0x6082 +#define GL_BALI_NUM_PRIMS_CLIP_RESULT_INSTRUMENT 0x6083 + +#define GLEW_SGIX_bali_g_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_g_instruments) + +#endif /* GL_SGIX_bali_g_instruments */ + +/* ----------------------- GL_SGIX_bali_r_instruments ---------------------- */ + +#ifndef GL_SGIX_bali_r_instruments +#define GL_SGIX_bali_r_instruments 1 + +#define GL_BALI_FRAGMENTS_GENERATED_INSTRUMENT 0x6090 +#define GL_BALI_DEPTH_PASS_INSTRUMENT 0x6091 +#define GL_BALI_R_CHIP_COUNT 0x6092 + +#define GLEW_SGIX_bali_r_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_r_instruments) + +#endif /* GL_SGIX_bali_r_instruments */ + +/* --------------------- GL_SGIX_bali_timer_instruments -------------------- */ + +#ifndef GL_SGIX_bali_timer_instruments +#define GL_SGIX_bali_timer_instruments 1 + +#define GLEW_SGIX_bali_timer_instruments GLEW_GET_VAR(__GLEW_SGIX_bali_timer_instruments) + +#endif /* GL_SGIX_bali_timer_instruments */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#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 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* --------------------------- GL_SGIX_blend_cadd -------------------------- */ + +#ifndef GL_SGIX_blend_cadd +#define GL_SGIX_blend_cadd 1 + +#define GL_FUNC_COMPLEX_ADD_EXT 0x601C + +#define GLEW_SGIX_blend_cadd GLEW_GET_VAR(__GLEW_SGIX_blend_cadd) + +#endif /* GL_SGIX_blend_cadd */ + +/* ------------------------ GL_SGIX_blend_cmultiply ------------------------ */ + +#ifndef GL_SGIX_blend_cmultiply +#define GL_SGIX_blend_cmultiply 1 + +#define GL_FUNC_COMPLEX_MULTIPLY_EXT 0x601B + +#define GLEW_SGIX_blend_cmultiply GLEW_GET_VAR(__GLEW_SGIX_blend_cmultiply) + +#endif /* GL_SGIX_blend_cmultiply */ + +/* --------------------- GL_SGIX_calligraphic_fragment --------------------- */ + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 + +#define GLEW_SGIX_calligraphic_fragment GLEW_GET_VAR(__GLEW_SGIX_calligraphic_fragment) + +#endif /* GL_SGIX_calligraphic_fragment */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* --------------------- GL_SGIX_color_matrix_accuracy --------------------- */ + +#ifndef GL_SGIX_color_matrix_accuracy +#define GL_SGIX_color_matrix_accuracy 1 + +#define GL_COLOR_MATRIX_HINT 0x8317 + +#define GLEW_SGIX_color_matrix_accuracy GLEW_GET_VAR(__GLEW_SGIX_color_matrix_accuracy) + +#endif /* GL_SGIX_color_matrix_accuracy */ + +/* --------------------- GL_SGIX_color_table_index_mode -------------------- */ + +#ifndef GL_SGIX_color_table_index_mode +#define GL_SGIX_color_table_index_mode 1 + +#define GLEW_SGIX_color_table_index_mode GLEW_GET_VAR(__GLEW_SGIX_color_table_index_mode) + +#endif /* GL_SGIX_color_table_index_mode */ + +/* ------------------------- GL_SGIX_complex_polar ------------------------- */ + +#ifndef GL_SGIX_complex_polar +#define GL_SGIX_complex_polar 1 + +#define GLEW_SGIX_complex_polar GLEW_GET_VAR(__GLEW_SGIX_complex_polar) + +#endif /* GL_SGIX_complex_polar */ + +/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 + +#define GL_CONVOLUTION_HINT_SGIX 0x8316 + +#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy) + +#endif /* GL_SGIX_convolution_accuracy */ + +/* ---------------------------- GL_SGIX_cube_map --------------------------- */ + +#ifndef GL_SGIX_cube_map +#define GL_SGIX_cube_map 1 + +#define GL_ENV_MAP_SGIX 0x8340 +#define GL_CUBE_MAP_SGIX 0x8341 +#define GL_CUBE_MAP_ZP_SGIX 0x8342 +#define GL_CUBE_MAP_ZN_SGIX 0x8343 +#define GL_CUBE_MAP_XN_SGIX 0x8344 +#define GL_CUBE_MAP_XP_SGIX 0x8345 +#define GL_CUBE_MAP_YN_SGIX 0x8346 +#define GL_CUBE_MAP_YP_SGIX 0x8347 +#define GL_CUBE_MAP_BINDING_SGIX 0x8348 + +#define GLEW_SGIX_cube_map GLEW_GET_VAR(__GLEW_SGIX_cube_map) + +#endif /* GL_SGIX_cube_map */ + +/* ------------------------ GL_SGIX_cylinder_texgen ------------------------ */ + +#ifndef GL_SGIX_cylinder_texgen +#define GL_SGIX_cylinder_texgen 1 + +#define GLEW_SGIX_cylinder_texgen GLEW_GET_VAR(__GLEW_SGIX_cylinder_texgen) + +#endif /* GL_SGIX_cylinder_texgen */ + +/* ---------------------------- GL_SGIX_datapipe --------------------------- */ + +#ifndef GL_SGIX_datapipe +#define GL_SGIX_datapipe 1 + +#define GL_GEOMETRY_BIT 0x1 +#define GL_IMAGE_BIT 0x2 + +typedef void (GLAPIENTRY * PFNGLADDRESSSPACEPROC) (GLenum space, GLbitfield mask); +typedef GLint (GLAPIENTRY * PFNGLDATAPIPEPROC) (GLenum space); + +#define glAddressSpace GLEW_GET_FUN(__glewAddressSpace) +#define glDataPipe GLEW_GET_FUN(__glewDataPipe) + +#define GLEW_SGIX_datapipe GLEW_GET_VAR(__GLEW_SGIX_datapipe) + +#endif /* GL_SGIX_datapipe */ + +/* --------------------------- GL_SGIX_decimation -------------------------- */ + +#ifndef GL_SGIX_decimation +#define GL_SGIX_decimation 1 + +#define GLEW_SGIX_decimation GLEW_GET_VAR(__GLEW_SGIX_decimation) + +#endif /* GL_SGIX_decimation */ + +/* --------------------- GL_SGIX_depth_pass_instrument --------------------- */ + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 + +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 + +#define GLEW_SGIX_depth_pass_instrument GLEW_GET_VAR(__GLEW_SGIX_depth_pass_instrument) + +#endif /* GL_SGIX_depth_pass_instrument */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#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 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* ------------------------------ GL_SGIX_dvc ------------------------------ */ + +#ifndef GL_SGIX_dvc +#define GL_SGIX_dvc 1 + +#define GLEW_SGIX_dvc GLEW_GET_VAR(__GLEW_SGIX_dvc) + +#endif /* GL_SGIX_dvc */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_blend --------------------------- */ + +#ifndef GL_SGIX_fog_blend +#define GL_SGIX_fog_blend 1 + +#define GL_FOG_BLEND_ALPHA_SGIX 0x81FE +#define GL_FOG_BLEND_COLOR_SGIX 0x81FF + +#define GLEW_SGIX_fog_blend GLEW_GET_VAR(__GLEW_SGIX_fog_blend) + +#endif /* GL_SGIX_fog_blend */ + +/* ---------------------- GL_SGIX_fog_factor_to_alpha ---------------------- */ + +#ifndef GL_SGIX_fog_factor_to_alpha +#define GL_SGIX_fog_factor_to_alpha 1 + +#define GLEW_SGIX_fog_factor_to_alpha GLEW_GET_VAR(__GLEW_SGIX_fog_factor_to_alpha) + +#endif /* GL_SGIX_fog_factor_to_alpha */ + +/* --------------------------- GL_SGIX_fog_layers -------------------------- */ + +#ifndef GL_SGIX_fog_layers +#define GL_SGIX_fog_layers 1 + +#define GL_FOG_TYPE_SGIX 0x8323 +#define GL_UNIFORM_SGIX 0x8324 +#define GL_LAYERED_SGIX 0x8325 +#define GL_FOG_GROUND_PLANE_SGIX 0x8326 +#define GL_FOG_LAYERS_POINTS_SGIX 0x8327 +#define GL_MAX_FOG_LAYERS_POINTS_SGIX 0x8328 + +typedef void (GLAPIENTRY * PFNGLFOGLAYERSSGIXPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGLAYERSSGIXPROC) (GLfloat* points); + +#define glFogLayersSGIX GLEW_GET_FUN(__glewFogLayersSGIX) +#define glGetFogLayersSGIX GLEW_GET_FUN(__glewGetFogLayersSGIX) + +#define GLEW_SGIX_fog_layers GLEW_GET_VAR(__GLEW_SGIX_fog_layers) + +#endif /* GL_SGIX_fog_layers */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* --------------------------- GL_SGIX_fog_patchy -------------------------- */ + +#ifndef GL_SGIX_fog_patchy +#define GL_SGIX_fog_patchy 1 + +#define GLEW_SGIX_fog_patchy GLEW_GET_VAR(__GLEW_SGIX_fog_patchy) + +#endif /* GL_SGIX_fog_patchy */ + +/* --------------------------- GL_SGIX_fog_scale --------------------------- */ + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 + +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD + +#define GLEW_SGIX_fog_scale GLEW_GET_VAR(__GLEW_SGIX_fog_scale) + +#endif /* GL_SGIX_fog_scale */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +/* -------------------- GL_SGIX_fragment_lighting_space -------------------- */ + +#ifndef GL_SGIX_fragment_lighting_space +#define GL_SGIX_fragment_lighting_space 1 + +#define GL_EYE_SPACE_SGIX 0x8436 +#define GL_TANGENT_SPACE_SGIX 0x8437 +#define GL_OBJECT_SPACE_SGIX 0x8438 +#define GL_FRAGMENT_LIGHT_SPACE_SGIX 0x843D + +#define GLEW_SGIX_fragment_lighting_space GLEW_GET_VAR(__GLEW_SGIX_fragment_lighting_space) + +#endif /* GL_SGIX_fragment_lighting_space */ + +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* ---------------------- GL_SGIX_fragments_instrument --------------------- */ + +#ifndef GL_SGIX_fragments_instrument +#define GL_SGIX_fragments_instrument 1 + +#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313 +#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314 +#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315 + +#define GLEW_SGIX_fragments_instrument GLEW_GET_VAR(__GLEW_SGIX_fragments_instrument) + +#endif /* GL_SGIX_fragments_instrument */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* -------------------------- GL_SGIX_icc_texture -------------------------- */ + +#ifndef GL_SGIX_icc_texture +#define GL_SGIX_icc_texture 1 + +#define GL_RGB_ICC_SGIX 0x8460 +#define GL_RGBA_ICC_SGIX 0x8461 +#define GL_ALPHA_ICC_SGIX 0x8462 +#define GL_LUMINANCE_ICC_SGIX 0x8463 +#define GL_INTENSITY_ICC_SGIX 0x8464 +#define GL_LUMINANCE_ALPHA_ICC_SGIX 0x8465 +#define GL_R5_G6_B5_ICC_SGIX 0x8466 +#define GL_R5_G6_B5_A8_ICC_SGIX 0x8467 +#define GL_ALPHA16_ICC_SGIX 0x8468 +#define GL_LUMINANCE16_ICC_SGIX 0x8469 +#define GL_INTENSITY16_ICC_SGIX 0x846A +#define GL_LUMINANCE16_ALPHA8_ICC_SGIX 0x846B + +#define GLEW_SGIX_icc_texture GLEW_GET_VAR(__GLEW_SGIX_icc_texture) + +#endif /* GL_SGIX_icc_texture */ + +/* ------------------------ GL_SGIX_igloo_interface ------------------------ */ + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 + +#define GL_IGLOO_FULLSCREEN_SGIX 0x819E +#define GL_IGLOO_VIEWPORT_OFFSET_SGIX 0x819F +#define GL_IGLOO_SWAPTMESH_SGIX 0x81A0 +#define GL_IGLOO_COLORNORMAL_SGIX 0x81A1 +#define GL_IGLOO_IRISGL_MODE_SGIX 0x81A2 +#define GL_IGLOO_LMC_COLOR_SGIX 0x81A3 +#define GL_IGLOO_TMESHMODE_SGIX 0x81A4 +#define GL_LIGHT31 0xBEAD + +typedef void (GLAPIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, void *param); + +#define glIglooInterfaceSGIX GLEW_GET_FUN(__glewIglooInterfaceSGIX) + +#define GLEW_SGIX_igloo_interface GLEW_GET_VAR(__GLEW_SGIX_igloo_interface) + +#endif /* GL_SGIX_igloo_interface */ + +/* ----------------------- GL_SGIX_image_compression ----------------------- */ + +#ifndef GL_SGIX_image_compression +#define GL_SGIX_image_compression 1 + +#define GLEW_SGIX_image_compression GLEW_GET_VAR(__GLEW_SGIX_image_compression) + +#endif /* GL_SGIX_image_compression */ + +/* ---------------------- GL_SGIX_impact_pixel_texture --------------------- */ + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_SGIX_impact_pixel_texture 1 + +#define GLEW_SGIX_impact_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_impact_pixel_texture) + +#endif /* GL_SGIX_impact_pixel_texture */ + +/* ------------------------ GL_SGIX_instrument_error ----------------------- */ + +#ifndef GL_SGIX_instrument_error +#define GL_SGIX_instrument_error 1 + +#define GLEW_SGIX_instrument_error GLEW_GET_VAR(__GLEW_SGIX_instrument_error) + +#endif /* GL_SGIX_instrument_error */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ----------------------- GL_SGIX_line_quality_hint ----------------------- */ + +#ifndef GL_SGIX_line_quality_hint +#define GL_SGIX_line_quality_hint 1 + +#define GL_LINE_QUALITY_HINT_SGIX 0x835B + +#define GLEW_SGIX_line_quality_hint GLEW_GET_VAR(__GLEW_SGIX_line_quality_hint) + +#endif /* GL_SGIX_line_quality_hint */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ----------------------------- GL_SGIX_mpeg1 ----------------------------- */ + +#ifndef GL_SGIX_mpeg1 +#define GL_SGIX_mpeg1 1 + +typedef void (GLAPIENTRY * PFNGLALLOCMPEGPREDICTORSSGIXPROC) (GLsizei width, GLsizei height, GLsizei n, GLuint* predictors); +typedef void (GLAPIENTRY * PFNGLDELETEMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors); +typedef void (GLAPIENTRY * PFNGLGENMPEGPREDICTORSSGIXPROC) (GLsizei n, GLuint* predictors); +typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERFVSGIXPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMPEGPARAMETERIVSGIXPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels); +typedef void (GLAPIENTRY * PFNGLGETMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values); +typedef GLboolean (GLAPIENTRY * PFNGLISMPEGPREDICTORSGIXPROC) (GLuint predictor); +typedef void (GLAPIENTRY * PFNGLMPEGPREDICTORSGIXPROC) (GLenum target, GLenum format, GLenum type, void *pixels); +typedef void (GLAPIENTRY * PFNGLMPEGQUANTTABLEUBVPROC) (GLenum target, GLubyte* values); +typedef void (GLAPIENTRY * PFNGLSWAPMPEGPREDICTORSSGIXPROC) (GLenum target0, GLenum target1); + +#define glAllocMPEGPredictorsSGIX GLEW_GET_FUN(__glewAllocMPEGPredictorsSGIX) +#define glDeleteMPEGPredictorsSGIX GLEW_GET_FUN(__glewDeleteMPEGPredictorsSGIX) +#define glGenMPEGPredictorsSGIX GLEW_GET_FUN(__glewGenMPEGPredictorsSGIX) +#define glGetMPEGParameterfvSGIX GLEW_GET_FUN(__glewGetMPEGParameterfvSGIX) +#define glGetMPEGParameterivSGIX GLEW_GET_FUN(__glewGetMPEGParameterivSGIX) +#define glGetMPEGPredictorSGIX GLEW_GET_FUN(__glewGetMPEGPredictorSGIX) +#define glGetMPEGQuantTableubv GLEW_GET_FUN(__glewGetMPEGQuantTableubv) +#define glIsMPEGPredictorSGIX GLEW_GET_FUN(__glewIsMPEGPredictorSGIX) +#define glMPEGPredictorSGIX GLEW_GET_FUN(__glewMPEGPredictorSGIX) +#define glMPEGQuantTableubv GLEW_GET_FUN(__glewMPEGQuantTableubv) +#define glSwapMPEGPredictorsSGIX GLEW_GET_FUN(__glewSwapMPEGPredictorsSGIX) + +#define GLEW_SGIX_mpeg1 GLEW_GET_VAR(__GLEW_SGIX_mpeg1) + +#endif /* GL_SGIX_mpeg1 */ + +/* ----------------------------- GL_SGIX_mpeg2 ----------------------------- */ + +#ifndef GL_SGIX_mpeg2 +#define GL_SGIX_mpeg2 1 + +#define GLEW_SGIX_mpeg2 GLEW_GET_VAR(__GLEW_SGIX_mpeg2) + +#endif /* GL_SGIX_mpeg2 */ + +/* ------------------ GL_SGIX_nonlinear_lighting_pervertex ----------------- */ + +#ifndef GL_SGIX_nonlinear_lighting_pervertex +#define GL_SGIX_nonlinear_lighting_pervertex 1 + +typedef void (GLAPIENTRY * PFNGLGETNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint* terms, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint* terms, const GLfloat *data); +typedef void (GLAPIENTRY * PFNGLNONLINLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLint terms, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLNONLINMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLint terms, const GLfloat* params); + +#define glGetNonlinLightfvSGIX GLEW_GET_FUN(__glewGetNonlinLightfvSGIX) +#define glGetNonlinMaterialfvSGIX GLEW_GET_FUN(__glewGetNonlinMaterialfvSGIX) +#define glNonlinLightfvSGIX GLEW_GET_FUN(__glewNonlinLightfvSGIX) +#define glNonlinMaterialfvSGIX GLEW_GET_FUN(__glewNonlinMaterialfvSGIX) + +#define GLEW_SGIX_nonlinear_lighting_pervertex GLEW_GET_VAR(__GLEW_SGIX_nonlinear_lighting_pervertex) + +#endif /* GL_SGIX_nonlinear_lighting_pervertex */ + +/* --------------------------- GL_SGIX_nurbs_eval -------------------------- */ + +#ifndef GL_SGIX_nurbs_eval +#define GL_SGIX_nurbs_eval 1 + +#define GL_MAP1_VERTEX_3_NURBS_SGIX 0x81CB +#define GL_MAP1_VERTEX_4_NURBS_SGIX 0x81CC +#define GL_MAP1_INDEX_NURBS_SGIX 0x81CD +#define GL_MAP1_COLOR_4_NURBS_SGIX 0x81CE +#define GL_MAP1_NORMAL_NURBS_SGIX 0x81CF +#define GL_MAP1_TEXTURE_COORD_1_NURBS_SGIX 0x81E0 +#define GL_MAP1_TEXTURE_COORD_2_NURBS_SGIX 0x81E1 +#define GL_MAP1_TEXTURE_COORD_3_NURBS_SGIX 0x81E2 +#define GL_MAP1_TEXTURE_COORD_4_NURBS_SGIX 0x81E3 +#define GL_MAP2_VERTEX_3_NURBS_SGIX 0x81E4 +#define GL_MAP2_VERTEX_4_NURBS_SGIX 0x81E5 +#define GL_MAP2_INDEX_NURBS_SGIX 0x81E6 +#define GL_MAP2_COLOR_4_NURBS_SGIX 0x81E7 +#define GL_MAP2_NORMAL_NURBS_SGIX 0x81E8 +#define GL_MAP2_TEXTURE_COORD_1_NURBS_SGIX 0x81E9 +#define GL_MAP2_TEXTURE_COORD_2_NURBS_SGIX 0x81EA +#define GL_MAP2_TEXTURE_COORD_3_NURBS_SGIX 0x81EB +#define GL_MAP2_TEXTURE_COORD_4_NURBS_SGIX 0x81EC +#define GL_NURBS_KNOT_COUNT_SGIX 0x81ED +#define GL_NURBS_KNOT_VECTOR_SGIX 0x81EE + +#define GLEW_SGIX_nurbs_eval GLEW_GET_VAR(__GLEW_SGIX_nurbs_eval) + +#endif /* GL_SGIX_nurbs_eval */ + +/* ---------------------- GL_SGIX_occlusion_instrument --------------------- */ + +#ifndef GL_SGIX_occlusion_instrument +#define GL_SGIX_occlusion_instrument 1 + +#define GL_OCCLUSION_INSTRUMENT_SGIX 0x6060 + +#define GLEW_SGIX_occlusion_instrument GLEW_GET_VAR(__GLEW_SGIX_occlusion_instrument) + +#endif /* GL_SGIX_occlusion_instrument */ + +/* ------------------------- GL_SGIX_packed_6bytes ------------------------- */ + +#ifndef GL_SGIX_packed_6bytes +#define GL_SGIX_packed_6bytes 1 + +#define GLEW_SGIX_packed_6bytes GLEW_GET_VAR(__GLEW_SGIX_packed_6bytes) + +#endif /* GL_SGIX_packed_6bytes */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ----------------------- GL_SGIX_pixel_texture_lod ----------------------- */ + +#ifndef GL_SGIX_pixel_texture_lod +#define GL_SGIX_pixel_texture_lod 1 + +#define GLEW_SGIX_pixel_texture_lod GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_lod) + +#endif /* GL_SGIX_pixel_texture_lod */ + +/* -------------------------- GL_SGIX_pixel_tiles -------------------------- */ + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 + +#define GLEW_SGIX_pixel_tiles GLEW_GET_VAR(__GLEW_SGIX_pixel_tiles) + +#endif /* GL_SGIX_pixel_tiles */ + +/* ------------------------- GL_SGIX_polynomial_ffd ------------------------ */ + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 + +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x1 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x2 + +typedef void (GLAPIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); + +#define glDeformSGIX GLEW_GET_FUN(__glewDeformSGIX) +#define glLoadIdentityDeformationMapSGIX GLEW_GET_FUN(__glewLoadIdentityDeformationMapSGIX) + +#define GLEW_SGIX_polynomial_ffd GLEW_GET_VAR(__GLEW_SGIX_polynomial_ffd) + +#endif /* GL_SGIX_polynomial_ffd */ + +/* --------------------------- GL_SGIX_quad_mesh --------------------------- */ + +#ifndef GL_SGIX_quad_mesh +#define GL_SGIX_quad_mesh 1 + +typedef void (GLAPIENTRY * PFNGLMESHBREADTHSGIXPROC) (GLint breadth); +typedef void (GLAPIENTRY * PFNGLMESHSTRIDESGIXPROC) (GLint stride); + +#define glMeshBreadthSGIX GLEW_GET_FUN(__glewMeshBreadthSGIX) +#define glMeshStrideSGIX GLEW_GET_FUN(__glewMeshStrideSGIX) + +#define GLEW_SGIX_quad_mesh GLEW_GET_VAR(__GLEW_SGIX_quad_mesh) + +#endif /* GL_SGIX_quad_mesh */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ------------------------- GL_SGIX_scalebias_hint ------------------------ */ + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 + +#define GL_SCALEBIAS_HINT_SGIX 0x8322 + +#define GLEW_SGIX_scalebias_hint GLEW_GET_VAR(__GLEW_SGIX_scalebias_hint) + +#endif /* GL_SGIX_scalebias_hint */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#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 + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ------------------------------ GL_SGIX_slim ----------------------------- */ + +#ifndef GL_SGIX_slim +#define GL_SGIX_slim 1 + +#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B +#define GL_SLIM8U_SGIX 0x831D +#define GL_SLIM10U_SGIX 0x831E +#define GL_SLIM12S_SGIX 0x831F + +#define GLEW_SGIX_slim GLEW_GET_VAR(__GLEW_SGIX_slim) + +#endif /* GL_SGIX_slim */ + +/* ------------------------ GL_SGIX_spotlight_cutoff ----------------------- */ + +#ifndef GL_SGIX_spotlight_cutoff +#define GL_SGIX_spotlight_cutoff 1 + +#define GL_SPOT_CUTOFF_DELTA_SGIX 0x8193 + +#define GLEW_SGIX_spotlight_cutoff GLEW_GET_VAR(__GLEW_SGIX_spotlight_cutoff) + +#endif /* GL_SGIX_spotlight_cutoff */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* -------------------------- GL_SGIX_subdiv_patch ------------------------- */ + +#ifndef GL_SGIX_subdiv_patch +#define GL_SGIX_subdiv_patch 1 + +#define GLEW_SGIX_subdiv_patch GLEW_GET_VAR(__GLEW_SGIX_subdiv_patch) + +#endif /* GL_SGIX_subdiv_patch */ + +/* --------------------------- GL_SGIX_subsample --------------------------- */ + +#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 + +#define GLEW_SGIX_subsample GLEW_GET_VAR(__GLEW_SGIX_subsample) + +#endif /* GL_SGIX_subsample */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#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 + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ------------------- GL_SGIX_texture_mipmap_anisotropic ------------------ */ + +#ifndef GL_SGIX_texture_mipmap_anisotropic +#define GL_SGIX_texture_mipmap_anisotropic 1 + +#define GL_TEXTURE_MIPMAP_ANISOTROPY_SGIX 0x832E +#define GL_MAX_MIPMAP_ANISOTROPY_SGIX 0x832F + +#define GLEW_SGIX_texture_mipmap_anisotropic GLEW_GET_VAR(__GLEW_SGIX_texture_mipmap_anisotropic) + +#endif /* GL_SGIX_texture_mipmap_anisotropic */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_phase ------------------------- */ + +#ifndef GL_SGIX_texture_phase +#define GL_SGIX_texture_phase 1 + +#define GL_PHASE_SGIX 0x832A + +#define GLEW_SGIX_texture_phase GLEW_GET_VAR(__GLEW_SGIX_texture_phase) + +#endif /* GL_SGIX_texture_phase */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#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 + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ---------------------- GL_SGIX_texture_supersample ---------------------- */ + +#ifndef GL_SGIX_texture_supersample +#define GL_SGIX_texture_supersample 1 + +#define GLEW_SGIX_texture_supersample GLEW_GET_VAR(__GLEW_SGIX_texture_supersample) + +#endif /* GL_SGIX_texture_supersample */ + +/* --------------------------- GL_SGIX_vector_ops -------------------------- */ + +#ifndef GL_SGIX_vector_ops +#define GL_SGIX_vector_ops 1 + +typedef void (GLAPIENTRY * PFNGLGETVECTOROPERATIONSGIXPROC) (GLenum operation); +typedef void (GLAPIENTRY * PFNGLVECTOROPERATIONSGIXPROC) (GLenum operation); + +#define glGetVectorOperationSGIX GLEW_GET_FUN(__glewGetVectorOperationSGIX) +#define glVectorOperationSGIX GLEW_GET_FUN(__glewVectorOperationSGIX) + +#define GLEW_SGIX_vector_ops GLEW_GET_VAR(__GLEW_SGIX_vector_ops) + +#endif /* GL_SGIX_vector_ops */ + +/* ---------------------- GL_SGIX_vertex_array_object ---------------------- */ + +#ifndef GL_SGIX_vertex_array_object +#define GL_SGIX_vertex_array_object 1 + +typedef GLboolean (GLAPIENTRY * PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC) (GLsizei n, const GLuint* arrays, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYSGIXPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSSGIXPROC) (GLsizei n, GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYSGIXPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC) (GLsizei n, const GLuint* arrays, const GLclampf* priorities); + +#define glAreVertexArraysResidentSGIX GLEW_GET_FUN(__glewAreVertexArraysResidentSGIX) +#define glBindVertexArraySGIX GLEW_GET_FUN(__glewBindVertexArraySGIX) +#define glDeleteVertexArraysSGIX GLEW_GET_FUN(__glewDeleteVertexArraysSGIX) +#define glGenVertexArraysSGIX GLEW_GET_FUN(__glewGenVertexArraysSGIX) +#define glIsVertexArraySGIX GLEW_GET_FUN(__glewIsVertexArraySGIX) +#define glPrioritizeVertexArraysSGIX GLEW_GET_FUN(__glewPrioritizeVertexArraysSGIX) + +#define GLEW_SGIX_vertex_array_object GLEW_GET_VAR(__GLEW_SGIX_vertex_array_object) + +#endif /* GL_SGIX_vertex_array_object */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* ------------------------ GL_SGIX_ycrcb_subsample ------------------------ */ + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 + +#define GLEW_SGIX_ycrcb_subsample GLEW_GET_VAR(__GLEW_SGIX_ycrcb_subsample) + +#endif /* GL_SGIX_ycrcb_subsample */ + +/* ----------------------------- GL_SGIX_ycrcba ---------------------------- */ + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 + +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 + +#define GLEW_SGIX_ycrcba GLEW_GET_VAR(__GLEW_SGIX_ycrcba) + +#endif /* GL_SGIX_ycrcba */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#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 + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#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 (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------------- GL_SGI_complex ---------------------------- */ + +#ifndef GL_SGI_complex +#define GL_SGI_complex 1 + +#define GLEW_SGI_complex GLEW_GET_VAR(__GLEW_SGI_complex) + +#endif /* GL_SGI_complex */ + +/* -------------------------- GL_SGI_complex_type -------------------------- */ + +#ifndef GL_SGI_complex_type +#define GL_SGI_complex_type 1 + +#define GL_COMPLEX_UNSIGNED_BYTE_SGI 0x81BD +#define GL_COMPLEX_BYTE_SGI 0x81BE +#define GL_COMPLEX_UNSIGNED_SHORT_SGI 0x81BF +#define GL_COMPLEX_SHORT_SGI 0x81C0 +#define GL_COMPLEX_UNSIGNED_INT_SGI 0x81C1 +#define GL_COMPLEX_INT_SGI 0x81C2 +#define GL_COMPLEX_FLOAT_SGI 0x81C3 + +#define GLEW_SGI_complex_type GLEW_GET_VAR(__GLEW_SGI_complex_type) + +#endif /* GL_SGI_complex_type */ + +/* ------------------------------- GL_SGI_fft ------------------------------ */ + +#ifndef GL_SGI_fft +#define GL_SGI_fft 1 + +#define GL_PIXEL_TRANSFORM_OPERATOR_SGI 0x81C4 +#define GL_CONVOLUTION_SGI 0x81C5 +#define GL_FFT_1D_SGI 0x81C6 +#define GL_PIXEL_TRANSFORM_SGI 0x81C7 +#define GL_MAX_FFT_WIDTH_SGI 0x81C8 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFSGIPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERISGIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMSGIPROC) (GLenum target); + +#define glGetPixelTransformParameterfvSGI GLEW_GET_FUN(__glewGetPixelTransformParameterfvSGI) +#define glGetPixelTransformParameterivSGI GLEW_GET_FUN(__glewGetPixelTransformParameterivSGI) +#define glPixelTransformParameterfSGI GLEW_GET_FUN(__glewPixelTransformParameterfSGI) +#define glPixelTransformParameterfvSGI GLEW_GET_FUN(__glewPixelTransformParameterfvSGI) +#define glPixelTransformParameteriSGI GLEW_GET_FUN(__glewPixelTransformParameteriSGI) +#define glPixelTransformParameterivSGI GLEW_GET_FUN(__glewPixelTransformParameterivSGI) +#define glPixelTransformSGI GLEW_GET_FUN(__glewPixelTransformSGI) + +#define GLEW_SGI_fft GLEW_GET_VAR(__GLEW_SGI_fft) + +#endif /* GL_SGI_fft */ + +/* ----------------------- GL_SGI_texture_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 + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#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 (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#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 (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#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 (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * 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 (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* ------------------------- GL_WIN_scene_markerXXX ------------------------ */ + +#ifndef GL_WIN_scene_markerXXX +#define GL_WIN_scene_markerXXX 1 + +#define GLEW_WIN_scene_markerXXX GLEW_GET_VAR(__GLEW_WIN_scene_markerXXX) + +#endif /* GL_WIN_scene_markerXXX */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + + + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback; +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation; +GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv; +GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski; +GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei; +GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback; +GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation; +GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv; +GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex; +GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v; +GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci; +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading; + +GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSPROC __glewGetGraphicsResetStatus; +GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEPROC __glewGetnCompressedTexImage; +GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEPROC __glewGetnTexImage; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVPROC __glewGetnUniformdv; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC __glewMultiDrawArraysIndirectCount; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC __glewMultiDrawElementsIndirectCount; +GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERPROC __glewSpecializeShader; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewFramebufferSamplePositionsfvAMD; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC __glewGetFramebufferParameterfvAMD; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC __glewGetNamedFramebufferParameterfvAMD; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewNamedFramebufferSamplePositionsfvAMD; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD; + +GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD; +GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD; +GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD; + +GLEW_FUN_EXPORT PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD; + +GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD; +GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD; +GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD; +GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD; + +GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD; + +GLEW_FUN_EXPORT PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD; + +GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD; +GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE; +GLEW_FUN_EXPORT PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE; +GLEW_FUN_EXPORT PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE; +GLEW_FUN_EXPORT PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE; +GLEW_FUN_EXPORT PFNGLISQUERYANGLEPROC __glewIsQueryANGLE; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE; + +GLEW_FUN_EXPORT PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE; + +GLEW_FUN_EXPORT PFNGLCOPYTEXTURELEVELSAPPLEPROC __glewCopyTextureLevelsAPPLE; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC __glewRenderbufferStorageMultisampleAPPLE; +GLEW_FUN_EXPORT PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC __glewResolveMultisampleFramebufferAPPLE; + +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE; +GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE; + +GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCAPPLEPROC __glewClientWaitSyncAPPLE; +GLEW_FUN_EXPORT PFNGLDELETESYNCAPPLEPROC __glewDeleteSyncAPPLE; +GLEW_FUN_EXPORT PFNGLFENCESYNCAPPLEPROC __glewFenceSyncAPPLE; +GLEW_FUN_EXPORT PFNGLGETINTEGER64VAPPLEPROC __glewGetInteger64vAPPLE; +GLEW_FUN_EXPORT PFNGLGETSYNCIVAPPLEPROC __glewGetSyncivAPPLE; +GLEW_FUN_EXPORT PFNGLISSYNCAPPLEPROC __glewIsSyncAPPLE; +GLEW_FUN_EXPORT PFNGLWAITSYNCAPPLEPROC __glewWaitSyncAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE; +GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef; +GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat; +GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler; +GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary; + +GLEW_FUN_EXPORT PFNGLMEMORYBARRIERBYREGIONPROC __glewMemoryBarrierByRegion; + +GLEW_FUN_EXPORT PFNGLPRIMITIVEBOUNDINGBOXARBPROC __glewPrimitiveBoundingBoxARB; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance; + +GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB; +GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB; +GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB; +GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB; +GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed; +GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex; + +GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEPROC __glewBufferStorage; + +GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB; + +GLEW_FUN_EXPORT PFNGLCLEARBUFFERDATAPROC __glewClearBufferData; +GLEW_FUN_EXPORT PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT; + +GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEPROC __glewClearTexImage; +GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage; + +GLEW_FUN_EXPORT PFNGLCLIPCONTROLPROC __glewClipControl; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute; +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect; + +GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB; + +GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB; + +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPROC __glewBindTextureUnit; +GLEW_FUN_EXPORT PFNGLBLITNAMEDFRAMEBUFFERPROC __glewBlitNamedFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC __glewCheckNamedFramebufferStatus; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAPROC __glewClearNamedBufferData; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAPROC __glewClearNamedBufferSubData; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFIPROC __glewClearNamedFramebufferfi; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERFVPROC __glewClearNamedFramebufferfv; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERIVPROC __glewClearNamedFramebufferiv; +GLEW_FUN_EXPORT PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC __glewClearNamedFramebufferuiv; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC __glewCompressedTextureSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC __glewCompressedTextureSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC __glewCompressedTextureSubImage3D; +GLEW_FUN_EXPORT PFNGLCOPYNAMEDBUFFERSUBDATAPROC __glewCopyNamedBufferSubData; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DPROC __glewCopyTextureSubImage1D; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DPROC __glewCopyTextureSubImage2D; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DPROC __glewCopyTextureSubImage3D; +GLEW_FUN_EXPORT PFNGLCREATEBUFFERSPROC __glewCreateBuffers; +GLEW_FUN_EXPORT PFNGLCREATEFRAMEBUFFERSPROC __glewCreateFramebuffers; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPIPELINESPROC __glewCreateProgramPipelines; +GLEW_FUN_EXPORT PFNGLCREATEQUERIESPROC __glewCreateQueries; +GLEW_FUN_EXPORT PFNGLCREATERENDERBUFFERSPROC __glewCreateRenderbuffers; +GLEW_FUN_EXPORT PFNGLCREATESAMPLERSPROC __glewCreateSamplers; +GLEW_FUN_EXPORT PFNGLCREATETEXTURESPROC __glewCreateTextures; +GLEW_FUN_EXPORT PFNGLCREATETRANSFORMFEEDBACKSPROC __glewCreateTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLCREATEVERTEXARRAYSPROC __glewCreateVertexArrays; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBPROC __glewDisableVertexArrayAttrib; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBPROC __glewEnableVertexArrayAttrib; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC __glewFlushMappedNamedBufferRange; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPPROC __glewGenerateTextureMipmap; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC __glewGetCompressedTextureImage; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERI64VPROC __glewGetNamedBufferParameteri64v; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVPROC __glewGetNamedBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVPROC __glewGetNamedBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAPROC __glewGetNamedBufferSubData; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetNamedFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC __glewGetNamedFramebufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC __glewGetNamedRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTI64VPROC __glewGetQueryBufferObjecti64v; +GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTIVPROC __glewGetQueryBufferObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUI64VPROC __glewGetQueryBufferObjectui64v; +GLEW_FUN_EXPORT PFNGLGETQUERYBUFFEROBJECTUIVPROC __glewGetQueryBufferObjectuiv; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEPROC __glewGetTextureImage; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVPROC __glewGetTextureLevelParameterfv; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVPROC __glewGetTextureLevelParameteriv; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVPROC __glewGetTextureParameterIiv; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVPROC __glewGetTextureParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVPROC __glewGetTextureParameterfv; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVPROC __glewGetTextureParameteriv; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI64_VPROC __glewGetTransformFeedbacki64_v; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKI_VPROC __glewGetTransformFeedbacki_v; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKIVPROC __glewGetTransformFeedbackiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXED64IVPROC __glewGetVertexArrayIndexed64iv; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINDEXEDIVPROC __glewGetVertexArrayIndexediv; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYIVPROC __glewGetVertexArrayiv; +GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC __glewInvalidateNamedFramebufferData; +GLEW_FUN_EXPORT PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC __glewInvalidateNamedFramebufferSubData; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERPROC __glewMapNamedBuffer; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEPROC __glewMapNamedBufferRange; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAPROC __glewNamedBufferData; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEPROC __glewNamedBufferStorage; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAPROC __glewNamedBufferSubData; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC __glewNamedFramebufferDrawBuffer; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC __glewNamedFramebufferDrawBuffers; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC __glewNamedFramebufferParameteri; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC __glewNamedFramebufferReadBuffer; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC __glewNamedFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREPROC __glewNamedFramebufferTexture; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC __glewNamedFramebufferTextureLayer; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEPROC __glewNamedRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewNamedRenderbufferStorageMultisample; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERPROC __glewTextureBuffer; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEPROC __glewTextureBufferRange; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVPROC __glewTextureParameterIiv; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVPROC __glewTextureParameterIuiv; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFPROC __glewTextureParameterf; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVPROC __glewTextureParameterfv; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIPROC __glewTextureParameteri; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVPROC __glewTextureParameteriv; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DPROC __glewTextureStorage1D; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DPROC __glewTextureStorage2D; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC __glewTextureStorage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DPROC __glewTextureStorage3D; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC __glewTextureStorage3DMultisample; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DPROC __glewTextureSubImage1D; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DPROC __glewTextureSubImage2D; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DPROC __glewTextureSubImage3D; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC __glewTransformFeedbackBufferBase; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC __glewTransformFeedbackBufferRange; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFERPROC __glewUnmapNamedBuffer; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBBINDINGPROC __glewVertexArrayAttribBinding; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBFORMATPROC __glewVertexArrayAttribFormat; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBIFORMATPROC __glewVertexArrayAttribIFormat; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYATTRIBLFORMATPROC __glewVertexArrayAttribLFormat; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDINGDIVISORPROC __glewVertexArrayBindingDivisor; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYELEMENTBUFFERPROC __glewVertexArrayElementBuffer; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERPROC __glewVertexArrayVertexBuffer; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBUFFERSPROC __glewVertexArrayVertexBuffers; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer; +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri; + +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage; +GLEW_FUN_EXPORT PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage; + +GLEW_FUN_EXPORT PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv; +GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d; +GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv; +GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d; +GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv; +GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d; +GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv; +GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d; +GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VARBPROC __glewGetUniformi64vARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VARBPROC __glewGetUniformui64vARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMI64VARBPROC __glewGetnUniformi64vARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMUI64VARBPROC __glewGetnUniformui64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64ARBPROC __glewProgramUniform1i64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VARBPROC __glewProgramUniform1i64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64ARBPROC __glewProgramUniform1ui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VARBPROC __glewProgramUniform1ui64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64ARBPROC __glewProgramUniform2i64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VARBPROC __glewProgramUniform2i64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64ARBPROC __glewProgramUniform2ui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VARBPROC __glewProgramUniform2ui64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64ARBPROC __glewProgramUniform3i64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VARBPROC __glewProgramUniform3i64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64ARBPROC __glewProgramUniform3ui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VARBPROC __glewProgramUniform3ui64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64ARBPROC __glewProgramUniform4i64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VARBPROC __glewProgramUniform4i64vARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64ARBPROC __glewProgramUniform4ui64ARB; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VARBPROC __glewProgramUniform4ui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64ARBPROC __glewUniform1i64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64VARBPROC __glewUniform1i64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64ARBPROC __glewUniform1ui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VARBPROC __glewUniform1ui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64ARBPROC __glewUniform2i64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64VARBPROC __glewUniform2i64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64ARBPROC __glewUniform2ui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VARBPROC __glewUniform2ui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64ARBPROC __glewUniform3i64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64VARBPROC __glewUniform3i64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64ARBPROC __glewUniform3ui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VARBPROC __glewUniform3ui64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64ARBPROC __glewUniform4i64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64VARBPROC __glewUniform4i64vARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64ARBPROC __glewUniform4ui64ARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VARBPROC __glewUniform4ui64vARB; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB; + +GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ; + +GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v; + +GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData; +GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData; +GLEW_FUN_EXPORT PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer; +GLEW_FUN_EXPORT PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer; +GLEW_FUN_EXPORT PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage; +GLEW_FUN_EXPORT PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange; +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures; +GLEW_FUN_EXPORT PFNGLBINDSAMPLERSPROC __glewBindSamplers; +GLEW_FUN_EXPORT PFNGLBINDTEXTURESPROC __glewBindTextures; +GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSARBPROC __glewMaxShaderCompilerThreadsARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPPROC __glewPolygonOffsetClamp; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex; + +GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB; +GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB; +GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB; +GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB; +GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB; +GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB; +GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB; +GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB; +GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB; +GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB; +GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewFramebufferSampleLocationsfvARB; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewNamedFramebufferSampleLocationsfvARB; + +GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB; + +GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler; +GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers; +GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv; +GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri; +GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv; + +GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines; +GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline; + +GLEW_FUN_EXPORT PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIERPROC __glewMemoryBarrier; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding; + +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex; +GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv; +GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv; + +GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB; +GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB; +GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB; +GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB; +GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB; + +GLEW_FUN_EXPORT PFNGLBUFFERPAGECOMMITMENTARBPROC __glewBufferPageCommitmentARB; + +GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB; + +GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync; +GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync; +GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync; +GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v; +GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv; +GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync; +GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync; + +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv; +GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri; + +GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERPROC __glewTextureBarrier; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB; + +GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski; +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DPROC __glewTexStorage1D; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DPROC __glewTexStorage2D; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DPROC __glewTexStorage3D; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLTEXTUREVIEWPROC __glewTextureView; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v; +GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream; +GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed; +GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv; + +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v; +GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex; +GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices; +GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat; +GLEW_FUN_EXPORT PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui; +GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv; +GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui; +GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui; +GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui; +GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui; +GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui; +GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui; +GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv; + +GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v; +GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv; +GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __glewDrawArraysInstancedBaseInstanceEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseInstanceEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseVertexBaseInstanceEXT; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT; +GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __glewBindFragDataLocationIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXEXTPROC __glewGetFragDataIndexEXT; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __glewGetProgramResourceLocationIndexEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTPROC __glewBufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEEXTPROC __glewClearTexImageEXT; +GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEEXTPROC __glewClearTexSubImageEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAEXTPROC __glewCopyImageSubDataEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT; +GLEW_FUN_EXPORT PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT; + +GLEW_FUN_EXPORT PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT; +GLEW_FUN_EXPORT PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT; +GLEW_FUN_EXPORT PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT; +GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT; +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT; +GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT; +GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT; +GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT; +GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT; +GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT; +GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT; +GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT; +GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT; +GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT; +GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT; +GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT; +GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT; + +GLEW_FUN_EXPORT PFNGLDISCARDFRAMEBUFFEREXTPROC __glewDiscardFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSEXTPROC __glewDrawBuffersEXT; + +GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT; +GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT; +GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIEXTPROC __glewBlendEquationSeparateiEXT; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIEXTPROC __glewBlendEquationiEXT; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIEXTPROC __glewBlendFuncSeparateiEXT; +GLEW_FUN_EXPORT PFNGLBLENDFUNCIEXTPROC __glewBlendFunciEXT; +GLEW_FUN_EXPORT PFNGLCOLORMASKIEXTPROC __glewColorMaskiEXT; +GLEW_FUN_EXPORT PFNGLDISABLEIEXTPROC __glewDisableiEXT; +GLEW_FUN_EXPORT PFNGLENABLEIEXTPROC __glewEnableiEXT; +GLEW_FUN_EXPORT PFNGLISENABLEDIEXTPROC __glewIsEnablediEXT; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXEXTPROC __glewDrawElementsBaseVertexEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __glewDrawElementsInstancedBaseVertexEXT; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __glewDrawRangeElementsBaseVertexEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __glewMultiDrawElementsBaseVertexEXT; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEEXTERNALEXTPROC __glewBufferStorageExternalEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC __glewNamedBufferStorageExternalEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT; +GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISOREXTPROC __glewVertexAttribDivisorEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC __glewFlushMappedBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEEXTPROC __glewMapBufferRangeEXT; + +GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEMEMEXTPROC __glewBufferStorageMemEXT; +GLEW_FUN_EXPORT PFNGLCREATEMEMORYOBJECTSEXTPROC __glewCreateMemoryObjectsEXT; +GLEW_FUN_EXPORT PFNGLDELETEMEMORYOBJECTSEXTPROC __glewDeleteMemoryObjectsEXT; +GLEW_FUN_EXPORT PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC __glewGetMemoryObjectParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEI_VEXTPROC __glewGetUnsignedBytei_vEXT; +GLEW_FUN_EXPORT PFNGLGETUNSIGNEDBYTEVEXTPROC __glewGetUnsignedBytevEXT; +GLEW_FUN_EXPORT PFNGLISMEMORYOBJECTEXTPROC __glewIsMemoryObjectEXT; +GLEW_FUN_EXPORT PFNGLMEMORYOBJECTPARAMETERIVEXTPROC __glewMemoryObjectParameterivEXT; +GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC __glewNamedBufferStorageMemEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM1DEXTPROC __glewTexStorageMem1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DEXTPROC __glewTexStorageMem2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC __glewTexStorageMem2DMultisampleEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DEXTPROC __glewTexStorageMem3DEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC __glewTexStorageMem3DMultisampleEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM1DEXTPROC __glewTextureStorageMem1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DEXTPROC __glewTextureStorageMem2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC __glewTextureStorageMem2DMultisampleEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DEXTPROC __glewTextureStorageMem3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC __glewTextureStorageMem3DMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTMEMORYFDEXTPROC __glewImportMemoryFdEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC __glewImportMemoryWin32HandleEXT; +GLEW_FUN_EXPORT PFNGLIMPORTMEMORYWIN32NAMEEXTPROC __glewImportMemoryWin32NameEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC __glewMultiDrawArraysIndirectEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC __glewMultiDrawElementsIndirectEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __glewFramebufferTexture2DMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSINDEXEDEXTPROC __glewDrawBuffersIndexedEXT; +GLEW_FUN_EXPORT PFNGLGETINTEGERI_VEXTPROC __glewGetIntegeri_vEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERINDEXEDEXTPROC __glewReadBufferIndexedEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETCLAMPEXTPROC __glewPolygonOffsetClampEXT; + +GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT; + +GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONNVPROC __glewCoverageModulationNV; +GLEW_FUN_EXPORT PFNGLCOVERAGEMODULATIONTABLENVPROC __glewCoverageModulationTableNV; +GLEW_FUN_EXPORT PFNGLGETCOVERAGEMODULATIONTABLENVPROC __glewGetCoverageModulationTableNV; +GLEW_FUN_EXPORT PFNGLRASTERSAMPLESEXTPROC __glewRasterSamplesEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLDELETESEMAPHORESEXTPROC __glewDeleteSemaphoresEXT; +GLEW_FUN_EXPORT PFNGLGENSEMAPHORESEXTPROC __glewGenSemaphoresEXT; +GLEW_FUN_EXPORT PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC __glewGetSemaphoreParameterui64vEXT; +GLEW_FUN_EXPORT PFNGLISSEMAPHOREEXTPROC __glewIsSemaphoreEXT; +GLEW_FUN_EXPORT PFNGLSEMAPHOREPARAMETERUI64VEXTPROC __glewSemaphoreParameterui64vEXT; +GLEW_FUN_EXPORT PFNGLSIGNALSEMAPHOREEXTPROC __glewSignalSemaphoreEXT; +GLEW_FUN_EXPORT PFNGLWAITSEMAPHOREEXTPROC __glewWaitSemaphoreEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREFDEXTPROC __glewImportSemaphoreFdEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC __glewImportSemaphoreWin32HandleEXT; +GLEW_FUN_EXPORT PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC __glewImportSemaphoreWin32NameEXT; + +GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT; +GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT; + +GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT; +GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT; + +GLEW_FUN_EXPORT PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC __glewClearPixelLocalStorageuiEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewFramebufferPixelLocalStorageSizeEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewGetFramebufferPixelLocalStorageSizeEXT; + +GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTEXTPROC __glewTexPageCommitmentEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT; + +GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT; + +GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT; +GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DEXTPROC __glewTexStorage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DEXTPROC __glewTexStorage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DEXTPROC __glewTexStorage3DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXTUREVIEWEXTPROC __glewTextureViewEXT; + +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT; + +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLBINDARRAYSETEXTPROC __glewBindArraySetEXT; +GLEW_FUN_EXPORT PFNGLCREATEARRAYSETEXTPROC __glewCreateArraySetExt; +GLEW_FUN_EXPORT PFNGLDELETEARRAYSETSEXTPROC __glewDeleteArraySetsEXT; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC __glewAcquireKeyedMutexWin32EXT; +GLEW_FUN_EXPORT PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC __glewReleaseKeyedMutexWin32EXT; + +GLEW_FUN_EXPORT PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT; + +GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT; + +GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL; +GLEW_FUN_EXPORT PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL; +GLEW_FUN_EXPORT PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL; +GLEW_FUN_EXPORT PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL; +GLEW_FUN_EXPORT PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL; +GLEW_FUN_EXPORT PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBLENDBARRIERKHRPROC __glewBlendBarrierKHR; + +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl; +GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert; +GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog; +GLEW_FUN_EXPORT PFNGLGETOBJECTLABELPROC __glewGetObjectLabel; +GLEW_FUN_EXPORT PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel; +GLEW_FUN_EXPORT PFNGLOBJECTLABELPROC __glewObjectLabel; +GLEW_FUN_EXPORT PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel; +GLEW_FUN_EXPORT PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup; +GLEW_FUN_EXPORT PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup; + +GLEW_FUN_EXPORT PFNGLMAXSHADERCOMPILERTHREADSKHRPROC __glewMaxShaderCompilerThreadsKHR; + +GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVPROC __glewGetnUniformfv; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVPROC __glewGetnUniformiv; +GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVPROC __glewGetnUniformuiv; +GLEW_FUN_EXPORT PFNGLREADNPIXELSPROC __glewReadnPixels; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX; + +GLEW_FUN_EXPORT PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX; +GLEW_FUN_EXPORT PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX; +GLEW_FUN_EXPORT PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX; + +GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERFNVPROC __glewStereoParameterfNV; +GLEW_FUN_EXPORT PFNGLSTEREOPARAMETERINVPROC __glewStereoParameteriNV; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawArraysIndirectBindlessCountNV; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawElementsIndirectBindlessCountNV; + +GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV; +GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV; +GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV; +GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV; +GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV; + +GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV; +GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV; + +GLEW_FUN_EXPORT PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV; + +GLEW_FUN_EXPORT PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV; +GLEW_FUN_EXPORT PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV; +GLEW_FUN_EXPORT PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV; +GLEW_FUN_EXPORT PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV; +GLEW_FUN_EXPORT PFNGLCREATESTATESNVPROC __glewCreateStatesNV; +GLEW_FUN_EXPORT PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV; +GLEW_FUN_EXPORT PFNGLDELETESTATESNVPROC __glewDeleteStatesNV; +GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV; +GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV; +GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV; +GLEW_FUN_EXPORT PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV; +GLEW_FUN_EXPORT PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV; +GLEW_FUN_EXPORT PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV; +GLEW_FUN_EXPORT PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV; +GLEW_FUN_EXPORT PFNGLISSTATENVPROC __glewIsStateNV; +GLEW_FUN_EXPORT PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV; +GLEW_FUN_EXPORT PFNGLSTATECAPTURENVPROC __glewStateCaptureNV; + +GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV; +GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV; + +GLEW_FUN_EXPORT PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV; + +GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV; + +GLEW_FUN_EXPORT PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV; + +GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATANVPROC __glewCopyBufferSubDataNV; + +GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV; + +GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV; +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSNVPROC __glewDrawBuffersNV; + +GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDNVPROC __glewDrawArraysInstancedNV; +GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDNVPROC __glewDrawElementsInstancedNV; + +GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV; + +GLEW_FUN_EXPORT PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV; +GLEW_FUN_EXPORT PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV; +GLEW_FUN_EXPORT PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV; +GLEW_FUN_EXPORT PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV; +GLEW_FUN_EXPORT PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV; +GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV; +GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOVERAGECOLORNVPROC __glewFragmentCoverageColorNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERNVPROC __glewBlitFramebufferNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC __glewRenderbufferStorageMultisampleNV; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV; + +GLEW_FUN_EXPORT PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV; +GLEW_FUN_EXPORT PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV; +GLEW_FUN_EXPORT PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV; +GLEW_FUN_EXPORT PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV; +GLEW_FUN_EXPORT PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV; +GLEW_FUN_EXPORT PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV; +GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV; +GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV; +GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV; +GLEW_FUN_EXPORT PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV; +GLEW_FUN_EXPORT PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV; +GLEW_FUN_EXPORT PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV; + +GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV; +GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORNVPROC __glewVertexAttribDivisorNV; + +GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATSAMPLEIVNVPROC __glewGetInternalformatSampleivNV; + +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVNVPROC __glewUniformMatrix2x3fvNV; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVNVPROC __glewUniformMatrix2x4fvNV; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVNVPROC __glewUniformMatrix3x2fvNV; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVNVPROC __glewUniformMatrix3x4fvNV; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVNVPROC __glewUniformMatrix4x2fvNV; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVNVPROC __glewUniformMatrix4x3fvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV; +GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV; + +GLEW_FUN_EXPORT PFNGLCOPYPATHNVPROC __glewCopyPathNV; +GLEW_FUN_EXPORT PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV; +GLEW_FUN_EXPORT PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV; +GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV; +GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV; +GLEW_FUN_EXPORT PFNGLDELETEPATHSNVPROC __glewDeletePathsNV; +GLEW_FUN_EXPORT PFNGLGENPATHSNVPROC __glewGenPathsNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV; +GLEW_FUN_EXPORT PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV; +GLEW_FUN_EXPORT PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV; +GLEW_FUN_EXPORT PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV; +GLEW_FUN_EXPORT PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV; +GLEW_FUN_EXPORT PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV; +GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV; +GLEW_FUN_EXPORT PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV; +GLEW_FUN_EXPORT PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV; +GLEW_FUN_EXPORT PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEFVNVPROC __glewGetProgramResourcefvNV; +GLEW_FUN_EXPORT PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV; +GLEW_FUN_EXPORT PFNGLISPATHNVPROC __glewIsPathNV; +GLEW_FUN_EXPORT PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV; +GLEW_FUN_EXPORT PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV; +GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X2FNVPROC __glewMatrixLoad3x2fNV; +GLEW_FUN_EXPORT PFNGLMATRIXLOAD3X3FNVPROC __glewMatrixLoad3x3fNV; +GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC __glewMatrixLoadTranspose3x3fNV; +GLEW_FUN_EXPORT PFNGLMATRIXMULT3X2FNVPROC __glewMatrixMult3x2fNV; +GLEW_FUN_EXPORT PFNGLMATRIXMULT3X3FNVPROC __glewMatrixMult3x3fNV; +GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC __glewMatrixMultTranspose3x3fNV; +GLEW_FUN_EXPORT PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV; +GLEW_FUN_EXPORT PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV; +GLEW_FUN_EXPORT PFNGLPATHCOORDSNVPROC __glewPathCoordsNV; +GLEW_FUN_EXPORT PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV; +GLEW_FUN_EXPORT PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV; +GLEW_FUN_EXPORT PFNGLPATHFOGGENNVPROC __glewPathFogGenNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXARRAYNVPROC __glewPathGlyphIndexArrayNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHINDEXRANGENVPROC __glewPathGlyphIndexRangeNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV; +GLEW_FUN_EXPORT PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV; +GLEW_FUN_EXPORT PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC __glewPathMemoryGlyphIndexArrayNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV; +GLEW_FUN_EXPORT PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV; +GLEW_FUN_EXPORT PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV; +GLEW_FUN_EXPORT PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV; +GLEW_FUN_EXPORT PFNGLPATHSTRINGNVPROC __glewPathStringNV; +GLEW_FUN_EXPORT PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV; +GLEW_FUN_EXPORT PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV; +GLEW_FUN_EXPORT PFNGLPATHTEXGENNVPROC __glewPathTexGenNV; +GLEW_FUN_EXPORT PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC __glewProgramPathFragmentInputGenNV; +GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV; +GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV; +GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC __glewStencilThenCoverFillPathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERFILLPATHNVPROC __glewStencilThenCoverFillPathNV; +GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC __glewStencilThenCoverStrokePathInstancedNV; +GLEW_FUN_EXPORT PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC __glewStencilThenCoverStrokePathNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV; +GLEW_FUN_EXPORT PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLPOLYGONMODENVPROC __glewPolygonModeNV; + +GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV; +GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewFramebufferSampleLocationsfvNV; +GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewNamedFramebufferSampleLocationsfvNV; + +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV; +GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV; +GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV; +GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV; +GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV; +GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV; +GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DNVPROC __glewCompressedTexImage3DNV; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC __glewCompressedTexSubImage3DNV; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DNVPROC __glewCopyTexSubImage3DNV; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERNVPROC __glewFramebufferTextureLayerNV; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DNVPROC __glewTexImage3DNV; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DNVPROC __glewTexSubImage3DNV; + +GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV; +GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV; + +GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV; +GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV; +GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV; +GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV; +GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV; +GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV; + +GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV; +GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV; +GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV; + +GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV; +GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV; +GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV; +GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV; +GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV; +GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV; + +GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV; +GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV; +GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV; +GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV; +GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV; +GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV; +GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV; +GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV; +GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV; +GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV; +GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV; +GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV; + +GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYFVNVPROC __glewDepthRangeArrayfvNV; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDFNVPROC __glewDepthRangeIndexedfNV; +GLEW_FUN_EXPORT PFNGLDISABLEINVPROC __glewDisableiNV; +GLEW_FUN_EXPORT PFNGLENABLEINVPROC __glewEnableiNV; +GLEW_FUN_EXPORT PFNGLGETFLOATI_VNVPROC __glewGetFloati_vNV; +GLEW_FUN_EXPORT PFNGLISENABLEDINVPROC __glewIsEnablediNV; +GLEW_FUN_EXPORT PFNGLSCISSORARRAYVNVPROC __glewScissorArrayvNV; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDNVPROC __glewScissorIndexedNV; +GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVNVPROC __glewScissorIndexedvNV; +GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVNVPROC __glewViewportArrayvNV; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFNVPROC __glewViewportIndexedfNV; +GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVNVPROC __glewViewportIndexedfvNV; + +GLEW_FUN_EXPORT PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewFramebufferTextureMultiviewOVR; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __glewFramebufferTextureMultisampleMultiviewOVR; + +GLEW_FUN_EXPORT PFNGLALPHAFUNCQCOMPROC __glewAlphaFuncQCOM; + +GLEW_FUN_EXPORT PFNGLDISABLEDRIVERCONTROLQCOMPROC __glewDisableDriverControlQCOM; +GLEW_FUN_EXPORT PFNGLENABLEDRIVERCONTROLQCOMPROC __glewEnableDriverControlQCOM; +GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSTRINGQCOMPROC __glewGetDriverControlStringQCOM; +GLEW_FUN_EXPORT PFNGLGETDRIVERCONTROLSQCOMPROC __glewGetDriverControlsQCOM; + +GLEW_FUN_EXPORT PFNGLEXTGETBUFFERPOINTERVQCOMPROC __glewExtGetBufferPointervQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETBUFFERSQCOMPROC __glewExtGetBuffersQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETFRAMEBUFFERSQCOMPROC __glewExtGetFramebuffersQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETRENDERBUFFERSQCOMPROC __glewExtGetRenderbuffersQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC __glewExtGetTexLevelParameterivQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETTEXSUBIMAGEQCOMPROC __glewExtGetTexSubImageQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETTEXTURESQCOMPROC __glewExtGetTexturesQCOM; +GLEW_FUN_EXPORT PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC __glewExtTexObjectStateOverrideiQCOM; + +GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC __glewExtGetProgramBinarySourceQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETPROGRAMSQCOMPROC __glewExtGetProgramsQCOM; +GLEW_FUN_EXPORT PFNGLEXTGETSHADERSQCOMPROC __glewExtGetShadersQCOM; +GLEW_FUN_EXPORT PFNGLEXTISPROGRAMBINARYQCOMPROC __glewExtIsProgramBinaryQCOM; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC __glewFramebufferFoveationConfigQCOM; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC __glewFramebufferFoveationParametersQCOM; + +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC __glewFramebufferFetchBarrierQCOM; + +GLEW_FUN_EXPORT PFNGLENDTILINGQCOMPROC __glewEndTilingQCOM; +GLEW_FUN_EXPORT PFNGLSTARTTILINGQCOMPROC __glewStartTilingQCOM; + +GLEW_FUN_EXPORT PFNGLALPHAFUNCXPROC __glewAlphaFuncx; +GLEW_FUN_EXPORT PFNGLCLEARCOLORXPROC __glewClearColorx; +GLEW_FUN_EXPORT PFNGLCLEARDEPTHXPROC __glewClearDepthx; +GLEW_FUN_EXPORT PFNGLCOLOR4XPROC __glewColor4x; +GLEW_FUN_EXPORT PFNGLDEPTHRANGEXPROC __glewDepthRangex; +GLEW_FUN_EXPORT PFNGLFOGXPROC __glewFogx; +GLEW_FUN_EXPORT PFNGLFOGXVPROC __glewFogxv; +GLEW_FUN_EXPORT PFNGLFRUSTUMFPROC __glewFrustumf; +GLEW_FUN_EXPORT PFNGLFRUSTUMXPROC __glewFrustumx; +GLEW_FUN_EXPORT PFNGLLIGHTMODELXPROC __glewLightModelx; +GLEW_FUN_EXPORT PFNGLLIGHTMODELXVPROC __glewLightModelxv; +GLEW_FUN_EXPORT PFNGLLIGHTXPROC __glewLightx; +GLEW_FUN_EXPORT PFNGLLIGHTXVPROC __glewLightxv; +GLEW_FUN_EXPORT PFNGLLINEWIDTHXPROC __glewLineWidthx; +GLEW_FUN_EXPORT PFNGLLOADMATRIXXPROC __glewLoadMatrixx; +GLEW_FUN_EXPORT PFNGLMATERIALXPROC __glewMaterialx; +GLEW_FUN_EXPORT PFNGLMATERIALXVPROC __glewMaterialxv; +GLEW_FUN_EXPORT PFNGLMULTMATRIXXPROC __glewMultMatrixx; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x; +GLEW_FUN_EXPORT PFNGLNORMAL3XPROC __glewNormal3x; +GLEW_FUN_EXPORT PFNGLORTHOFPROC __glewOrthof; +GLEW_FUN_EXPORT PFNGLORTHOXPROC __glewOrthox; +GLEW_FUN_EXPORT PFNGLPOINTSIZEXPROC __glewPointSizex; +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx; +GLEW_FUN_EXPORT PFNGLROTATEXPROC __glewRotatex; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex; +GLEW_FUN_EXPORT PFNGLSCALEXPROC __glewScalex; +GLEW_FUN_EXPORT PFNGLTEXENVXPROC __glewTexEnvx; +GLEW_FUN_EXPORT PFNGLTEXENVXVPROC __glewTexEnvxv; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERXPROC __glewTexParameterx; +GLEW_FUN_EXPORT PFNGLTRANSLATEXPROC __glewTranslatex; + +GLEW_FUN_EXPORT PFNGLCLIPPLANEFPROC __glewClipPlanef; +GLEW_FUN_EXPORT PFNGLCLIPPLANEXPROC __glewClipPlanex; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef; +GLEW_FUN_EXPORT PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex; +GLEW_FUN_EXPORT PFNGLGETFIXEDVPROC __glewGetFixedv; +GLEW_FUN_EXPORT PFNGLGETLIGHTXVPROC __glewGetLightxv; +GLEW_FUN_EXPORT PFNGLGETMATERIALXVPROC __glewGetMaterialxv; +GLEW_FUN_EXPORT PFNGLGETTEXENVXVPROC __glewGetTexEnvxv; +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXPROC __glewPointParameterx; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv; +GLEW_FUN_EXPORT PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES; +GLEW_FUN_EXPORT PFNGLTEXPARAMETERXVPROC __glewTexParameterxv; + +GLEW_FUN_EXPORT PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL; + +GLEW_FUN_EXPORT PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL; +GLEW_FUN_EXPORT PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL; + +GLEW_FUN_EXPORT PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL; + +GLEW_FUN_EXPORT PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC __glewInterleavedTextureCoordSetsSGIS; +GLEW_FUN_EXPORT PFNGLSELECTTEXTURECOORDSETSGISPROC __glewSelectTextureCoordSetSGIS; +GLEW_FUN_EXPORT PFNGLSELECTTEXTURESGISPROC __glewSelectTextureSGIS; +GLEW_FUN_EXPORT PFNGLSELECTTEXTURETRANSFORMSGISPROC __glewSelectTextureTransformSGIS; + +GLEW_FUN_EXPORT PFNGLMULTISAMPLESUBRECTPOSSGISPROC __glewMultisampleSubRectPosSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLADDRESSSPACEPROC __glewAddressSpace; +GLEW_FUN_EXPORT PFNGLDATAPIPEPROC __glewDataPipe; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLFOGLAYERSSGIXPROC __glewFogLayersSGIX; +GLEW_FUN_EXPORT PFNGLGETFOGLAYERSSGIXPROC __glewGetFogLayersSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLIGLOOINTERFACESGIXPROC __glewIglooInterfaceSGIX; + +GLEW_FUN_EXPORT PFNGLALLOCMPEGPREDICTORSSGIXPROC __glewAllocMPEGPredictorsSGIX; +GLEW_FUN_EXPORT PFNGLDELETEMPEGPREDICTORSSGIXPROC __glewDeleteMPEGPredictorsSGIX; +GLEW_FUN_EXPORT PFNGLGENMPEGPREDICTORSSGIXPROC __glewGenMPEGPredictorsSGIX; +GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERFVSGIXPROC __glewGetMPEGParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLGETMPEGPARAMETERIVSGIXPROC __glewGetMPEGParameterivSGIX; +GLEW_FUN_EXPORT PFNGLGETMPEGPREDICTORSGIXPROC __glewGetMPEGPredictorSGIX; +GLEW_FUN_EXPORT PFNGLGETMPEGQUANTTABLEUBVPROC __glewGetMPEGQuantTableubv; +GLEW_FUN_EXPORT PFNGLISMPEGPREDICTORSGIXPROC __glewIsMPEGPredictorSGIX; +GLEW_FUN_EXPORT PFNGLMPEGPREDICTORSGIXPROC __glewMPEGPredictorSGIX; +GLEW_FUN_EXPORT PFNGLMPEGQUANTTABLEUBVPROC __glewMPEGQuantTableubv; +GLEW_FUN_EXPORT PFNGLSWAPMPEGPREDICTORSSGIXPROC __glewSwapMPEGPredictorsSGIX; + +GLEW_FUN_EXPORT PFNGLGETNONLINLIGHTFVSGIXPROC __glewGetNonlinLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETNONLINMATERIALFVSGIXPROC __glewGetNonlinMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLNONLINLIGHTFVSGIXPROC __glewNonlinLightfvSGIX; +GLEW_FUN_EXPORT PFNGLNONLINMATERIALFVSGIXPROC __glewNonlinMaterialfvSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLDEFORMSGIXPROC __glewDeformSGIX; +GLEW_FUN_EXPORT PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC __glewLoadIdentityDeformationMapSGIX; + +GLEW_FUN_EXPORT PFNGLMESHBREADTHSGIXPROC __glewMeshBreadthSGIX; +GLEW_FUN_EXPORT PFNGLMESHSTRIDESGIXPROC __glewMeshStrideSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLGETVECTOROPERATIONSGIXPROC __glewGetVectorOperationSGIX; +GLEW_FUN_EXPORT PFNGLVECTOROPERATIONSGIXPROC __glewVectorOperationSGIX; + +GLEW_FUN_EXPORT PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC __glewAreVertexArraysResidentSGIX; +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYSGIXPROC __glewBindVertexArraySGIX; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSSGIXPROC __glewDeleteVertexArraysSGIX; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSSGIXPROC __glewGenVertexArraysSGIX; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYSGIXPROC __glewIsVertexArraySGIX; +GLEW_FUN_EXPORT PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC __glewPrioritizeVertexArraysSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC __glewGetPixelTransformParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC __glewGetPixelTransformParameterivSGI; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFSGIPROC __glewPixelTransformParameterfSGI; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC __glewPixelTransformParameterfvSGI; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERISGIPROC __glewPixelTransformParameteriSGI; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC __glewPixelTransformParameterivSGI; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMSGIPROC __glewPixelTransformSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_6; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_blend_minmax_factor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_3DC_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_compressed_ATC_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_framebuffer_sample_positions; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gcn_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int16; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_gpu_shader_int64; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_interleaved_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_occlusion_query_event; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_pinned_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_program_binary_Z400; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_atomic_counter_ops; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_ballot; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_explicit_vertex_parameter; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_value_export; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sparse_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_stencil_operation_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_gather_bias_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback4; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_layer; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator; +GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_viewport_index; +GLEW_VAR_EXPORT GLboolean __GLEW_ANDROID_extension_pack_es31a; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_pack_reverse_row_order; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt3; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt5; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_usage; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_translated_shader_source; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_clip_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_color_buffer_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_copy_texture_levels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_sync; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_2D_limited_npot; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_format_BGRA8888; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_max_level; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_1_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_2_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_arrays_of_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_base_instance; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_bindless_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_buffer_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clip_control; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compressed_texture_pixel_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_variable_group_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conditional_render_inverted; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cull_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_derivative_control; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_enhanced_layouts; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_uniform_location; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_layer_viewport; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader_interlock; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_no_attachments; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_texture_sub_image; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gl_spirv; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_int64; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_indirect_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_invalidate_subdata; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_alignment; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_bind; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_parallel_shader_compile; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pipeline_statistics_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_polygon_offset_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_post_depth_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_program_interface_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_query_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robust_buffer_access_behavior; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_application_isolation; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_share_group_isolation; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_locations; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cubemap_per_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counter_ops; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_ballot; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_clock; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_draw_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_group_vote; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_storage_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_image_samples; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_viewport_layer_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_420pack; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_packing; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_spirv_extensions; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_stencil_texturing; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_barrier; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_filter_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_levels; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_stencil8; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_view; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_overflow_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_binding; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_program_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ARM_mali_shader_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_ARM_rgba8; +GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch; +GLEW_VAR_EXPORT GLboolean __GLEW_ARM_shader_framebuffer_fetch_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EGL_KHR_context_flush_control; +GLEW_VAR_EXPORT GLboolean __GLEW_EGL_NV_robustness_video_memory_purge; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_EGL_image_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_YUV_target; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_base_instance; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_buffer_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clear_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_cull_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_buffer_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compressed_ETC1_RGB8_sub_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_conservative_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_label; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_discard_framebuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers_indexed; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_elements_base_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_external_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_float_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_frag_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_map_buffer_range; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_fd; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_memory_object_win32; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiple_textures; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisampled_render_to_texture2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multiview_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_post_depth_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pvrtc_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_raster_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_read_format_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_render_snorm; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sRGB_write_control; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_fd; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_semaphore_win32; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_framebuffer_fetch; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_group_vote; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_formatted; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_implicit_conversions; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_integer_mix; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_io_blocks; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_non_constant_global_initializers; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_pixel_local_storage2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_samplers; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_sparse_texture2; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_bptc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_format_BGRA8888; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_norm16; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rg; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_R8; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_RG8; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_decode; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_type_2_10_10_10_REV; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_view; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_unpack_subimage; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_setXXX; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_win32_keyed_mutex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_window_rectangles; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_conservative_rasterization; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_fragment_shader_ordering; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_framebuffer_CMAA; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_performance_query; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_blend_equation_advanced_coherent; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_context_flush_control; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_debug; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_no_error; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_parallel_shader_compile; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robust_buffer_access_behavior; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_robustness; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_hdr; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr; +GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_shader_integer_functions; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info; +GLEW_VAR_EXPORT GLboolean __GLEW_NVX_linked_gpu_multicast; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_3dvision_settings; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_EGL_stream_consumer_external; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_alpha_to_coverage_dither_control; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bgr; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect_count; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_minmax_factor; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_clip_space_w_scaling; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_command_list; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_dilate; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_instanced; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_vulkan_image; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_attrib_location; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fbo_color_attachments; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fill_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_coverage_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_shader_interlock; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_mixed_samples; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_generate_mipmap_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader_passthrough; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_multicast; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_image_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_instanced_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_internalformat_sample_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_non_square_matrices; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pack_subimage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_float_linear; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering_shared_edge; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_platform_binary; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_polygon_mode; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_read_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_robustness_video_memory_purge; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_sRGB_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_locations; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_sample_mask_override_coverage; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_counters; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_fp16_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_int64; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_noperspective_interpolation; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_group; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_thread_shuffle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_array; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_shadow_samplers_cube; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_stereo_view_rendering; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_array; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_latc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_s3tc_update; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_npot_2D_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle_compressed; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_uniform_buffer_unified_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_array2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_viewport_swizzle; +GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview; +GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview2; +GLEW_VAR_EXPORT GLboolean __GLEW_OVR_multiview_multisampled_render_to_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_alpha_test; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_binning_control; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_driver_control; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_extended_get2; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_framebuffer_foveated; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_perfmon_global_mode; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_shader_framebuffer_fetch_noncoherent; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_tiled_rendering; +GLEW_VAR_EXPORT GLboolean __GLEW_QCOM_writeonly_rendering; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_0_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_1_compatibility; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_enable; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_error_string; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_extension_query; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_log; +GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_proc_address; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_clip_band_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_shared_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_g_instruments; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_r_instruments; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_bali_timer_instruments; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cadd; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_cmultiply; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_calligraphic_fragment; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_matrix_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_color_table_index_mode; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_complex_polar; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_cylinder_texgen; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_datapipe; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_decimation; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_pass_instrument; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_dvc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_factor_to_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_layers; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_patchy; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_scale; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_lighting_space; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragments_instrument; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_icc_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_igloo_interface; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_image_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_impact_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_instrument_error; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_line_quality_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_mpeg2; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nonlinear_lighting_pervertex; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_nurbs_eval; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_occlusion_instrument; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_packed_6bytes; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_tiles; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_polynomial_ffd; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_quad_mesh; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_scalebias_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_slim; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_spotlight_cutoff; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subdiv_patch; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_mipmap_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_phase; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_supersample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vector_ops; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcba; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_complex_type; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_fft; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_scene_markerXXX; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* Need at least OpenGL 1.1 */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */ +#define GLEW_ERROR_NO_GLX_DISPLAY 4 /* Need GLX display for GLX support */ + +/* string codes */ +#define GLEW_VERSION 1 +#define GLEW_VERSION_MAJOR 2 +#define GLEW_VERSION_MINOR 3 +#define GLEW_VERSION_MICRO 4 + +/* ------------------------------------------------------------------------- */ + +/* GLEW version info */ + +/* +VERSION 2.1.0 +VERSION_MAJOR 2 +VERSION_MINOR 1 +VERSION_MICRO 0 +*/ + +/* API */ +GLEWAPI GLenum GLEWAPIENTRY glewInit (void); +GLEWAPI GLboolean GLEWAPIENTRY glewIsSupported (const char *name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#ifndef GLEW_GET_VAR +#define GLEW_GET_VAR(x) (*(const GLboolean*)&x) +#endif + +#ifndef GLEW_GET_FUN +#define GLEW_GET_FUN(x) x +#endif + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean GLEWAPIENTRY glewGetExtension (const char *name); +GLEWAPI const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error); +GLEWAPI const GLubyte * GLEWAPIENTRY glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/libultraship/libultraship/Lib/GLEW/GL/glxew.h b/libultraship/libultraship/Lib/GLEW/GL/glxew.h new file mode 100644 index 000000000..7e39c2fd9 --- /dev/null +++ b/libultraship/libultraship/Lib/GLEW/GL/glxew.h @@ -0,0 +1,1775 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2017, Nigel Stewart +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/* + * Mesa 3-D graphics library + * Version: 7.0 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * 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 + * BRIAN PAUL 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. + */ + +/* +** Copyright (c) 2007 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. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif + +#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) +#error glx.h included before glxew.h +#endif + +#define __glxext_h_ + +#define GLX_H +#define __GLX_glx_h__ +#define __glx_h__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +#ifdef __sun +typedef struct __glXContextRec *GLXContext; +#else +typedef struct __GLXcontextRec *GLXContext; +#endif + +typedef unsigned int GLXVideoDeviceNV; + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#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_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#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 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXPbuffer; +typedef XID GLXWindow; +typedef struct __GLXFBConfigRec *GLXFBConfig; + +typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; +} GLXPbufferClobberEvent; +typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; +} GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------ GLX_AMD_gpu_association ------------------------ */ + +#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 + +typedef void ( * PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list); +typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int* attribList); +typedef Bool ( * PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx); +typedef unsigned int ( * PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx); +typedef GLXContext ( * PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef unsigned int ( * PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int* ids); +typedef int ( * PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void* data); +typedef Bool ( * PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx); + +#define glXBlitContextFramebufferAMD GLXEW_GET_FUN(__glewXBlitContextFramebufferAMD) +#define glXCreateAssociatedContextAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAMD) +#define glXCreateAssociatedContextAttribsAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAttribsAMD) +#define glXDeleteAssociatedContextAMD GLXEW_GET_FUN(__glewXDeleteAssociatedContextAMD) +#define glXGetContextGPUIDAMD GLXEW_GET_FUN(__glewXGetContextGPUIDAMD) +#define glXGetCurrentAssociatedContextAMD GLXEW_GET_FUN(__glewXGetCurrentAssociatedContextAMD) +#define glXGetGPUIDsAMD GLXEW_GET_FUN(__glewXGetGPUIDsAMD) +#define glXGetGPUInfoAMD GLXEW_GET_FUN(__glewXGetGPUInfoAMD) +#define glXMakeAssociatedContextCurrentAMD GLXEW_GET_FUN(__glewXMakeAssociatedContextCurrentAMD) + +#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association) + +#endif /* GLX_AMD_gpu_association */ + +/* --------------------- GLX_ARB_context_flush_control --------------------- */ + +#ifndef GLX_ARB_context_flush_control +#define GLX_ARB_context_flush_control 1 + +#define GLXEW_ARB_context_flush_control GLXEW_GET_VAR(__GLXEW_ARB_context_flush_control) + +#endif /* GLX_ARB_context_flush_control */ + +/* ------------------------- GLX_ARB_create_context ------------------------ */ + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context 1 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#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); + +#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB) + +#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context) + +#endif /* GLX_ARB_create_context */ + +/* -------------------- GLX_ARB_create_context_no_error -------------------- */ + +#ifndef GLX_ARB_create_context_no_error +#define GLX_ARB_create_context_no_error 1 + +#define GLXEW_ARB_create_context_no_error GLXEW_GET_VAR(__GLXEW_ARB_create_context_no_error) + +#endif /* GLX_ARB_create_context_no_error */ + +/* --------------------- GLX_ARB_create_context_profile -------------------- */ + +#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 + +#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile) + +#endif /* GLX_ARB_create_context_profile */ + +/* ------------------- GLX_ARB_create_context_robustness ------------------- */ + +#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 + +#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness) + +#endif /* GLX_ARB_create_context_robustness */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_ARB_framebuffer_sRGB +#define GLX_ARB_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 + +#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB) + +#endif /* GLX_ARB_framebuffer_sRGB */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ---------------- GLX_ARB_robustness_application_isolation --------------- */ + +#ifndef GLX_ARB_robustness_application_isolation +#define GLX_ARB_robustness_application_isolation 1 + +#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define GLXEW_ARB_robustness_application_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_application_isolation) + +#endif /* GLX_ARB_robustness_application_isolation */ + +/* ---------------- GLX_ARB_robustness_share_group_isolation --------------- */ + +#ifndef GLX_ARB_robustness_share_group_isolation +#define GLX_ARB_robustness_share_group_isolation 1 + +#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define GLXEW_ARB_robustness_share_group_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_share_group_isolation) + +#endif /* GLX_ARB_robustness_share_group_isolation */ + +/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */ + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object 1 + +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 + +#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object) + +#endif /* GLX_ARB_vertex_buffer_object */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* --------------------------- GLX_EXT_buffer_age -------------------------- */ + +#ifndef GLX_EXT_buffer_age +#define GLX_EXT_buffer_age 1 + +#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 + +#define GLXEW_EXT_buffer_age GLXEW_GET_VAR(__GLXEW_EXT_buffer_age) + +#endif /* GLX_EXT_buffer_age */ + +/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */ + +#ifndef GLX_EXT_create_context_es2_profile +#define GLX_EXT_create_context_es2_profile 1 + +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile) + +#endif /* GLX_EXT_create_context_es2_profile */ + +/* ------------------- GLX_EXT_create_context_es_profile ------------------- */ + +#ifndef GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es_profile 1 + +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 + +#define GLXEW_EXT_create_context_es_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es_profile) + +#endif /* GLX_EXT_create_context_es_profile */ + +/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */ + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float 1 + +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 + +#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float) + +#endif /* GLX_EXT_fbconfig_packed_float */ + +/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB 1 + +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 + +#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB) + +#endif /* GLX_EXT_framebuffer_sRGB */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#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 XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* ---------------------------- GLX_EXT_libglvnd --------------------------- */ + +#ifndef GLX_EXT_libglvnd +#define GLX_EXT_libglvnd 1 + +#define GLX_VENDOR_NAMES_EXT 0x20F6 + +#define GLXEW_EXT_libglvnd GLXEW_GET_VAR(__GLXEW_EXT_libglvnd) + +#endif /* GLX_EXT_libglvnd */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* -------------------------- GLX_EXT_stereo_tree -------------------------- */ + +#ifndef GLX_EXT_stereo_tree +#define GLX_EXT_stereo_tree 1 + +#define GLX_STEREO_NOTIFY_EXT 0x00000000 +#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001 +#define GLX_STEREO_TREE_EXT 0x20F5 + +#define GLXEW_EXT_stereo_tree GLXEW_GET_VAR(__GLXEW_EXT_stereo_tree) + +#endif /* GLX_EXT_stereo_tree */ + +/* -------------------------- GLX_EXT_swap_control ------------------------- */ + +#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); + +#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT) + +#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control) + +#endif /* GLX_EXT_swap_control */ + +/* ----------------------- GLX_EXT_swap_control_tear ----------------------- */ + +#ifndef GLX_EXT_swap_control_tear +#define GLX_EXT_swap_control_tear 1 + +#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 + +#define GLXEW_EXT_swap_control_tear GLXEW_GET_VAR(__GLXEW_EXT_swap_control_tear) + +#endif /* GLX_EXT_swap_control_tear */ + +/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */ + +#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_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* display, GLXDrawable drawable, int buffer, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer); + +#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT) +#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT) + +#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap) + +#endif /* GLX_EXT_texture_from_pixmap */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#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 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#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 + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_INTEL_swap_event ------------------------- */ + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event 1 + +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 + +#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event) + +#endif /* GLX_INTEL_swap_event */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#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); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_query_renderer ------------------------ */ + +#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); + +#define glXQueryCurrentRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererIntegerMESA) +#define glXQueryCurrentRendererStringMESA GLXEW_GET_FUN(__glewXQueryCurrentRendererStringMESA) +#define glXQueryRendererIntegerMESA GLXEW_GET_FUN(__glewXQueryRendererIntegerMESA) +#define glXQueryRendererStringMESA GLXEW_GET_FUN(__glewXQueryRendererStringMESA) + +#define GLXEW_MESA_query_renderer GLXEW_GET_VAR(__GLXEW_MESA_query_renderer) + +#endif /* GLX_MESA_query_renderer */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#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 GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* ------------------------- GLX_MESA_swap_control ------------------------- */ + +#ifndef GLX_MESA_swap_control +#define GLX_MESA_swap_control 1 + +typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void); +typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); + +#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA) +#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA) + +#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control) + +#endif /* GLX_MESA_swap_control */ + +/* --------------------------- GLX_NV_copy_buffer -------------------------- */ + +#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); + +#define glXCopyBufferSubDataNV GLXEW_GET_FUN(__glewXCopyBufferSubDataNV) +#define glXNamedCopyBufferSubDataNV GLXEW_GET_FUN(__glewXNamedCopyBufferSubDataNV) + +#define GLXEW_NV_copy_buffer GLXEW_GET_VAR(__GLXEW_NV_copy_buffer) + +#endif /* GLX_NV_copy_buffer */ + +/* --------------------------- GLX_NV_copy_image --------------------------- */ + +#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); + +#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV) + +#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image) + +#endif /* GLX_NV_copy_image */ + +/* ------------------------ GLX_NV_delay_before_swap ----------------------- */ + +#ifndef GLX_NV_delay_before_swap +#define GLX_NV_delay_before_swap 1 + +typedef Bool ( * PFNGLXDELAYBEFORESWAPNVPROC) (Display* dpy, GLXDrawable drawable, GLfloat seconds); + +#define glXDelayBeforeSwapNV GLXEW_GET_FUN(__glewXDelayBeforeSwapNV) + +#define GLXEW_NV_delay_before_swap GLXEW_GET_VAR(__GLXEW_NV_delay_before_swap) + +#endif /* GLX_NV_delay_before_swap */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* ---------------------- GLX_NV_multisample_coverage ---------------------- */ + +#ifndef GLX_NV_multisample_coverage +#define GLX_NV_multisample_coverage 1 + +#define GLX_COLOR_SAMPLES_NV 0x20B3 +#define GLX_COVERAGE_SAMPLES_NV 100001 + +#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage) + +#endif /* GLX_NV_multisample_coverage */ + +/* -------------------------- GLX_NV_present_video ------------------------- */ + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video 1 + +#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0 + +typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); +typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements); + +#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV) +#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV) + +#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video) + +#endif /* GLX_NV_present_video */ + +/* ------------------ GLX_NV_robustness_video_memory_purge ----------------- */ + +#ifndef GLX_NV_robustness_video_memory_purge +#define GLX_NV_robustness_video_memory_purge 1 + +#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 + +#define GLXEW_NV_robustness_video_memory_purge GLXEW_GET_VAR(__GLXEW_NV_robustness_video_memory_purge) + +#endif /* GLX_NV_robustness_video_memory_purge */ + +/* --------------------------- GLX_NV_swap_group --------------------------- */ + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group 1 + +typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier); +typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group); +typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count); +typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); +typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); +typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen); + +#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV) +#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV) +#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV) +#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV) +#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV) +#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV) + +#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group) + +#endif /* GLX_NV_swap_group */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_NV_video_capture ------------------------- */ + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture 1 + +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +typedef XID GLXVideoCaptureDeviceNV; + +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); + +#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV) +#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV) +#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV) +#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV) +#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV) + +#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture) + +#endif /* GLX_NV_video_capture */ + +/* ---------------------------- GLX_NV_video_out --------------------------- */ + +#ifndef GLX_NV_video_out +#define GLX_NV_video_out 1 + +#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 ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); +typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); +typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice); +typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf); +typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); + +#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV) +#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV) +#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV) +#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV) +#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV) +#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV) + +#define GLXEW_NV_video_out GLXEW_GET_VAR(__GLXEW_NV_video_out) + +#endif /* GLX_NV_video_out */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#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 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +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); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_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 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#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 XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */ + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe 1 + +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 +#define GLX_HYPERPIPE_ID_SGIX 0x8030 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); +typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); +typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); +typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); +typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); +typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); +typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); + +#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX) +#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX) +#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX) +#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX) +#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX) +#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX) +#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX) +#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX) + +#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe) + +#endif /* GLX_SGIX_hyperpipe */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#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_PBUFFER_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 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#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); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#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 ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (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); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#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); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT +#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT + +GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +GLXEW_FUN_EXPORT PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +GLXEW_FUN_EXPORT PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +GLXEW_FUN_EXPORT PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +GLXEW_FUN_EXPORT PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +GLXEW_FUN_EXPORT PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +GLXEW_FUN_EXPORT PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +GLXEW_FUN_EXPORT PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +GLXEW_FUN_EXPORT PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +GLXEW_FUN_EXPORT PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +GLXEW_FUN_EXPORT PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +GLXEW_FUN_EXPORT PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD; +GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD; +GLXEW_FUN_EXPORT PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD; +GLXEW_FUN_EXPORT PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD; +GLXEW_FUN_EXPORT PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD; +GLXEW_FUN_EXPORT PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD; +GLXEW_FUN_EXPORT PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD; + +GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB; + +GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +GLXEW_FUN_EXPORT PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +GLXEW_FUN_EXPORT PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +GLXEW_FUN_EXPORT PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +GLXEW_FUN_EXPORT PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT; + +GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT; +GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT; + +GLXEW_FUN_EXPORT PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +GLXEW_FUN_EXPORT PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC __glewXQueryCurrentRendererIntegerMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC __glewXQueryCurrentRendererStringMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERINTEGERMESAPROC __glewXQueryRendererIntegerMESA; +GLXEW_FUN_EXPORT PFNGLXQUERYRENDERERSTRINGMESAPROC __glewXQueryRendererStringMESA; + +GLXEW_FUN_EXPORT PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +GLXEW_FUN_EXPORT PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +GLXEW_FUN_EXPORT PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA; +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA; + +GLXEW_FUN_EXPORT PFNGLXCOPYBUFFERSUBDATANVPROC __glewXCopyBufferSubDataNV; +GLXEW_FUN_EXPORT PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC __glewXNamedCopyBufferSubDataNV; + +GLXEW_FUN_EXPORT PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV; + +GLXEW_FUN_EXPORT PFNGLXDELAYBEFORESWAPNVPROC __glewXDelayBeforeSwapNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV; + +GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV; +GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV; +GLXEW_FUN_EXPORT PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV; +GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV; +GLXEW_FUN_EXPORT PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV; +GLXEW_FUN_EXPORT PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV; + +GLXEW_FUN_EXPORT PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +GLXEW_FUN_EXPORT PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV; +GLXEW_FUN_EXPORT PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV; + +GLXEW_FUN_EXPORT PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV; +GLXEW_FUN_EXPORT PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV; +GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV; +GLXEW_FUN_EXPORT PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV; + +GLXEW_FUN_EXPORT PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +GLXEW_FUN_EXPORT PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +GLXEW_FUN_EXPORT PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +GLXEW_FUN_EXPORT PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; + +GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX; +GLXEW_FUN_EXPORT PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX; + +GLXEW_FUN_EXPORT PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +GLXEW_FUN_EXPORT PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +GLXEW_FUN_EXPORT PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +GLXEW_FUN_EXPORT PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +GLXEW_FUN_EXPORT PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +GLXEW_FUN_EXPORT PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +GLXEW_FUN_EXPORT PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_VAR_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_AMD_gpu_association; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_context_flush_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_no_error; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_robustness; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_application_isolation; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_share_group_isolation; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_buffer_age; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_libglvnd; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_stereo_tree; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control_tear; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_VAR_EXPORT GLboolean __GLXEW_INTEL_swap_event; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_query_renderer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_buffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_image; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_delay_before_swap; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_robustness_video_memory_purge; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture; +GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_out; +GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_hyperpipe; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize; +/* ------------------------------------------------------------------------ */ + +GLEWAPI GLenum GLEWAPIENTRY glxewInit (); +GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name); + +#ifndef GLXEW_GET_VAR +#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x) +#endif + +#ifndef GLXEW_GET_FUN +#define GLXEW_GET_FUN(x) x +#endif + +GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/libultraship/libultraship/Lib/GLEW/GL/wglew.h b/libultraship/libultraship/Lib/GLEW/GL/wglew.h new file mode 100644 index 000000000..2097c0f03 --- /dev/null +++ b/libultraship/libultraship/Lib/GLEW/GL/wglew.h @@ -0,0 +1,1447 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2017, Nigel Stewart +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/* +** Copyright (c) 2007 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. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(WINAPI) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +# undef WIN32_LEAN_AND_MEAN +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#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); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------ WGL_AMD_gpu_association ------------------------ */ + +#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 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); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); + +#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD) +#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD) +#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD) +#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD) +#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD) +#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD) +#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD) +#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD) +#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD) + +#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association) + +#endif /* WGL_AMD_gpu_association */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#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 * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* --------------------- WGL_ARB_context_flush_control --------------------- */ + +#ifndef WGL_ARB_context_flush_control +#define WGL_ARB_context_flush_control 1 + +#define WGLEW_ARB_context_flush_control WGLEW_GET_VAR(__WGLEW_ARB_context_flush_control) + +#endif /* WGL_ARB_context_flush_control */ + +/* ------------------------- WGL_ARB_create_context ------------------------ */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 + +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#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 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList); + +#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB) + +#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context) + +#endif /* WGL_ARB_create_context */ + +/* -------------------- WGL_ARB_create_context_no_error -------------------- */ + +#ifndef WGL_ARB_create_context_no_error +#define WGL_ARB_create_context_no_error 1 + +#define WGLEW_ARB_create_context_no_error WGLEW_GET_VAR(__WGLEW_ARB_create_context_no_error) + +#endif /* WGL_ARB_create_context_no_error */ + +/* --------------------- WGL_ARB_create_context_profile -------------------- */ + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 + +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile) + +#endif /* WGL_ARB_create_context_profile */ + +/* ------------------- WGL_ARB_create_context_robustness ------------------- */ + +#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 + +#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness) + +#endif /* WGL_ARB_create_context_robustness */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + +#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB) + +#endif /* WGL_ARB_framebuffer_sRGB */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#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 HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#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 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#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_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 +#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 + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#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); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ---------------- WGL_ARB_robustness_application_isolation --------------- */ + +#ifndef WGL_ARB_robustness_application_isolation +#define WGL_ARB_robustness_application_isolation 1 + +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define WGLEW_ARB_robustness_application_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_application_isolation) + +#endif /* WGL_ARB_robustness_application_isolation */ + +/* ---------------- WGL_ARB_robustness_share_group_isolation --------------- */ + +#ifndef WGL_ARB_robustness_share_group_isolation +#define WGL_ARB_robustness_share_group_isolation 1 + +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 + +#define WGLEW_ARB_robustness_share_group_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_share_group_isolation) + +#endif /* WGL_ARB_robustness_share_group_isolation */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* --------------------------- WGL_EXT_colorspace -------------------------- */ + +#ifndef WGL_EXT_colorspace +#define WGL_EXT_colorspace 1 + +#define WGL_COLORSPACE_SRGB_EXT 0x3089 +#define WGL_COLORSPACE_LINEAR_EXT 0x308A +#define WGL_COLORSPACE_EXT 0x309D + +#define WGLEW_EXT_colorspace WGLEW_GET_VAR(__WGLEW_EXT_colorspace) + +#endif /* WGL_EXT_colorspace */ + +/* ------------------- WGL_EXT_create_context_es2_profile ------------------ */ + +#ifndef WGL_EXT_create_context_es2_profile +#define WGL_EXT_create_context_es2_profile 1 + +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile) + +#endif /* WGL_EXT_create_context_es2_profile */ + +/* ------------------- WGL_EXT_create_context_es_profile ------------------- */ + +#ifndef WGL_EXT_create_context_es_profile +#define WGL_EXT_create_context_es_profile 1 + +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 + +#define WGLEW_EXT_create_context_es_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es_profile) + +#endif /* WGL_EXT_create_context_es_profile */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 + +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 + +#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB) + +#endif /* WGL_EXT_framebuffer_sRGB */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#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 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#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 * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 + +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 + +#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float) + +#endif /* WGL_EXT_pixel_format_packed_float */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* ----------------------- WGL_EXT_swap_control_tear ----------------------- */ + +#ifndef WGL_EXT_swap_control_tear +#define WGL_EXT_swap_control_tear 1 + +#define WGLEW_EXT_swap_control_tear WGLEW_GET_VAR(__WGLEW_EXT_swap_control_tear) + +#endif /* WGL_EXT_swap_control_tear */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#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); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#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 * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#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 * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#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 BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* --------------------------- WGL_NV_DX_interop --------------------------- */ + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 + +#define WGL_ACCESS_READ_ONLY_NV 0x0000 +#define WGL_ACCESS_READ_WRITE_NV 0x0001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 + +typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); +typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); +typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); +typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); +typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); + +#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV) +#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV) +#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV) +#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV) +#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV) +#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV) +#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV) +#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV) + +#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop) + +#endif /* WGL_NV_DX_interop */ + +/* --------------------------- WGL_NV_DX_interop2 -------------------------- */ + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 + +#define WGLEW_NV_DX_interop2 WGLEW_GET_VAR(__WGLEW_NV_DX_interop2) + +#endif /* WGL_NV_DX_interop2 */ + +/* --------------------------- WGL_NV_copy_image --------------------------- */ + +#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); + +#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV) + +#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image) + +#endif /* WGL_NV_copy_image */ + +/* ------------------------ WGL_NV_delay_before_swap ----------------------- */ + +#ifndef WGL_NV_delay_before_swap +#define WGL_NV_delay_before_swap 1 + +typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); + +#define wglDelayBeforeSwapNV WGLEW_GET_FUN(__wglewDelayBeforeSwapNV) + +#define WGLEW_NV_delay_before_swap WGLEW_GET_VAR(__WGLEW_NV_delay_before_swap) + +#endif /* WGL_NV_delay_before_swap */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#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 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* -------------------------- WGL_NV_gpu_affinity -------------------------- */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 + +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 + +DECLARE_HANDLE(HGPUNV); +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; + +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); + +#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV) +#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV) +#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV) +#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV) +#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV) + +#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity) + +#endif /* WGL_NV_gpu_affinity */ + +/* ---------------------- WGL_NV_multisample_coverage ---------------------- */ + +#ifndef WGL_NV_multisample_coverage +#define WGL_NV_multisample_coverage 1 + +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 + +#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage) + +#endif /* WGL_NV_multisample_coverage */ + +/* -------------------------- WGL_NV_present_video ------------------------- */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 + +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 + +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList); +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue); + +#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV) +#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV) +#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV) + +#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video) + +#endif /* WGL_NV_present_video */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#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 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#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 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* --------------------------- WGL_NV_swap_group --------------------------- */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 + +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + +#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV) +#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV) +#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV) +#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV) +#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV) +#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV) + +#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group) + +#endif /* WGL_NV_swap_group */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_NV_video_capture ------------------------- */ + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 + +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + +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); + +#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV) +#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV) +#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV) +#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV) +#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV) + +#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture) + +#endif /* WGL_NV_video_capture */ + +/* -------------------------- WGL_NV_video_output -------------------------- */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 + +#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 + +DECLARE_HANDLE(HPVIDEODEV); + +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock); + +#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV) +#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV) +#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV) +#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV) +#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV) +#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV) + +#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output) + +#endif /* WGL_NV_video_output */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +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); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT +#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT + +WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_FUN_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD; +WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD; +WGLEW_FUN_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD; +WGLEW_FUN_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD; +WGLEW_FUN_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD; +WGLEW_FUN_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD; +WGLEW_FUN_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD; + +WGLEW_FUN_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_FUN_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_FUN_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB; + +WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_FUN_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_FUN_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_FUN_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_FUN_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_FUN_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_FUN_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_FUN_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_FUN_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_FUN_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_FUN_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_FUN_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_FUN_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_FUN_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_FUN_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_FUN_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_FUN_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_FUN_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_FUN_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_FUN_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_FUN_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV; +WGLEW_FUN_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV; +WGLEW_FUN_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV; +WGLEW_FUN_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV; +WGLEW_FUN_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV; +WGLEW_FUN_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV; +WGLEW_FUN_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV; +WGLEW_FUN_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV; + +WGLEW_FUN_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV; + +WGLEW_FUN_EXPORT PFNWGLDELAYBEFORESWAPNVPROC __wglewDelayBeforeSwapNV; + +WGLEW_FUN_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV; +WGLEW_FUN_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV; +WGLEW_FUN_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV; +WGLEW_FUN_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV; + +WGLEW_FUN_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV; +WGLEW_FUN_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV; +WGLEW_FUN_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV; +WGLEW_FUN_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV; +WGLEW_FUN_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV; +WGLEW_FUN_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV; + +WGLEW_FUN_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_FUN_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV; +WGLEW_FUN_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV; + +WGLEW_FUN_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV; +WGLEW_FUN_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV; +WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV; +WGLEW_FUN_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV; + +WGLEW_FUN_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_FUN_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_FUN_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_FUN_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_FUN_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_FUN_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_VAR_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_AMD_gpu_association; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_context_flush_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_no_error; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_robustness; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_application_isolation; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_share_group_isolation; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_colorspace; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es_profile; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control_tear; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop2; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_copy_image; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_delay_before_swap; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_gpu_affinity; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multisample_coverage; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_present_video; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_swap_group; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture; +WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output; +WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control; +/* ------------------------------------------------------------------------- */ + +GLEWAPI GLenum GLEWAPIENTRY wglewInit (); +GLEWAPI GLboolean GLEWAPIENTRY wglewIsSupported (const char *name); + +#ifndef WGLEW_GET_VAR +#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x) +#endif + +#ifndef WGLEW_GET_FUN +#define WGLEW_GET_FUN(x) x +#endif + +GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/libultraship/libultraship/Lib/GLEW/x64/glew32.dll b/libultraship/libultraship/Lib/GLEW/x64/glew32.dll new file mode 100644 index 0000000000000000000000000000000000000000..66c84931819392d0f4e83517c224238f248d8a4d GIT binary patch literal 464896 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

b>MyET;cb?>&ZKX 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%0DL-}7;4{?1l{5W`;;rp21 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

  • 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
      qBCh(Ci%J@+2T5b^&78GrE6wp8IL_RUd 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 literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/GLEW/x64/glew32.lib b/libultraship/libultraship/Lib/GLEW/x64/glew32.lib new file mode 100644 index 0000000000000000000000000000000000000000..02b2927239ea39a133d27a43997ca3b8d618ad14 GIT binary patch literal 757468 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ི(*o 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�|?vQcCaqas5N_ti>K+jc< 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ƜEB(Ey4GB5$iJWH*fX~lWh8h4{_=}HXE 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�)GLo#cT0K{1v{7Ei_-@ssct{A4`&H17X+2Hp?P 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

      %p=r z%%Ws)ANCcQFY<`i9ZIIl*~%R2SIyf`El{#u&Zo>di`NUT`1HK(h-EMyk#fi*92&wf$K`w$;H=8|d(Hncp@v9NBad*B zpyaxoZOpNLWBZ_^mskehnN<#Xgp&m&&*gm19INN=pZe2$%V6AR<&Z}>#ZdBH&KJyS zrpu@Kdt)B548~to4ta!g#;d4*Tuv!-tY7`=`fANBgYiX?qDCI!^nz08a<((a`i;|T z?ua;VN>>hfgfkmTk<0m#Ikvwa`MplW{jV35LmuJmhEnWuzG9BmKYulxJJm9HUQ0RT z5l)-eQ2)4`9n7)mshb$Wt}hupr-u|Z@`yGGN~z2FnmM+7x^$1cJ~mG|gHKB&&IFD--Px^l=PoWoG6T+VLh*m3a8mtrFN4Iao7 z^Fw!R3@Q$JTq&mJa{R;QUrO~an<$JYDN{Ur}r2H&$& z4ta$00hAP%bC@}{zE(GD@VjL~q5aAsk8oK~U= z!5o{O79C%I#WMJ?F;djXBb?z-GF{G5=GgxA`1Ze_vJCc9<&Z}>Z$im(IX^H5GsErd z)uH8D0wdDC+66Gnz{aowU!Bm8oVv@MIPa#K*@JG zKQqUs=bL)T5%*;>l|vrkEQM0waw?f)`}^T~2P2LbCCVX>aDIYP=yHBxj%`1`UwXqf z%V6A|cVxcEBb*c{MK0%8=2*Y6V{&4|`npXyE1;CQ zoIjXj%Xz`lt(Y{);JE_jkVmwipp?6ulgzR0@Y_1~;!tLs>hH>Ykw>(yP%2zb6?5!3 z*y_Z)Q!Rt%h?GMf;Y@{6>2m&LjxFcA_jO3J3`WaV4ta#L8A_GQ`HMMNN!$kYUz2AU z+^~Zul_m39GkC^-#-#@T_TZEXyg%28k889^EY#BKkfZYmp3gF3f-$5 z@(AYzD6uZ*ALdv+zh&GL5$6T(D~CM7ISM7t<^0Q>7Cim)Pv(m}!nqVm zyvzBIIaX)BzhTf4%i#L6a>yf`2~ZMT4qbYSj{4v6;)jnPw@fIMs~qwO=Pf9SE+>jP zHa+KW>pR*qIDb)-P)h`2xav~tKJoR6TSx}4Jk)ALo;i~q~uyh%Ca5zcAr zQUAD{GnixhMcd+Ie_ICU%Scfpk8rMqlJ0WOWRC3@o0d%)U>Q7@q8#!FXAYDMmlMMr ztDn;sXAQLs>SyJUM>tm;nZu<^>w%jtcc{kw-Y4pyaunI?S=-SJHyQh~wa3<&Z}>)1lFGDo4J<3_fwQZ9^sThDRwz$Gsm{)`OP=r zYJttyDdmtyw00k&{&6|=nPcm#TdfnfSO)i-kfKH&;bcK6bvX@~W7|*0ytqM@!F@*M zkViP5K`C=N4FjA%t7ZOW8N83C9P$XK?bw)=1aLZtvCFPJuI4hu3x}3($vF&Hyi;a$12KO12LmuHAg;M2mnlPs}Pd}c> z?0r^5y&CnA%ollt(~6X2ul{Mu9GkCmO3rxKGI)z!Iph(}C@3*5rx|mspP!z6={uIe z`+CYDk8oax665l3Y$}=2*Xxz2}>`mI;NLZIEs=LR_K`c2qu8GOG$Iph(}=TK5zP8;Uf^7;6O3nHfHsB*|7oO&Ol z{&6{NnPdA!gG;Zy!!n`J1xQgNk8p-SNq0HznA3#)c*5q9dgvM@6ADdK4tYdd0VTub zBrwPJuNoJ8(#kRzpG`UB5zZe_GF{Gj%(3;}bA9;QCB_}wBJ)Ka;q-)(<#O6Hr=HH& zUERMzmuB-dS~=tq?MW!vF6Vsa*zw}G0|i%G2IG_}hdjbL3?;|qT)-S#J}-`V$+(}6j*e0mKSgHtHU;Cioe$RpYlQ1V>Ph0L-2qSlf>fHcl(<&a0T z9Z>RJ&PB|ze&f{D-8WbU?`bNBJi=+W74?tHNn}o)khJqw%vxX>oTnf~jXc81gi@I7 z9WO3sjxC?&y9?S`CKP&BIph(}M^K7f&LzyT<@5fbALA{9=OvUw9^usb1oe;0>Bt;g z?>n0>+hrMyhlLb1@(5=rloFTIDZu%r|C?PbgYoo~LmuHQgi`8qE@e(j`e)I4cUyf`!%)hSz2)3FFg>4j&VAJ~824E@p)6(Z#j1fOwX0y&4}3FyDNu0!nqGhjLYfD99!@I zH5rPjw&{6HIph)T9VoFbryFzZxO1%iqsJ{13T;ykd4zKkN}S8Nk~!9|_TJJn;yzKW zZBZd=KaMoXpZBl~-dk4=d4w|sN`lKtW{zz?r(bib&@#ABq#W`H zrx;42%jq7No@0NGdeJhtpQ0S{2 zW{z#on_g`bv7Zi84taz#3rdR1xrRBm-e1|Z>MhIQIW*;vM>yM|q`I7*%&Dd8t3&LL z=PZNozA1-1!ioI?^^eQBmN`~O&Db&VF3X@_MT#1Egfjq2y36UsoO(Jv+YZ0`sAce; zxN^uNoOw_(Tuuse?ELgt>5jve!SYcKd4%%~luVa%9dm5Gw;VHKjAihh3FVMSIQ2?V z|G1pq0Z!cQX)`T@aVn9bMjqkxfs*ZV`UE(KH$C=?WiVcba>yf`N1^1noW9Jl<$P1= zlAA4q+#|7jVF zpMVrK@(5=nlzf-dpE>6!r{%;~BJNwwP!4&7^B$A}my^mI>ksoE&75Ev+%HfLd4yB< zOVmFuX8?0-IX}B}{W!~DzL26u9^njvQsi<5GRKy4!hp23mce(;ltUijJP)PV<=ns= z>sM<(eC3ap!Slh&A&+nlLMd@MgP7Aqm-Cc2R~J|&6pH#v=8HVSxd=+B%NfiZTh2Ro z_4(d1I9@1+Ji^I=Qs#1oFb5|U+*bZ|QAEG`qH@S1oE=cgUCvPE*!rrT`rH|o!Shkd zA&+oc>_GkFa?+S%b$Gk7-p^VF^%GLm$RnJQP%2%{jm)v-{7j9;TPza_O;8SbgtHt< zmCLz_Id;5g-r(!6Eraj5Du+D6IY3Geul^av96K-g``0NEb?@)WA&+nxe2x0Y<=hq$d#Jijk%(3mc-tui9TL#ySl|vrkB<@80<8soOW9#edub1_-48{dT ziW+%@GYLwf%eghcDQL0yV$0yYO68D8I2)iOxtx*AvGb;{>mU8hGN_}JLmuIr@eS%9 zmothvwml!5{NE#%!F?j6sF6oF{h*|{oZFaV{o(kvF%ipov~tKJoLNv(UCwCc*nYbF zM9WOe;5w3W$RnKXP|{q^?aZ-$BeT|l3oV23jg>n13NJi=KBCDY}MWsWVM?;iSOy=8E`P!4&7a{x+~ z%NfUNKqq?aBhc^<8tm~ zPHml@#KT7-j_=czLmuI*gp%uW?qZG|cZN(Hd(blYN}h7aBb;BLCd zTL$BJ?3Vc=k8s*T$#*&9nbSb$tHY^#Beuh{TUkEj5zf_6 zie1iq%xR^|XXH(L*H{Mqj&jH&oM)kwxSac$W9z-m?ycyGB!laa${~+v`=OM&oC(Z1 zN2jOG#ZLigoWGSr9?=r_p#E_=6PaVjo#JQTi>T)ZAVrNl!g&NrxyzZv96RoG7+vQU z%iy~(${~+%wnC|JIavYDtLqmIw+zN_Q4V>86T27nkIR|N96RnzTQ>g_%b-6*iW+%@ zGaO2l%Xxq~c0O2{{p~=@V7VxVJi=K;%GF-|^B{AqPH2=jHe&lJRt|ZD^F5RpmotSq zHa*WC=rYkVs1uY!9^qWL5A~1Bd5AgIKkt8NSj2hdFr=uFM>x}=#JQZQ%(3ZN)$`kk z`)DsIhdjdB1ts3)Jj@)c53gU)KB6D1R1SHBQ+Ge=AD5HO9NXWoTKY>wU3VT*)W{>8 z!B7%i&NSv&zxsW%;m0k5=d6@N9^pI#CCTMH!W^qN(nG&R98U|CLmuIjK}mKwk21%$ zpF7??ufJt*exV%l2&ZK^>K~W$7;|jCI!3>}%Q6_>1}SRf5zfs}QeDn;=Gc5~p78DG zmce$T9P$WfC6qLm^Eh+tK5XX)`kZMQjF+n%@(AY$lysLfgE_Xp_nP=6E=@@W$H4)eoZnaXC*i$BxU7pRs+kWpIBHDQe^qPG2ZFF6Sxc z;9$coJG*$UWpG}h9P$Wf7L;6XyOxWt2l6;WR#s`p4xw6X1N)`*_6p`z1(GBad(fK`C`P^8=hIbuW6@GNI7j z${~+%a-o#DoCN_+xA;!CTL$A$DTh45`3y?A%Xv1yX*_XW#Pyc%l|vrkRR0e3kITsm zaMF6^?6VBsJ4T8cd4zKfluDQLT!8a@{go#y6AIm;9P$V!8%mYSSs38#Zu7x0%iz6! z<&Z}>?~`(kSN}X8;N)L_%}tiUbpYj%M>u~%iE%lL0-OU6kGR@0c;D)XEFba+rxTP| zm$Nv)X??-H8J5BIV&#xWIGIr5T+WgJXH@gC_gDtwVkw6_!dVR^-sLO}a8^8-aHVB% zH%vL?5zbL42`(o;!1-=n$99&%TKQg<4|#-hE|f%<^Fn~r_GsjIJKdB+9^s6DlH_uh zF~|DnSB7=#Z5h!e>l>C5_52YZW z6hbKsC?!ye0?J+}#Q~)fN=ZOD^9LLY0?N5i$^yz2P|5>JDwK+VG8RhZ|1owh;5L?iV)kQ{mER2E)We!h^xMAiu@ zNo1dpvP6#CA@@6xdP1rbX)UA>nZxg-j=MnUJ|eZWXeC z$m2qm5SbxlC6UEK))DzuNFI@bzsmk0Qc1{eA`OJ>C(=$xj=a)}_fIz=g^AoNq$H6E zLdp{PNJuV`Z9=LODX~lT50N@T8W3qGqzRG!LRu0TE2IsP8A3V|Stg`2k?)0cC-Se5 zK19mzmiqr1M4l2dmdNWuCJNYBA*M%X_4GNTZI%RlJ7U!KSat4DNCfj zkX$0|gj6TeOGq6e4-08PWTKEJL>3BZNhD858zO%R=}4s1UfDlH>Ivyi2pLJ_8zEzf{3B!nk?g88NRE7`7vGhC2`NmZ)IYL+h@2{(3?}l4 zkl{qO2^mS`uzzL$5II4}1R`e%nM~vgA=8QU7BZK}2q6oIj2E(m$UGq{iF__(9g$5! z@`(H?A0m&ha`3y6FoWC@WxAuEX-6ta%U@%i)T zQ@@gvi@MS`yhPqz#dRhspjSQb9;(B4-HcPUKP{eTZ}uGJwbsA%lsG6Ed90 z93dl#tP(Po$S*=B5Ghnp_79PYLZ%ZrN61_vR|{D{`Z0Br;vdIwGG6$s@8+$TlLs z3)xNNh$6Coh*T1ib7^w_)E82i$fZI`61h=GSt5gkU?T4d8BS!qkdZ_V2pLP{ z_@c6Zh%^&2naEW_rV|+;WG;~>ge)L3O~?`=D}}5ivQx-9B87{|{vlFH$TlKp3E55L zIwAXs3=@*mI=O#l2q{eDJ0T^B6fZ9Ohe#D6xkMTZsZQh?A$5oh64HRk^Fo>s`9MfZ zBHsyVL!>|n**`?83h7Mb0wLXrbQjWx$o)bF5E&k@LU?F9Rj24nh?EifXG`ymJs*&(D3k$;6WAX4IJ**`=o3Ta8Cu8=lFS_|n& z1LM9WLCuBO2 zZ-mSxazMxeBIS>f{X^s&AuEa8B4izrkwWr_%oMVX$XX%0iTovGKar!4mHi{1l#RcC zKUqj&A{PoNNu-C6vP4D*$tCi-km^L138_P5r;r9jN|crTL!^$7mP9TS(uPQXAsvZ~ z71Ei=dqTPsSuLawksU$?5IOuf**`>16f&I1IYLGf=_F(jBY3G&UEDSS~@3WqB*OD?Ear~reIDkyg50`TKs%= zrjwJiTjzvKG^b`c+2Q|l&g+;{N#|4d0RNDXs7oGSR=?6-c|xeUV(BH!!D! z&iVPRnSW$D^0`Bu6Ee}98A1x%oKX5iNJ%2!3Moruw~$;S1+zM8*o~Ok}E%?nFKk(uc@8Ap?vg*YHiO;o-W5yRZ6vaAv*a zqdn3JUm+9yTmA}i5B|?NQ!yt>$=|wud7qt`PEJl~X@#$liT_ULUt4BE@VHEAwqI4&)gT`+@BXxn8;f~N)q`T37Jgfd?C|`TrFfSk^Vv!5P4k45+aj? ztR%8P$T}il3&|t0Q^+1 z5;B-bb0NctTqk5CkwHSn5*Z_80+F|cOeV5i$aEsRh0G;#bQRe@M9vhlgh&e^D~a4B zWF3*ah2#+#CuAFu*+O;`St?{dk#B_LT#?*AzY8f$q(oKOKSWLvQkKZsLUM_;7gC)_ zPa$=PJS3z6k#Rzr5Sc5aC6U!a+7S6!NJk?1Pm=vZ`0A-jouA!I+1pM~UfNba9})n)$>Ia)|bB4-LIOQe;MTq0eCR3~z`kUB)3 z7Se#oEFn#ZEECd_$ag~85cxw$M<2jWF(Q5LdFvLOUMKw?iWOken-%`{$_IvVVxw5>k>#8zE(h^bwLvZ>i1ZRNfXHAWgNck0GMvbCAtQ;b7BZH| zJ|Po`l&mNFhe%B!(}`RpWG<1xLKYBtQOFV^bA+rU@|BQvM1B*JN2J)9vVVwF6SAAg zc|!IRxmHL{r{w+_Afzynr-YOw@|KXYL_QOeOXNo()rlMuQisU#^=1DMIa5dzB5j1U zB+^qz8zK)0=}6>dA)SeQAf!8y^+Ng(*(qcIk;59u{vlFM$Z#U{gp4F|p^&jet`#zY z$RHt;i99J}I+3YD<`P*dWC4-yge)QQmynf2N;H)HL!_#ZJR)Zc*+!&|kljRj3E5BN zQ6V{3C-=`pA%%&&E2Jcm)k4Y=*()TMNb$2|{}8Drqz;j$LK+ZhC!`6HZbDiTxnD>d zA}sONbnEw(K7wrwUm|q`8nhBG(AnMx>vR-9#Q0vY*H+LUQD9 ziiw}U<_jrI%Er~oKqz#eD zLOK%pSV(6g8-;Wy@`sQB9980VC2+(T?h25 za%->fe(f|_`U3g7=sU4ZrtIn~f1jiLzf*7QdPDziRpi}X`R}A5^Pb?N!vB@8X$1<( zKa+E2AX5u}D*q*+tByU!&zXr#N11bk=4QA#vyiDOe=a*C=YpZP_4ae#MkZJ06xKPj z+??6SRM9!3?rPB4&w0nqneFDxL8h|Ik$=gVxU$bfe$HHEzLG!B9M2p#XC5+-NT!(l z@4I$a{f~8i7n!r=yfQyen&;-s&tlGd$ef>;GvCd59~t@ZTTb}7%bf!^$=~}V1-kAZ zAQRR(bG_bob3V-CcoraYN#b}ubaNIWQ(2Bc{^dW``6FcVY} ziSt_I<}60$7IB52ea?OSpj^8DzdoNJQ(bVlrr~R`oAW6$mF3UmU;g8~mLQWSf1Ww7 zPu-lQ$lNHdN|HPH)+zG$BmMv5`3xEP)!dx&k_lf+-JE5}RF*%JfBBE&`5c*V<gwnYGf*> z9?w_E+=gT z$;XWyZq80*(w|R%MJD+?xYNzqg-rVT>_#TJKD*qUJ;)omiheZq8n0()aW4 z$RzjkUN>hSGL_{z$iMu@2vZUlYE_-@38;>I=lcf>G#E9$RzKJ0&Y%0WYX8? zaAbzCPwh1{GXSCnY_fDB5qDmWYW*87&6JnpQ3I~ z@hpy~1Tx_9MJ9d!ltm`FKF7K_$03t`UdJPoyf2P( zbIN5gr#vz(<-9ZB$CYz)Dj<`-4^KcQd4E-Kb1G(WJh{kRk~p4WBF z+)(Z#f4xpb=3~j6imN5xi?}(JvpAkA$TUeDPh~f!Dl+NM7bhW;d|s~V=2Sx_eVwZ# zlYE@7=H}EuCVd~Cj7;+JxrUol6B&8yC+AFA!|M0{A`hLi5cE3g6l6w9=44&xnr==l zWO~X!!y0Y+Y}8CY=Tu~x$UiUDIknuJ+Q@`QsxFc_{@89i{G2+-gjYc=bxv(Jr!F$- z>wFqA$#t&l=A4d9`gK18ndJA~r@J}zkV(H@XCjj)=ahMTuIJ{|&tgskH>bXv(-4`Z z;tKDf9asB?)BHN0g-k!$4w?7a8oD`+kV#+Xvyn+Ye>HM*8Y7ebI`bT4lCLuxyE*3~ zlYU-d2NuY8OX9rFb#s~`lYU<3A(PxcP2HSk$fRHQ^N~qDUo>-bnj;hLvYX_3z4X%d zoBj2=0GaS=;UdX|ujXz}3uMy2uWX6T1X-WV_mwT&oC}djKd+0B`B9D|v!5??b1p_E zeVs2sCb@quc5_-GlYTsxB9oUmo>p#7Yh=>*Pa9+gB=%2hH>YhD$8#An$=Bg+-JEvF zq(2W{j?8MA}nRKt; z&sQNMAF#+dQ8MA{N;jtyGVKcGmYu0`fY znULAf*SI;?A(Ot&osmhtPja1`b3HOkN!t^T}jKxVl7^YZAla;|rCx*(H& zUN<7MEpc95+?=k+q(5%lgiP{rqpO?K4Vm=&t2;8u`>UIq(*v3G^ST+CCG8vghDQN574TlW0XdcAISb9y6_zJK~4lYHLk?dIHuO!|4< zj!g2rZgX?`W-+H9GI@#p)7Q=Ek4*Y`-GNNwaXC?~e^}bA}?5e!U(*CV9Pvx;YOblYYG(LMC~=9&~etA(Orj!y{^eeC1{T9HIB= zFgIsJ7RU22GRf~NN4PnUAk$o2Cy1-%`eFa$=gW^G^Oa+>`+pC{Jm zDK}>{GB--5l6e02&nurn<`>D7$I-}tq0Y@2gUl#-z45MOE@|@XUH-hrA~RiHZ``kQ z#<)4pB9nf9J%>#4{(9EUc^;W5^3U7Fb@CPYulL9E0y5!I=rTQ?=iQuf$fU3Hi^!~$ z^~vnRac<6dWYXUcpMcEOa@{lUhmUu2UP31QaqMMel8<9AxjC;OlfKTcB9mO_SKOS5 z$fQ61yoOBjexK;(OhP98b?;;t`zurcstYkXtoLO$pY-G}}*E`50uh(ohXAUyy=QS6ZCWt|7=6%7FnCj&mFe9Iopv*e?RJHWL}jynfI}`yE!|M zNq=4U3o^-{pYCvTb|RC0U;K(p@_ygx=IlZyeIM>dCVAa=xjB2XIG*2-Nxl!c$IaQB z#hl-fNuJkUH)kI*>5o5uAk!xC__NQ=`4gG+pI7cjCi(NqKi!-I$fU3HU&tiy_XBRu z-&xH02bmue_vznm&Ou~OkjISECAaGRDntF_#=pqiEt%?)310`@oI}W@KOW}DE7bz| zlCSFyxjFfeN#D=;kxA~Kd<6y3=kUV^iwfkcB}et&Ker0<0{Mzb<|3Sx{69A*fCBl_ zAIAd%=f1S-JC+mq+j>K$Rr=f3b{E&vY2xOGRgf@#LX$1#hhYpPEj|fI5O$i zy#zAJ=fUD`&XLHZU-y#8B=7el-JDX$gzxbi$~9ekeAj+{KOcq6tCBfIuX`ysr!+F@ z*Xw9xlIvXB%_)OS`gt9LO!D<%88_$HEarso1PkO#uFtV<&T(1HIo=)5ac)kzEasF) zCi!}-oSRbtne=r&0hwRqT4i2uRB&@DB9p!kbCIbd_h~V`?iJmfO30)?FQ14^^8J=d zZcb%n(qC^>L8gx!Pv-STWjCiPGU@y0BxI7;y{em24Vmry%oVVopsrr&bnoPDLhpUbWnu+Q_6|_d3X&FV`#cdA8baPF-Zu_u*;C zBp(m!x;dvKlYZULKqh&Ao$lt;Lni(C{Y+#AB%a^vxjFTb*(TTGzkkly0GYwEKAE30 z)^~FnB9p!k&q5~oJlN39X@pGr`kakS^1f)~<}^ko{d%2)O!9G~v72))GU?~l1exT1 zKG)4@icI=>org^F^-ohbrx`No=XE|ZXCxjEo4Gm7vpAj$kV&p{b2q02GU@Bn5}D+E z+QQAb5SjGzx(J!%{dJ+6b8!~Oa|trZ>vgf4(<+NOmm>33;&H5%o6|arIc<i{rT*nY_e#wR3aYBa{9-cm*I}-JA|t%<1UnbZ~R7 zL?(S7UWH8Zx?kz$bjsp*u6D=M$<4VYi{rT#ndEi9#?847ne@kv&d4O6FRpWQu16;Q zasCEm9!)&XU+?C0K_>luk{gkELFQ!MC+XtmbVVlpe!mHsQxcD3UEQ2+$lNHIO0r-7 z_s?OwBlC-7%1b7Eb#rriAX8QT89vi>+TbsC`tL7pMkc&_d=;kTHon{z8N>DRp%GRep1Tiu-A$fVyFeUM2$KKFKWZp&iM?QYI(Zcg7U=JZ1*Pu4i| zeL-J0r+*f6?r_J`-_5xbne@l80mvjD$L@4<1|pMwz3xIL`TgKPH)jws>G#*&$h<21 zIdgvva&zuMCjGqbMJ9P(_qaLtA(MVygON$TZn@9R8Ir}E`;p0&^UC~Oc!--b6q)q< z>j7kvuM>v4IS(R}{(SlnGRf};A9QnuA(Q?-(r{#w?}ra_b4DPOzRnLLlf2(YxH*p? zlYYNHicIo(@DVrXF=W!u>v3d0mg|*yf9x?g=ZP$iXQVrxC)}J-$fRGdCy`11-qt8L z=P6{;-#305nakz8GC#L^%FP*#O#1bD2ASmjKHAM0gG~DM8jDQw@p+7!^DHud%J+IL z<#F@qOB&qmpTC|%rhI|ucXPs1*t2fV^T?#1*9*ub&+Blc{yug2KlFQ}pCL0{a9R12@U_&EADZfy~`D_g8Hbg0nBafVP;+*)^~FnW-;e1WRlOz4c(kZ z$fVyFXCsrm?v31>#>k{UpPqwE^7*u}n{#d!bDAKNd_Fzb&1s5E`u;f&ndJUy>gF^< zCjGjfk4*A$zL}fT9GUd@TP{Fmu3Y!B(KgI!?&h>WCjEM~L?-#ZUkf+q!Yt-ogiP{2 zz0l3M7@73%<1Rtwd^xYo=lw2rb6O#jzRs5-lYCrl<>s_TCVhR{AoIJdapv)`wVTs6 zi#eAelU$#+ZcaO7(%0v5WSS(_r=6SA9+~w0d<8Nu$ehg2soT3b9kMu{j_!CmxH(rM zlYYIfLMHimc%_@u37Pckbu}`{{oKjTxh9J_*CLaA9J|KNxel51^XiOD@_xV0&AA?# z@HdUieZbYWMJb&ftoGxxoS7g%H z`6gtN>(kZE>4r@D`gBJoxjx<8oE}*m&&|lJlyl15r#;-9o>|Pf1)1b|^>lM?MJD~c zdLffMuUp-m-dW7)gG@2m4w=`7z1^JKvY2zbn{%6+(-)ca$De-4B;RN2>*n-FCVl_h zflOZFdi8g6?nEYiod+P3T<1I8oPk-)xeJ-(IuCSn24yklZg)I`+?;!mNq_xwFEZWb zx@X>xy2s7AFN@waXC&tF5_oS|79&jZLL*LkR$^I#Uo^N>59 z2i=@u$fW;VcsMc-$m3ykeLNiI=8VYVcpi4gGs4YzB#SwZB9naldBn|m44L%zTOLOy zPxeoFJ+H^yoF|Y;zu!k9bBWB!ydHbP%^8JE`u=$mndEtma&w+SCjEYY8kyw%{*;?D zI*U2aAd}pOqurb_$fTdwSY(ptHO9?(7Mb*Qeh!%iiFJO~&3QhH<9Pv@fkV#(miEhp$WYS-UPevyBI((9wGbM}TdEFh)6gTG$WYX99O=Obm z{Dzw|6`Anc{R8Bhjh^}AUjKUaEo8#qj&+4T{!DdqrXiDlUra|Pd0$L(b7mlu{`1qB z$RvM$I>XJGg-rOw$YXNMcYgBF{rt&rCjEWdcaWJN&pVm-X=l4R zbC9{LXim+=~h$@N+4<}Ax%&gaM^A6J*T zIm?kre}C)?Wai3wmDP1#?&hpOCVib(BGW|XWM2QQaC256lfFJ*B9lC?Rc_AeEarTL zOrD%mW*@G0bJie}{`~$mGRgN_*0?!qkxAdr>ySzA=e2ImdSue~;Wx-sN$kV*Zq9}* z=6s7x^~9VFZq7zz(y#k>$ef?J?i<~lO~|BQ_dH~h*K3oTvl*H6>-9Y{$?LV*&G`YD z^y~E_GRf=pgPXGjne^-R6Eex`wZ+ZZicI=>Z9^vcI&-U=vptJBKO<9Cu2<%LlI?EJ z4rJ1=`!C2OA6Iv{IXjU_|M}^!$n2Nn$^86ur<=1Yi{sgiO!EDfU2e{vEav=%O!9GT zkDIeMi#g%hzd*j^oV{+&K4j8g_x^!Q@^$Y%H|I}e((kYR$RyvF_|wffkj0$8kV!s1 zA8>R2Mkf9K`UjcI<+^8{-~V=V4kD9&fBlP0^8PyL<{UyM{dHZAd@79p`xl4YoP5Zn z->3PJNk0DME95@^gG~DR9EMDCeG0fa1(8WVufvhKMb9O>qiLgoye)9AMLHT|5U zkaWf*^4IC%t4;go<sp2VDE-JIi)=@E^|*;8@MK0oJpWImTU zM{DjlH>Vsj_v)WdELv`%pHm*0b%{CU+?)!?WZ(;d+MlXV(n)+0Uth%r^P+%$&+@PE|V|xqWhGjcW5hzCS$)necoeONg(kZca61 z-g`m*yJm8y&shJFJT(6Q^Qw+am4Wg5wAI|48pwp74F=b$qFtW!b52I4Wa56W;pWst zrq&ViKARlIs<*$EACvz7<2ePHCL)rHfUlZvPAy~(%A5s~IK9$4SNb`pBJ;LnGLM_J zFei+hcurW?=qviSc|^M1()G>@d-doS5>*T3;=jh8le0`S)r@RVQpw0KN-7#Tq@=Qu z;^+QLOFR8=zD$T>>p80ny7o{>IE<{KHIRk%a3cj$jC`b78_}yYj_ zMg}QaYh=8V^+rBWvcbsDN;VoPb$))>HyJri$z~%LEBV35ZA!Knc|plmBMX#lH?mI2 z4kHJY>@@m_;$zCJRDA{LZzLGzU(;KN*Q@nNogam zD=A}Sg_2{9>{N1`ky0(A<0)t4Y$X+pbW&2$$S@_9jJ%w(?~ldwT$#vQrpPmO6nS!rQ~!YYn0S8^0$)uMozpaI-Z6`E>P0QNOvWTjSN?E zu8~)jG&QnRNi!oqDQRxxu!|#m3nNvPTxjG{B^Mj%qokFQXOy%y@}ZKpMm8&HXXK!g z_C_j(56sF}2P5Yyxzb2yC7q0nP;!lt8A`4*@{N+~jr^sgi;?QBB70XO7c1#zq`#6L zMxIvE)5zOOZZ-0mlHNvkDY?x^$x9=9UnBLE^fz*ik~@vuuVkQ+NlFG8S)$|~Bm0!x zXQXuN$UekK9VJ7Jv{&+=k-L-(GcsAp2qT{nvyX_K2h?lku6G|H&Uu?WFKdwu9ERaS}A$SNKYlN7&nPg;{k|{=h zRq}?BVwXk7Gu6ncN~RfUr(}ka`;^QwGG57SBOfW5V`Q_Ec}5Dfi|q4_DcNk~DJ4G`nWtonk+n*;8u>%Xb|dAl zh>mB6krqmJ8tJBFmyt)6>@hN1$zCI0E7@mckCH!)9Ni(ZA24#JlD~~yr{tiKp-K)J znW!XR!OZKQe%}8@4eU0=~(%;DAO71lBmXd)+)+iZd91tIkx@$CH}a;E z4~?u)ve3vcN){O@+BLE-Hd0;5r$#PPveZadCCiLFtYo>72})KNS*B!_kzbUoHd6ei z=y=u`si$PEk(-pPH!@tw1|zR2*=S^ul1)Z7DcNk~FC{-1Dc3DJo-IaNDA{VHhm!3^ z9#pc!$P^_zjVx8N%g7!jdyJIq9@+OAsjFn4kxP~QX{4u;14c$D`P;}FN)8(NRLLPD zKP$;+?^TxQ5gktfBej(jG}2Z{AtU{i6frVJNl_!Sl@vF!M#+&z4k#&Qr2Ng%@su{w zL`fMV*D5*I$URDqGcrL*IU}DdsbJ)Ql8Q#k_KfV6jGU>YvXS;msv5aNNi`#*l+-Zt zu9BKYHYurP+&yl{7YT_^pxs zTq7qcX=8PZwk^V~B8F@xY zdn2=zbTG0;$(2U_QPRoC>Aj=lxyHy9O0F|9K*{w+#w+P!L+l;)Zq_2_pmGn3Ay^=eP9CllDJOhp7Dj8(tJSF!Sxk|}> zM*1rmV&rKhLygQ(@}Q9wN`@KvN682yWp9s;@DU?tDS6DuWlEkfGDOKJBQGg=%E(7b zMjQD~$rvL!eIxs`MvhbRyphIA#u>Rv$#^4!mAqtRoRU|J%v3Vb$d^hc8QHC5ijmU& zq9c66$Z1NZ8o5ZxQX^fJ%qWogetD3RX+}mVnQdf>l37L;Dk*9|4P2?Dh>`D=R50?J zl4W*0rTgc{cU#Mi)Kjv;NP8u#jNGAQwUOtPtTFO|lC?(GDOqpiPbC|Sl)WQ5o{dJ% zQL@R%4N5i}c}U3*MkXlPV&p?5TaA3DWV?~W?~Lp_jGUlkr;!Fqb{XlQWRH=7O7@L2^RbsN?_1E^YtSf)~j)X$)r8B+IjMYW8`2T|}< z1LV{JH(uZG`iRsPQXpUE(;TZBE(Q$dKzaa!uG&cS_tUGBCPc$dK!FcV5vaUV4046@idzk}g$%jsIalDtBbafAy<90a%FN@`G2qK zejsl3(-t!1YCx_71Kv3^ZVl5GGURHA*3s&kShd#pxb>X2kRjJuS^IycRsoFw@ zT#e95?v3~pFAKDV47tuG*P3fjSP-|?YYQ22HAXA5=UoG6-gj@K3RkVc+xtdrjT;)ms`UPr-%%*IHZ1kn22a1=q;=udaw&UA2V_xtgJsS;M6_jOrDAQZBge(iSr0I-gvv z&+T+Z+#0DZWXRPVt;{|=t@rIy(OW1mWW%Ow1o`0S~*wr+k(M0NL$E| z>r!&fUb5+oxb=dzkRexV=Zb!#Fu2~+7Bb{&L#~nCU#uRtHfjqQa!7xf zA=hQ(n(*f_qvO^IcSlzl8FICAuIM)tgX*SIx7TgZ^BgL6f{;TT*Cw1o`0I+E+*+Iz~ztT5`?qdf?8u^{TdzA=h=}3XdDnZ(Ih~$J#=MT%E~v{@;%^id$Q> zg$%i_cdqESGJ~t&z0vhThFmw0D?CQUt&_Bc47s{ESM-~k!F7SQkRjKNGUVzuz#|y%DztYYQ22-9xT$UMtKsNn6N}>t1q& z^NL#=w1o`0?ju(?uT|zMF*I63WXLs`T;aUpR#R;uL#`p@3g@-jTz$2L47u(nS2(Y@ zHC|iDkZY)OtufbU+Cqk04>(ucI;bsV$n_w(!WynMSM3L)HAIG750NX}%W-2YG?}?ay?0|a4*NL4%$M7Tu(XI7IQtIEo8{`v~$I+ zIod*oT%(<9tGTvo3mI}fL#}Xt#jP^KqBTT@Tw|PTySbWZ3mI~aCD&Ky)N2#BI%^9V zay{!@JIr;TwvZv$bL0xwD{f8J7Bb{|-nn*~Yo)f3A=eA!3a{DX)*)>nL#}bowaZ+! zhDR%p47pw;SGZnrtCO~nA=h~4+GDQa+Cqk06UY^=SKNAETgZ^>CFj~}u07g9hFmX` zD?Dz*t@0zH)j)<^uaGM|_U<#+1=>P}T(6QVJod(|zS=^DToaw^Pjije7Bb{|&AH;% z=h{MsT$9KZ9(xa%YrnRTA=hMbg}o8CDn1;oAu{Be;#_~5tGTw2A=m5Vx~%xwgX30j zZ6QOhH=OIBxyEV>8FIZzu5d5Mt;O0xhFnw0752sYev)({zT zO>?e%hh@GuZ=x+^$Ti)$;?@n?LWW#3$QAZR0do!27Bb|TNv`l16}P5q3mJ0Fa;}2r z`c_-Wkn3%7h3gf!3OpLEAu{BeO|Edg3Yn{hwvZv$JLC%2D{i&c7Bb|T<6K3|)lXZ< zkZZ1U#jOe2LWW%P$Q7$7Ogxo zVGZL}Yi%JzuJ@hmNOKL<7Bb}ez`5eqWNjfst`D87l(|0F7Bb{o;9PNQx3-WW*FtiI z>s8uZr5}&h5E*iPM6Pgu#jS?gLWW$6oU4qvuGJPYQ*wnhJkDJCpNQ5F8FDQlS6IWib*i?IA=gspDrc@M zwS^41K69?P^{BRxA=fhJs$i}Uw1o`0J||bWm*dtJZ6QOh<<3>nTt!DlYlsZFz93gv z!?<;>wvZv$3g@b1uG_VR47pa4Yu5`CZ;D$lY6}^1t#Yo)=31&PWXSa;xx#tHt-abp zhFq(itE#!mkBZh18FGC^uJAf4Zne}FGUQt0T-D6gS6j%C>uYj_y%D!w))q44T1&2Q zFV`^FN^K!Su65)J_j26&O=y&$*5lejhFlw+tG2o3XbTx~eMhcJXD;3xx7KM38FFoMuDa&h zuPtQAl}E0yH{w>+r=pcdhFqJS>vVIq)fO`3`kq{2&&RDn+Cqk0KaeZz!+Pd=Ra?lA z>ql~heHgdC)D|-2+TvXG&2>my$dKzN=ZagWJ{_$gGUVDyuCV7Dn(Jz9Aw#Zh``bJyGkZV7=!Wzb{qGO^pM21`k$Q9P`Vskap z7Bb}ei(FxE#I3H{LWW#_lPjE8D|0=rEo8{`54pm5#jW?Wg$%h4k}I57YjbVa7Bb}e zmt5igid)Bzjn)tuavdU9IIp(mx=35dkSqN4ZUypXKHnS8D{l4E7Bb`tA0v)GOB~Lt zow>$o3mJ0dCs%ka8n+f|3mI}1aIW^|`cYfRkn1pVg}o8CN<15_Au{ADNUpGk9n4i< zTgZ^>aB_t;j9b@f3mI}1B3D?$E6w$gwvZuLVRBWtWKhYtHBDQ{kgJGubu!mlZ6QOh zBgpl}XC+RETZNyC)({zT6(v_#!)wgdKwHR=s~EY$8pf^e+Cqk0#mN=c@H%si(H1h~ zDnYKWH{#Y3Z6QOhBc1DdbM4m_GUO^ru2BPuT@$x*pO4lM8FG~(S6IU?=4zoWWXN?C zxxyO8t$VbE47o~^E39ExbIsHiGUPg%T;Vw-Zf(>SGUO`bT;0r7=!IxCkRjJG!$dKze=jv&$Iod*oT*o_C+}flqWXM&H zT;Y1%YOce_MQex*xyq9({G2FmRnZnQ1agJ@D{l4D7Bb|jNUm_b zZZp?&+Cqk0x#SAhD{d{)7Bb|j5$aNOE z8h?7kr*Z2%Z6QOhM$Yw^x%y}e8FHOXu5ey)Yn--_Ay;GPdcs^wwS^41&LLMguekMx zwvZv$xz07pTqnK~tsyexYC^8ZMl2c>x7un88FDpsuBXg(pSF-8*Lma$=M}dmY6}^1 zHFK`f=K4%q$dK!Na)r<7#jX9?LWW$;ookG_s=gYnAu{B;fLxm&e(a>U)k<5)kgJ7r zJ!`Ih+Cqk0Ey)!g598MJ+Cqk07dqGT=31yNWXN?9x!zvas%hNXr!8d2b+L1eGgtMA z(HbH{u1m-j_D0-lqb+2})ylcXo9j+(Aw#Z9$rV1A61Se$7Bb{&O|I}<`I5Ol&=xY} zYD2E@Tp721)D|-2YD=#0T=|N*io6!BAu{B;j9g)F#H~8oLWW%JoNJ=FuFw`TrQfo>$TKeb+m;HxdxCcT(7uw zg|?6(*FbWGHC$${LE1uwTz8QxtYO@GMO(;_Ymjp-H`iy{LWW#-J6GH~peDuCRu2>n?2}L#|=YwccDWY6}^14R@}%wMbjYkZXixx(IvTi0j{8FD>FuCO;YnQNG~kRjLOz=a9*3um8UIa$TgB&;k@Ej@#)bTB15iGZ6QOhXUG+P{uQ?lpAoGg zGUOWLT-(icinfp;*I06epX;WHI7_iZ|pKxBW)o=t{2G__D0<5t}SH9HJ)5yZ|pJG z)7nCYTocF@&MR&$))q44dda!=nrol7kRjL0&K0*#m=&!dGUR&2x%Qds0&O8fu2;zw zp1#^|!fB*A_D5dfmC=){WXihFouuE9}FA=6YIN$dKzza@9HQt$*Xz0&O8f zuBpy-$Xq+Lg$%jgB3F1`j$37BM{9@-xu!W+zJi(G|2juo$dGF~xx)Pww|Z#{8FI~V zt^(#7r!8d2HIrQ7Gl6mIBW)o=u364i&|E)h3mI~~O|I}<8MlhO6RjaKw0Y=L#_|V7504GdPG~u zkn2O|DrK&>wS^417LY6aooR7vgSL<%*FtiIeOTID`Q}Dzhzz+tB3IalajT}bkRjJ1 za)s+v#$16wVYgGZ&Wl_>35?wM21{nkSpBFajTiOkRjI!=c;6`+qH!ZxmJ=ZyvB}OFK7!H za;2j{A1 zuD7&>47q+JS9m=ix7KP48FFoLuKMOWq%CB~^%J?m=f2|Bi62BOj|{oCk}KTH4b64F zwvZv$Hgbh~Id0voEo8{Gom^obHZs=}+Cqk0Ka(q5uedc=TgZ@WhjTSHSDvovXRIdT9$8a{W%Oa9(li8Eqj$ zu6^VR*QKe@sh#;r57g$%h4 zkSm($m=7ikL_a^)0B{{B~Zu8dm)w1o`0@}VU{e1+@P&Ri3< zg$%j!lPg@Wxb>B`kRewAa)tA1Z?61{qSZi#T!)b>ycUgHHMNBdxe7X02XnR47Bb{I z+_~b`AZ;N-u0rGrYj~x(Ue*>e-cAy-Lqh1WK5>!`)i$|FOrQqI-IT#dDb47rXXSNPdY-0Gq&WXM(8 zxw@KbxVDfX*U{t(kMnVBwziNVR~hH(X0FZJLWW$&kSlzaIBu2rBw9mc$aSo9^)T02 z+Cqk0Wyv+V*;_xvt?RXg47rYTuAb%^rY&U1bv(Jk8pf>|+Cqk0<(%tQbA6*NWXM&X zTw%}0t%9FMYlsZFDv&GO%e~E2TU*GG>jZLzdpT}hr7dL0RnfU_GuH#!LWW$q&K0+& zY6}^1RdTMr=31jIWXN@*bH%L!OQJPIhFq1MtG~JGXbTx~RdKGk)k#~(kgF=W!sFqc z=6X#AuryjjWXM&+xdxf5uC|aN z*U97xkB4#V8f_s%uA0tukGY0x3mI~qLawleacicwkRews=eo~a8?=QCxlSclSi`tg z^s{IUks()Y=Ne+Jv$TZ_x#~Dq+`3&`$dIe9a}71u6m20xuG7dB9uMQzN^K!SuG5|C zL390~Eo8`b2D!rP-ndn1S+s`8kgJ|^4Kvrp+Cqk0XOb)YtSxR0&=xY}s_$GQ%=N0a zkRewCa)rGSw^nEi8FDowS9qL%#9Rlog$%jQB3F2vk6R~y9<3oVG_!47r++ zE9}F#RepK2hRBessdGJLu5-1847tuDSNKdt+`36y$dIdV&@uXuCKL)47n~LS9t!4TmNbc8FIC9 zuJPuox*}S6WXN?Xxx(Xo+-j#SWXRRpxn45YU~M5ot~SmUwoRhM>lL>SXbTx~wIf&9^ApW=;>u_Zks;URQSAw#Y! z$Q8~jZY|LkGUV#uTvN>TkG7B@S4ZcHTlH5(tAPx;u5_+9%ypZ#kRjJq zI&y`*F~eMUX$u*0btYH%IZ@miuPtQAb-i=VGS?z)Aw#Yk$Q9NwZvCn)WXRQpTwx7o zo2%^VXbq7e*Nx-~YZ$lA*A_D5>grr`%+*_4$dKzM=Zae|YYQ22b#tzH=K4xo$dIeM zbH%OFUq!2d47qwZ*L-ue)fO`3y4ktnR)1|FL$03A^}e~rY6}^1-QrwvYreLSA=jvnR5`zvm}tSw~7)t6l1ycU~liMEg-S3h!v^NL$LwS^41`jac1*Qe$x z^>wuJ$dKy}a)sBuajTKGkRjKd&b8EBH);zRat$C?*Ur73ja$RCg$%g{I@dCDP0l|$%L#`3z3VUONxw>f!8FD>LuJC*GaqBT{Aw#Z5oNJ@GW@-x= zay{x?acix%kRjJ&&b7&0e`^aFay?G2@Hz9iRq>l><&h!R6VA2ST<2*E8FGyzSNLx| z$E~i~LWW$U$QACdAIvpOTgZ^>Np{Ko6}P5q3mI}f3LwN6{ekn3sZid)4tL~Do) zxki&K?8B|*I#*lBkn0(8g~zD4)k9mzkZX){Z8z7G+Cqk0W62fXkBVFGXbTx~J?mUM z%(Y%y$dKzfa)tAXTLr(3)({zTJ?~sQ%~eNR$dKy=a)sxwxYbcx$dGHCbL}$MecD2X zTrZLvC-&L#|hxYoEF9))q44deyn&)=Sz#hFlZL6&^SKG}mHnAw#a$$Q7QK*Na8D{c+d7Bb{| zgIr+^51Q*uZ6QOhH^~*&FmA2X7Bb|TO0KYmhs?ECTgZ^>EpmnTZQ|Amo1&FRhFsH} zE8pRn-~VcgkRjKH&Q;1>-)RdOaxEZN_-s$yD)N1_hRBd> zp>vfs*Xi0qhFl+!E4&7XTi0m|8FDRht}^C&SX;=D>tk|-pI64M>DoeuT#LyS_QtX1 zTB9vw$n^=i!rq8m|7Z&ta(zm!us4n~*NHzwD~}AhmXIqvZp5ut+Cqk0OP#Bnx$e{! zGUWPEw9voIdxLixb>{IkRjI(&Q;G`A8QL4a{WlIu;=5}Zfzk$ zt}V`0-(2OkMQex*xqc#7c-IZ@oYMO(;_YahA7K5SvG(b__WTz`-&?8CUVT3g7F z>rdyp&|D>VM5}=ex%N9(+&WWR$dKy*xx${m*j$~og$%j=B3F2?GHwmm7Bb}e+qqhq z>uqfzL#}_w74}BlTB|K&$aRoh;d-?;*8y!IL#}_x6|Ps@YV=FA^2m_ukaM*)*WKDe zhFm#EB!B-axZ>7J+Cqk0`OwPz{#UqO?aZ}UTgZ?rKe@v7id(;G3mI}1aIW^|I%a3I z8px3AFmi>*jkwiVTgZ^BpmTLFR~Ky|L$1Tg70xSeJ)$jS$W_R>t~A$7Z6QOh!sH73 zFm7$u7Bb{2Lawk6JDKaqU!yfdhFnLGE9{N9b*Z+HAy-l7y2f0OY6}^16?3k*HAh>> zkgGVk!alstT${Cp47o~>E39GMD!MCL4P?l5q;p+wt~0cS47o~@YsfA8>c_1v+Cqk0 zrJSpaxkhOV8FC#(uJArv+*+V5WXM&TTw!l?HP^4&LWW#NlPm0vxOL3#Xbq7eR~d4J z>($L%jkSdgxsD-MxL$FqyS9)a*RkXZ=heepPihMpa+M`lIIp-hLtDs@>p17?X|5I8 zLWW$&J6GKLQ(MT8s~ow)8s2KI6ZS+aj|{oWlPj!Y+-jjMWXM&)xq6$cx3-WW*9p!Q zx1P}!GUTf0T(_C)J#8UFu3YDeTig$%iBIoEyWTCXi+$aN~Y!u5(<|7Z&ta@8hR*oQ;Rb;9q_^+JYRb;uR=Vccr2 zEo8`5mt0{V4mDR#Z6QOh)5sOhD{hU{7Bb{Iom}C(9yHh6+Cqk0XOJtLSKRtWTgZ^B z9=XDK4KvpvZ6QOhGszV`BOSNS*cYulGUTdHu5ex>%++06$dIc6xx#tHtw*(m47nOQ z*CXbdrY&U1b(V9*t@YYMhFp!v71r=EbLIadS`B2#bvC)e&xzvJiP}PjT#cRU33D~o z7Bb{Ihg{)tK5h-r7Bb{Imt5g`jWX9;+Cqk0O~@6lSKRtqTgZ^BDY?QLK4q?h+Cqk0 z=lvg9cNtzqx@-YBxVyW%y9Rd%9&B*8;1Jvb4DJ@(-JReB4-N-saCdh&yQ-^Fy&m=t z?%eaNcUJG}uQiz&=%VAxRK_pPuMi)Lu*fGEyDS4HTe83u-SJr%_n=&A%=v^Gpd`RdG&GtgBTy6Ah&4eiPz ziZjqv1-j^aner9I8R)7CUG%-?hjtAW#Tn?T23@o^Of4718R+u)t7~Cs*GW;Ffv)P% zMb}DGUqo>Rx@!E@wK%jZ{WoXwoPn;I&_zGyZl6P2D)nh)n#g| zD9%7v9q6L9u{^YEg(%KIS6%3$wPEV4D9%8aFLcq`SQ*;&Nfc+Gs~&XGyA)H&zB`lW z40P3pF8W@pL%T|e;tX^(fG+x8raFn@40JVwF8W?;L%U{(;tX^(f-YJcruK^B40QeT zSJ(Q`uKS`m16_@wt5f7ggG`0};mnXT(A5OGXoe?4yV8i_40JVxE}EgKa-ui`UCp42 zX1Fn&{(e+jQJjIU=Frt(W$UJEN~6lb8T z)n8p(L%Z&Z;tX`PhOWGwXKps-_0!p3oPn-3p^E;+Sa-J_UX~(~&M=iI&Ole&P!-Oj z8hjWZXsVDX&Olc?R`ET8)XA4YrA$>9#Tn>o4_(hERt;mSohZ&gR|n_{*CldMQ$s~@ z2D&;z*R$&@5}67V#Tn@81YL(-wY_C(izv=OS7+$z)uqlSQz4=_16_WsV#^F8H%GJ-Z0f&6lb8TCv?$y<4kB*peW8jS1;(IpMRMO7R4Fp>it*O zxzMhcqBsLxeV~i(*-XX%?M$9C(B%(ZG{Xy_UByIk2Dvm{YGCucvd2t51MnD&>c~g}|aR$0ZLKm(1JE2{DL~#bXMnM;?c~eV7 zaR$2ng)Ul$_d>hQh~f-%jfO5-ho-)X;tX_+`K#+eXjl3$bp7=5;tX_+g)Ul$rYeZy z40MhAtLsr{S36Ohfv)k;MeESiL{Xf9t_gp2JqhjFCWs4siLQ$N7 zuIbQ4zgKDMkSNYT*Nnfq-h_7D7sVOqnh9O>y-Y<3=S-e6&^7C?u6LnbxkPaWx@P~? zWvZbl&Ole-UtJ$UyM~M640O%;tIO1SQJjIUxqo$i3hlZoiZjqP54z|X*3=JCoPnv@1dcXNH`Cu4T|g=R;H3MR5kYmjBiDC$y`! zD9%9F3h1KuQKtHc;tX`H{HrTW=(Ap+D9%9FD(Iqfuc@P=I0Id)|LO`C+VxfxXP|2h zbkY7Yl_;V!dCoxB+P}IYgm!t0;tX`HgD#q(saB#m16}L?>WUQFHChyBpliclU8XjQ z;*3|$)-8Iq;H$fr*G5*8i+Xw0h$R10=>PejD9-Tz`rPxsY--{>TRW5bxx8B5mXL=H+Pp@4AJ->G&uAiydq9}vvI4hmu&C-cI%U@UT0a27e zbppEl&J1pE>X9hQpgIX%@dw=YoNKi!dNgN-ltFb0y82vQ(#lj`QItUy0$nqcyvSv$ zp(x6rIt^Wk!)0u4YKSPxpgIFx4I}hiWom^e%Ah(6T^Y*t?_}z9Q3lm{=n7~V(%)2)=+5LRgX#iwrHhj)xv5g3D1+)Ebj910@}{Y_q9}vv5_B!@ znI)&G38E;2>N0c_ERf)NdQ;CuQ3lm}=o)x;tm|$$ZX9RwltJ|Yy8i9ZF12+P5k(nPAEE2_ z@Vx=1T8N?ys!!1MY~O=)rbdgR464u2m1jZv@TNA2q714p&~^Fyfy}0^ilPjvuh8|p zb(C$U{)nOss&CNM<5tWfrZUELCQlhu-$Bjr&*53fdPh`U6lGBTV3k15Hm9e@`(~<- zD9WJv30+M$Tz_k7p(x6r`UPD%22}WD>ZmBnp!yA6BkO)FW$Lvk%AooKUE`X3d1xwO zJZFZKLFE;V{uwcSuFMntgXRQLn!E1McG ziZZCeL6_g3Rbx$U5JeeO;i0Qzrl)4F^`Q3h2M=(_f$@orQ8q9}tZDs;8D zcKMyD*`g?eDjIY(n$dBbsUT65K^2{qu8mmHYrZ#iQxs)T#bBlDaK@PTo|_2WU%y0A z231Vx%3C$M>kN=GfwR9TgDMtuRquIcuXU9YMHy7Fp=-L|KG(ai7NRJFDh?~Xx0z6K z!ffjb5JeeOaX|%FX!hFFQc;va6%SO)e(&3v3Km5fRPkBqUFFV^*Ls?IAc``m5`ap- zbD`_LH&Q}p@{~c95R}h}yRN&GY@#TGDiJHsANX(FI#HBCm5i0%+ibeGzlo` zn^@(z>v{Q)D9WHp0V-aq$78H3VyT`A+lay`+^d59c}Ys9Gk9GN^L1(r4J?CEmE! z{6$feL6wJ6lG8qXQiumaP&!COidF-8C2e^bZz|kdL_WrAyJe;RRYwM?6rrQ zdM1i8s7iub*D2;WQ*n|zlcx--Qmpiv@_WtnD5i>tq716itUQ14r$xfD^-VPpMHy6O zSn1k0c6`wlQ+-5H231*Bx|gp+X_~^+EK!s}RgRTs8S!Uf$7B&q?G{BDROLbad#a!7 zs`o$?Wl&XMrF%J1!wZwGD@F=u@{~bUk(ExqcfnOPOcfAC8B~>6>0QdF59M9w!@8m< zgQ_xg1!c{B!n%5iq714k&~;*4lG>)GiJ}aus?e2v^lR7IW~(U5psEI4$r`_{YF!sa zQ3jO{E1ltk>3vR_dM}DHsH(Hl8D>nju9T@bDV_aA8B{f(E7|?*)lB6PMHy5zp=)rl zY9CD16h#?SwV>Uymq9}u^4lAAEf{(3SZ$;LNq716K z&~-fAT-W*Vv?$7;@`bKiPk)@XEqp18GN|f7*Y|SA+n9=$%GqC(K~2*1C zw73l@;d~B=q716WtUNb`{Mq!uJ^4qXD1)jAbj6x^YKwJ6P3=scGN_tDSKcXSewxZH ziZZC0L05}1)i;~+6-60T&7mu!f8P*O14K~lcx--&d^n9=}*@c)>{;1Q29Yu_ZMrzSXWC? zltI;nm7dw&9nS1}t3O&4Wl(hm6+6eEZ`QR@6lG9#1GOXC>8GZyh@uRt?x1QddUM#+ zFHw|1)q|DZM{TJY;yTZ#Pv=aYGN^ijs&imL2kWXPiZZBrf%+7ftFNhEq9}u^H!D4s zCnXIWW@?@&%Ao4QO3xerv|%JGN}4O*Y!FPznhAY-kBj~ zQ1yeZI$I`>GL=^pWl;48)#cOa38or|q7145taKV@wr_Qv0S1er461?9b>h;XdDgX5 z6lG8iVx>n)t$krHnmQqhGN=ZF+Ely#f2Q7uq714bpc3|ae9lzD49?^!gK8)%eNNdu zC7S!ZA&N4nhOyG;KiJ}au;h?@8Ofb~8aIz@Mpb7vrv07T!o!)LyltDED zRPA_`t6JB6QItV75>&x~nR=RvmeH9ZWl)U*RVUfp5L5X@Q3ln&tdcl4L|!9%526`Yow~y?wuAQPNgK8`*y+7Q3;l(&p_eD_#)i_rA zUUbB_P9IE#&E(9GGN{IbO8O;F2~!zGQ3llnP?M*0og>Wl&9FrSIpD{E0K$)CEzLK{b_? z?&Se(FXS@yN)%;KO#`(qVtCg(*ukLp<6lGA&V5Mi9+c`^& zuq|vWiZZBXveL;fn4LGWsmY=!gK8ElJx5jayWhmrCQ+0@HJg=gVY!C|T<7`gq9}tZ zkX1_A%ku`GeP>j^PL6lG8?WTn^25kDXG zv95QbD1&MdtK>5II$7>~HkCN5GkMCOTFgqnSDCv*#+s@miZZB{u!<>N*@t=GGu2)c zWl$}Ju5~p|xsK&Aq9}uE8Fc;pF@J@1trkTYRLi03Wad7pO`Q@&8B{BvtJ=k1uD6cQ zMNtOTO6ckqd$H^NMzn0sVPQ9pjyvLzt`O|SzXVt zPef4$)dp7jy{aUcyd!~Y@Am4641L zMhto9x)S9UMHy84Sm_c)czk4#+`MHy6wSm`_SY*}7-{!-6T5pp>*qztOVtn|*|$nc6EOr;k^ z8C1cn^f_hH@yvTo`G}$nsw1p)&A%Nzu%M~_q9}vvC@Yc8C1tu=@$0* z@~*0>Q=%w?>NqQX3fOR?lk52UB8oDoPO#D$`pr7yV_nH}JCmmjs*|kreq%}aT&}fI zUKC|eonocu!%1-urLnFyq9}tZgq2RiC*HyNrpAe)464(hW)6GmIx2UGq714ttYXQU z&wq7zKkIrViZZCqveNtBVh^&rt`3p%I5VUSs&lMTN!QhZeO>3?Y@#TG>O3pY;P^B0 ztI{8)OZn^H+ri!8rs*9|2&F5VGCdj&Wi=qswORSR07Pd@SeTJz! zq9}vvGAljXY>NCbg{c^Mof%RF)&D@1^j`1!UPVMv2Gtc%pRz4>9hGfFQ3lmjR{Fi_ z`7B&!TR24&Wl&vXl~$%vcKE8krVfar465s_^t=%~aEj}$@`EVKpt`|IpW0dlENW?8 zDe^fpqztN?tn$bfZflppb#lW4) zMHy80SS1&=r|XltrbdaP466IAJPVya^AqKF&2Wb(%Ak6{N~aN+s^%-}dLoK4s2;M? zt3#N_%RGOn-z#YWXBw12^@x=|A*Op7;#pj(N{XTks>iJKYW`DeZBoUiq)>$)h)pnA?q?<&8i*gxG= z_=3(1DTC?-E4{)-d0y(JsqCUCgX$$K-OCft=dEDMR}^JXy#iHnRjnJQMvI~hs@JUa znld(3uR5moh@uRtH>`AjweTDF)zlkNltJ~Dm42^Qm4aMrK2;%ShLl0|j+LH!OAXGp z*}7_rq716{(AB1Y(i*0QilPjv53F=WWgY%9qp7W;D1+)FsHnrTdX|YEDYr#Y2Gu84 z`n|@r>EpSzR~4zSGY!h1`pin#;n8vTx0)&-iZZCau+lXj;+58O`=(t@L{SFSS5`WW z4Z{=NH#J5SWl()%rOzo5huq#_YO5&9p!&|rGj9IGOTBA~ssBV#2GtK%o*ydnCs&_V zuD3mLi#Ri+462{3^xWH_*v327Raz8fQ2m0ge|}~1H`PNFWl;TQrT04YZ}646p1*;vsG_1MgDM;=U58P(FW7CWy(r3{3eQUS^7dB?x|*6UiZZAou+nFT zKdYOCm&1uhB*CA1q zK^2{q9$#rn^b9ohN)%;K#bBjpn}V^t7n@31+?gR|P{o9E>0Vk*72GegRtiqA?{ZW)OS&oL6wS?9?Oq>dhaxqsiZSQ%AiWk zO84@PJWV>9swIjtsM4^~6?Hq_Zr5FH>RSr<)`;<6q zs;wx>pvuWg&r$12jt^sMmMF@g%Ee0Wh(`Qb;(99*EQ&Iya49M?Zd4nF5a6aM7I@6#GszRV%>~a750Wyf9 z464GcbT1#MGA^feRS-oPR7F_niprRMK~__}MNtM-QC4~nP#; z64#Sduqeu)D$YvRVgIE2U1ys&q9}vPn^jtw_1EyJ-q;qVDCbO`GN?+h^4#q5XZNfr zWlhx*MHy5jS$W3IpN~6z7ML0-iZZB5vC^|>qol80zg4wc6lGAAW~JB4#Oe3nx2}7l zD1)jDD?KVx_Iv%sRJ8KWG$@0rEGu16%QhsQZmO6l%AhI-YDCXD%}sR_MHy7(S?Lyb zFLu;Es8RzDzVZPH8y>suhx~T zf-^(PpsLJDudtQAjw)%Yl_<)fs=`X|Dx)SS%}?*n*PJPeGN`ITSF)g_t{I*XMHy7p zSm||nO{FQWbJPz}ltJagO3xb`PHx{#3FnisqB9N3psEh4O6_fzOw|@e8B{e`>DA$M z%#@zL)ULszD1)jdE1hBXr5#<@$~B@WgQ^xQ&n1CB{wSGI6a)(odi)e}V-RKBeA-eza!0N2j~ z28yB#s(P&S+&eG%6W8xZFBe4_RP|ZuvAm{pvFo;lmqbwpRRdN!!;J-ks+$U5*_k0_ zP&H(w`)km@D?LAu(Y29T6lG8~Vx`yRMmHvU#;K~hD9WJvhm~&Oon)Kuo9ZfxGN>A} z(*1S5ed#5prir2qswS*-@)2^}cCGo{q9}u^DJxy`!&6_JXcC3(*NxeeeN3GYMHy5b zLA9RpyRxazq9}u^6R7VCm$~k-(^qq5NEuX}K^?#Lb&_?}7DX9UeysG|dtp$s?xu!{ zq714otaS2;D~xlUZ8nOc463f6N`F1$d4&^J&foV$Q3h2vP<^Jx^4ylHis$1@gEFYP zv(h7F>6KvDJ$89fltI;ll^!WALVEdGR}WE?LDdsf;of;&_ZtgDQ3h2nP_a_I?P6W0 zL{SD+Z&rHl?ftRd22-C!Q3h2XR(jPtwx{+4Q%S2kGo%bEe^xrfq=R}5F;!L+Wl;5H zrCXSMTo%tOH{D;|L{SD+KUR7_e=}#Sv!fWD- zqpa(`D9WH3$V!it3I$isF%_wXGegRt8pKK`-*}t%R8s{-Q3lmu=t|Wt{bp0mL{SFS z5LSAQIuP%Aps9(XD1&M!D?OH9HJ|C4{9aL%K{bq(9w~t}kGkH$z7|CpRKr>6JJ=ST z+Vrt4Oj^^KA!Senu+lA@Ql{-bQ>haB)LK!L zK{bk%P9xTw?8{AE6Ga(R|FX&^XTX=qDti{P9x35#In$sFs?n_UCs`%xK3Hq2uqeu) z8pA5BbgjR1_NA%Lq9}uEEGu2}4d)y$WonTq%Agv@N@o}+<963m_Bm0MK{cM0u8lT7 zE)KM=pQ0#(Y62@=^Jgp0@+=dbVYb@N3@L+ZA}hU1DX{)Z3sVh6Q3ll{R(e1Gqj}d4 zriO^3464bXj%CXC)zn5<DFxmCkUx&ym-r?ueocs;R7W8g*+GIA1v1af4+7_m$>&%ccr~+B(7G51b&-G8JRTD)S zRC8GAv%|4e9iv)Te^Hb{HJ6p10lsy9-OAKrQItV7kCndD`_?||VpIPUMHy7{S?LwF zXWNVGO-1o_ra>803s~vZyjuF!O-#-mrs|8L45~$}^a{ITONo4@ z28p5!s>Ps=mkb(YYK17upjyI8&j9l(E-h;6oG8kmTFOeVUn%NM`DMzho-;$rpjrl9 zYcIAbZz_){%Ai^f%IDFFs-{|sq714PtWwFr$&g*SYtjD9WH(%}TFCslNnWvMtP1-$)n6GN?AN(&yy|0c%`8 z^9|F$nFeK0ZDghIH}(%$>ACgLYh`v(ltHzLm42_GPiFa=sw;{zs5V1a_jV=MnHnUD zGN`t&(yo1rLR{yK<)SEqYAY)}i|#3tkQ2^gJ}ZhcsJ4N+|FdRH+rm$xD1&M{D?OH% zL>_z9RPu(-RyxC^iA(P`m8y|5L&~7q%Sz8tg$8%4 zXsVVd%AnfEO4r7N$KPg{8X<}@sP?ncvrUfGKV5ezYei88)d5y|KHOZR%s%V7A&N4n z4nkM=Th;rSiu{i=4a%T81S-Kr_rJflkSNNaI?PJ%Z6Zb7($c!xilPjvVCWj&ba{ZO znW89z>If^H#t)xQnL2;jbSQnV`qkxL3Ny! zPGiKqSFSCrD2g(uPO#GB>tc+FKdsAO6lGAIWTp4mZ{kMqoaFS}yFe6WP@Q6>SE9^; z3+9?SC5kerLRjg2uUGe807g_0wx^*MObzROUiZZA!vC=#9kL#vgx2{&AD1+)UtJL!S zub->zy3?B_iZZDF$4c+9J8$kg$GSp9Q3ll&R(cjaxG1sfd%YD!8B|xH>sPn}t|zHP z&72uh2GuoIx_Wz#ygAsm&|4H`P+e!GYh&#O_dBAFq9}vv1}nY$$`+}(>&|?tD9WI^ z$x6>`Ii_UWZCkik6lGA|Vx{YFWyE=&#|T}$&qYxN)ooC}cir$@097Su?#z%fsQv?W z@?v7o0jjE$D9WI^!%Dx`rEZ-@o9ZNrGN|sd(iN2_W9$>A0!2{<)jd|aqP|6&_R7=& zQItV-pOv2H2cJ0Mc?j0;^;i^TP(5I!PXUYH=00sIS_@}}ltJ~7m1igM$G>m1C8kP> zq714>tn`dMC}U&SQ(HGtltJ~Fm42_~%lti^`n{%$q714htaSBW`P$TT(5TuiiZZC4 zveLH)k9&6cYU+U~%Ak72O3#PWzxMiODp5;khLl0|oRyvrS6%GodPh`N6lGAoV5O5k zwxq^K>*^_rGN@j%(&H;k;k(aFEfGZ-RIga+IviB((l%3PL{SFSYgW3K%LSZv9hDzN zQ3ll;R(j{Kqg$Y>D^V+FhLl0|mX+T3P7XLc(YCOpD9WIE$4bwK31%J0YO04Q%Ak7B zN>@~gVk=zFL~}(^2Gs{vo<|z~G~e_+vvnO6MHy5dS$Y28&zHIj2AO&!iZZA^vGUyB z@n>$PLyb&@Z|%&GGN?YY^8CS{4bQI)F_m5vWl()#rCq&8_o`&7tSHK$`pU}l2Y&*G zCUsrET8W|zs&A~cEB2ccZ>?*%D9WJv&dT!#f0EDib-g`UB#JVqez4N6)mKybS=Rwk zltJ~Al^!V*R(ITQ>W(PNp!&s1*J0}H6 zf+)(M3I|;cRxRyD3Fq@w6lG9_2jzV(mFv2krmZu1%AktCO3zUdcR#*vT~$O;2317p zy1gf$x2YbYD1#~zsL1KB?KCx46lG9FW~Jw-imQC5nhF+08B|eN>Gi8xr)t$qy%I$k zR8d)ZF01@GSm(a$s7%t%nIUCRMFVxM++^1q&I+O^gDN^Jz5Cj7ZN2NQV^2|(K^23Q zey@$4gAY@}`79Pi8B{S@>Gz7zwd+Y!XGBp3RV+{``le`L>boe)po+~(zt`qgb6%Rt z)ZUpPWl+UorQa)0=MJtbk*_Gqpo+^%zgL9;@&B`~VWKF5Djuk&o!izhwLuhRP{n7Z z-)mB2dS$4SzbT3`s1mT!@0GdDy6~o=ba19Y8B_^b>GztHuy>HD0-`8`DiNqzVIsNS z_qG&88B~c`>G%2^Z^S+8nk0%csFJYKJJ_?IUb(h#pD4)cyN6lJh0JuCfQ%Yqtt z9td=QH4#M_R2f+5_geEKhHDxlL{SD+MppX0Qur3wZC$HHQ3h2eP!Y;hblvx!6Ga(R znOW)gy1jVRAM5%giZZCOu+k@vJDmaoOeOE^OrA2Rva<60!JlZ2&U*%^Gb|;FGN`h# z(sPto>s{?lH5Wx0RM|m!r+e7S)Ob;pL6w7*Ud`_`IPSVz-X)4MsB(fD^?2Ao>$)$B zGN^K~((hGxQ*A_1 z2D|b?SG`H|8kw3RiZZD3vC@0CpMe)#*RTDeD1$0LD?L)Sl{_-dx*m(745|XG^y=V0 zBFJ?4pltEPz)a~N2>zE1_MHy73 zSVfop6}xak&&KLG>a8fspeoHuCx2ny^5&*ub#rD&8B}FJy}bFYlc}PjD1)jjD}6$| zdfNTp$Y>*qGN{V2((kpX;gk^Tnkb4gsLHeQ`~%YbS-tYsM^o!XQ3h27R(dQa%y;>! zsS~0ogQ_Ac&y6*ICZ(I~`t68Uq9}u^5-UC1?C*W2mvzPL?o6ICs4BBcD_xty``k2D zP!wfQRbiz+8M!k2a9>j$MNtM-RaSb&UfaL_SyKx{Q3h2tR(jqDoSCwpsSr_=LFEHo zH{x{IZtA-z%Al&wO0Rm){qwtimYu1GGegRts=-RHU#EMzfAh1JD9WI!$x4rukVZFL zYkrU@%Al&nO3wi2iu>iHg!5S?iZZBbv(hcBd2#VxQ&&V$22~waI{95oUbi$Awx=@< z%Al&tN{`Bm35IxfxNcz{QItXD%SyL!TbJ+=Of?ck8C3OH>5BT_%;-lRPYFu6vu( zq9}u^B`e*+QXiuG*cP@DMHy7BSm}yN8`ATJsd1txgQ_(vy-V43IpmtD-J&RistqgM z!Z^wNvzvM*iZZC$veNxkao+8XrsDK*W=I)S?O5qi`DD)eC#DLEq716`tn|E5W#O4j zrrL<245|*S^o$+G|GDdIGf@;}P<4c^tfyl%v94XBD1)jKbVa?Awyvprq9}u^Gj#p< zr^y{tQT?46QU;YDblqv)Yq_a>q9}u^3v^w(9OILzCZZ^Vsw;G*Eng&(sZpXRgQ^>J zJ$%)0v8hd>D1)jybj|Y%>v}f7E{Za!dO+8R{eiB#lyH5W8BzvSPw1L;`cxa+!tA0b zgQ^#F`DQuU&{RE9ltI-Sy2=cmH{H|_QItW|2fF&K2<&NUwJ6G<@`tVi%`Ui}i7tww z4644+Rk}n3*YAq_6h#?S{h%vz+ujpx3p4a{CQlhu{h=$3-%-!QqTU145JeeO1E4G2 z@qNLj`ii0qs)5k;_WKOiQ`-_zltDEJx<2=Q;d(+05k(nPgQ4qE@1whH3qOgX45}f} z6|L@y$)-~DcVo=v=lM#fCcCb%uS8J>)kx^-TeaF3N;sc{1DqLB2GuC& z>Qw%q>nvJI6lGBT3tb~ShViwo4x%W7YBVc-EAnFdqjjdHilPjvF|70oo2T+NSJw_v zltDF?l|CVMd3)9M>~LEYWl)V{rCZqi*(J~Io6hjJD9WH3&r0`lkG z8B`Nk>C;W66B$~Wsw#>ys3x+~Ei7Ep%XOF1M-*jHO=9KwgFmCkl^ttcb3{=F)nrzl zAA9qs$l>CypS1;vq714jtaSA@X@1gmK71*PGN`7q(is-{Jb8|7VS+)<3@L+Z8g$L6 zTIr{$lAd6;vFk3Sy(r3{n!!r%MLVxcb)q+pqkA}?<$jQPW8@I#=*`EDT6AIm9E3!=^cxhsw0Xr zsOGTJr<*lL!n^Lw2aBQ%s=2K6&OAr&gwd^QnJCJjn#am>Q1Pcig)u> z^snT`VRd1On%Ai^TD&qG^qpa(gD9WH(%1X~Rlj5{?{Y3StD9WH(#!C0s zn8=ftSXcC+&I~DoYB?)CZw#BX?SQHLq9}uE1*m}=zPWzZ)>sr}P_1O8XMlq}YkOXG z=ox#YD9WH(#Y&H_t#K!=Hnmw4Wl*hVrANx$_&u7N`cD*PP_1F5D=K`>j;_gvALh)E zGN{&qiZyA8>k6Aq6lGAY19ijuqw86(wkXP=TF*-Na=f`M_E5t4^btjdWfP7svuUnmpdk0ki*mzQItWohm~F{s~nkg-P9gY zltHzZl^!YSc22uu>ai%wpxVbu&xhNKUv@pw#~k6zkTR(DL)Xi-(P~*&AyJe;bpX0X z4;X#kR5MYOK}F9%;lk()o2G4W)zoNF&U2Fc=gWsc6?u@kxT!6oD1%*xS?T06zCJn4 z)GbkzK^4qO*L?W58S|KmG}4(NWl$YqrQfUM-7l^uj{Kr1gX$3T;LX_PZV%Ah(0U6)>#8*g2?L{SD+2z0$qlCQ0)dZH+U>NIpEf9w3Wh@A7mU{RDo zbq2c5HSOwWUCTvL2GvE!(<&i~Ex(%Ah*WO7~af-1+xf zSIU2#$x{Z^1y;H?dbAAdZ>qc~%AmRkU1Mv9bv?EDiJ}auOVE{k$EaS`HC+^CP+f+u z^3~^ferT*$hrOaGgX(|KmFC?I*9;$sq714lpw=$myVAO%jdo^88B|wU>HgZD_*h|6 z`9x6$)iqYSze+axyw6l)QItV-ot5sdL=pC%GZi3;GN^7q*S^9BUGIq2ilPjvo6yzo zLebOKbx{;$P~C#A9_bsnuFKy=Q3lm*=qfj}?Q!c$Gsc-bWl;SG>g-{!RHiD6q714# ztaN`x$g?7XsqUgEgX%6T-Cse~cDwF~=7^#Us(Y+-e{JyYP}{l=iJ}au`_NT5=Oot~ zm}jCWgX#fv9eno6bv2JY)|nw?P(6gMFL@Jj!Z{xn7DX9Uk67vV`n6$mBT6`*W}+yA z>M^lJVhMMED``9x6$)eBG~Pu{L>s+B0ppn3_ac7}J6y%t7>{)kf=&C-kBj~P`zcPGt9PncL`H9 zL{SFSJ5c2Zd3&20B8oDo-h=w``J!tJH;SSRst=$7)7EoMhM5oZ8e}QItXT71Zb7 zUUN-_h@uRtZ=hyp9WmR~4^fms^_`WTd+V1!<2qw!o9N7tGN^vA(#fxR)WY*{uj{b3 zD9WJv$tsPU%W_5kyx7!GQItXTiGlJ8C1Vn#g?wEU5mMX?r>8SWl;TL zrSFKMWi9#Ey8eiw3@R_rD}ZoebPGFYKID43$uP;8A!Sg7VWrPR?f1WPJ#kbMMHy6K zS$Pf*{_MHnc^&0RIG=u^D1#~-EB#(!x9oOZzm|)l465*;g0}u~-NA;4q714Ctn{gE zMy1(NZ42Ltq715ttn_=;%~s-@sbrI#8BzvSBv$(7c1O+v^G#J0MHy6)S?SuSw((RY zQyoN622~VRy5>JL^GR!Jf+)(MiV7;@t7NXL!yZwTK^2XaUY8dwoYBm>o{6Fis_3kA zhOZ8{7-%Z)6laE%K^23Qu8m!V{PLPAA&N4nVuJD;SuEI8Yf+Rz6^m6IS+C{pPOfZf ztSHK$iVa=q+n#Do^{7g3Z!6%V?` zbzSDE)uS@mRA=&(K@}gmuD)FS$&|M!%AiUBT_49bk7lZcD9WHp2we-yr7B=5Kon(A zC4#ODDRPf7wNeyiP$h=0DxWL6e%JA&D9WHp0$sHl7C&fRuS8J>RZ{56R-^qiQ?aHw zlcx--WY9JAZ09nj@`<7hs^rl1`&WsUrhG+F22~2^de)(c>y30jQItWI61tXmKUdGX z=8B>Ws#MTb_;&}_dE^104Y!$naBRR&gi?j2tL^eWrJb)qPP zDkCesKa5;+pXV?24DdfultGn=m0nZ&lx=s;RD>DM3@L*uGb_E1N>=EK>+UO`D9WJ9 z!pid)&!5=@xFh z+t2elR%iG^6lGB5V5Ku$7UyUUGo%cvoUHU(xibC1A*QN{q715B&^7qiJI_s@ zZed?hltGo7mFLUwr$x>MuA_2=D9WJ9!%8QgX~*#l)^$M?Wl-g1rAKAHFMDR2`X-7p zsPeJ$d>Q^kh`ZEv21qx{nIUCRJc{fKsYpSa#%AhL9 zN@wV^XhxRUuZog{9ivnPKXLD9WHJ%*u0{&!21^uesi{y%I$kR7F_n&%bh= zu5rk^V$61CNEuW`S?T@8p*kZMn944SGN_6{SBfiLTx-6jD9WHJ&dT$Wmp`ed4t72H zb`?b#RNkySHyQjHl;xP~SRN~iGN?+h(iP?XrrA77IG#D+c;5sQ|Clc z2309mx|d@&*!siNCsC9^RhpIFA0~R#@T94vfzJM-45~8FHD}Ki&p7pa6&FPrRApJ| z*`~|MLI0R)A&N4n%CXWTrDxMau6wreq9}u^JgD2*eYaXykSNNassO6*pD2AzJrzY6 zR25mJko{V1Rr{l+63%gENEuX>K;6Ibv#hC#q9}u^GN_7C7L7L5R}^JXRbiD(wy z%AoQE_2X4z*E;MhiZZC`vGV-EpD(Wy<+HAZq9}u^J}bSC8XEIs4pRq3Q3h25R(cOG zY{{koQ_n6iZZC0fV!FP;ZIY0MNtM-Q&u{|aL*=`HuY2#Wl%L^rSJ4= z)qLTaM%)F?3@L-EIV)ZByQcfOei~R(6lGAgV5Rqm1;31ZU|Z-XiZZBLvPvoIa9}+5 zzbkl#D9WH}#Y(TseSW2L-5(woMHy7BS?LyLo!#@IZQ(0XltI;ol^&Ia{13R+VSDs&=e&@&$U`a!r1qD9WH}56U-F@*UQ-MigaGbpW;R z$XL%oqi36Iq9}u^BdFW6s5eRJ~Z~_sadSrE3dUi=qsw-mG*lA1MDZmu=xCQItW|hm~H5@+^+B#MC!Y zltJYWU2C%pxoRry5@+(1LDiR)PJYA1^KVU65=9wQ{aEQ1o=S8ur>V}OD1)j$E1kx% z9?6TCnjwlZs0Of#Cu{!S<^OmdkMvmHBZ@Mp213`u(~XLmx-W_{s0Kk-hp4YTmly4d zywsT?Wl#-Ze;ZQ)q9}vvUsl>xv2dM%rgn;=464zfB1{j@ zKhbomUx=a%sxhoQFQNETY*6Y>)|G0xGY!h18p}%0Q3Hy%ay|Lh5k(nP<5=mjoI0de zR_huliZZCiLszEC7k-;sE{Za!CV(niG0zTD=R{Ek)kIdh4(s@N-!=736lG9NVx`w* zpW$b6no7UInIUCRO=hKMo1VjO4>DC*6lG9NVdeRQKb>Mvaow|Z6Ga(RQ$h9laH6|) zO%X*IRMS8Ws_o@EmbZwa465m%R^6?4#=0(vq714TpnMM{>uTzwD9WIk$x5GYQe5|T zsRS#X$x{Z^EKvVt`5wW#3W=f&s@b5@Mc(O}d_z%`K^4eKuX?dtA1Y;C14K~<)f`YO zR~&9{YN05~pqk4{S5&Nmd54+`7DX9U^FZy|w6VXb=b|WsYCbFdUe98m@HQ1^l{0zD zpjyC6?+>#MS~9{^0a27ewUCt_l^v^ir#96}6lG8?Vx{M(b2;z3eq(&1D9WH(%*yiz ze+KR;;ac;%L{SFS5>~nnQ%#Fm*0%7vD9WH(%1X~0G5TfOW$K40%Ai^Xs#H7wE2dJf zb|z05RLfcEz37Aq5qFy^FN!j#RVhcBpbCPnXfa|RH5G2XGY!h1+5=rPZeDV|OUW;aGN|^l(yQLR3NM>jS6fk( zLA8&So(~I58q(C%1W}YhwV##V!R}q1<+`cuq9}vv0Cf4@I^emr*S-9oD9WHZ2wgiP z-g=JFy2%yQItV-7`hhD{eIk3eNmJ_6%1W-f4#V7YN#m6pgICw zX|^76z3*KmiZZB1yPhibqu<)#*N~-rhF4c8C1uiE6R>+QLQWOMrZPr zL3IMU!VZi3*;Ex#ltFb8x=Q5S=~>9SHhPMp460MmHDlL~>Zaz3q714KR=Vb!4)X6{ z>WC=HpgPS;*ZhJcgFOS#Eqp18GN{f#*Sa?ThfF2d9sP$%SEoqw-rShROdlGPTp>wbxjsU8B`ZQCG*Z&!c>qb%AmRks@$7+gG@aXMHy6= zSm_nE&xpvsO~u^o%#bpuE`!?M>zwPnQA8AFQ2h^7CEwu%t*f;t%AmT!O4mljHkDlG z-btb;gX$_PU5BGmI#+Jz(z#0%Wl&v%u4JR)jI%AgD~d9xu0z*jpB}wTMcLxakTR%l zKv(Qc*ImC=l}8k1P~8M|bjGAY*40Q9Wl-H>rPGM-+vAq008x}dbsM@0Z#z80)LK!L zLG>RiJyIs5IMUeEWl@wtbq7@SSK(Z1*?yQb(m?ZGkMCOy2r}%GL%0f zYh2r7TUbjJWl-H`<+)wp&(NQjvYQ$#iZZAku+r5VWqb|SyRS8(D1+)DD?KXvU;NiK z`AecGgX$5h=(2@A+s1XXE&MHtGN>N2(%)Hn*1oUny-kX3&I~Do>Irmx9N+krb$N@T z463Kl^=(^&U{j4nQ3lmBR=RpG2RHG&640x|Kv9%I^_-PXe(;QtucnrXq714R&{eea zQ%{k0oe@PDR4<`x!<$a7``%BYD1+)1bTx}sH^{nDYH{m?%QrKe@iFDK!>j=cp)&v$)=UWf4UgRG(PsvtEmedt9rxjws5Y z`pn9+Wcl+gf4s7`g}p^l2Gtknn)Ed01yg~dD1+)NbY-c&HN2@kq9}vv8+1LNw8eGL zc1ILtP<@B4z;>64SXY>x&g3bB>IZby+1ci!sSKhhgX$-AjoI_TbzQC~iZZBvvC^lu z+lfC7wysX1D1+)ZD?QtU8QE``si~qUgX#}-<=a`Rv#B6altJa?Sxn)=XxD{5?t6fH zq9}tZ3@iO!_0IpiY+X@yIg_Uhs<6=2;>zwHrgDp-461O@_2y|d*H4P;i=qsw@X*yg zYM@IE7DX9U5m@PY<3QoS?Y4z0L{SD+L{^^B^2hgC%(SMCiJ}auNYHhoSq4w7p64Hn zq716Y(DmqGmsF-A?sg_m8B|fAt5v)AlTBq3MHy64q3cuf>g!Ea6h#?S(OBu)@V;?p zzp3`3D1$0GD_w_vuVSq;HAxg@P{m;7`GY^RpYOkEYNsg5po+;#_gAA9cU@Pa>!K)w zDi$j}i)Jk{g%eKmH&K*96`Pg5@2#BCFPCj$iXdlyQ3h2UR{DmsWtA#@OqCHu8B}pu zX;*Nb%o|L#7eyIV@mT5pN>Sv^K2sA!Q3h3fR=U3?H~G)?PH&qi%AiWXO1Cg~fg*pb z>y{|WprZdKhW&S!#w5GH+Ekc5&J3OZZif5c5tInJYPS70(o`lqAr3 zL{SD+66hNCZgnJ6Jw#CkRZ{4xA9z6+^^;8sP zP^E{ilxZt?2BT{u#y)5AltGmNy6T+I?s{jQPZVWPWn`uIqJ2l*bFIS$q9}tZ6D$1* z!seArT;FTBD9WJ9%u3H2KgM16{4hbk*CtVvL6rr&0?t=7bxjmyP-O+xI?t#brXuZk zW=I)S*;wgQcD172Jc~=Wu%IZ)pvn#^aCF88rdo=k45}Qgbn*#vH>hK3qA1Fs$_eUN zm9L(0>K5)4MHy7NK=o-gJBz7%q9}tZH!FQp(Jf-Pm!_f}aArsuRC!qG3p2Q3h3U zRyxCl{-HlE5se+;?gQ^6m_r0}5Q3h3cRyvLU<+$j2@*Nwm@>)2e z8zr32a#55)RgqN+$+c>GwwbB(q9}u^5~v-QXS?pP!vs6ipbVys%oH~CLGt-)J9R1LFL0Lt<3P+ z+qSMdqMM>9gQ_~H7-e#ov96d$oEcIERSj0UzcL4Ob=_~25k(nPHCd&UEvypa9o4#e zilPjvTC8+`rMS~7m#O8VD1)jtE8SnUBd_rcM%UpPQItVdhn05i%bISHsn4P)gQ_lc z)p+sYqp6ffof%RFl`nMN?)Tt^sfwZ~gQ^~Mm8(*0x2dk8D1)j#bVYx?wSlQwq9}u^ z0d!6I>Q~9s0a27e)eyRJwRq6O)KgKELDdMlI$uxiI`_st=FE^XsQv+!d(jWqUM?bv zGN>AZx>sneYcIDHMHy60Sn1jr?^nn*`EjBsgQ_WX<^7Z2_4@!@MNtM-Gw6C*;!7|k zoX;&$ltI-Tx{5UY>H0l~@W-7QQU+BE=<;5@(sjR)Llk9DwS=yhFV}c3wz`GBq9}u^ z6?CP{_{H_}ufd`ygQ_)j#X0lD^%J@kq9}u^4RobVwX~#d;aO3XLDd$zHa@yF-PC7M zltI-Fy2?~*Ro+yp6VBu*gQ`7rEh`uQx~YnyD1)j4bWOXN@3^UMq9}u^BXo8DTqd)r z*`g?esuOf=s@v+7sY9YDgQ_!hjlUXetf^Iq#5{w8RATyGN=YX*ZQ4Biq+uaV=rm$k0h zq9}uEFe}exl|LU32f6MlPl=)osv)d0h)T0OOd0F?C5kerhO){eYD9qotxV-P?aYue zsD`o1BWl)^nPE(|5k(nP!&&LugU&0@y3V43q9}tZfR#SAo&WE@mezG#6lGA2U=>fc z@OJNHwN1SfMHy5hS?SL>;-%@~Ybx;>XBw12HHwwK34D04T687Ve+5 zDvGI2q9}uEG%KCPkmKw8O)V5f8B}9f>Dt&n=Hx|FCq+>P)mT>gG@5etGS|J$Pf?UX zHI9`|KJj8&{d$*@>8vwD%Agt#s^pX{`Ak(8MHy5RSn0D~rUU&}paL?3MQItV76V%ajQ(W)a?uw!es#&b`s4SACrjK>SIPc7mGN@*=^1PJi zPo9tdr%e?XMHy6q(Dihp*Ev(2MNtOT99G)(utFMdQ*%X82Gv|v`W~QD!TJSEg@~dI zs(GM}mJ8l$>Zd5mpqkH0&)6Aq6`N-&#|3AGltHzCmA)6P@c6y!JpYd<%Ai^ZYFgc8 z1+8nMD9WH(#7fTq_4gM(Y3h(D%Ai`zN{^It|J9po>Xj(UpjyI8-)}S-&~>P(#21}u zPzKdfR{9J(eP+FJrb>&V460?U^lTHhXy5IoI*6hSs^!qtIbAc?UY;h3GN@L7I$SHn zwW9Wjq715)taOHh3*{JKTlhc}Wl*gGb-w&=*EuTYC1-||LA4rG@0pKWYomxL%Ai`q zO7~Z!Qis>s7Pb~e8B}XQMZXu-b&i@KiZZCyvC_SqG(-MB*0nScRgkMilPjv z&8+l$4WC-ob+jKxcH8n#NWl$Xk74}8p zyQU6{q715FR(h8*q+IgzrrwC645}lbE)*PH&s3^w&NL{4>L{pQk1o$QRYMeIP#t5X z_W+4TT)J#(h$zaSIu2_0=ZdZ;#I>R*gX#n;y{nwyd&u>+=ZYxGpgIXET_)c}wuKR{ zJJX;Hs#BmweT>q{RDMyEK^4ME&rv~>GG{W?N)%;Koo1yg>XrWj*BM}@D9WHZ!%C0k zq+9$wr+hssgGEsW)mc`$zsfdRaLd#uQItV-4!Vl8NWR`wnj6jxDTC@fbmcF3s;j9w zq9}vv0xP}84s*L^DN{p4Q3lmTR(f6DpSHmWQ=3Fl2Gu22dbZhHE6EvCH$+he)n!(? z4*Or-?zyn*80|6`@c^74tvUYPP0MHy6ApzG<9<-JV#iJ}autI)M9pk`T9 z^F&bw)ivlEweqOz4)(Mt%AmT=Dz%sMxly(GFzfmuiZZBf{GY0O4ij5l!T?@#YjJBTt%JnMObY6nB^UXz32Gw0w`o5e#Ym#T%Ak74N{=vk`jZ7raHltpn3+X zS@F2et){iY-FJIP8C1_%=?oCD^0vOFvWcP$su!T{{&_ssR7+8mLG_ZA&TMtlZuK)Y zOB7{Ly<(;FeC`lAJ->@}QWRxSy=JAeP3$6RQd+HFq9}vv4X8sCx?VPw;ep#j%Ag8j zrK5Mw>O&7r)fYt>RBxfymn@;anhFp_8C36B>D;?FT;LK@`$SO&)q7T1WRA*IbD(q6 z=-3DnMHy5dSUHOf-X2xn=jleWhi*40gX$wI=fTfg&#*~6wQ7o@460A8^eb`n|K>cf zBOD`&GN?X-@{L=4s;NDqD1+(?EA3(R-ld0_dM}DHsJ^n&xwl+S_rE#ko@J6pZZ{}{ z>KiLPuO~n5IDde4zMLq^p!&}0|ErXBiNcv0B#JVqez1xqov-zxYz7Tfa^)ybkLgX%9U9UEIG_PAq5ct{jwQ2hhdx=?D*o9_ovltC3D zI{n=Wo!JtE`tDixCVk>|gEFW>veIrmE1%N2L3Kn`6Ga(Rp`ccja^sGg8YYS|s6s=n zun#kP-fp&vq714qteiz5ZyBBs@jUgOh@uRtu&negp!|@qp4leyQ@0zGK^2abj`=dP zQk12HyX6x_8C2m}>HRe#+MesCnuwwdstBy~i}Zrnp*=I(cu|x=6%o|mGDkXEtzDuh zgDMg$T}M?}bf}f77osSGDl(|7pF=tiCGCdKGq;D7LFL0r&#O}YFjGur7eyIVQ9xyG zf7G*{Zz75^sG_pc^V;_7V6fE+5JeeO(Lh~Y9b&YpEutucDmthhzruNDfE%JHgDM6q z=Vs;Y(SI%TSgk*zD1#~{D`&^swovap-))jScRNoRRIym;=w01*@KUSgCyFwtVuLzW zaQ`h+?L<)qRUB3^T;;l=D1*wEmG-dh z+Aq$JRQ3KEC5ker60y>&{3v_;i>B6zq716UthCmyLd(vYx+01)sFJYKTDeA4c9!;f zgg-@5231n1)i2|;xu%l7bURNORLP*$wBCbun<^=aGN_V6tpt5*JTlcm6lGAQfLeh! zwtqJ@MHFRFrG#21--m8tYNsg5ph^X`Dz$pzS$*9XMHy77S?N0JWY=q+Cv4bPZVxGg zDh;UCp^E$25oQrZ8B}RO9l4a)^Zr#w6lGAQW2Iw0+4DrztkzIbltGoAm9B_>)&Bd- z)Ot~rL6w1(K4C|1%rMW?T~U-lm64UM0eqqld1xxaYqy7#L6r$=)y~)7SyJhk&n=2F zs4_#XTT9YA4<%L2L{SD+7FOEBuzQ=7GZi3;GN`h$(rzSLu`<7@J)$UsDjTRRS92aP z^+FV7P-O=dFMJoz7qeJz+#XT}RSs4f_rq!x6-60TIiXhZ1Nl66Wm{2{L6wV@ zu3+D`+jzxlO&3KORJmEDkY`GiNb|3oIx31XsPeFKmO;Fg?lRr;yQx1!Q3h3BP%jgQ z@UdDMgWMic230;#mCiRjVXCnx%Am^6O5al^oG-TB)D%&aK~;d2ez&=NZ>8t{IxLDZ zs0y;u9^SbzxUSXuCWTelmOK~N^5=ISJCsXw?-6YP&ETp zY{<+1tkyMAltI;;mG-}s&=gO2%p{z5z%VZ7eyIV?V(nRGy@Kr8ZU}6s5*d}nc1hcsr{lT zgQ_DdJ;H9KR%J2uQ50oRbzw^nLlk>(KR0EfGZ-RD)RQ92IeL zl_#byi=qsw!JtZqeCS!3hyCexgEFXwu+k&U8z=CS)ygM|GN^{K(l@DAQ@cBh4P9@v z6-60T!&vETQ*-)kXEIPVPZVWP4QHiqQmL9J@LaERq9}uE1S{=fvQ51`_gBbYZZ{}{ zY9uQ?uZW|^tg$1^C5ker{6P&b+R`%)+lrzLs!^;`$}E~Gcx*GPHBS^}P>p7#J)G4x z!AVmWMNtOT7*;xO9F4JPv8j;1-EL3@)mT=}j<XUALTz)o9C` zpDByy{%RzOGN`7qiYaRFrS{GTW4$W}iJ}auX{?+Nue=SsoNt<`rJ^W!?nmD1&M?EA2-9uuWfEt=Xa|gK7>dov|;M9(vu>5mA&uHJ6q4aO9dN z%}sq4MHy7{SZOzQZEx%8hVNguhm=7zpOv%YZE%s#VXamfQItWo092iRO^%rAAc``m z7P8WLy^};y2Gt@~dZ%1jH`KGX*(8cGs1~zwcD!Z&U1g-zx+sb=sFtwO z>(z7D{HdnCh@uRtrL6R+clY5c=Yy7>SE_$*=P83~87t>ylDFrle|X*k>WZQas^y?M zpE;h*YE2MD8B{A+=}Is7Uc9QN4vL}-s+FvqDTcQT*?YV&^;Q&RP_1I6v*_Q};XQw+ z*f&HN{LrRYsMfO5^UAdDpy!=vwJ6G< zTE{Ax+l&xJ8>jcEo1!R#YCS9G)ta~3Jz_nyBlHRBc7rmgHn7s)j!2ZRZU$4iMNtOT zMpn*_w>s%!d)}mKi=qswO{}!mzz%^`tyX_gltHzbm9yim;n=&UP0bTU8B|+XY3Glv zn-Ia&K~a=JwUw2Q-i#N!4l?y#6lG9tW2NtUo0k7AYAR7ExAT-iwH<2xDwFJ=sq&&I zgK7uVY87wQc~gBvQ3ln2taP5=_^LuWQ_DqB2GvehI-)k+8hp*vIZ>2BwF_zu9_+iu z)HhL-LA4udwd#=0xz%)LOA^}cA!ShQVWl%b`#Uq6nkplTGN|^l(&yK{9Qlfv>Mn{h zsP;jvJr$2XHnl($Wl-&hT5X4RzF_KNWl$Xiwf_A6Kc;&WWN7s$;C2VZ_@F|6|UgPiuV>MHy7bS!u1ozC%8l$`ID=A!SgVV5Mue z!@<1^nW`a*GN?|n(ltQ$zaN~1vmW6fQItV-ij|JuW~)wDGqqk6Wl)`Fr8CD>D=aq*j` zVug2mNEuX@S?SL!@2&3i%Tz&8ltFccm2+6U)%MNjS@(7kMHy6AS^fW=C_~^|tF=@V zWl&vXrRTMwQsgtHPK%-ps_U$D9FB_-!t*utlPJody1`1v{NW}E+E}fm5!@b92Gvbg zdVl@xmB2IGR1ifORJT~^Go{YLfIe1hfGEnKy3I=OlzO)tFEzD76lGA|VWr=rR%VOt zc_+FdiZZC~veNr&Zm|%ZtX8CmZZ{}{>K-fYeBNOHCZ_U>-m=QOcZ5MJ!a)h zxV)v06Q=EWf4UgR8LuHtZC(Ibo)+3h@KP`zfQb8pUtL$aF6A&N4n-hdj~=*})v4MkA~ zRS+wk0UGrzGT788QItXTmX)4Y(gDjBnc6IhGN|6M((~HjKP!o;+oC9g>OH8$Wpa)& z6~@QyA!Sf~V5R4^zsKeerm~2l462W;^t^Vj`r%n0))Pe;RG(Psc_p0qaHrK8E{Za! zK7(3av83l|zD^WnP<>&g=asC7uV?jjT@+TxU zgL|9GD2g(uzC*3)o630JD{G3P45}ZX+D(b{z-kQ^MHy5-S!p+ZjZ4tb)GASwLG=r2 zrS1O2vm&}8iZZBvL#_P%@8_{v!J;UG>JO-+4W>;ul`g8=dCH&)W~EQPXT=kH-so$H zq716Ptn@o}qP*oi=QT_eWl;TNrBCzpIX-%xL@Py622}`WDhwS`)t{j&e^bKUZi=D| zs*tSoooM*82k%Wqh~{>KGN?ka(ry$VzS;A|EQ2V@pb8CYdbStN4XQ_2R}^JXg<+*f zn6u6v=L4jwQKBe=Dl97>Isf_d^Q|(qQWRxSg=3|w$^%c%dhV3tq9}tZJS%6%TgLB$ zwpp!rq9}tZ0xLbQw<%X`Hx(5yY;G=x+aP;sG_pcHTJ(- zjXXX4D~d9xqOsDeyl|pVW2==VhTD0{po-4Q8M3@x3Nx;jsoJ6_gDM6q?flg+@7kIg zB8oDoVuCt7cCTlZvQ89bP{m@EOpb7G%9h`))-6$#K^2>ou9oMuD)G@&l$dTeD1#~v zEA7UaA*($sN%8GnJv3t)ckgY<3&*hReVtv-J*F`=D$Qy z230avsbuut>YLVcUTI>xJ){h( zj?5*GTCF{zD1#~$D;>QNUi`gp>WL`Ipi0e3M{n^JuboLwpL((5xZR)(sx+*0^mffY zp{uD9q9}tZEh}BKE$MoFiK&jFD1#~;D?P6epZlFQHA@s_P|@Fu3Qd2Jn71&$6ML@m zNm1_Ko$~${05h<1mOQ*Q3&`nFzeQ07Yh`4m&&tR#ZdJA;Od8kiA!SfyVx>RjtQ-{b zj;Ye3D1$09E1gC6W_ab9=lhDH45}=w^azWu%U#fFEfYl2WFK~;d2&Kr?W zEaSHex24xbQ3h2(R=Ni0QZ3kNfOg}bD9WHJ#7ak0^Q%RNno6I*?IC4Q6=tRP*Q3mP z$D67uiZZB*u+sOGO#7~^H#JZcWl$AmrQK*-d__l7YeZ27RWVk2S3W$kH^9^tQItVd zoRzL%6J#AQ+|(aYltJakN=H=Z!hgq_%9POUA!SgNV5OaZ*fQ-HQ%yus231K=_0nDN z%)O&TQ3h2hP!s0N_Wb6|dQp@?RhpHvxLmyK=MNtM- zSyoY{R=0oiHknH7>-LZ`sLHX@F~4X_q$#F~h@uRt@~m`h^!M*u%2ZoXltER2mDUPT zro1!p=>0WK6lG9Vgj#J{C!c0&pD4A`()lp@*tDBXl@LW4R1H}rlOs$N=lDNU?L|=rRU=l; zj<>X_7F;m3Kon(AHD;x2>?u9hWjA$16lG8~VWrQn-nRyNzV>_(MHy60S!p-M{oHWU zY9&tU_K-5Dnz7QE?a=Q;p0QC<6lG8~XO&F45qUi> zsM@g7tNdYhg!Jb;DL{SD+S615jpn<0zTdgmmD1)jSD8HzU zTAK1r;r5U+sJerCaWACjPVo~(8B{%3>AZ2?=glaq)lL*;Q1xV`tFMw>k9pRIQ$t~4wpwLHQ3h2%R{F*S`HJp{R<1Je5 z&3&xa8&Q-&HG-9XKYW+IXbDr%Q@cH+462c=oE>kOvc_&=DxWCIpz>#>BWmf3Q#nmF z5=9wQqgd%x{?sHz1ye&rQ3lm$Ryv|eB)iwp)LK!LK{bYzj^4~i3VBxMmqk$q)mTs? zHm@pgwSI`A461RU(lq}v%v6#zZs#e3YCJ0)Q3H>scyFqtD9WIk0P6C#9qmkY7DX9U z0igP{dA-C`peV|qn#ju8@ix6%yeFm(i=qswNv!lLcdK&snyD9}D1&M;E4@=j)`+vx zRIIda4=ICc3M-wlGbAW9*imEI{^%I-{Is*5Pfpqj=?uUC&U-hUs_EK!s} zHJz2tHt)9Q>}|CUilPjv8LV`k|2*c!6jQH6Q3lmaR>|dh1#iFOEOT@%8ZVvOL&~6< z#Y(^SJfGA&lc@@#D1$1HmEK=t6DIbI!@;5`gK9RYg)1gSuv*JRQ3llR5y2Gv|v+WF%{cZDe}~Q};ws2GurJI_AsosJPu!w9IY~DT8V|EA3%}1#vy|e11`sLA8UG zK8f02ndDqLodH^jq7174Sm}AaD(wBYkpzmO462>1bOsoC;gM(FI4z1YsCKc^Zj_qW z>wz8NXHk?vwVRbbzji*XUddGAEN%}egK7`d8k_lm=Vu(nMNtOTURHXiG&zydDXTr~ zAc``m_Oa6I6+h#uLZ)Vmq7172P^-Zd_r7%p*fCL*L3MzYUa!tC_tmgkpG8py)j?Le z(wmTES)i%ZS=}B|2Gt>`)qa1D>ZWRmq716Tth5`KqaSu|Q0?JpQItV-gq4nsjuYlJ zGqqI|Wl$Z3TGvZg@;vqKiJ}auW1#W`m3U~iB4%^DK^auXS?QR+wdGzeQ@KS^2Gt2x zdR`SDWEp6xu_(%*I>}1c8$+MP_A@m`6lGAIf?5HU{T7(oAc``mPP5Xt(XIn4dOCko z6lGAI0ktSxP#UZCOB7{Lodp#=>jY=Y*RkQ7-R(SOP@Q8HMdseaGopF!%EF>3gX%mh zU43O8UALgsY9xv>s4lS5ZVVgJt$`_jQItV-5!AeS={!G^S}BS$s4jt;RrujSt942g zWl&uPD-&j=UGmxl~ojFP+bG{;!lct zrfP_y465s(65i|b+f*M>ltFcam0qt<*WSN1HCGg6P~BvuYk=-$s_inhPZVWP-D2fT zXT0U>@LzvZuSHP?)ooTf4zHywv&U47oNnhSgX#_|ow0|8Uhvseeo>S`br;kmzjsSa zwG%}dRQFiv92InLwdZFXvqez`)qPevHnRFv8)3DMh@uRt2duR7JG)gaYwCq4%Ak74 zN{=v9(AV^)V&`&uNEuX*SS6S1wKT)Gt)_~Iq716Xpt|o{k=;~xQItXTgq40X_j`L_ zwy71OD1+)LD}9sT-mwgX$U7iXD8{^PUnhx7!WMpn49qCZ=oV85;#eQ3llu zR(id%2Cl7YN7zvmWl+6j}(8+hGsoA0^gX$G4y~^WTwP-(6hAc``m-m=m+sej?O)Hl^j6lGAo zW2Ni)MMnpFehRZl6lGAoXQka}v!~2ut93;bWl()!rAOFzeY7v8LgaP3K^asZS!p-^ zB?|9ZnP(J58C0KG>7DYkc%8adtClFrp!&>8@07Qhe=IXKN)%;KePN|N{4;#%K~p;i>)vu7eVoSV+9qy3w}+HL^_^8Jxl@|XtuXOmnh1h3e8H#eD@}i%9v^_iZZCefGV?KAI_ewlwmDO4CS4Qx`;0230av`dlvf^ouiH>Gk?9 ziZZB@vvPL4MUBw%s;MMJ-Of`6RSH&GD`uQ|>rIsuMHy5nS?Mf#Decv;raFkC460PD zlF1P^etq<@skx#kgDN#Ey({}X4fD^`c~O)>m4=nG<85D|1-DIo6-60TX<2DE_5}56 zYs$Bn+e6BrO2^9C@wQ`r?OCS$L{SD+dRAI%YVd2%d9@Km8B`fqIXm83WDVh&=O>Dy z462N*wAO%tC7z!kY!gKpRGC;gJKh#Vt#p(U?si8MWl&{irL}%n_Bm}TWO28LltGn+ zm9yh5V%}E+O{Eh>8B|$WX|2>j50;s#EQ&Iyvaxb@yoH*XJiDo0q9}tZJ1ec_6I?8( zskx#kgDM9rXUE%(RDBMbIxLDZsB*H>TF(L^95eM&6lGB5V&&|3%Mi9eb5qg$+|E-5 zRc=;Vt5xL{;Y{TgMHy6iSUEf1Mn|md`3}%f6lGB5Wu>(WJxl2M4lrC4Wl-f~6^ljkQ|qL{SD+DOP&DQcvjPS=&4m zMHy73S!w5ef(v-w5W|;pyFnRLWuVrmJ69^$5#|;}8B}Fi>DU;Na?@~A4MkA~RXJAL z!`t6a_BAy@6lGAAXQf}vX5V`5yuj%=+$V}Ms4B41_muo8;(DHXuS8J>RYg|1`ueo) zDVwG}sgtHU@P zbJBaJUW%d&sya}sMvkQcrs9@$dq^2nby?|m(OEG=dY%rYMNtM-J*c%ic$la2{X|g) zRee@E4(k?g>$#U#i=qsw2CVd5FJ<0Dp6hj26lG8~WTi7e`LXFbQNrD#mUFv78B~p+ zR*kw@8<{F9iZZAgv(opk5&`F$nd&BrGN_uc(s|=^*ng=^%@su%R83jwdu5(jcWawE zE{Za!nz7RNl&>>-c#iOmD9WH}&Ptzp-Nywvj~DG>tnzLTDTAs7)Jm3M?*mhQq9}u^ zB`asb@qE>W!NEuXJSUEf10?+>)W-6~J%Ao2Bs_o}iOHDNrMHy7xSUHPb-j2@*Drjni zD9WJf&PwOQz>ya{&&nmDD1)j8D;V<0)sL0V*s&_F_H_QWD9WJf&q~K((Uz$_b8qa*ZZ{}{Y5*(ersC~J`JJ`w2n&m% z461>w^eWGOQTL9iW}+yAY7o>~-{qR8hoeMM2Gw9t(RKuT)&OfnQ3llzRyx~!nmI7Y zj_|xF%Agv`O2@{8g=ce{`X!1osD`o99)4e3Z-uFJRou=~2Gwv-xB5nSWU8Vl%Agv- z%GtTsYx%^6rn-uv462c!vJ5!+#?(wvltJasO2=WlJtIBO%Dti}gNkO&&>{6{KKMpQ z&sY8DqTHF)`)_9&%_@qVSCofgi`WrHt?KrWGFWR2D_z0Hd+6^OQCUP$2Gv+l$NOAs zVznBJq715WtaL=BYB;~CsfnT}gK9i0?P2_cCnK2JEs8RzCV)B>5ID}%Q&E&b6~Ibo zfS{j|cbbY?&Fvv&P)%f|ZyYy6#eZxnk0{EZnglB1jIy3?G!jJ_RFhfh5q{fM!nt(% zG#@F7GN`7o(jL}({qvxy^`a<)YAP!ohf79O>SgMND9WIk#!6?lM_K>#eAD|UiZZCC zv(g!$NV|rf=W?p*Zs#e3Y6dI)dCHO0HzV2+mK8-AR5MvclRG8e&@>xOwG%}dRI^y= z8erSeF>g(c7eyIVfvohd{1_0Sm8mtND1&M?D?P8xY3EKeby^f)6SWC zBZ@Mp=CVpE-T3gav8RU#YPg-J461pcCNEjg!)jF&MHy7{S?O$3ck4~hI2-JlGr#jNyBX%qC< zbA-i3Q3ll#Rw?DY=3GBl$7;0`MHy5}S?O1i$a6<|W`OykD1&MlD_xn_9}&g#B)TMu zGN_ib(%Hthd3UF*&NhEUQ3lltR(ieWl@F?JDs?Tlhm=9Jl9jGti?)pDd8X7BMHy79 zSn23pGohwuedsTWGN@LwN+O+)(rCv(JHnl!D1&MZs|=#npXu4#)N4_cLA91uGEwDo zt^HvtNo}_qltHzQl^)^R6;rC3sxFE$sMfR6HTJi&C!N=9y9LA8;UK2z2doam|bMigaGZDQr@c>7YWeq=ksICb1^PzKdzRysBYcK)>4R6$Xc zLA8aI&Ni9jm78j+y(r3{+6t;ohLlB3%@IWzRNGkTnD>vi#98KO=TD2G465y*Vy25- z%G7UBltHzFm5zP(g?5KQWc2p4$z|pxVnSnL7+a^nSPL zi>Z2|D1&MrD_!Yz>>KigsQ^)wLA9TiJ{`(D`Q=m zgX$nFU1P^dlfqdJXsz(|-EL3@)ge#~R@ZZuIjVAsq716Ttn}-_u!w*2nrb47GN_KQ z((}r{rkm$_O%O#HR7Y9qd3{U1e!A8APZVWP9RsysqZgq9}vv6sR;C239sTRTO1Voo1!y z6+U?c=O6Vd?-xZGRA*S}d4*oMc&Mq@q9}vvEGs>)Zs`tJHx;{~+e6BrItQxg%3UQ* z6%|DpROeagd7ZD=Zjh-Cq9}vv0xNyv=+-XzX;XosD1+)ED}B3}wR1#}slB2ogX$8f zTX}!{GWAFlWl&vaNYE9$J>nNWj%9m7EzQzb%&Ln*Y(l~ z0+Lu567E|*@Q3ln0R?d#MhSAawHg#AOWl%j} zN-K&os2)SD+9BRL zlbnvj(xNDX>Ip07k-*!brg27?YAuQ~sGhRYZw@hwu1#xdv?$7;dd5mu4i$r6cQ>_4 z6lG97XQgj#F^ksNX6m9S%Ak6|N^8vLt|LTj@j&Q^}gT*NZZ!Ua`_z znKoqbeA6o@iZZBPv(ocQuwd>_tJO^uWl+6=T7|kt+HGo%D9WG;f?A6=EO=__uqeu) zddo^jZ`Y8Uwwih)iZZC)vC{n^iFv8f@VD1+(~E1lV9EEwMV*fsKT?-`7ma-Vh>Es6h#?S5kT$ryIRlG0a27e6%kZ| zDPyLZdMS!Bs3L({yf|QzsTi%?9#RHXWLC~V; zMNtM-6ju7ymakl)%2sQ%D9WIU%1XaS1vZ`R`~f=8ZxuxuRP^5?3LR44D>Idh;Q1|r zXQJHyW|8-&oY7gOlk+O^=-d>m6}`3FL&{*S7_9V5V5IMfYM3f1iZZBTvPvqovJLdP zZmOp!%AktHN=NUH?(v*|)NZU4MHy7FS!w47p1SAxvUEWdWl+Uo<-BI_)@0L)K340u zD9WIU%SuPogCR%Tm`dNq?IC4Q#bcF9YHe8*y@aVMq9}tZJ}d3v0KW{LBOD=$GN=-; z(y=k5Nk7lbwnG$UP$dL)qRYVAc7%^aQ3jPSsFD*VRW#+(*6jvmP$dFYugmp0rt*rS z464MS8u^zmZK}B_%AiUD>PPLk0j2^(Q3h2~Ryv~IY#!uUWA6|}8C1zw`N~!9x#{aG ztMynEWl$w&rK`&4pJF8&U0cZO@pRDvC0wQnS)$%A1G7vYI*|iZZCuu+lLfa?Gk)re2Do463xOl1b-( z4&Ueeph(~)~5k(nPnOW)FyRh2ZVWv`d zaC=A@R9RT*drH)Yl|4_`N}?!(Dl04PVVQ6H)>*A?q9}tZ8!Nq2j;Fto#?%y1ltGmp zRJ{G8mzmlliZZBju+nZ+FEG+Gvpo|<8B{r0>GeAHpzmWl-gYS`Dvwf2X~nD9WJ9!%CkHBcg6wZ?%Stq716MtehQh<4S~TW@^1C%Am@} zN^AM9iFM!9RZ)~dl^@jU!X+A-`X`Dqs0y%hcDyaEm$9R%44vH0QwCK*R(h3l_}_VB zs+uUupeh9FNzCz{x6yv0D1)jnE1gAqqzw_;YAqH;8B|4B>DZ_c{LZt+J}-(gsEV?R zEZw-Z#rvM}T@+1ACoEv|i=Sq9}u^0xO*XMy0F0#MBj0ltERImCmBwLcO?X z>aQrupsK`5k1)%~rk>H8s;k?1%Al&uN=I+uSIwP2K+mhRD9WI!0_xDH-{nnp7eyIV zRarSZ-u~u~`Nh-%QItVdjg_9)Z=YAiOdS(N8C2C->DngclX{-H_k}3RpsK;j+3_|% z$)vVcD?vB6hm=88la2lf;))hq=R1I0_5#~t}BCDyvq9}u^5i4iM+w_34 zxlJt;MHy6$Svl?It^EAVZ%rK+MHy60Sm_FOV%-g%_phI#D1)jgD;*nkn+z{vwKDW@ zJ5L!@%~+=hkYA1>^ zs5-OKH9(lunLOY00z^>;RTow|0}T0*x3JaPB8oDoy0X%%+%@g7My9Tcq715Ttn|FL z6mL7<)Gtw#LDij=u9hFv&f)pamZZ1adCH*b!AkGSPz5`OwOSQKQ3h2{R?bbuTlwVK zubS#5iZZBrvC^wtwA7;Frk0AL465F&wDX_N^!0oPI4g=WsQR$d&bJ%AxQW$zCyFwt z`m%C%yp>o~e}SpkecT>W230>+x@H?#@TlkhDkzFFsQRc+JYf+RzH2`X5 z$hh*5si~qUgK8kuTD>E?Gq`jX-6x7Ns0Kl;IUU}5)`zb|Q3lmuR>`D?KTEFl{B$XH zU$=*pK{W(ax+}jub8lHultDF=RdT5{ua&Q779A*xGN^`us`RPCdrG+5CQ+0@HJnvy z$!+c*`n##8q9}uE1gNHOYxFV|zn|L;%Agv_DzVi1Ii;Rw%vTge8C3qPl8Ng1A*bhF z9wdq~s7A5U9`?-~>Y*LsW>J(uHJX(^mk(Dx;(3}s6Ga(RV_4~(a{Ojj&(l0Xf43Wy zK{b|@u0{9tiR<}#P*N0SP>o}yv&})D?kyQ8iB#Wl&9E zrBA)Hd85xVbygH*PzA8k&R-lm;fkp*q9}uEA}c+wK}kk=)*I;txILr{s!6PL#-9KD znlt6=c~uid8B~)&RjzbloT(wAD1&MWE4|A7GPM|CYP~4Rpqk1`*HKR{5Ai&|Ziu1` zs%fnBdKG?IVYtwl(NiJ}aunXL3_ z?whYwe^XOLQ3lm4R=P?V+OuYHQ`<#R22~&{T?1S!b+?(R+oC9gYBnqFe9O-1JD3VT z$n7CzP|abLQtqhsAzB5SDjvg{4u9c=biJ}aud7xqqT-Vgpd{LA^HJ_E< zU)y>lFJ$VRD9WH(z)E{~uJ6^Kra}&OyFnRL3t8!TH444iv);%eiZZAcvC`F7x~o3U z;L^LYu_(%*S`4+O<^JmVayv#8Wl$|)rR%5-AI?6pT02Ei2Gvqlx{k{DC+=5Mw?$C~ z)iPGjj<-VXXYDc-Vu;&A%Ai`#Dut*Y>+b(Dl~xpGP^|#<;MDH{rW%N%462o^^!ZgS z>{lOClSEMl)hbr{ji_?+;4h|*h@uRt)ljQ<(~AM7zKEg>sx?sS!KNAYO{E*^_K-5D z*0R#;6`Z>DCsXxBQ3lmIR{DgUbZ~nQQ$s~j2Gx32&W^WS4JVc~wNVshP;FqP&#wcy z@4Pg1T@+ znkp)aGN_KQ(lI}}`ix_yx{0C;s-vv*uI$?&WI0nyMNtOTF;H(OL|2GvPcdN0pUk!!Z8hN38g>J%%zUO6-6 z|6ppID9WHZ%}VFqWt%g6HMLa~Wl)`ArAO#9yw7-34@FT1)mc_L=2vd*e%w^lQEoRV zgX$bBy~^w674^KQ-F(%B|f(%b%~0z^>;)kRi%UIkXq z@jQukiJ}auORV&~s?6OK#cDkfMHy6=L4}Nc#u<`&FGn5i_K-5DuCUVcx}LJmUQ_u+ zQ3lmjR(f6&m%OcJs+B0ppt{CN&+F3MgojK`6h#?S*Fi0e-Ry>`U7{$1>IN%4uNiqW ztu^&j6lGA|WTod7VqW>_rlOB=dq^2nw^-?Uot*l>^R=gdD9WI^4Qf>4W%sOBD^Zj| zb%&LnSHt?1JS&IEq9}vvE~vYyA}+UDdqq(O)jd{vUa#v#sBG$`D9WI^&r08yYxca_ z+f=NvZVxGg>H#Zf$J^D0g_@emD~d9x9)emqBjAXs#-b>L>Jclw%HgY}E^W$R6lG97 zW~Jx#^VAp5x0H>dD1+(=EBy{|FjVe6R_lr=%Ak76O6T5wds_vW`XP!ksGhNMcDz05 zzw4=~)Z^UFQwG&@R(h4cRk`83V(Pq6Q50oRy9 zLG^)^t{i^v^!_`mpNpals*kMnDxVr#p^nvxHo@&7Wl(*BTGKyW>SrpKD9WJv%t}}0 zM>D<8VyclS%AoqfN@swnjaTk46(EW-sJ?>w6s65sQ~!yg461LSQqIZinMEIoq716< ztn}TX+_hVt-|vka;P#L*sD7~05fw4%*(!E~8AVYB)lXJB1LS#>*t52&B8oDoezDRS zAX8QPk+RMk{X|g))o-Y^FMaH+rk0DM45~j+t77PFgH2r&MHy7VtaKI)TV_UQQ-4HJ z2Gw6stzy@5K3eE`rJv|_o-(NZvC?rka?`&>rfP|z45|>$pB*}+Ua##BS8g}uFN!j# z=wJ31I;8W5@fJLLx@TrvEs8RzLa}moymdSr!}A*^7e!G9RcKaPt9P~ef9wcjVo|O7x zwR|SKJ){h($gH$hB+ql`^$T6lG9FW2Lp?hH5m*)J0L0K^2{qv*Rs%wgg2@eHTR;R54g-tv$=< zJTjGZirab0po+=L+41%@T>{U_p|mKAda|9Ge84TltGn{m9A}yWSlY7j&Ou1%AoRPrBA(V zsa~ftwN4aeP$hy|vF>ehmTx-S+!RF_REa_LnAo+csgTp$9#RHX5>Uftc0Fk-gDA?N zN(yS<##Hl6)euD)RLMZy`}6dgDN?wtWTeMRz%B1Q3h2CQ1J)$^{gt-i=qsw zl%V=%-I>{r@Vh9=ph^X5T;83Y6;ZP3Zs#e3DmAD@6$h2KTIEDh22~nR2b1p0W~#d= z%AiUMDo6Nzp7s1(QItWIj+L%^Cp<4)%xWDKMHy7-LB0GI)3auKCyFwtGO*I0-mae% z>z37uKf~=IWl&{gSa^)ca{F`7F1GltGn;mA>7iD{ykFsS2VfgDNj8=ff*+nYvtd8l#=>Es8Rz z^09J$6wTZDqTM**{=b=`D1$0LD}4)iIXjH!YtMF3ltER1mGiNNw<*ioJO8LhcuN#z zP!(hqQ`G7h<5!saEs8Rz3bE3a!_hD`TA4~7=yskms0y=kcD(%zNb8xg%Zj25sv@kk z*66N5X{}aQQItVdl$AcspM;*^8S^tmQ3h2pRyv|)ycq2HS=#|oltERTm9yh*%=JVA z>0`ec6&$}R3%vH&tXrMtLOQST}l*XP?comE45mVs_a?M z_ZCGNRHazyowDHlio14%%SBNJRcTgwy#ik(%4O=JD9WHJ!%90pd|>}!roM}!463rM zbjGe8V)$cI$>+E|qztNZtehQhVS*mjHdRd&Wl)u8r7OMspW7cW)lU>=ty7{XgQ^lM{YF&h^ro<;-io3Os>-Z%W~=dfxM#+WI@j$X zWl&XNrRTMNU!_e}D~l+~psLDB@5;Z81|2t5T@+6fJrjONxkuQbgy;G7P!wfQ)n}DnRHOG@&f5`2nD6$GGN>A`N+#-hqXM2WUq}>XP&H(w zb5#3|b3AL&uA(S|su3$^$6J=j5&zi{&Jsl#RE=5b*oagoRIsW2q9}u^2`lY<_->O5 zntCIOGN_ue((^jeu8C)C#983>kTR&6vC?^d@7n5~x9mcqD1)jwD_w7#>fY>?9bs!x zltI;kRSfCjoxqaL(nD7%V?-ow4dQp@?)rytg%PIQwFKe~#h@uRt z)~vLL%Uf)@VJiGWw}+HL)rOT`ul+YF*Ef|#6lGAgWu@I1b+c_PQ*}g9230#&I`^)q zUtyA|fubmbsy);imO0xqQ;S4V22}@E`b_!t^VvC5$3#&ERYz9Z!-X?yrZV+h6lG9# zVx_C)2J?@2<_(`kZs#e3sxvDc8yk|ezHGHJilPjvF06F!o$~TR3RCq&Q3h34R(hv= zz4*czx;lEtiJ}ZDTJ?txsYiHj?mFimRc#mLz8QGGeRXH0SNUk36X8rf5k(oS)q|CG zzRldwb4`U`?Dmi{sCu%}XXVi5qgI>BB8oDoda=?Tc3su@tEtAKD1)juE4?ebg~@Tj z)I?E~LDh$q&Z6_~5BI#$?-oTFRDD4OR(#OjYP}Fe8C3mP>Gg`x?xW``R_rBi4=IDH zKP!F0?pnOe876v_{X|g))c{sHZ|n*6Y>lZ7q9}uEAS<1F4~5Co!qf~=ltDF!m9yim zeXi|$P5mc|GN=Z#(m5(Zml91)JrG41R6{`ByBBAQsW4039#RI?P*6{N7S=PBUKC|e z4P&J%*xs8SIya4WzOpFFpc>9fXSN{^PJA}iSrlbZjeuG!({7q-YLY0*pc)Ca)^wWU z9G)KGMp2YO&d!B9nVKnzGN|UU z(mN&gp`6uB9S}tsRP$NsdChHI!1Ep8vna}-TEI$=F!1l|f>tZ-Dz}G}LA8*Tv*YdN zxY?ekLse0fLA8jLUggI3_OG*AeMC_P)nZoKjUB^#d^fdB6lG8?VU=2r@b&PSo)yte zQItWol$HMe{LohAepxM_)owQ^gK8NoJ;EQ;NB%TbSQKSYEoY^(&G?L8bDQcWiZZBH zuyS4td8QGvltHzLm0qtd z5i|K)ty7{XgK9G?T`g~#_;#78*PWC=HpxVVsXMo@J(|W$MJrzY6RJ&Q}ILy|$ zL2s)SX`Oq$D1&MbE4|8z(uY1}DxE0GpxO)SNL)W>!J_N=5~3)BY9A}@;ifwk15Gs& zMHy84S?L=4a?&ijObrr68B_;Y={UUI@5UTcOGHry)j?L;`IF^hJTSFi6lG8yVx>LI zRj@=8Q%^-v2GwC!dW3_|PVyY#KT(uHb%d2(<xwwgEwn-(5 zGN{h7((?)$9J-CwDk+LGsLrv{*`{5muX9bc6-60T=UF*B-cCnvwIQItV-ftB7V zHQt;lXKJ%3%AmT)O5ZE5#i=~r)D2OTL3N3hej_SbD&hD?iRuV-SR99I!JKiExiS8L2Jw;Il)iqXH>t**gf9(k8iJ}au z>#X#h=-0KcRZJZbMHy5#SZNPSWxG4k)JIX2L3NXrv*T^ZyR@ZD`EGK1NEuYOSm{^d z8-G^cH&sFuWl-H_rK9)On~t|kbrwY#RCieERo>9xrDtZFB#JVq?t)6xFLzz5wM`Ud zP~BtY?07rwo8_yiTcRj~>OQL!qE`L<{LfT~&2A4VgX#e*{UV)xQhm?Z$R&z0s2;L% zcD!}YlKp|zYAK2`s2;J>Zw_ZS`}Z_8K@??BJ!Yjxm|$u$&pf|R6lG97VHIDFaDODf zuvY7>D9WIE$|{bi-W#uazL+K0;`Wd-sGhOXv5~IT%TFYO zL{SFS3sySjw?zC`!PF#CltJ~9m9yh5p>MZ~rgn>>460YGbnd;K;6Z3pk3~@i)oWG> zq}G#k|9Mt=5w^NLqztMzP^3ocBZs#e3>JuwHuQ78{ueDlvMNtOTXIA=5*<7oD(@R}PH4sG^R9{%> zoiZ-g`UR$ji=qswudH+i2;a9@ds8b#Q3lmFR{H!3Q(<&wQ#V9W2Gw^~`mJ)`r1+kB zKJ0e4hm=9}18QCRdFigz$|Z_2sD47Nn*XZqHPu`cWl;TMrE^r6yx~unnj(rasD883 zJLOQcPoDGIEs8Rz{y?ou{?+nWt*4?WgDMzmr5m!_b6!z)xILr{s=uss#*TQmcqXfr zR}^JX{bQxG&8*z3a+zu&iZZA|IPD7^QfuAq9M3b)PZmWPR3TYut-+-p9=2M0MNtM- zC{WL@%9o-dpwL{SD+SWvAy>4iZZBTveM3f^ljb8)KXEDK^2RY_HanX zFH22b6h#?Sv03Rj{J!ML6H~uMQ3h2UR@#jl`TOTHm43I|L&~6v%Sw;1Sl5B2O;r;` z8C3CD=^9|bheV$D%7LONgDO5N{d(|hz{japYl$ezpi00hxm@M2aZi3QbyyT-P$gug zM_By&l?|r8iJ}ZDUsk$ui0#{Ml&M5}+#XT}RU%f-j<;t0-%l`AToh$cC1$0apBn4G zRHoXCq714etaRR(K6X$IQ!_+S231n1Rc7&{Yo-p0q715JthCmkpShQtdLxQ5sFJhN zd%1hH?GH`G+w1m_GN@9p();V}^0b9b6&FPrR4Jj>>3+plnd&TxGN@9qN+Q>5RIw0& zrUFG#232aPHGXgWd8ST_q714utn|F5w(9H*f1RHvqcnTP-SQ3JotHgc>nSht945hWl-e+mAm6e z=MT{HigLj1A!ShIWTo907IpnNQ^iG5230OrN#zLrR+jgC@9iOqGN^Jxt*WzwJ--jI zLKJ0C<$+qW;v|}BM|e{dWl-g1rDJ1Jm!|JcMLg(sgEFY{fvP%km@~;~53`G+466LB zbQUe}mPU!MNkk0K?J3vfQa;7r1u(nTQ^R|?=n-pZUYKw|nRQKj}>WR8d z3Nl)?Q)ONMrF|t)B{w^D2pO%~tFkUPYGsY1+LD5dRvlDX4-B3#QOX)j3Nl)CRArs7 z*V~%ynM(>XT1BHW7ZrZK`J(T~Qr0d~kkP6Ws^>`+C^9mKs0Y4xY6CJ_bw*X5RLMVA zoe@=y6lApOg6btw?~N&G%~bRw1sScnqT)Rq@}6tBl=U$w$Y|9KmFcGOlP&+0Q=;~g zf{a$(RaxU|yWQib?V;ytY3qEYkb;a>y-?L8 z^=8s&pOiI+6lApOjjAH4vI#q^`HlUgAfr_uROa%)Pu8D{kCU<<+3M5=WVCXjDnlyA zL*H)|RgV;8wCanhEUCOp556GEPYNrKUO`pl#&Z=F|pcw2D(@E#7qdoT!&cK}IVNDsJ<)j~{td)BsYD(JCGl zxA}c9FS5pm^GQKQs{~YB8{1lzvRc$3QjpOq5f#r=4B3#^I?K6!aB2fGT6tAjwa?w% z2?^)ZfD~l3>Zi&|-Sm((N0d$qGFtUV#UqEM=Mt>BltrW2ev!40U51QQ1SWdSEcn~QPoI6Mk^mGKCU?*&BBCJhy6%FMypg* zd|Ve-J=RakdXE%jv>JfQ{J_uELKRDh+C&O6TKQ4&_;AUEd?Q3%A_W<(0;qVrF==K| zkEmyMICTgatPs}W0 z-H9%ff{a!}Q5B>;Jk{fsS+a)(cRFJ|z=ZMP0tTZQ_ zd$s^6$Y}LCD&E6q4`kmZY7QyLXf*;A@8Q@zMXl$`J)|I`)ksua^QYHsX)0yiB?TF+ zMxo-_gL8j1SuLvcE~gG5qt$3s<_CUi9xH0yQ`(b)j8TOh9ha0xvJS}QCDadFw9u@ad<>J5kRMbLJkkM)a zDz3w78?&1S0&ep^k%Ej?@1Wwl!?UxRS#x^#NI^!ciKw`rZ?<`abzJ54ICTgattO%3 z@!|1b$M%;!>_ZANT1`g9d$@1^;*O#wk%Ej?Q&91>+$z=6UevdwAfwg0sJIS~4{Y(mv z5-G@NH4PQF!?C9iv=lX!6lAoTuG9;S_iYpP6)DJQ^#Llb!zC5}OcQmQ6lApe5EWm` z_3ljVE$XqoP8~uHTJHKr^}j{cBn26*K2mB#Rk!t&?Ii^ntv*J@SEcKx!RFNQ z`TBqqWVD)zifexE)-uaPZ6*a7tzZf{a$5pyJj$ z{-Yh%U9U4K$Y`|)755uM4%DtIWeq0<8LbwpvVMN2$8u52NI^!cC8+qgmQ1gkRn#F; zkkM)>DjrAuoOg@WHnRNU)FEWFT84^y?1vY$_)N;GKngNiEmviY&(bxwsJ^5iqt&OV zxVL$8;5%Q4dWRHbv|6Fml*gxL7xg76$Y}K$Dt^j7@!%t7XwN;sSyGVEYNb-k3Y4{a zfT#C6bqE=)R-xh+HEU&*HA~!v6lAnojfz{;`PT8bWe*3Ff{a$5qvHE=!!>iqh+04j zGFq)c#Wi1fS{ZB1c8C;YwE6-S_oD9>TW#IH9z5XG24u8ai;9n{@U1NsWe>}ff{a${ zP;u*BadvtQQ9VgPMyoGXS*y?8oFwW^QjpPVJu0q^$7j`!74-!v$Y}KyD!wXf)SF>$ zW!$1pk%Ej?U!&sMcxQ_DmZ(P#I&}yctu~>Mf z(P|?qKCaJ(-ZMMJ$2FQ1WVHGgRUYcG=iV!6ZZE8sk%Ej?-=X3bHDKep??nAf3Nl)4 zLdEy5vR@Cko-6+$1sSb2qcT76Gkwfs?WC-i4mmXs8LhrY#nEyWP50HY4RzILJ(-Zjl zbY6RFjGg7MQyY-cYC9@!8zcT5d`8MDP6{$w?Lfu%ly~MNOc&LX6lApe5f$&@z_Ja^ z2Kcy!kb;a>J5iY*`024_++9&0l7fs@yHIg&Q}Eq&6+~?&1sSb&qvC5hI=<4kqHd6a zj8=P4nIHJMx^LBHQALk9H4hoBenQ1PK+>Jbe~D^A3Nl*lMP+{AXUl8z&x%SV1sSb= zM#XKu+5DMzL`^3J8LjrA;Nw8LbYhvYx%Tw6&DAg%o78I)aLyq=ub&(z;jPA_W<(j-uj`L+<)3tues!$DBHZ zj8?}`am`=xpKc<1*n<>gv^uWTh2vYl7d3(uWVAYgiti~C-`;jx)M8SQ(dr~BZoMtW zf1Ds{4=KoK^(!hK1C-siyr-ypq#&c!DOJ{AHS?Jba3A&jaiNll!y#M}dqMkY7)FEV?dTn5qeA3%IVVmQD{~s0A$1LgQ z<|Xzs^#$B=7EJLEK0B|_mLa3}=XX@*2Y#-+^N2NPHGvdlw7Q6j+fUB% z3Nl(P~Y^_TyOdhDcAW02A63Mw8ooy<7-si+#HAfwe) zRD4{oJ^rIhR6kOX(drtiqEv^sN;cUoYAPwnXmuSG_ejP2J(W$=52PTY)gP#eQ(2D< zyRbymJyMX->IN!q;aN^pwXUWLzdCgY8Le)j;yeD4{I}~#S$#-BMyo$nS*J7Rnbykf z@GVl1(drf|zTR6tZT}_Ab)+Dp)nBOi9+xZS&KCby64d@{18Y#$V^)ISoREOJ29r{F6k<(5cLPo3qQ1Q4fx!H`D zL`9Q=j8;+R;?J6;1eMju`<+$RU{a9LDhn#UQa<>2-8WL!GE$Jy>H$>T4u5#1X!Q^(zABrIc}cBhS3& zoH~SzR*$3Nn*a849y8S7itpz2_VrpRsxK+XXq5*Qx86BhM&1?mHYvzx zl@}F{jrUh;ZS@=LNI^!cCsA>4v%q(Cgp_rH6lAo@r^+hz#}hw^%68tVL&#{A9~B?h zu{zO~Dn|-3T0Mn|udk{n+gaaF=uQeUS`|=gT<21`WDj2_1sScLM#bkVDdRKiHz^j8 zf{a!LQE|_JTzoJ)_F1oIR^G(ko92GFm;0 zs;F~mM2*_8`yDB(4=KoKRTvewsOxnL{3mKMDadG51QquHU0)r%LeyGPkkP6rDz1(6 zd-JUsymO==qg63f+&1pSwy|b2a$j)j5Hea7S7qHm0H#Bu|!deNkK-dmz4UWXTAZVHj;vjRuz;Q zTj8qpz0>`qAfr`9rGChA^SG3Ci4*J}tn~J(b3Nl*NLB+j#hnE*t6P5Ln(>5TZRb5p46gj%tlG>tPAO#t%>M2!f zMmaN+WhIh=j8?5t@e|OO>CafR%@avMMyocc%n$r@y}Ngsl(m`^WVC9FiubUJ z|Mm`1$4Nm(t9GdP$?k`2YptiPY*(E+gp5}0RasfzxV=%zdY%+ywCbQ#kuAS`CaN7N z$Y|9O6}OFN2e*nAHINi!w2DT>SIV&TU#;1~8KfYiRVP#hspfOmJX%r8+DQsBT6IRn zb=c+JALf7Z^>vpNWVGsnihF>(*V>Khsf6|CtWioSQjpQAH!6Pi{9xT|tDlc11sSdSpyGCzXZ03y z1LQp%MhY@oxlom)J*?EQ(KS)?NI^!czNq+GK7IB5cu@yQK}IXLQp-0Sx-2T{52p?x zqg4zlZu4F`rqer(` z?>!&9;nX~2wDO|jb~xhN9&@Sjag`wj8Lj%MvUWZHt~FZjObRku^+&~HwiotHs48U* zAq5$&l2Gwgc`)jIYYt>SDadG*jEYCFKhL;l%@u4V1sSbUlQ4$XS`9|U zdsyW2M^1>ELJBfk4MD|Eh(8Ve$ox;Pjn$+eqtz>@_=)4+z6Gpn`A1Ta(dt!H{Oqt} zov*Kyb%_*Yw0aE{_clL_K54c2ytka1hm2N3QSlyT)cL53lvRTiWV9NFil1Ru7uad_ z^W8{6MyuhdOf$mIvErM|je_gYPYN+W$D=)tv7~6|8mY3WV9NC zitl>)z8-u~_OK}_$Y}KjDsJ=773&x)%0~(^T8%};JwWpOp({mABn26*#-ZY?^2)bs z-V(Kv6lAn|6BW1l&h?tSCh9OL$Y}KzD(*K5_1usqD$Cza9YRK{w^4CBEcr}tQ!(5Q zUm^t=t;VC`7Ik*{;+CRXk%Ej?6HxJ49`jh!Iig}nK}M^0P;njhJ94R(sIjCVqt!&E zruj;m>g3~EK?*WjO+v+c_|(ku=2ph)ASuXbH5nE6Hpg$iYRw+}OA0btO+m%&aQ?Qh zev-0E+;+|vWVCu$m9=5+ha*KbCIuO-rlR6HTwmWVHGS6+ij5 z=-BkSsMknAMyroe@%h^K<;PYJ@EIw{Xf+d+IZ62W>!H5yNLfFVf{a$Pl={hYCX1-7 zcbz(fj8?NznTrZPEvhtHAgVGc$Y?bO)uW`=zg+gbsE(u{qt#qgT=R#THQgdAl@w&O znum(d@-Mkp^b<9S6lAoTkBX10*<&r&iCRkvGFmNAW&PvbXU#brAO#t%7NX)SrQ?L_ zqou5WNkK-dPf&52-`e5ZsiK~{=bSIdXtf9x-%~!$Gu9gEH6;ZZtrnx=nlJtJ+_6$t z8Y#$VwFDKn-u1sNTOw*IDadHG6czWqfhCjri~52TWVBj_ik~>ny>axYsH3DHqt$X$ zTpNwXSF!GTIsS3#5HebQii&4osthy_0Vd&ms*{3@Rx42P=qviCrMpGNlY)#^pP}N~ z7k!Y8Es!0kmTJ1o^wXr|xnc<>(lY)#^ zKceD({)g|^j}tY56lAp8iHdvCq9goCqL!0_j8?l)aqAu2=)xQ8Ljr9;+oHWqp0-^TZR;5wE77Zx5Kk9{p*pkT9AT_R(nzLaSb>*Vw5O9 zDadH`Gb*n6oAI;ziu!;QWVG6ciff~0`Z8JTzo9Ye)!Bj2y@1w>UQ1sSc5qvAIR)9*ZKZkt>iE>e)u>I5ooy+y8{m@eu~QjpQ= zBr3kXu3YR~LDWi8kkRT_RJ@0~Mvk+-m$H`>WVAYkitDhz%bxvG)<2{mqt$6tT!)3~ zjj8cjvL zPYN3#}Q>%cLNq)df}7gg4?E$R6g+=F}l% zwE7(tj{zR*`enSR#-t#l)kRc153sguHS1kKe^QXq>JlpMvF8q6Y1RCPq#&c!WmNq9 zwX3b)JS_5+vWXOAw7Q~H);-hPiMmD#GFn|#YFzjJZA3l$uv3SS(drs1e!KKw!Of3| zYDo$*T3tuQ?XX8uK{LSQMk$=sRYNFyvK}M_FsJJ%TpRnIAzex%*THQfqe&A>IN3*PJ zc@-(hXmuAAUti~P9Nr^)c#ITew7Q3i_i)Y;`@KW198MiVMyr2NaUJ#=9vC5IRV4)( zt^P&DS7pngqn{Vmn-pZU`cJ7VW0qJ?9B-0>j8;+RCX_V`x2OrfUtKF@eL)H`T4h1S z_pjNDGERy*N(wSsJ%EbaM$1WqR)~7|5vL9zqg7T^T!*`N?)*yB3#1^U)q|+`d{s(s z`GcrvQjpQ=Ayix&xQQwh*j8>1K;t#YH{Ui6!i+kK**%IVZ0WVCu*sYQPmtR$)~DadH`1S)>wsC@Rr-lAej zK}M@QsCc|_{@cwTih7+CWVFhQirf60Kgur^^$97+X!Rs2zLux;KCoNVPEwH33jXpz z)-2rjHY$DRnyBlfoWG7>{{~HdRn~$%J*S8&mdmMm$mp`3Ld7HV&QDjf?s`o~K}M?r zsJI<^n(wS2WqC+JMysclDmi$68Bya&K}M^BsQCK2`(3Oxg8iHnWV9-T%5*XK>Hfo@ zic;1&QjpQ=8B~0hm*wtjUCRX@bLtQ>T0M)3`>5H6vRTi1^+`cStHP-GN_n^O)WNcc zUQ&?Jst78s`CO}3SToY^kb;a>MN#n{Hk|vaRU2QBf{a$hP;uLscla^Wg>WDBD=Elm zRU8%f8|jz&{VXa=Zl?|*qg4r1-1jyaxa_Q`vZNrRRY_Fb&(C@*$?PoeVQW&5(W(?G zzP{cl(>7I9GAYPt^&Bd`e_eU`LN!q{NI^!c=TY%-y>Yka1W`LkK}M_6sJLf~-*jNB zsLP}vqg5GHP7Oyz9lUVMdj5L!ac4PXv?_~=Thx(aL(`)eES&7roJGRWng7 zNkK-da;VH}IsDux)q9Sp0i+lTU5g*CQlU=M+!1pH9*DJ*Kg~4?hy3~DadHmP?a^Z zdYx^eW{`r6R*g_`kKM6*Ol?uCNI^!c#;D9>4Sp&gUbbG;PoyBDRTET?llptiL#7+% zyWV9|kkP6ss=}lm99wLYsN7FFbqg7-nxW$B>%xp?$3!(C1sScHqsl>L?Hl<=vZw@7 zkkP6IDz3vl@69bMY6L0BXw?!Gw~cuVFL^}GA_W<(S}D~o*TfW2Uyy=~R;^L-wY=c{ zi`GbQ7b(bS)drQhk>F={{!!*e!RPA+DadHm78PI1uQhQO7nLWUbG(qzsvRo6mY?kO z&Mr~)NI^!c_Ne%(oRB-~_oCuSK}M?%sJK6DwdSVPM~x)~8Lc|1vaZeuyeDOSLJBfk zMWf>JMqt^S)}3fODadHm2^F8OC$@gGLCU&L3Nl)CM#XpYnyyLTiprngsd>m~)ddxw zuapwMSiMboQjpQAD=Mz}hB<$ald^h{f{a$(Q1N(v)wq_sMZHQ2GFo*<#bcZC`=0nm z)B;kF(W(b3ZoNlSeyk(vFe%7r)e{xh{MHHOmWaAd3Nl*tLd7jA|A0;FL=}F@sd>m~ z)f*M>;pR#YR}oc@6lApOqg0-^doL8#n-pZUa-rfqtaW~ZHF9{B6lApOi;8>E?ThWd zU@(IeWVCXl;%oWm6;UN*55FS?8LeVa@yOxY>{srH`kfSHw2DQ=_sYuOo&8Nz-U3d| zLq@AORo1!=XO@bpLJBfkc~J3jjsK%T4N<*GK}M^1RD6A{>-^AGkkKj$RY}}tR8+>f8y->7q#&bJGAce_h2rX66!iuv z$Y_;21sSbUQStdo+tO{jsDDX8Mymm+ z_w0aE{e?O|i%te<)eM1T|S`9^Irfc!DD$A~{qArty zj8?-?6(!YlP$BDmWzlDxnum;5!%>+Z`1yLu*i}+iCsL5n>UC7llX~WEQ;(=&q#&c! z2vq!>(s1ZQ)^p`5QjpPVBq|;e{n@;*HD)_Y3Nl)aLdEx#ytzj%kUh-(tWz71(P}g* zzQZoK{$XEHwMjunt1+l}Mc}!RW@Gp-(XRN z3p+Ir8Li$%Wq#o2M2E?fM7>N3GFpvC#m^2i5~o-#sy`{nXf**9_t@+AwLdClO(F#u zt=>^(t$tzhXQDnO1sSa-qT=(Fn4`onQTs_jMypAvxJ3>AyUt!wcS%7;tI4Ri=GWBE zwO>@BB2LXiMyn~PoV8I=H!ogF6jhfLWVCu071w;u0#lz8)rk~jw3>>FkE`MQ#x+F^ zAq5$&-b2N$_vZf1jYNGw3Nl)~kBY|t@BB0Dw5ScFAfweZRJ?~<7R7ZIb(j=nw3?2J z_prga|Ul&!lsB=ajqt%C~Om*YOzjM+oQ7uV9Myna9_*$;M z@r5K&LrFnKtB;hr_57*VMJ*=<8Ld7>#ciW!zeCGK9VZ1Dt!AR)D<$`-fT>RIZ5}G- z)COd8Lbwh;(q?msWZ%D1lPs}QjpPV2`auSe|`O+HFJBE6lAnoipo6F;OBPJMP`bW z%gSEDsd>m~wG0*aQ5E8E|0b$9DadHG92Jio#-)3#+NehgGFp9#iti5X>Qq`QWw}T} zMynO5O3`thX=2anzfKA=T78D99I2w0Z=RI0J|_hktyZFXn$%C%9#0i@ffQu4TBX#I z>ho@h%3so{dB|wB8WoR4|N7kiz3fJ$AfwgisJLeO%i3R5RZ@`AYCS4$hrjJC+*ec|QjpQ=E2ReBn%7X&a8i)b>T6Wy z2Y#+K|EImEIiw(?)dp1D+kCz5L9eKtq#&c!H>kMg^PVkbI#fQ(mq|fJtBt6*=9m37 z?MG3MKj+juWVHGg75CWH18-aRud1XVqt$n)xb=4aYIRX5t2ZggXtfCy_lNVZwpuJ| zBq_*fwHX!nQS&bBe_7P0q#&c!_o(;|`%=`))|~ksQjpPV3o1S?-?6?cq^zjtojQb! zR$Ec=`6_m!#=oMTCj}X;wxQy-apn8f*7enj6lApe0TrLGrM_ru=C(g6$Y`}46}OG& zDlN3y{A5y)(P{@OzAx9D5dQ@voX;1eAfwffN;P^dk992{BLx|)cB0}s?3SMEfRvTB zv{Unt(P|ee(+T1ysci?l=1D+K_^bRtHfzdlD5j=Fgetr52avCj}X;4x!>XB3GS1H;NiZ3Nl(9M#aa~Iam3P zqE?ZDj8;cb@!fn;)(%@l{Xz;dS{+5jeblCkG5bW_Bn26*j-le($kw-iny5l$o#l|x z>NqO%13$6NmzaqCAfwd@RD4|B>y5Bx9eb04j8-R6@eJqqMRQ6?S+A0Uj8?y* z;^(g>IeHBhwU`uSv^s^VBpp}fAE!+cb%+#Xv^tH7M=9-h9=a|n=L=39LPo1IsIpO6 zZQ@&hD5@$c$Y^yI71yEXr7S;*YC{S#TAf41?J)o0gyN!-NI^!c^Qa!CJskgOZEIe1 zJSoU%^&2X_Di2MqKU&IKKngNiT|mX>tM@+#dy3jY3Nl*#j*9!J5ANE(d3T2tWVE`7 ziubVL<6|)49Om=oobv@4tuCSBnm_1Wnl5|TniOQTx{QkZ!z`0r8$|Ud1sScbpyE61 z`LVf9iF$_=WVE`9im#N3d)$6epOb=&R@YGR9=03y)Id?ENkK-d>!_T%ii+AjXIcqS z55MRvhm2N#pyH8U(e^vcO^N%B!lWRh)eTgpo5s(KZnrjyYDo$*THQp&J$Cnvugn%T zloVvN`V$pjmBo)0enHeHq#&c!EmS-PXf`*|G!s6qjiex>)nBN%=HL9gsx|9)gcM}7 z`WqELwbeUW$9kgwj}&CIx~-IVV4nop!wTh{^932L?w~TK7C(30zgc$&Hz~+ybr%)4 zje5H`R*|x%l7fs@_fYZJW=zL>W&)Dya0w~MX!Q>&?xWV!K5mVccaVaNR{yH9(ubY5 zdbTs9AfwfPsJLw`*_MBe?BPQ%ImZhbt)fhG&zgnr%m044X1S=zwfUJ3FkAF6lAn| z6cwMZ6SbbIAZi^c$Y_-l6^~Mmq__J@)DcpU(JGfJtKoQ$RU26=I&}*ftsXd)PA14Ks<$XZa{8$Y}K>D(-u`KiaIes9cqtnum;5 z`B3rfL4|cgHi~LM3Nl*dN5ySp%-{p#MY%~qMysb(S(BIE>MiO`QjpQA04g4RohfqF z8WAlf1sScLM#ba9r`8;>+Qx2DkkP6jswe4+8qmi(N%rtxQjpQAkSgobx&7yhdakll z^N`W%8B~0hfA#h$EUGgp$Y}K}D)ab+pMj_PcNR5<6lAn2jEbLA{(JBCYEfU3f{a#0 zP;qT+es6>s9C16mLJBfk6-C9p&8PACZi>oZ#ir8bb;)T9rh_z0H(^4^|YlfD~l3DuwD%I$!VJ zjp{1uM^cc{>N!+=eSLoF5i?ZeJ^Y;%WVCu771zf2vkS|L%3IZ`dB|v08Wo?fuJv<& zBC0Ma$Y@mt71v>{xu>kLsEZV2v?{CATmG@uoZc`}kkRS|RD3O$jp?;R_HZUC$Y@m# z6`!xi_Pk=cMy|tMq#&c!i%N|hSS(%CO;V82syr(513v`@46yFz1*pyH>t+6iN=Z&hWGf{a!bQStrjbk%yhq^x4v#&3?c;?t*R^4YtnA(X>=MX$Y@mq6`!vu+uyt(Lrc%|k}3+Nih=PaJ$@ANXl9X|Xv8TpPJ-IyDa&ts0`@JM0AiE^~phs!a+q zS~Wt&=WFf8mew6MmK0>PYOKmiYipWDu&hy}Afr_iROSbMI_IfoeZyoaDadHm6cs<~ z71-MLmXvjn6lAn&hKlb*4LaS;D(azHP8~u!ei6Pd!%?47C z(W(t9zEZC2*kavbPmqF)R&7!7Rhi@IcDv=`$X+01sSb6qv9T5t!HCE)IX#kqg5AF{Oqv&aQ;D}O4V`B z7i6^Ripo4@;OCL0olA-8LJBfkbwkCq(PhBJH$;sk1sScntFn%tX=L5aKOqGft$Lv1 zwlQkc$_rA~VN#IMswXP0!#$5YXWh-C>N>Rn8LfJu;?eRSJ&RdwzBDPwXw@4P-_1A9 zy1PU6up=qRXw?T5@8OQt#m9;oP6{$wxlnQIeZKRyFGPJp3Nl*tMP&xN_=)K_vzMsd zq#&b}8x`NpkG5_YD=KR}rw$>bRSYWb=Uwf#nr@h{%F3i5qg5;_u8ma}UNPM;D;Fuq zXcdQw&)3!x-A9RfgA`=6@}S~6TtB7y3{jtvf{a%2s;tqgt921|kQ8LJNU`_CI+22mR{c=%J*9cRGA~G3LrFnK ztNy6?s!V!mrZrRXF)7Gsm4vD&wZl4f$L*1_Hj{#kR>`Q$5Bxk)Cw+pbzezzxs}xjR z^M!tGvqDtKmz|o2j8;BW+@ccuRriW&O$stvrJ~|F^XzY|oF*!R6lAm-fQozUS4z5u zh?-3bGFtgj@rdZ+@;k>x?Ii^ntpcccl=9NljKiXCl7fs@X-cKcOWq`^Km(@^A){3~ zD!!*&E!s6jR2@=~(JBKKw?qHAmDYVZg%o788iBkQ8LJ8iIe)u>NQl{djE);w$CV zV?C_em`w^YT8&4==WAjAMph5-BPqyeH360RfuDifTqhynd~T3}j8^ZU;(nvehx;yx zD$>NMdB|ur5taFYpW!*3rzYoLO-MmTt4XN1^^Wp?eL~6_KngNiO-A)7mDTjgf6U8p zKCbbkAfwe3RNM|P485~a)DlvV(du1P<_CTT4QkL=)E-ih(P}Cx-osZHW#1y|9x2FZ z^&TqT!@d>rTV)k&>eM`Bw0a*E--&)Mc=<0Wt3D~nXf+KL&)h!P?4wzt;z>b9tLdnC z5BC;XT3^%$q#&c!2dH=)RlN4F-l8^;f{a!lqB5^2@N?~QqBVj&PYN~IpR)5mnyay>MWi63)f`l%sOER|ns{E+52PTY)m&8EZ={~z z{i>*cNI^!cd8oKQoKWJcm7+>Ccg`1Nw3?5~SsNAAY{*cn&9@~58Lbwe;@;-O_bDT# zEDtHjXtfX(x5KQLmzq<@z0K>SAfweMs;uT;WDF8DgA`=6T7-&^Yi`No@uJp}f{a#+ zQSosV=-t19sNJL>qty~r+zy8ZYQul7fs@ zt5NaOO-#imi$vvZ>6{VBX!SWNuESGf*Bud6l@w&OT7!zm*vnErohzy{DadH`1uDKf zEUG!It*8uAkkM)_D(-vNetW?!Y9=YjXtfSiDLTuON6#52YAY$oX!Rwk!ld%W=bI?% zE-A=pwH_7UD@XOL`kts4TRAlk8LhrTRf5WzePvjzsE(u{qt(}_xNQt^ANy6*7*deY zY6B{+!>@ZT?JR0BDadH`4Jz|UgP&oSAGZ3ay`&(c)kam;pknPONm;*>f{a$*Ds^E+ z4QsrSr?pdukkRTpRJ@1lzis)3lvRrqWVG6Zirf6L-V3gZiY5gatu~|Lny*)I`g5WJ zq#&c!_oyDEI^0roD<+(OzE27=T5Unad-(T1QP!Pk87atU1>2Ut?Ap3&`IEATJ4rd^ z+ke@08!GPEDm>|ZQPf#dkkMuRfQpZ+@Rw`86ZL2t=X^m%tL>L*luT-Og(`a$;a z7AeSRwHFol^Cd=fHr2^@*nDlB^9UKOen!RP!!ODNOee>x8Y#$VwGS1y!_o8pv-;j% zq#&c!FQ~XSa;9uKE@h1*1sSdOqvCPY=c#Khi&{tuGFlx_Wj!`xsMY2-k%Ej?2T^g& zH!fu=-XxsQc~X$k>JTb!y}x`vGgVZ!c23PhMytc9_(~~xp!*?FrAa|Xt0PLS9hjCN z>Sa=p(dsBFuK8L+;!Ux9T-``PMyq3}xHg`Sy);nNtE3>K)p1nZHhwJpN;Od*l7fs@ zCzRURy5Bxg-;sihRwq&Mb4u6sm6wRRKngNi{i@2^U$sR;QBSsa&KG2~I)#eIhxzJH zd|gy+QjpQ=G%Bw7&lBG7C#pLs$Y^y26~C>RJ!F=d2IKSf8Y#$Vbru!Rm@U~>x4)=` zq#&c!IaSu?J5O4p%5OH;bri~cdv-Au}=P6{$w{f;UJUAWYpl7HgQOs%)m2nH2H4yBx5ZM{ z109{3hm2O&Q1M-_@2HP~|9n5|N_mwOWVE`eRMNTRvr^Uvq#&c!pGr+^{MpB%){=sZR<}@bZM@yY zYxVQLkb;a>f1%>Ox52Bmrbt=WNkK-dzfqYV`1$RvCq5AMc(iktA*0o8ROWR)e#Z71 zKVMWGQjpQ=4l2GX3vBJwOH_YSkkRTcDz1$NkF>PL^Y4;^j8^whaczwM$#qJ~T0sgj zTK$8HujR5Qu5A~!n-pZU`WF?Ci0Y60W}c`Uq#&c!f2g=NQaeuIo$R0*@ zc4{6nT0M-4`;Fpl4qIhaBn26*vZLa&y!iYDtM#@c1sSb!pyE30)1sgCmU9p($Y}Kl zDjrAeeyV~sGM`QgGFm-~iqG=w7MCVK!ufnd3Nl*dM8((F_Nuw9yWUw+kkKj^DsG4G zC$ut`HJ9~Z7pLYSqZRzuezIoa9$>-r{7XbVN6Psx0@+W#xl!@8{8Opf*7enp6l8Q+ zkE7x}{ORh)TcxacQjpQ=2~^JhM@9Ww{XjQSV@W|qt30T9X6d6`4XshiOj3~1Dle*s z=?vAMa>*)dGbzYu^&~33FK=HmeXQ)^F;bAxDjzCt8x4!}v_=m9kb;a>`B8Dr*U8em zq?A>nt5Zvm(dsEw<_CVh?YnoGsAi-fqg4S^d?%V-XmJlwX`~>d)zhf>svPw5%ydz6 zNkK-df~feaTyT3!Ur|4jf{a#$Q1Mmy;q2C>L|rBY8Lgf{#bcXsv$}jLDo;134k4q} zv#7X_iY?H~dS0$Y3Nl(1M#XLZ;?>;Oq^xeFAfr_gRJ?~LJY9YfHG~vov?_{<`}q@1 zel9O+4k^fJRSXrkr~>utZxHn*DadG592H+F=bFyzC+avU$Y@mpl~cn}QLTy>s4eOi zDadG55*1%x4Yq9>Eh=YsXKRqrsuU{jMQhy|Zkh@Ahvi5?MyuygnHxWTCjC-+ji^?n zAfwgusCW<0e0_1RC=V&fXjK{&KLvazmGhQ$wc17{QjpQ=B~;w^=4o@XgOt^t6lAojfQnnxu+8ni6qP{= zGFnwc#dUZy|2?bbr;>tx3&QR?7N^6l8Q+)lhM7v!u|H-J%NjboK!-PLl(m!;WVEV-itDi7%ChT3?IHykt?HuUvQECdt(>SoNI^!cdZ^5! z5`IdRdHJBIyuF-Sf{a%6QSp4#S9j*E7FC}VWVCu2RY5AN--tHDMD-&D8Lb+i;%j+E za_NPlrjde-Rt=RJx_Mn0Q5#4>Myp1s`0g+_@v9Z0&X9tPR?x3!&BCqs_2J8`JJG+S zoW9?_zM7!ovCZ8LAKZ|#3iozu9x}SDrl|NVyO&Ng7by1tO-MmTt7fRo5Bx0cvSE{` z1X7UEsyQm|d+W67G)mOFq#&bJ3sgL+tk$;q1W_wVK}M^VsJLw`ZnpfAs9#AzMypn+ zxW`_&uY8=S+GCGFr7k#e4W^u7;-b=9=$93Nl)?Ma6C7 zxfTa@h#Ex-GFr7m#cjUV?Ao(M%_9XFt=gkuF77dAfr_mRQz07`%udTQr1vXkkP6uD!x*hj~a*x=W3fv3Nl)C zL&dGP>+dO3rL1pBK}M_YsJLyEUiMTiQ71`3MynpExDLnUAG=jlw!Y5!f{a!@QE_c7 z`YOLw8_$t~j8?r+@e^XjH_msGvRaXXj8?r-aUJ^JDPg^bO(O*vt@@ziJvNbCv7Q zUb9t~D&8Xxk;?iulY{1TtHZ9wTcSdJ?=TUA%D~Un6&F zTDsp8ETy40CC*+Eo#ywrlN+YT$9w$$Bh<+=NNuW#-cnFE^Q48BU>#`0_15u5Tfo ziSrEd#Ki}9v#~eej!E)(gA1CZ=zp8TZkptCr+Hmc6)gfzDo$8*tTzzw`LSdP(o!ll zScYCK@h)D^z*L_JZT+0raJsF z*b1Z5e15Z{U6W|KFm#k!VWq|rXqaSplL6_bZhR@xo>X&s(=3mxo2IA4X0nQfXDw^wOY-^KxC8yIW!yrfG-@KUK-z;WgDbu% zGz;~`bzME)gv7M4#cjMP(eC8bBu{jrJILj#PVrdFq`R~hHua|m($bTyCFbZGC57vD{H>6PW5{N0Z*K1T6lR^wmK2D z)?D`y0;z)yjI_!+^VDkXEk`OXlMR_8aq7$;Y-24#8e-V`^pJqrbf#FXQ!s3^_Ey7I zDylYWGqoa=gtk8ub{64{Q`&{860^!&;PF5VjTT zdT=5k1<`d}xpABHq%?CohsLi8hT#+3DrF%K$D9!%3>9RB)5X$Y5mxCwE%J&M0c*Kz zE4+E)4raifbm>TU*|z2mVc#dr5yI|9NM^D*=XfLJ8ziMBy5Zi}p;5awR2tpO8vDH& z9)BZWN}Au7WUY2?Y?-Y!Ct9sCqdL>SSUfZku+}vhlx9{tO^tiYOjd_8>(Ikj+Fg41 zT2r5`JsF;);I-+^2rJfPxO<7T4$eo&hK*C+Z>|D zZcnd7_U{~f60A|mo)Vy z*#9$wHqG}k{ZCG|hWlz8Uz{f?!V=yDhSd5&vMR;X)f<7J5^T!1bxvkHi>`to8+jZ`}bXfQgUW3@w-z3Nmd~; zgb1E@8dESamqJ*`US{Q*ddDaIY!-(G7rX1b2p261sP8nf3l_N2MJNoL3JNvT;2egZTivsLE83J-@bbXpKR zP({mTorUe)X1wc9v6i=hA+#BzX5dH>dR=Vm(Vnz`m5MeGL9uYo>_BGgGh5yXT4B7o zcB}y2LY=#*xf^seg|zqC1)JJ1J+eR5lM-H2nXWKV9MM*3Y?Wjd^8H3FHzmNPy-B7X zLTWd&Ho!S9Gd7*2DW^9^~75Q~94wlhOlbk|tmd(b|@2Ij!A;&CSkQW@;nSVp9`v=FKWA zYwlJF@EA$Y?`GqsbB(ZGy7u_{ug$pcYVZBmW{NW{G(J<3X;I!tguAy$1qIjL4@N4E zp(+v14pll1t{P`IiH;sK=k7^~_29IJ zm5xsJd(%9@JG^}jg|4zMp^$a<6%@M4W}Vy#&W+G{CbIU!oP#dr?&I^fONBW!m|T^X zp81*v<{?)eY0dmsz#MlUhJmPq)FZ5V9haREejD&&+6eAZ!!qF;20SLW`{;YcfS) z`x-=*&8;a|Et&6S=o$-!)}=S3GGz1rEBQY+8eUERYvbYKe;2~_X;)h0U5{LgVcF2i zyU$LCM(?+`rh~z!zDn^}^cx z`^*t*Gg3yT%{8627e};oGVb zzO5>ewiR}aRa{}mSjAP1kFj#&rrli0^6pA4Pm95CXXs_l6o@O9-mID@1Xt5;oq{#g zpiN_!d3a2Tb0vGtJLf?z^H6LCX1onp&D0a;s@%AdE6v$rCW!`}GD)Na%sX%Mgp%QL z#le?vY>(gIa{1EJQq$A)auamLCYjfCt^j>$M6LI`2fCbt4md|)uZ@>457<@aa>r%3 z%_Ci0W?5%m&z0&6n8y-dO2Ez~#HP3c_^w4QO--kzu0(fIyel5Q1oS@xu6TG^l1a>5 zWfg;G9nM06lwsDH@3PUw2kXoNo(*-GDNh(Vh> z?G2|oU!HKq;I}7SJ*rd)UdM1mPHE1mb@}l1nXT`4iUQ`#a!F>^+7+7~<1yc&aG70< z)M%a4=yIp|lD)B}k*7l?x_qgs<|t&IT9SO~xM_uFP->Dl)|=+az{hDlK;R}Yn4 zW){g4aG6~;U&%8k@BVSMHL7^3yd;=Z*V(xbou$rOE9Aw~$Gy^8agF z!P}d2JiM)Rco!A20dKNtUf30ctl$@e=1Ov|tpL6+52o6;H|N2fK8Vf*T`_ufY?9aX zWq2vtB_lQKQeAOgr=~*~yhf&*j=9`p`4cSgSyd>fMG4*0qB9>z}xk!x)LrxFtN=-N4^n|%&T{sp?Md&sD zgcw(qO2JW61Kb!iyO_b|Qq$Q$swXx*$?Z2?r5a(Nfmc&H&h4U7W79b#o5|KVS4yhY z2P5MU-h$Fx4V!grP{Vv8ZwW>>cqSsR&iq_*DG_Q{`m#iG6V@B1UIj1H(0dr}y$VFw zIIZXF)dL+qbX_48J2*Bb)~`-O$A+#Z(UoxEW=32w=1Uc6a`VNNX7qdi)&E07{}6H0 zPN(GZ#fNrJrq~#_>6Ezt3f2{@Fg-2avZiqHfv(dEmVzG zaGCj9Bb$(6MR0Y5oxuJe*7**Uy>qd4XP|ol*j#3n#J#I&)7-Y4YYfH(c4tHzNl){H zjykP18E$jiG#9Na!S72q17$OnuJ_Rl`CuUHPI8%d8Rm9i&H*+p8GYc^G997gTGO5B z$BPEM7{@iL#Pp=3@ZQtJBaZWNIgIn^REAX}J}x*<0d^_Q;s__p9HEz&cz$HiLmiEYrZbjN%5p4I`?`rt}%~C zYEOehPxIvn^NT8G1Qv@gfb1fJne-Gd^pO!m<_>``#7%oOqXqNRv<~wI&3^JRI~h#j z5X;4bB)ha=gnF#|t;6>08yGR-+|%!~$~0hj;PJ)w4+-%%=v^s3GqC3`jH_z1?}y<% zfW0=*u~|cV`w1SO`IQtiqIULAMxmy55lJ@JrUio_1MnrW~B8pyug6D3wq<=;x#pC{;v$a&02Weqi)2c5>ntv*xqw%y}sX~ zHJ8yKb4>W{dZl2#1#eQ}OCvv2!{)*#X`si%#SuEKkOytMppaFnI^cOTDam7+k24O2 zJB!yEznKzK%@=Cm@d~>`%NI2W|jVw|*PV>9ZWD0C2Qb_Nv zlL(n^5gKD=TFk?dFRTU}7aMv@pc3&S4NlEOD$zM789rLLORTXRkWu2XftYkl}Z)hdF;O1@TQo#$+)nCQrm%z zgkCM?jOl>~)RTE;btlKbjDRZBnJEh&_y!_Rp~0c3HLA1LtHOIk90JG$lRgbJGv}O# z&_lAHp3Oc4r@2haqN~n6Dn6Gn<~*72=|^0J^G4yj7^Kc)S9qI?7;u?+g378YLSkVz zV_wfsN+Fj>gw?K?)HInwz)HX`f8tXZe2W?C!k>^y#!MB5_Kv|aXkExmja7mtCBwW_ zPy=_yu*w{RdB9ceRIT>=0s(U>BAo`{alW+5k=DiIcYj@O^9@~}`Q4mUZ^Wagl=E^Y z;%3yl3hStx+1*Ga*$ZDmcN&K)&FAvOS(8rI7Mz@U$n|?t&F`2*+*IUI64y_PIcKT9 zfiN#0?@Al!i?j*nP9HMGX6*&7x8~ZdmGCMAr<@~g*{?>uyicYrSFGT2S4#IrGSq9! z6qHq1gr|GnDEH-=j2eS6=U22N6%1XlS{`BY6!yhjYWQvT;N-i$F2h#qwimWKIG>}N ze|Qdtc;?Z5VE8Z&cgc(f;R=KyxP27-+)9J`@czbmU~#TZSB&|6TwAM^nOo=ixmp!7 zx`?Em)i6gD((Tgb@%3p0_`mi!!c#JB(YbL)*ksz^RJeD>yDC<6{=b>(&n#BS1nK{U zruYR%*nN7SIY@Jg%*l|gwlSwA$(!lZEv=@phVwel#^!QyTUSFH9tGM@+WJLk$ILUC z%;y`yS4etF3jUgtnFNEW409VZZ^7)j=uR!Vnd5`U8RwBjjuh7LW~_c&E`ZPgjH;wt zhqdbb(F<)Z&7PL))WVrEa+-*}3p|SyaPymYE2pPCZkC7f9p5jgihm2Du92aC3q$qw`rfr6$5J` zUMx+zb%II!ke58Lv{6FHAPyFqKe<6~l+{(NSHas`KTP}%^qYo|Y<^EMxQ99za%mYQ=GcAH03|=;A+yTQAL-TVyyuac@e9^%s@x}&X7}73LLOK+u|(dE+0CbYQucHB+h)l!4psyPJ}lb zu%GvNMd7Rt#JbHyy>$mwC3*w>@cxz-J_1A@;SERV^5B>-bcGr2;U7g(1^%y>AHj_T zXNJSL884by0e*uLwmN*&YDa>-oPJJ+V)2%s-`C(`UxG6@ur~v@QD=Y=x)i37&0A>m ztKQZK5VvD}#mxRbN9ei;!}|L~%>J5rE_0HT(gh8jM;HwQtCz{!5{F6F%A=uz(eDAz9P`5B=HFWmj z$UIKqFL#Eop+SdU5&3&Huw!`YBXv>EfDHaHn+sd8y+P+YZy_TF*qU15iVr?Gg|9Qi zahW#3)!slXyx21D`>dfSuEBQ{IMIpY0aZ!Z{33t_&N6)QDeRV?*{dPkG4%>aZCtI<^Nfzn^yLt)_QO|#;Jd^zaA!5WviTpu zi32BL=JI3VTSIh4Riie&R>U_)C^P(Nv98b_)Q`W09_g(f82D{c7roOA9pqBG55RM& zT?J-N5_)*^sv7<*hgyR#r|fr5P)6t;!N1M8-h4C4oErS=JoYvMu^#ivFMK=_@R)EM zd@nR?XdQrW%O;vHrmF4m!jO(C7VWwSc4q>eQB(c zOfsfUQ_S(1FQ;1b`4$L&+heV?-u5_W)HEVhBTk`K3?80zrE!G59E@M7@WTwWt_6yj zFEb>VJ4mujec8L?Gs6M%O@~O*IZXUQXqx%UrSQv@W`Jfc3^QRf#C!!b!frbkJiK5u z?~L`gjjTc=q*NbF53t->T95p^5i^SfH|4NhFw5z6W#}sNOZR-OhQ5TyjjH!5>d4d@ zy`Sb=KIS>je$ZEvUaHX3m^(P%iv{uoho_HWUqtAYPCW0Ok_r*X0pOws_sIO zM_?)vet(L%Q7or&V_lN-&LeC}fX`G+g!ejdK*9CuH%P+QM7V`8wI^^)XBlgT(&j}i z{8oUjyZ=ufUKrK%sKH?*X20^W_toAN``gQzWz0)^HGGUzmi_7|v+V>b|L^TU#uYHf z7wNpguPnfv-Tl_-nL&G3;5|(Et&|VO%$`NsEKI6dFR#@0WWFskX}_GZY347dBBa8n zRCu51mKyrKUbPLleVV5wxEsPd2KWmOk@gn8M`C)}NUKcug}=lQX`TJ9>wm2eeHUi$ zCfw!a7kcb9;ZJgW^yZf^Oji;UVT8bmuykjW1m___N3A8GH}-A0bI3GPp7Tbeq(pN7mEnIx0Uv0T;l z?iU?hC|gsqq!A^T-M@aHhyVf+NTl5FZlCH?B_Q!Ia1X@w_!G1A4bM@>e+NyHu0eO( z|M>9Xl0?hdZPINb%P4B3%T--p9AY*2 zjsinG7RW8e3&in>@N_zH@t0APo^@7+hl;qYa_LZC4I-|U5sXk&%uh?Y73BfzpX>C2 zyfvVN!(o1}cLCLq)iU@QYxYRRk%$?EJAD!t0Qn3-o^eXH#Qm_EHNdAj%YkFNK6+UI zePQ0pg~z*g9bZOikyjHEhIv8R27%F>ejmGRuli?tx!KmUA1RYaKOMiKn@|m|?3Uc${cn*-D~yP*APFCvnq~`@f7!Z$@}=b4 z271CBtiyUr^S~%^CQcF{KVodxpG1Uvsd}H>hxeUNCJ#aS79&bO2Kg{~Ptjk9Zfk#! z#r(Da7Uf_rl5r@Z=#Yf|(PA{#xAe(>WN4Z`w2yu&4Zyf2_|0kwii2f$0Q22nZscQ01%U)}H%`S4>+tcfHFbqle4Pm_=~0I9`SEjd1%v zFgUDYoGey3D2rlCYK2vpIqFzU61E4)u~phrL#`ru><#8$w-nXD?wkA*-3Jzw&ture zL9}9YL$AgD z!r5*EqR}7IUy$juHyGb5WwG@yKErRqo!bzjn3LI>n=IRSW;$~T6A{Iq%7Z2grJ%JZ zD6f-%0L85Hg>fiu21rLBnK4H;RX=@$fBh}r+J-9H_v9EB?o@p&OAD?FOFub8*=c-l zx$(rR?p1Ca_tTU62$M^ZdVlc|?42)9kLi8Ov`(?&XH#30nFf#nL)Hi120R7LdBk5& z9M@uLa3G@v3dy#kJl7MW$?fr|7h@8-aK)VSnpScI3-bf=%aGoYUq-V0)bB+b3h^05 zzDUwXsxK&SWAQ}08Y`x2o?*VfJ^Xd`=oR8rv7Nyr7!{h386h+FUrGO9CM91&o}u-89J+l&Z;0^#$6!nyFCa%h&G>@ zyYd&Y>rw}+@ zk?|fhb4cZ--%G{z@HAil54v&1Am4<*2)`63)_UQEDw!(_IyI!hr}Es)l-g826XJoZ z#Goq(#$+)tr@j&y57l@+v@NrvNlKnAU%cL zdU%%80#9aWs7-Hc_i{i@QA85Tv6PD%)Ku*hs97;_M*id_UY;|KMb_5K<+y$E3wt6! z4gNK};QSr#D`<#Wwq*?G=?5sh!~D;4Ej|6ctpPQ})k`aaSSOq!Whc{jR5c6b@~Cd5OBNX!43vlQU`@d%VOWedjOofN?JUAwK?VZM1XRp=P+QRtfvB2R1}yF@j-p`* zWC`hXmxsMO@%008sQQLj_$t#b9k$_}j9t!An!a21E8G{}BhMcD{)2q86l#;RF_9>` z%K(4({NXo;1He&7NEebH0SXGEkT_*yMf|o z;Vn(Ccf^SXyXZKq@Kt;@-#tCO!nM_{(fG+%Uaan6o=C^_L`DIpuh6I^hulz)!vUKZ z%)1l*hDxI%^}3!yJt>UrQp18jKCyFt@fdPy#&ChzYYM%lIAF(b*YHU)xS{;zh^}BR z(u*G?#gTG4M^m18nc13xGSXCA!G_h)&3s~&Z|{6^`SwiSKmc!p~E5n@dEy5yq+TL5UfTKdp7z3%97_XR>k&*ivB+ zLEq%ewwXBhyjy8OGj|^P^Bxzuup|cM`|b198~7kB=VXJ8k#yx2*on8DDIT?w*lfH& z2AVs9B5uESE9Rk1*r& zQ721_k`<^H#dFt!3PT)sZf;D#O^y5@x8>IQLa$=9GBLM(Gxs62A_HtlV6c(dfe$yU zi=jcE(DOf7!ubP^E7K!8_`|~%I6dvcC;CYBoH^C%`*3PqzP_9#LMOfMS`(YGCv~pxS4yz5MJtv=K@Tfi@8DN%yI~;X^D7&C>l{eZ{pQVdY3~#25_9lPJ#!jcX`v_-WyGUwBujbpwC*_CoPUB*v)d zk!<%ok0qXl#@?O~+$YmD88>heGfE?|?JAjYxq4^9WozQm1pe)kG)10jK`$K|k)BvL zU61h#W{@&}c1yvGg4%v!gZ$a@(oDpkjhw$-HXm>2$+Q+6^c#*rn4T`7dMd*)ZG&fS zaJbbw@-Vs5rLo7hoYFap1E5$qhVZYk16&<+KE}<7i}C(`q$f|N`Qf@-&M#W5(rd+>socg^ z=m>C)m1W*RItfl+pOyRpDXI~tI9khE0SMQJ!^z=Lm}Zh;<@%oY8_@gC4NhFGMY{4z zvJ8^N0L2dnfAd(-SH_t&Co@yTHsR1M{G2`kIg=k^Lw>mY2QxHyN&D!K>4Ta0kn+Ki z6W>RQLKz2z5bK+)Cgvsdf=X!yPfPzbcv<+kNan#*vu~godpY89THwzv&Mxii4~b~N zuaSQFn%-kp7%5fk$>3fITz<>B4Rgkdt4O;*45fYhaz!TZjs$ZZ$ruR@-?(yfOijzf zLU0wqOGEaZui^V;?uW3L>DHh7J*q~E!eWO58Ru$V%sq;$v~&l#52mK5u3E&zdegc( zV-D!b5x5z$2h;mMafzA0H~2V|OdZKg9gn3$fz|x|7MaW%!ve5YDm zEoVPrrLdfh-quxqfU9qe5w0!f$$NfKp)S`!M+_N1jL*Nq8Z62uU8iXI8$)7g#p^zB zq=+JwSIkOQb4|2E{|C7eRu8f{pHw)fRtX?w4n{1Rn+0Ko^ z*SVj8J!z)qWgL0?kYdP8Ro0LcwbT8D-}$b*5Mzl|kXL(41&#rJT{>Vs95`(PnLF@2 zPwF`^mfo=nCc*J0UqfAR^VLrc{Rle@O+GI5D6R=n1<~Eh_65Fee06DL=G=%;$PAy& zjw|1l|3;EUhkk!^QylAiO23FH0#8I-v~R;N2E(RiwRke&wZ?joQm51Y^QKzdjR_Yf zrFLWMYk;fxP=%=m1y9cJ5VEX+gBspnl)KJP6g2iFq43YSYEW0sVQq}57MvqGKckGYUH1?M2hF8V+D>7GKp$=70Yp2d2TD#RIg zgLr~OR#d4sZ?D*?StYsN`62`)z5fpBhe_)p$dQ+GpF>p^AJ|@+z-__;Cr*e0pZJ!6 z15d1wH#c4f(xq3XEx)_73{gC9i@?aji1OeoXbs4bj*2SYwT-85f`6gE z-cZgq15WuvU$Z1iB+Y!Tq&Y?htNPLFyOEOW z5)Q0%*?EB#Ral2u;~c?N(FqlIZ2Va+N4hIn4UjYa-TuIOgsaEnE1Nm~O=ZY8e!(iY z7VgOSj|++_e%9=O!u1s{k6J`TU9zD;f}8k3jd6NCE>EYYn|pezhL8V)FIZi1G9Si7 z-t$l^%5RE`_s8pM{Jn2XTdH|`A#d6DNWoX!(Ee&DLl`LoH(dQS?Nj`Lyz>>yt3I(I zF(M?#k&*7qRDObl0Y0}gwHHVWKT{>+9Y;BgVfs<@rj3u)(*@S!;}=6x8l_KA?KZWk zq8M@^#!y?A;0Ijz7Cg+liu|BF&EO~3wxhY?QSQj7ZQ6XNQP#4&a3 zCue@0e#BJpSloU8#RvEHg9?oM=a97Cv~*$ z2lwCo2b2)7CsrOo*-gz%F@CbS|8kG>Q!?a6i>p)5lJ0n-{_-2(tgc`a%}Jq6TUS2L zpch+WVW#q8ODr1-cC|V_k~6;f(UwJF)ACSq!3@kNob9GftYecY9CTMd=PFxRh|Sfx z^4Ex2{ynXp`AJ_t`Bh(Sez-qL|8J)Qz{@oh4_7}fiodMaO;1lhIka0!KVjE|Y#{T6 zAs}p`a%I>WrgDNE=9O>fU1?@ZHQMV^CHGq^1}IvNFNWX>7u_RQe}?#lf>WEy_VISE z3X7Yoey2QHrb+s_0$%fH{eTOgIev%D<(|A*d6PANQdbWWF5VVP(UP;GxN?XIryz7^ zQ}3je{T}-XS2WM~1<4@Ski$MW0)FRxR3PE^NAf8u!PZEr#Z!6lcHO`X()=K8q3Q_5 z=aG({R3R&8d3Q%qF@836suA|Wmb8y=-&W6W(#=!)GL)aXm#1$fq*$L?&|StSTs~y< zDO*RITJuXhm4ST-%!CJ}&Q)Nw5wts1Y#;)riWO!5NyTYh)Z`13RnUfvZE^~VPNnvT^1j-->_;wON)foE&rkew2@(VhryIIWpjeE%8HE>+ga1M4 zAWx>8R}1r;Cp5|`c9bYl&fBc^Usw09U>1FoPd8^dZJ)t_s>b6%o#U z14R_{6!hMn{Un(HyRY!$$43tLLymHypGz2b=_MH5BU0rzJS5;a&Tlb(L_1)w$w{rA zWz^iaBFGBff1V^hIS7f>2b`*^~I!F$VYXTr4=kU_CpNV*O_1x{Ja z@&_CF{5YU5z7R971aXP5*{^yAr;qvPc?c=J8RZN~KW^$`f>Ei2S!463s3F+G zv`|VSdo8}9e4b2#Exjei19^jp^I$q`C68bdnkp1I7+nRH#D344n=1433$&Vzk7~%n z#Oq2igTsOhvIPx0$5{pz>ceg?>@55^4`MWP*PjeFBF3uL;(jL=5@TeVnsJ5Z`j&Ds zli`3MX?c)%jX1u~#~SaPB9%9=V*ErAW80MMn#%F5|FG0}$<73*3CA1%5a)s| z)&!&Qqe?nHknm2Zi?NL3?|z)GQrc?^7<*R6jJ0LhSgXk30~|OHMWB@=A9x=;LZxv! z4s4})J6}bb4(j26!)2ybp~|+p$B@)yNc$oF3^g#Nq|k^zk&4R@cjb>M|Hc&JzWg!C zpQj(6iXVS0(){tZ{Be=yk7b%a7HR%iruk!$=8t8XIXc6ngK*<7_4}+y^I4hZvm(uB zWtz{5G@q4eJ}-{*d70+(BF*Pzn$L?gpOZtQPNyynb45lQH7Rz&0CPbb z;?mo)4rW6aM{+M@bs;tGp1$zr7|D8vW0Kj@I4bcg9gkQLM?(L0lT3%>GNuOC6+xxh zY01B?!mbFKl}2b^9EUe6jUQjcAfr4$XQVqLLh|C7&tw0y&vh8G@<@1IJcAxd&py|s zk(I}_kr&UPzs>aZ?Ru`k3_Wji1ij5r^p@7E8-1Q4U1R@(XyWPb@#&;zoGFPUrlL5u zreyk2>_PfSX-`FwYEv>n(lbmyO6ON9n$VQat@P1^rgUDVk0vywbBd*OEJ}!583QNJ ze{kPs$daUe0& zC`OEP$a?^`P}yyTVX*3DxhfT?~=pW6!X{}Z-u7#8}xl?^iUr9NMfoTtGa1K zQn}74iUf1=r4)-SKM^9Owt1j6n?T@(3ca>dk!@~AC>&sB8QWUD6#!(*?GM;;{gwXY zXS_d2FG8<&h@9jq4%k?b(U1<;@PRUG`gisd%Amy$bY4P%yiq2!OYwvtDNfAb z?@)TX{S4tKCymZZ&BoP-id`)qba}bbIKsX#cF~o_UFi!;pX!ZlKTVGgS6U(i>=Uo1q+N2M-^CNqmc{jD%5?!^z3Lwf+F0Pl1VIU3{k3KV|eJg-D`Dv0A4N+cDm`2+>oCucbd3bIem z^G{F^KXC)_A$B(_Eq|=2{_7cR2Sy{5>ah>a@`5- zu=?GD3mZQ=(xb}Az_D%RL*4B6zn#aqK_%IFAu`5q=jj}=quSgfVrW?!7CGHGUhW;| z3N0r+sfYyw>>b$3i8yk1sI0^z>cr*>WQ(i9643uRD;%dvjD?k#Q&HI6dW*9J+fI<= z>0^tCFxdJ@6t!U{;CO!n!MwyHr9B7{%EtF|^F-+z|-51#>Oz^M1 z%RhSOSM9FS-@H#$=^_&;Z(L%95As!*J`wo_5fzNNrMr(=Nq?e()Xa#4l(IKN8uMWz zJiCS`7+gKQq?SR*lB&$_f_o{pfz->Cn+BK{Q^9-d_(B|9`n}>OB+mH7C&B33E`jM! z&62`4SnosdCkEi+NN%m~{sye+%;LAJ52sex9T(46FDElo;cTC&RUrf$4W%LZjDzO* zAOY4oINRA7v~>fr7o=9?ZmUH0)yKBN-WC=+E zU0W)vl2$cjv9=-#WNldz!unDtKgE^#PVGB&Z*<$vHwE8Qs`RBn_-a4o9UFFtEyw;~ z1{iZ41&AWmvmXWhJ245n^YceS3kwEEkNl*t-^bN-Y(VC4{?HGZeBI_`oOE;*cJbX zF9M^nFNoZ_q6;UnBhNOW^}MG7A}ls|C4GYjLsngRvoLU=a{&D7!4p}8-DR~-$>JFO>G zrkNXM$gJ$IPU}oVI=yfSI00yQwS@(T>5m_9MJSfbC@`3zENEA8-jcUOO-zHGPa_01 zN^(=`RnuI-4=4F8Y6E-I_**26HMOB__5r4h7l>_yGJNcd?;+`phUzp8N%)&)52qvh z_R|@F%o_nRD~->wa;-cN5DqS(5|b6i(%BABIn(F|#lG8BAfP+O)k=rbFWJf<5zvO1 zWLr%V0j;AY5|%!eAlcQ^2ocxM!*5uKILcp-H-F`IP99U5+Ss@}uajEyvtAmX|FG&- z(vO<9Dq}6yCUK*a9?@ACmr&Vu(|%F5-?U$-4JS?dbWO*;i#e=qXnvecWo@1L*-2gc zK{k7r^%o`IvWv|a`HFCejR?#`F;aYGcuPf!8Qt=y{_AjS_`TLYVEvRv$OgL;FS*fb|^ zEq-C-v9^9<>0>JW@ezO8%r2}&VAw)|4H6~!@0ic$KeF>&{E8o=vex7Q;U&z|YD31P zl359z40(iG?6h^!=P*mzB!p6a+bY3&T%>0H13fX)2in-Ftpa?iERm$Oh2PaW_mlZf zz#v-9-bAmJ4x%#?cG#a6hBm@6#hYStA+&B7 z%WnoCu6^`%tV`Y+gJ&CZVC;zrNvFGv6?9tP@H?`Gl0*X=bwXWqRlx7^f{i8{`W+ zS!}?`3(ZZgIXJ}jkXXi~nwwO+_w}T%TYa$JLkSNYkE?@p9wQ*aM2voj5 z8E%<81EM29)NcoO2l=08d=#PIfw`tU#EE2Fg}X2QC~OdK{RBp-NALX_X#7(<*ih4?joJ z?}NB$`23kUXg= zMEF~6X7%s5OGClOXcwt}XCItpA0&s5&_aF0^zRHI7z*d4h2kF*z*v#o%mQ*SP%HzT z{YaL${`(&@Ky$@&Krm<2pH3rA52VseWO7tAh~_Gj7O^6064q7d%m*|}zcZ~fL}Zm- z)L5vTZTj(@-=wG?Y?scydEd%p=gGuN~@ zk*3i6N-Xv8wsiWjpRDk0HcPRzh?~z#_}EW~DV&m!O+oy&JPv-)!?)RJ$I>Fb`S`M} zE)G);Iu;I7E-M%4*{sj{^s(0IGa0hy7=N?7e}GG)=hu`V8*rOL>C z73)&NX9>{yH%*wuHiUKqm?eMRF*m%X>(1qS_hb`Gh!^TR%uh6H{Vq2 zE%X}ks-6&zouZir`JWbP0}D8PWkm%z{pIkt`z@%n zj<5L_T=@iKB|(iPZE9Kq_*MF$MW82 z45V!_p&YYN^B~z#%W81MhJi{#DtYl4ky2jerB-ytoV7KV^xqh#$8J}8Z){LS*fXs&~y{Gb2xvR+*NqiPrHcBm0YZL?VIF7tp; zi@3@-;sj&Bnwqd<`{iP{-L4PoZmsQKuUV>9Y75Jb)V8h`+udf_*L7+t7R?Bel2SQ# ze||1Ooh($fTeRJ>KUC`_VZpR5R}5PVd#MAqk=>_ z5KrfnRf`-_y8^nO7c%845 z+Lpt@SaMV$6G>?o+x@N|x0^8n+>*`lr37%XO((xSEZSzj@78HJBnk~@wZA-tkO&sS zN?>dshM{fNyLF=^K;{qv>zrhwB8na^{s@ZWQTL0X8oTA8(viJOk4hJ1XM&g?SBlv# z+Fi5hnvIUJ#XPa8I?`ppzBppaD94BrW=U7|V!y>Q+&5M1>z5nk&SvYB*xH4uv5ohO z!?GPW!`N$M&0lw!vR6eMvBjE0tDD9C09w`?-kG!|C^nIhV$d${juDUtAIl&FezBzW zi)z>GR`r_{u2$o!&_SU5c3wugv!o1*ZrH3>+ntUQS|UN$ z5mBQNYCl92ngMd;>=xr{*Eid`i{yOcIQh4jk#h^02D3TaU21 zMkc{WY)}#u&0siU_KRJ&8Gxe1q$CmlhXO|85~Daw>VVwdbir?W_v~=FiJ?o(ISfwFzrewJdWjE)2-^29PzXUpT(^= zWIDh6f6o8$j~N_C%5E{#>+NdY9O6{Tn8;NV@&%NE+~VmM{ZJj2+jbvu?EXe9!_y3i zrKWBdW3}Jx`!rXlr_3PhGZdJ)VZS-Nn9 zG`o7g-fj|I&*T}9^B(T3K648SchIn@+9BORu}_qZoda@&jIU*a9Fta!i+WtHhE=17 z8}~XXdwmJU zCAiGQJNOJaC?3n_?zvl1yG7MCeR~)ZNfWR#RS*yws&Le84(nAl_PX)HHVNwrfd-Gt zfx6i{w`&Q>D=REsxH3McztJaHV*pF>9%27ikL(K=06Ga?p8mc>WWKbT)Y&DWV5_a# zrW$vK5`Xo^oYt*b%C6+&2AsZ)WR1Lvt`#fc_QkZV${mGmR;f-ECe}zTet($KQ&Z;}?*WpPcP;>^dYfro`DHwZ1 zq80!a@V^!@}vO5_FiI>2E@^uX> z^Mvy7^UKrY;qDH?CpNo{FDu&O>rKDI<;bHHL7ov)RwP0Z1B)kU9$0=uiRB>F2@Ean z>H}WoxD;hE3Jm9D3hZCVmUj0r#e?*V!`QRzA|h5`wl}NodKC`qfQSgOasD6JU1}aq zLrp}cd%dWu-9QtVNBs2c|*LpeBa62!%4*Tm z5xG8?-6D~!y$B2R6ui$ZQnje+db1l_Ll3gCU!H&b=*dt)wMca>Mzg>oUo}H-sG+l- za{yWtmGIiun?U7IDCSU-G855F^FS#z?qcRTv7K3~O)%Q*!jAdAd^0f>uXF@;4O@ zz|9^K#R2CsT@yU2ks=)NY411;$DH6KK5P&DVQWu<#PCwiMAs$cYs6`M@p}J^G_Q7a z_KVFpj?1Op%z+uaBKzs=5ls|jiUNx^EShfLw|y(`I_{Z6n{@AU5P=&Mob2mEzuzyH zW&s71$gLddA?61==>6RKtr|%2+J0HD%~|#H=KAI(--DsGpYzS4-PX(HHi&SL$DqCV z$YN+sv28~=V7O(BIc|qxx!x~j`7y@XWtNA#fRe2lEER~dhfUy%1I!FDWM?Xi&+-)2 zW^riSezOaVXuu%GZPFd1wGgppyxJ&|g5h`|78tifx8BHv1Cm$G>GJ6=<7{)wt#@I& z#jaXaJLmy;hXD2(ws4#Rn8a0axS+oh7-FYz#dylPeY;yON2Tl5~NCa>`=Q~*Ig=g|n-?qZE2Z$u$UM;$2*lwFnL^y=ODv+F20{!sau9FFZx(52lx^MJI5Dg7ZS@>~LI$A_OiTw(+go_%6j4df4esW_6KFPNvPwh)A0m&xKukfV^0q3p5}^L{whM9mtH( z3_<3!#r*W^!vLkD>kwAD(_dw@r2V^E;2b!N)j{`f(0>J^jTs8e?DkMywUEd*IwZ%( zuN(p95>iiSn&)N(5!k}CKbC^rntu4m{mr!5{7*gy4p9~7w= zUIlxTXqFMJ3E-VAiQ@;F%ueId8zCYd zS8b1H0lfx5mSVAV7};Nre_I7c2Bqr>v~E} zz~H;->F*gRojY`AICTBcZsh%DsS)A#9D)uFJpsXXEO9GMhDIPH)eqLd43=3+^`c%4 z+jF+*FW={yrm<*n z6SV6d$(6OOS|j|AndWJM(5rl1H&q*6nX= z4+495Gow(`?yDdj1w^v(kc4XGu8?JV#Msa#-d7bkk1&b`LtfG|Ai6H_T5Z;C-v{#? zkU^?hys_pQreBA&`LLrdD9aUZ9b_RR2_Nh-X3l;@_KbZXRRvzFc(2Aj%;`+Bp)^+z zB$dl{)o+6Aj5JRP zI{4CFVw>C|7)E)7gNK8e3rb*V-eZYk_bBppgu_9zZx208PaNEdpPTPdWl!#w9!Q6A zNDp+TDdV3@BSg`;BPlR4+8&_FO*~CzAM`Fc?6nf1pxZeN!!V}%I)j>7-!ejQr7>hd zPXT+kZs?W!q@DlpaKvHGnlCU&tonMNJaeYuLRf=4UPGK72mLvOs$fnZs-ydx6L08W zU>Y)EGq8q$8M^R<3E6MlL+{<=(rZH?&i?I&r$QImGX-$?<(U_d3|Z}>TJHB%lcZmQ zbb5Y)jKS_!{1! zF@NFvaCQfb3sOZxMy&Vsb1(zrQ<~I$?;X%#+&Er*TEqKsz2C3adi4NO)K9@aDUz3R zNnE@_ZJFNLuqj)Qo7FOH?ssg;{s>2R*rxg86c4#>9QGB?{J6j**=k&2@;XJT$*++v zyu3x6v3z~{c7GFMJXS0?G&ftlXb;tPgBPaV z=f(w}A{Jt`fT`sM+@H!d0t6j6hHnu`O_;DLCD7QeiFZjNIe~cziVz)LEAg4aY+#Jg z9=b!V3(?sE(%l-zR^&bt2-py8s;)ZJTRrd`1l`V=Ibn087t92SjJ4`vSofWtOwmj` zp2km-G(M7~i!caE%sAs5u7_$nY=R95?)Gq^&l)BYTF7Z6v^k{&^lE(%ozYfb4n;g2 zcc4iOHbWE%p$;{StX8@b1Bkb8MB5<8vW<6(!w3`qb=vW%H8q(^!WK53kg}%m8O7UTJh#?8a(2?nh-f14+!WOu1-Kb-_OqqP-do4K%=q zWdlw+A79y;-=ETr0+cY}QQKpO337_{ezR@6oTl7n({wVx`61enP25XHxSoVk$!%+T-p zRZ_Fk6ge28#awd=W67aoWd$#Z#Nrc7lI6ulb||1MBMlSYzixTJ0_E!4HCcXT1Awey zW&m(9Lz;2eEt3)y(H6;GQQoOpV`ub=Uxp5}gMup^UD7stBn7g)kt^gmZF7MBDOeHE z6uQ>>oQcg{ui@r&Xq#@Eq}RT+=baV8^&J8}+ym<-DHT|fm26}6QVZ>crNu+aj^Ji7 z!h#1jWXi?IGe(ACI_Uy~XQF`_z#eUZqRY@&@wi{lMiJ~VUNwg*=}gtsm@GZzq|jN^ z1Z{G=ncv5Bbo;}qX_G=Q9t+nn8Mse6#f+!67?9_{j&Ze0(m};w(^o$!7krwASRoZ% zzr+z^xFQ1!-3V0tkacfW*sXY?sh8^{b`SSsP&MkoYOU+&{MvTdT&>=aMYzis6`~ao z!(>=sJWrvOU9RfAo+25rlh4e9ng;~la=6LsRilEa2pKin<`x8EV3_%_lwim#d9~`c zRk}M0FqhZQuQz58;o2JRrJhsTgx4FuV3-Pjr%^AE64=X^8L%*Nk$2Hq#+qL>W4lS} zSA~UJj%CHs&j6B0wBlXR)gGW1OAqrL$y;?!z)lv89K_nLYNo62`1t+u>Q)6@?#aCwEO|4*Y>tiJ_cioBwTcU4^GDn< z&rg4Y>4QPp>))zQ#ZK*G=BgwO#W}fKK`4@*O%X?AI1~GA$tw`)fKa}NsHR>f8F7i+jShK$0_BB0@wMV8!+Z6(6%*fbXVK9X;sS^e>GhcCAfULg#=_F%o(wudc5 zZz`ov0Q{7R6rjCq4znF_ZGw8ZlO86=S9}OXPn!wMCyZ>eZePQQ1GiD#>O)A$`1}6f z|4vg7yTO+{V^H+CC`820f*}WN|0eX%J0#LThw=+0)}bKUEN1)Am|lV5Usq(HyHERb z>IpIh`RG7kJPKVR4EYiWu6oYFs7`Il$4jtPhoj^ZjY|~V8$>ayb#MpFn|ro3uFsDy3~7RbFmI^3l|Bt3C1POn+xhjq-fR)d zM>LI4`$Yx!GCbLIfq5uW+L_l1zyfoQxJVHLi>igPZkvoE0tVaP#xY4v5vC?K#S`Z+ zv>n7kac*MM5;LD55H>MFtl*iB2L@DE83fb_6bY#G`(}a_2hI08czq^gy+De8FIgH2 zFgO_pTt|>IDMK7!UVlE54CC(d!w31lA&i5?iv-EdxH;lTM!s!f9tJ~}pb)jd9|0Zy zQC<(E8elj71{klzJ;b>O_$n)KuwL?2|zM+Aw)r>hlvSFnh1bq z`@^O=gd<|Wd++*6uTXk}evap)rY#Pg04D@Keur}*jNcHY>((^r?g(ZeQXt&e1W^@Q zSUYvKTX!84lswn}0VJ#rCxEec&>rFVgV{k;01Rs8^Y-{i@gyD~z$FVf!>mmcH7k8A zU#jq?3hv*Z`#&+^q&O9Ir%ru;nxzR3d3d8&eIE=C2;(*Qqnjs?K03y$x6^SR4GREl zeh0@b9Pd_- zlS1nH?b|c{9lH{DS!kc+29O4A4_&hxf>|{X)acP4k;UF`CDVWV&69 zjJ|;7s6xmcsF8P@pmzWk?YX&$q;pSre+o9O6F1_%hoH6D>Ilb;dlMLJ5;LCNs{AP7 zd~(b`1hzwit6PUC;*<^mEKHH)1qlsH2c5_bE-zIF(O@T+K@WfuOcALXam@6QKb7aO%&-L$=NW$Gu63>1YWWfeV7`}uT z7ZvCVk8Mgi5${{@O5+xn{Z32}63&Uw8eQCIZAY2U0s{gM?s3(L{ZccG^Y?WCLHm1{ z^eaLK545_k`V}A6giySwEeW)QtQfdnR0B9pgzlm99_$P`2a2tw_JZ2{k81{uhW&15+SKlH(};*YAH^BI)^;qrN?|rn(RZc(AtczTgv$e)9^ir%0@8 zlnnTB0XF*%C+bcIzUW|>H8;OmgUjtC1|I#UeXzMk&fdG*w20xd<|Bn$VNtP<)|)&c zi&R^aDR^iNhdP+lGXi@hvJ+gfu`w(ju~D#2q4$nsEG~`5{{u%_*5zce`&>V)r5nuV zU>^m&CQFGE8Aazvhr%%`keMW&AuzpI_h16R_lBKk+$`fA7dw`=pxh&hLXQrL&p7be zpXhmb`f`6`B4hS z2Ud#{v!g_ukwh(r8qZywFpHDS{p02lFh9OJDB$NexQ7}uxQs?Cl+LFNgw7l<6vL2i z;W^4YoOFtftjy#Mm`H5>&72XCcSy@B|?(L*`%fOt=~pX(2o@QL{+naO)7 zAA5ESF;E9XW^vsXYUYBY3MqNWfCk(IY?t*aBxf$H4>~0M4?7Jzxbz(azB@4dX-=S) zMyxmZA@cj(w|2@d#0W){fVy5b%-;#wxudF(>jObxr*+l7g`ZUV)fBSE|6&%U7tX_* z7GV}PX)n-r`p#@l*3uK(EVhU!w1cWJ{-}7gK3rWN)s|*R);9Kz*5@X6J8%DJxirAMRT?QxIQ6TX$JAWpfN7^zDiSw zyz|!ZYZ=BGx*EM^-tjaQrcbb(y(3VT4dT@4bRp`|%@te*jf5wTJ^XkJ2=M!WLvy#1 zP!QaU`_unsk;&^+#Q^qOFjRZwrxM2I5Jj)n^0s8Og6C^O2}udAa~JHE3+ z44Q3VAdK1}4sEp_eP7h|D9#LL%$iUE9uz)THDqIY67o<$+y|SpNK3?^MIOv5ED0k5 zkdf)I2v>AMz$#>lpNJz%Eg-qI1{cf$7SXFTxB4cK*-;3nXmQTl8)r#;h@}gGh~P}s z_UT;Zm#~l2?DB8&`(T2D_}++X(bnn7a`*Iw#DyYw9ZuCar-^0WLrH*ERGW!^Xm?GpLO= zn1~}Im4_MfMnto2cZfixYtS4GHk$Rc&mPv1SyM1{h$4c;PZ&KV^IK9==~FS0J2j}l zmC+pb{a(xuax|}iN;v-Lfo!yeiSs%!#Y5^X*A^P(;NX(Q1%DI_7ON<{Q1dTsXkTg*U zFbup>pM#^!bF>IhIfVvF@LP9)sWAdK>P4SiTa}E$I`=_QDRel3*>x+ux)Vz7Uu!oX zo{pB7ihRR1Sl)U@evOGX;)s+;aiT{=kgm2c+Y^HW8Wp}Gg7#FRgXxeI(Hu#zz&JDq zgh$k8sKC*KHlxY!Fh4*mxKJ)vn_%mjsDh3e@jS1TF$x6bP>v*$Kd!f+Ne>kvDM&Tn zr^<~LUOXe>bSy=uDO80Z4l-W(KxK6KWsMj*c=(Knav9G~J~E^HIHPNNZlF6&UpLF0 z9&VyHxVwXm58sm!!tRL=?!AGr>EQT^Seuas2|b=E-#vgEU0CMs_Xot}(r1`MxV+P= z$bqU;4BNV&|xF)(lkHcz!6e7f|vViqiJ#w?p~z( ztXb{rR(VQ3%|$!JVnm%{58~(`_7==bh#tXo(48PCSbQ#Sh{gHnCI_0B9fFM?M0ut# zFky&mq(}_>7VRN{vu3$m!VXc{IdegkR*3f`fV1ct?qoX=yDJgFBaB{^G2&Sn%hFOq zytFwWUa6RIXJBL;$8nKhXs53aH#&BzU>^tW1#S{z(DUENvV>v5)MU}K6F&z9BP*q% zX3&y#W+x5GNkkLeG@F&ad3m@Q$=Q1=W8|?cS>#nXE@9aUTb>})vtSY>TxPR0_|EZx zLb8r9q6(^5-^IdX$5G`EE-0FIRlkJLBvO^RH(y>qJt0JzKJguvokYCv;VlEET0HZJ zs1N{BUXxioU5{f&3VyVBF7y>*+(ep6kt8j^`Q8gVApeKi-BNGl(4Iq(75CZs-t!kQ zjoQGY7jKqC0{iG|JhRdyo$vjt9%o_SQ?y4tk(q+z!Sugj1z84qySDotCs;RhotRhg z$Wky)XiUT7XAZ*-E8d}NM3aZvjIx44jiTVSfxxfOFU-K@LjF#;Qtu1zja{V0&o&lbyK2BbDO2Dfy#Irv#%_1;%G*86?0ShyD?OTZQlz>hXW!nA>T`v4!PtdUTQuS3}e}kEqqw@l(SPo zQWUrsgI6NHm1MM*elq2Omak0@1!@b8C;}vWuMj*nzL zYNeKV56)A9sOLLy&8-+Z&|I93AmEk~fjIqLO=r`Hw3sTMuMn3UvEcWKTRl-WnXkx? z5(iKlsfrSp%N|Dg8}oA1R))WohDeL4zedmB4Z@NnF?MR_cv@|meshFb4-~)%5)qee zRN_UgyhsLgGY`aKeh$f{#t()JIISZ<@}WvP)&%u@ym@;-Fw+|vsyGA_C?yNpMYy71 z9VbC|uo1BG24_|0!C*rlhlgAgwgXb>NGyGxN3o#!&#{y+QoBP*cGx6QPatgSob4$x z%LCUP!d}6CL4r&eio}k9lj+F8Q64H_C5oU}0-MyV#8$ctMruY~d7dt_kU$qLK-^e* z6o$^-!=RZ{262?Umy(&};e?DMFK@_C?&Q1XZ4(7>ZADCAL?lpYg7+0xDS$RN+XU+XX8Z_T z(&=*v>j}Y(in>#akO)AGhaO?);M$=>5K>zn?Bo z_sK)uvMmIW=%8y7x%1leAdMJgf)oeQwYLj_7=@u75v5bR0R^2v!?i~Xq$$iLzwM;+ifINfDD7Yxt&3obbhqMkKp}?Xj%7S@@QLL7rd(zK>BS6 zKyk?qO%hfI!ZQ=x(AJJQ0&1+#Zb&?iZ(5Y?(Gjn|j!;ND_=;8`!=a@=nh}td6S#4e z=>|H?*dwrag$rxB+vl@}gFa=SErTRdmJ4LRfH&lzENkqIMX_$t&GGs5>nG9^vck+l z)yR^9H?hhsN>H~yUO&XOk)V3fo9f*|X?YRmW+NGB=SBz_hIE9$(l$?TPz@T(Pq0%6 zID*qAY4A!UWq#TndB}Pc#C`^&k(3f8l+#%v<^r)d?`X0e4r-J5ay%Rqw zJ59%1=#gF2wg?eu(fFNkqS+uoZN1hjA(8@n=(tky#;GUJ9QP|SMlnaAoFZgSZG6-J zbx$rjj zSaRTc*;JbmQ^jsl8hu2ZSl;x9epx>x<11>J9#P*O}PG zz&J7xehwE9Y#b)LKRCiCNA?8a76w8HHyjyra_vkV+T#)6GjhVB4bJrNGMY|p@@pq& z95JIgEkF11qQYz9Kw;Fz_2f*qq91D9N@iz1K`jE#Ez02s=aPJ7^VayJTZ};X-kn22 zw8RbG*2}dr#&J#rX{AsBAqucee;{y01_(Hn=`+n?+~T>I_-ov`pUF@D+p`*oK+I{- zAk;$6ooXq;AMGL~))WsXx2I3jm8vgbaUI8X1>hI|yeE&9po0f@?fwXGl6TXjs;83+=(rO$LWFZ4rST0Ar^vSWaOxDK~fwGKg@cmYKPi-r}5)UX62LQRGkOhOHFIo+mjkEDSj6I~WQ z&4Ab;#-NP2qDMsSh?9+L3){o9N*Nh$Sn+U%2;dN+B~o`Rf|Hhutz7KRba3HB+`v2) z`6)}pKxF&+=bwMZUco)`J){vKr(x%y&-zFd3#%`kUp)-oJd!&NDdRd4(yx=AB|!O? z=y-KHVPDl`NoN-fWMAtg3?`DjXlVX78)6%4w-{>R**4!G0}c$6*XaTBH(54Z{&oC` z)8QK|6n?}3xj4T1Zqz|I=J6178Og}W+*`b@fJdj6UMwo`fr;jUBa;S8OLJ_&fpkPH zFmx=U{P^(Ul3b0lmm*tg&Y>VvFbNFmB~MbfiBf8CrzDrh;=VY<&W-!e(Qot4_6N4B z{a96_c%Q63wXj2md9C-{winHTONcScu;QhbVBFB+rZ%PPtV4JanDvynIg(Pfh$-WhqDBp6b zR`ghwFp7VJ!?>x$f=a>EEWRFKsrP?fLb-SR+reZETGuR*rcj=UfZ{6(ArpH0Ez zxFIGXc-3{y$XBjV6Gk@3g;=d;(wo^$3S(Wvs6iA#!r5A)+X+_O4<`}m#_{nWZhXcC z;=>_Tptu}w*PlW@R&`#!y8X_%<%(E#kid3UP$aKAas7S=O8p=lUH-(~L$BN*mXbIy z6Bw2?bq`@8C?h)kWwM((Bs=7LM6UoNy5Wf<81|P+1L91pwz?n>BaMV2X2Cq`Kt0;{O?1xQna8Y4Y zmU}T>Ac(kR?Tt0n0?E)&0A~k=@X7rK1{!gS{##&nnLv<@EWFhk3h)1KSe7twF^6i| zBHgR3ozH*9$$B|{F}|*DsNDiW1lv_R_Av4wYKHb=nc^;i9ZkW}J%l5ILWjbid9ff_ z&yL~10NBNY^;d21;@*i6m!V)Z2k)aWyfYA%9AcT)`)y2!!WiWPI5Src^w>3nJFYoE z#3D+0hI+-G4v&sYzAB3Ynt{JX z1tScEmf=SNz^+JQOp2hGuL`N0Ddw`S8T?xR4N;drbMTqZ8lw_o#i*Y6zgIBXhm~Vk zha_N(qdRGBf+iXSbaLG7k&&)vCKhz*+m>IH#_1*^lb(WK@h6Q^MuD{A9~K<`Kya~z z2`8WH|0#ITUi=as=NqyKfiIT()xu|cnMf|8$_knxpWIru6%w_Jg(cyaw|N{HJZNKd zCw4i%z)@?51J59=X@uS2qh}uPQr~0=@xY1F3>r>Th(o(7B!*Bl(f?i|X_*oBIkGGW z80;M!3h?rmT_3u5LMWbOS;;Iu%e`$=xIRKX2#FZ0I`R7)zXS$n;O}8F2kSv2(3Mw0 z2=EiddlrrIt7F54hZ&(EV)@nMEemPl07qp41w@EO*1edPSS;+dYKL%OD`o)&i<8-h zi&T9?F}x%uCOC#MAh`Gj3a}fj;S5N){vf>!DZ(RlKpRDBf>?}CZ!b4TN239Uxh)>V z!xGCY4Ey|{&m(6=tQH3b8apIf2GhY85g$w0Q#MlPX24*eqni=2yF#j1?&#z_jI#;G zI0_}JTQp!6s-b7!s$IdwdzK!Y<;P1seL23p2-Pp9c!=YR^qs4~3(b(`@M<_tz2L0m zlhcw$dC?)Ig!$4tq`^}pSsFwrM2X1JpixHDE{Im*Wr=}Ds1qN`0HUMkT3%g-5Nun- zbb-~9nR+x8hb_Jhj3qhmIsE=-iiu!BFlY4=p>Eb`pz{zdH7J^Gk4F-M6b`|{2m^b2 zJgSr+8TVoR{v}7f{c${`M|hlyVH&rE#aQInT~NZ`A7MpYK)|~Sd4UgWdDSR{6DMKl zqOzdlBnuxJO9Xr&J4A_!x0Z|_%%E}TUj@dqf#u$>|t?wy?1E~0$5Fz_ngtszqIalO3uZMF~UHu_n%(0vfq` z87wUYH)^l}MFgoX=xNZ=yK7?gNNNfiCBJ)8K6v^R^4>xs=TP4vS5EA+V}$`Aw<->b zY4@n8S<@5m%t1 zb}I%9G$07Jf{;USS-4Rjj?c979%D!@(;T-H0xQ-yGU8RIl2+xP!|54mp>@OuHx5v` z;SCx%M+BK%lWsCBAVmu-f(41!i9di4WNU*E{2@y_^(Tsc1BAYqh>(ck#}q!V&?>>* znWfPMjPs0+co%t64vT%eMHslvTyGG1(8df41Vu1M6G^pkF>IIOHg9PPj1The{DjZh zt2t!3e-ZA?9jix*b_Lk_lb`(_1E~CSuL5`MHFWQU9$Szmwcjxf1AG1%IQVfuK@6$6ga-pv*iy$Aiv9NO zo`PaK2h#EBc}1ylr!ZKYus0eIf+wm195n(kx!`9^WD|!%@54{nF;LJyFUV{cUc|UAN zIJCyOFA65=ug9Cem@&oUAkM=DTw&f$77RMh6+AO~&=|Uw;^Anwg8q=TrOol~3WRwK z_);PxnDUWCP#9i)rPRUR|ET@qW6hlbSk~JeLUnCL<3a;vkVp_D$^LFFI}`K9#NlFC zcN$>F!C!IMhIpJF_VVuex75)xk?t@6+uY)%fh2zMwMj(EM84D8c(Aw*BQ+1AIbTSh7T13n)pr<5zV@)MS_!@mR0*B)?dr$G z$g&LQdyK0Pazg}LiL6PGJ0?bFmbf?}er{`6GSzT>3Iq7<2nCiblV1Y)j)LJMKXQ>c-&+cHvhERoDzeq~ga%_pKK3?zE8Vtkhxxw3W{fEl zIT6QGw1ZZ1-|Uh=AcO^xcUJJpdygzX^mt$)2?F9OSh8?oyGLi>Zps@9&u^ILBfOBL z_Qlc<6bUz*zaE*fQ6%3tSoBngjfnL1I!1I|(DaKSAhZ87bj88)gO0e^!)m#MXVm+E zIb%umMMO^`T=0;}4&hJ|iFm0?=mjI3D^TXf9n5#vA*BgYJt<`thxR5LXy2-LXCrYO z<@%$$6Y^mWooR1BGSBJ`t88!P1#*U)BZWZ4FIP(z?2{XEJjQw#j?RGKc?Vfu>|GJcafb-}g*8+o z7`(;ebFTpM2{uqudSHrMjR>fq%rnzdJUd~x%`ASrXa?r=ZRha*UhRmdFiYzyK%K3%_^UdaMPc288Y zs#m$f!N=4P20usy14kT`s2$~JSk7dkaYz2C1yaC^_XkqNi-irwJ}`ffv2wT>WfLNZ zCxCqQ5KM)9AwyR}`)^mLzc`cO3r+*(isA|-p!5XNN4XPA!SjxmXuXzP?nIUtQ-PI4 zK6xa3(L)Mwaeb1(m>V5TKjI9Hc)~>DBrXO-gWnK>;07;4tTNk01LX;VgdG70x~14v z5kU^hF$;zytbH$Sz^#OYImihSg@Of~^Z@cmu5);tZIH^fUaHJLLwf%38!VHp!p@`R z{i|@SR4Y|WdNjNcid6CI!Y;@S?3()#A&|5Fh5MJnwU~tvhkJMYeoXQi-%n@;;IRT> zM%>JSvd1SF|D6ylhj$=7VSWkhx{OU-BaPu2Ax-`22ze$9!&Ly*b=!MT#Mi2;0ZBii z^gmF03f5Usz-6bVZH>{*G zst|dw*~jZL5DK{m?u|=lN>)Pi1P(B#UhOw6LK?~~=h04IaW5uIJK&jnS9|RtH((18 zw;f6g14;fOEOp}7w3!!+CvsvpfCFT+Fw$<)F(tl)a$3EdygQbs4{UHQ>V-6HH`HBk zduu|v!2ROduEt#M10E;{>u357ubUNu&Tp2HX`tKi_=L*=!7nGQb|iNcMKLLe(`NGP z6I?N(WJCTIO$ zp_Fmt2EdmimJ)Wo+d@3VMNq%&+eJSj_I0mvfVhR&40(o1*qveF*$qjX2Ex^y3bZ2( z1lce5N#C1|pkLw0G*oT+4IG)%h|#+%`Y}1xWkmXf8|C;S$LY-KfzvA__psZFXHX;# z>=dyrCyEr3#lZ+}y(Ja_Psj~|_V3gnpaf?lP=M3`moW=8YEZtX!*LEt?Uexa*~qc% z6daIhV!Ph9Vu&cqgGbNy@_UM}k)YnWZ6N1H7z7xvsM;fvNUjor9aZ_{9HgISY&j&w z*n@G;rWyJ`GDZ>YmRWkC$2z;&7KW89bnJ-05})*u#BWIs^&VQbZ;@RTP<<~!1kE@; zK0m!)er$q({~biX!=T#j!IU5pMAlvPfP4qajU2Jvn>B1rB`csIO`&K?Xh|DL^E~Xq z6d=rlUxj2C49AB~g*9>bVMW1KAgbp{ckt5Lsb!*i&?&d`^X^ zvociy%TWaeY+oa+$SSf5>dZKCe#Q&fT$^@p!3=DP%zZFNjdM8hpw{krl>8A*&M{qu z%r<%$g=}zfP@3+raZz8>Z(x;L%-+|HW zZy}DjfBk7O5K_27uz1)Xhn_hM( z0p`P{#)nD-IXWoy&1MHNc3jb+X8|A^VIsu+K2}S!r08$uZhXv?;X=gW<@M{6ooYl7 z8~Y_308Ih-6UkQH@WIm=0av;Z+lR(K1b6a`v;4NScjJdhyUhjxs3h{tqPet~balP3tUS;Qjk*(?LdB zCNdj1MkB6G(;j%IF~CobW(-#jPBy1^y@9ZTY1}x_d%;OX4pc&j93ifmlxPpPb)hdg z1JWQ$0yuQ-je&Z`B7Kc9ymKfL{Mcb3zfOb_kx*1ZQ*K-t`;*IzkTD4=q1{Hzsi`eX zYd@wPAEp8g?Nq?|eY0P}(1D);+AgK-FhA&7I9!r+(i|jlueOYCVuili34n<^0D#fJFmxl*mj%#O0e2y*L=B@`8l|oJSA=OTx%946+!b8(@D( zEBgb|AzoAY$jm(jpgKeBUSyeNBLe~?i@*>DT?}*Pp|W=XGP5nm6=I#~tf^ER95%$S z^lJQy3}Um0cJV>Jv_ov6B_QJ>09-VD$+Vbp$h4b&Il_< z(-jsrgJQX*3CS(leOk?#B%qE(*?TG_uK5dJ)RL-0jf- zliGE)LyTJ%bTQV{f+d1PovdHraHv~C@)ER*1cB`(`y`*O2;diZ4ezK8^6ZFsTL5@L zen}~+a}xa8hMhpOLx|m0C#k%o&5I+KszFGHIL8}c#3l2dX5Ro6By{2o$L!qQdAl2zxlu8d<88}qYW!}oE7!C^#Wd8?S-#L3FRaQ_pV z<|iF;nf`z~MItEBoW0=cM+0m2GtO4G-D_*17>#!i4^Kx9RkS{O#$jV1t0;FqCCM2SO@E7D*@( zm{DmHbqpA|)jUU?2W3B!(qFeb{Gjch*V* zFL1Yo%5QYWg(0BF-HRi2EQx{P+UaQ>!GkVWgWiZIObPsE^{D?3Al-QnDOaJHjprSHIEh8)S119b_G zyVElx@{GxU=v}yM2;eYLL-qh!X`)lYYn6h2TjY|+zebQP1Y0tF4p`1zfl=(~U+_U& z;-!TM4k1UYOpRd0_XROqHUh&ODqqTS6x6}=(5?aK(U<#r49)=VhcYJoKllL)jLe-K zB4HvMP(HGeyZ6^@*a^XB^h0)Zz(*4onYasEB3bDE0`(EpDsczoNNxdviLH_N35uwk zteJpc8JgRe^pJ!fMb%CENTTr>di;XM2@b&=BoBJd#swYD9z8EILfjF7P^gD?h2UIb zv1>;tDy!p_Fhf0A)P@SHnk8aLjgh{EOHezi>6h)aMM?rhyz=maF z5J1GPB&#)7Yib6}x^vTT^hIP{+LKZ~Tu|0GY@cT%?Kx?N;ls3vK%> zrd)Y6&-^BWcpILJF&_B1>LrIL*+VNs;l~r16YLU$@N>YsPy7R^eOzJhBDfU+$MhD) zHb~D+GxEO>ukrG~erJ_5>m0vaQJ95tZ_eG^AXXy`__jN-;bWi>wE?z{a{!JM$ii31 z*twFBoQ!aN|M*Cz5yUK*fJ}Z+JU0aYpe1=>NbCqkxdofXMtARmI9j>|xX22x5LTx! z3Z5z=(lAfQj1WIN(4!p=>t-XttS1;VD=z1D5UUFBz5PbAb1;e(INafKB%yA3ghgtc z9ZaxkL6ETOAenm@k;09A!_E8!*^rRP$QsM~E(X9Keq+JJ96ks&Vwdx|%aFn=`KUn0 zq_r-?dUgzv8<9e8hcu%9zhFJB2qyq>`OvH-3O~~t@2>x3FwcJY;e`ACW(}SZCc3(V zay*Kxj8pEtIXe5{`wq0S4n_dT;^% zIkmef0%qOD#(>*n14}FB06w)a#=mSYK3x8TrP8pmyuN>cj`F=epJ&Smm7h-) zS(G3@%s@gF^b40UE3Tk5p zKeR6hXL0`{{TPB|^STHKbcV3N(fOEI5GS=jex0Fj$3~(+3C6>d+I!n}xsc)ji*a&E zOhftn@`MD{x3^>|lXYK(ikV3UxS@Kt#8V@T!oGpQ>dO(H3`dK{{Rf$xWnjE}BM|(@ZXk0tiU@laLX*bfHgr26${<2&U4Fs)7WXxR&zUC`XX^N0 zZ^svBKm}>#f%2M(=#K}7Azn%ll8}Nh?vKus3CjKD3O3FX_#>f6*82i6?c;5M6!@if zu?1v+5xwCif9^5PK|!!F*KEMPG6?8SuYw{v$>BG@kJm}-f2 zZwR>I^XmCQ**ZWl`4XqWUvm`j0rB91_b8*l{srFC$SV02ZYp@jaQNpq#U9Hu50E^J zkji#?Wg_$=SOBAJkF9eW;E+T)8dz>7H1M4tlz0em`v&t3?N5K2%m&5J*;YtWm1aXi z)4UQNiPZsZy?Ze+LM=Wxc9D_=2?9-kozsO*Qqc!AhnHd!1SWqwx3rMUV0$>gt<*Nx z_(7L>Pxx*d;H?x)pDiWuw`&pV|Io(^8>5+tO@qH?p)o>T3^Xc>bv-0Jb&gu!#%C8>9>=i}<^Ptu*+LVrj{jPzf@r9=8dAv*HAxT0O$W`X@I zgNdg(VqD-1ik#t}m$%>be0I%kGgu?;n;yoNW;`U4wM1x-eP93^9?yXw?;ZlQ?_0_G z!Mz~16pQ>(#S4nyS|T*q4w1Pb{?R4D3@wLMq_CZQa78L~WjYMFt0NyIV!N_^l>Yhy zX(RQy5>{o_a64`(4**NBwBZxSfQ-K>bClpcOuIOS(WID}a--T^NG^sIg0+ZAzM^FOo5evS8;$^VTLi?j8S(l@kQEuF zKlO~2pcN!aa@JBP)Hz|16C(u=@& z@b}ez2g7H6U&;^!;L;u>KxW)ixKlfzx^@jyONX8FHwi5*PLLiNuRaC^sQE(Qp^dPDX4E2`K zm{tIBzPSEI6wSwZj(gINgNcwT~Cnwl20BaC;I!8J_kk! z_fLpupr=c0ZKWNEl!3^4YviNSwur0vWkRykY=G4|z!_mJLSiPF8mWjGY%{Z3;poLk z-n$vZj)7VTQA`Zqs_`My*#R-JW}%IcJ6O)W4v4PsV0!@vZX~!zJZKT-GewWcgn8l^ zhH=FfFx)uq!9lK8n-D#QK~j{Kw8G}$+^M}nROvPNI0+WdXu%Haw`-W<>LoL!%JYA{$eYWf;s*p$G30frA&<}{OJO%2VQd6t!rh&650M6F5qJfT^XJ;0$xB;H1DPmf5;j?m0V%B5tG zPUT56PUfvAlY;zqb!X0GX?}Ty*b{gU$6aG!bY5(Ca7QBz0W$X(Iv(!zLM=4+gg_3C zIGo5K5QSfVf(LneWp)A2j#n^hkrW;TSkBw&fHfd=Xb28!o7=E36%J*LVl=_E_W-nb z%N_xY%t;PS%i$7~6tl?5({zc~80^&UHR$Wy~4p*7kT!Bq7^=9aSxi!Lw zt?+)*DMj>_X!LjO%xwt95@yMO^bbxa8+%8DE1Tr|$b6-zG>7Li)J!7tA$$vHIzUj6 zp0^Pz$@n>WRU9r6ei%^qOhpRfaZ~S97Mya6;4s3$cBLnZ;MhJ|Ab6xeSAa9p+#r## z5SsDo5i&FAg(G2xB#UZC4q7YZ3)}8Rt-}+jpk#a)y!Q%-pGAu7O;zFEh>T%7B)Nzu zMMOisf|EUN;_?hIUVsi=Qwu9_6@I5NbE*l`zX0Qf=(tuejmyypNg_FX{FAUoO)32|`S&0%|x{Fpr461oF^Wx5UkAmMl>VR-0W z*{(LK_xUp#IIvTDW^6A9Q5@%Ah9W?)O|a;=$+eH)qX*xSL`!iA0M>R-wOjs>8=$4{ z+F@^mL>|ta`~Arby;+_IgoZ$9`H-}lhwJCf%Z++B_9shPg*l;GB=@DjwsDU1g{m>_D)8soCj_PH@A_@V=@&`SBd zh;d1#R~e8ucg~=o!D#S5s2d_RcXxXKhWmmOD-a5auuM-VLM;*#VP$Do;-;3dbz>54 zWAZ>KVZopR`Fs$DSA<@_?>U1G2^C&1Ndgx;1(;yb=*6%QF(9jKy@TG7d-D4pW0GW$ zr98EOvdV-^!3UNUPJpC4c#0^zxDca~9^**w9( z8`5P2GvP&+elFL?vF5D*;C~VRMip$xGD zU;aA2{Q2jfWkTH4!91m3?^{GoWa%}7M49znvZc!Ca61JDV6#NeTn7V+HsA}u^m5e=3?32o+ zzF#zo3Q3%#7#s$v%`kAtkSH+zzYWsR)?=nJ}>}qy$*ow{Uc$j6Qb^? z7R9X8lB@JFC;u~XQfuF$zvp08qlqpmc29rmWf1XaJABhd;4ou)9UXJ{9diIIw^ocsq)a3Zxy^mdk zNr8LuRtqv=O9kWJxz&PJWielGb}KE+x|SEdt%aGbTUd#*YN_lfrR z-|ru<-Y>CqbV;om0GXmVBidM0mQ@OR&19vhSFnA?4|t)#xIF;t#?~2 zu4U7Uec~)mRVNGesES~mQ`NTZpn;ER>|^ISU-ePL1r&w9o{xx*#8~3EqoRT)ywp9cl0VOBxQByzC&B&WyQ z!F2F|0my`mulFxv*BZO(``#*cL;4X96v7Pj5?9v);nWiEfa2$jN9xg*>*0>S`xX|M z*;!E6v9)0H!M@ue?nD?Acg#Kql3sS$E>HKYG9!)J1?i+JJ#s8Z99x}lz3n^mW#(5q z^-L%vn*C17@`mfR+Eqr+M+$}AL^*IK_?=x5vaEe+{1kWW^p)c896IHX-MOfLa8@kD zCMx0n7iY>JN%OPcA@%n`zPg;LkzFsIaGi=_wlhkmq(bdCg6+jlGHceBIXP9+vh2v! zt2?lG){M(7Rhb31p2P|+HW+`;`Jz~oy+q*%1{#uehsN-1t;v2vTmzdFTWulC^`lP! z&*sO9y86pYEZF2lWbX-6fR!IFes!y*_?anJACscMv3$kPGHBZKk4JMTx*H?>{@06V z2Hh^`e>We`AXTD?yl+)`U+ImC!8cc}Dp$=a zE+|j(Wsa5)s#7T`2c48AkFM|T?v1NJ=0hbg;Ydr%dO1v^xbZWqf`h7EC_5fjJibrT zM(bU5i=k2GvNN%dP|mzKhf^`5FdNy~2oEDZ*Qw9`dXeyvT<1@x$K>o59`J8s%s(V+ zGa2iogs1Qi*GF$SZx$D8I+SY4lt!6@_Rw@H>OaJ$y zn2MI4qGlJa(7ZBj9s2>JJBsDU;m=2$M$X4(IdE*~enzyVs#ddw z{F?@cxJXUe)L)Lz-^JDW^t|{Po2%*n=dTbKOUWgJO-p3IeTPdAcWpSYzWi7oqKLl% zx{sg+;!B{?0$e0Bzhb@g$dw9z8A-Gd zKO$tHc2Q)im5;FZ)9LBY$Fn}2BKZ=hkF~c!-&?tEq*<{;(uI__jqb${;Co!0ewl6h z&Bs3V1@>q45U*CS>+pxIk}R2|1Ui-jP0Ethkd)|i;DDotz9wu-ju)*KIS!;+1kYdn zokcgle?Gs&!q2ubig&EZcBzzjH^uJp%PFfH>WM8;tE@x+ByyW(c}AB3{pb>&iRRDN ziY4|}bvN^}m-X^zKlRh&r`NArqF9I=1dmd2nyD4Jph1-q#{&2Q#>o=goW8~algd2* z@$mAj8Or_dCDQ$p!H9jYjcEpOUsW=K7e8)q|8o4aFe=#LKmVfntIly0=yxw%{_-RC zuK(@6@*A=S4>TfZ|BHK|{tP>h`I&}D`Rq&F(zNA$K~T-OYX0Zl(JO3{U!zhc`Pm#T z;f}oD&OVMjFvk0{`=@Ucs9SgtNw60zyDnS)e?!|FIDiDI@tC#lDMyf z>zzAS!B^Ej^O&pk?yA~n0v}bu)jne@Qw3N1d{yuBhiadBP1Y!XsP>t_MOARM&ls&# z!PP#0NcyaYG>@9knzQcq!CgnY-~R2_9f$5f=}5vR6v35a?NF}V8NyOIL}RgDba$wd z{9&k4h#!@55m1SW_#%Kst{?LINAW?8lzx4Z%!G@lS7FHG&*X*vRk~mAo|MX)>iOYx zmsPT+0QpzBr*Wb%5Jo1pnkgC5!l8O}<#-Bv|4UHVAo9{?wO4kR*2wLEF0MI-?gWLn&D=tm2{e)D_1 zV3FG;v65v?0$zU%3pK9Cejn%C)OSFb7*Xh8sl>)Ayuh=jq%!?afF_k2?0w?Fj63BNJ_zx~1PzLUiies!13Z-30i>$CVZsGLKI z+&jPhQT{&rar?mAGky@w@wZF!9w#Oq2-WiYyxdo;Lhlpj=ECqt9`SS`afVRT3ZKUTBoZHtK-5!yDz1 zK<4lozR%7{Z}}K!_KmQfWeRZL9VhPC++%bQiUJ$!U+9&B)Hk;RP@mVpAp6585N;o2 z2}I9@CK2;~bZc6q_F@=zHq#pDu>>+LaM|k&6Q`y@MfJs($nZEXA<7l=)(9nTk^@8U z2h2~B^=2alL8w$Oj?GoeUoX_R{jCro91nw5_z07WA?qWq8&ae+wn zV^S*F=deUPTPfyQVI1Pm>6-8Z=&QWbXHz=2rYMrjs<{_cz1~oJ@7wK3QL8;%g5-Hu zZBNTu6|dU$q^MbKpgmk}+7&;v+mj+`@28(`Cf7Ir{I6~|!=q}syxyID`qxnc{`M{= z=~%ON_1k?t`~V4&Kt@>n>9_Y}qJI4P)4vv*pZ>)~B=LR+h?v%KuiUK(&cD;ZAV2-< z-A^Ch{q!$h1wZ}k^@)ExAAkDSdOlc}xa`i1v)W5cSLf4Xp@A~~uANVhL9D1a* z;uqRG5-2PPm^Ho*ZfgqqV932&;BU4gPvLb+=)?Ds|s`q7mN_CuX^$B^!Sh%{5hpn>KEu}Wo7;!h>a3`GyK zqtO3mnvOq})XZo1F#E-hRWnWYKSWCI7t>t-Lk=-bIY`-%dl8w{;eh?mIYsw-(YyZV zI=twqgI}4IWLqtI?clAxpWij;ob4pp2F|UP&t)6VvLWsTN5}tK|6K3o7Pcl_gUVwu z(RTUt93N}=E2sS6GjH#{Ig4dm*?M?Q30Qvj?MQ5y^Xc{Z?s&FLm=W(*X;G=+o)(&8 zMOLfwyO?HG%S2XyKJVKv2&vD#)HF~`O2e;uLL^0f#Z+$E#syOTl*S&7RHg4FDM70U z?L@suvqH3rnzcSiQiXag&5aO>ROqz7yL)&QWyieIO<=WnWv2>tV9Hpj=WW{mu=+ap`xPNjQ!1y@uw5N5LchEP;~#76?}!6N5v za7I)|!~LF-aoHgIW6U(KN2Nqme$lCmUGB~@w4qV{6i2r1v0ocyNo9WBDX~GTCVM_q zu|HqcepXYkr_=d(#Q~F5lQXJ9&HY?O*Qwc+6Pj>8W{bxCn5-E0(~qN*0*ie{LZVzr zQURus8B2hRhrgfLX1Hpm3s2y&EL~%vtnqW4LqWRhEYd352}>`Iv{Z~gn?uL`ZbTl* z&neuy(5QIaS$-!2(0kbABk0TpQ|RlbLRlgmMV6&JclzCK8$<%KdPfh$RFEq1XSXrr zw_YCFJwCm@*m>%^*gO<7Kp^gakNcuLPYXz1`Im3U$K=p$(kPHkQg7%`AQrKKoUzk1 zBk2uR8OS&f8Y)2jxkRO(EmzU)RDMp}Wz7;xe>ZE)dBuvoW#}OX^lv!#oDwNV_%YV) ze@b7R@z;n%33bNcT&1H^LfgtI7@D(%YD#NLLD#Y)%&m5oZ^k!)&h~_`xCszI^ zGR-{e>MVZUzrL_&i=X2b9w>?**|!m@#o;fDVl|W&x1y1)^pBxT3Ib(w12r+}71q;n zpL&5%21+TF{cTVi02+#Y$3BXBwL$43=1pREeQ>-9DHr|2kE0&Czui8(8Wz`E(aio* z{`kjH?}Ip*d2v`cOjE{=7Q04xiLb}!;&<~<3geT4y0fEAztt%(wA!6b<)T!qCS1jq zIYfi3R5XNJwGE_bJC$(C=Y&p|MR9!n^C`ib-y%@#V8o~q&hKZKvqGDjmmM%=B5XwH z1oLGesV>K?UW3sla_v-Jo;PF4T^svn%nl~6XR@bG4@6*}%7wMBWXE`pe%I8=xA zEDB>?T#TPHr`1sNaQk|WUNpt5afFfEsa^dy650PM76^f${vrp7OGR&v4K3;L989sq zQ*hAqXRImw@9{&Ff><}7u}gIKb+v8}QHHLH@IQ|3kk4iG)xn|O^skT4zVRy2TC=}n z8F{$Blf4I9{Hp&5AF8~r7ki4!Ys&353uK|XENsr3v|w3nVR~sM^%5;;Q4+6}v?#fT z%A!WKL=TnJN)@1KQM;{7GnG_J^ixGiql2lgDy=mzhKb%Psnsh!o%$p#YJZoiw;ElX zlf&dT?jCnKdPBc->8RW*gZIv0+0VUJD*Kr=W>_<#KZQlx$$KP2JC#rNW2)TA3b`ls z0iOMAhiRawtCnRy61c&0RUvRg_y{?TePQ^`3l`n$J{}6QzsSFXq|5yt&>Xovb@N+q z02O%Fs_j!KO`kNL9_NI;SD6W4V9rv0Q;S{{9fYc&arrH@Jk+qFly;1Uey)*dGRH>WgXQ|j_lKftuCcESkc)c??$J9IX`l9n?Vnpq;@q12b8DKVWZoIhucJLzCC%XM}dsiEqjM%2A+3 z&@hYt!7nrj8|(jNn%1JEZF+zFlV;Ec{YU@rN%9BEv{1rp_?Z0hF8S+y^4FFB3$yaO zZ}Drj73tnh8cE!t%K}fPEcno>@vnLTalBgv{xkA62*6#hadp$I;m4pP)%XsAUf0|B zaMSpX4>$jr*0`F^$rtiT4QbPo(ROqLcifEeg2zdWNfCA&J&)|!putEsP88h>*=`!UH&ps zEk2($le)aGDik;Z2*pM&6v=;rV*dt_&k_E$GNwQD(WJq%HP0%Nrw25gMaOpJxKAeF z6DHVM(*;Hc*L_b7df)5JZ*Juon9re-a|w=hRBI$&_GQL+?MfnK-JieKIe6I;lSec*h zCGla_szNvl-vYWw=@UXXO}Z<4u59QNdtQ7p`(;rz>xwpPK{4#^4V!RK{k>pxzVx?BV{itUAVv z|GzCseJ5vw-(j^A5-JF=umR+|RP$7!plpa7N3F6U7DXC}9$5_v&GRE;Udrk+8xIdh zmV~Z6JuV0xQUQwP!QkXc{!Zd`-<&jywx<7ks?hO^SSM2Q8n@<<)$XEoH#h0?=@SaJ z$LeX}Ijx7@ZL92vN62?q7pyCP_Sa`+v7V1Ic;RRr0J@>&&isCV#|Xa)_gW+9aC(H^ zNDKzObt-e==gOTXZ9@Le>X&cp@bT2x0i66VSXWfW$_>&D`B1;Ua=^25(3^j*AszqP zx+4bJTb6o-l49lPPtua!>*Kw=t@ElU{A?`?rNN%7+kca463;{QwHut@5IUEkXfklJoS{Te7~JUxa~c$MzQv)a9%%ldvG2cAsy zqX)Tl@h0r~h42~Qvn~-V@@9tQ!yWb2oiC7q7mgM)U&^xk{gHl@BJ_oGC(nddAqoN~ zN9c#B1sr%M#ikT=i4uV^NikJv$L*BnaJUDRKjF&il7Y4UR+9edAPAeMxi2fVImlsr zK8HCLu|*9QQdiarv5uCgpGWsXs3GcaB-g_z!>H7JeR!yHLQ>T|uO4nc9kW+rEOhD5 zO1hsVe#gxxn3B)(R6b{?p%PHh*}(J6fyfv9%yT-5Kq`&hpZ|~YkxkK$l4`#6^3v>r z%8R*mH2Y7bBhtj>r(hr$9wrS^$|VGX4N!S^mOzo_$;+jB&PjK^oW8P_S!ZS4aExl6 z^y0?S+HrPxCFfUPj%e~NIk0xw3TF6Ss|a3{{kyjHGVF2g4$PjVQuqz)8GRa;W1=fS zWjw7io^MA)AC-+0CcP@dl!kSn`!{#l!0_8q2z=LUZ&hBjD8Bhpne&8z+~8N0J)!gH zu5i7xDz}k=Fk}^3xpt@Z5X}ld-=J{9{_*DJG%z?qOjwcu-a_d5clGBsC5?|1+1GL& zo(A8p+DP(ttx>r2wpA*9`YCswvIF@?<)RyY+6tv-%^B5Z^%c{2{z{omd0BqV`G`pI zGcqK1E7kxkUCA#rP*h!x=RVa?Ybo};K`(D`Cr4#L`d6vBPI#7(ET+<+D5P#n-L z7m*Ag^>AX{%AOf|sVXtAh(RUs}S)NuBJ5_?xCt% zx?SuOY~M+yv;kE6m14TVg{rpgZ91)+pnsR5wnDM>>E=;%WtB6x$2FP29#B4TwV$mA zt`-*0((*fc4!_R*+0q-_n#m^HCeeIhN?$ys+Oy6S|Eb~ct2enG^*4V=NPCV6My2eC zf6qxuMi;lfg#7jHoyuIQH;|7{?^rrkVjs~yCDWsL=*WRr<1?2B|I!H@P)dUE?(V4j zj{8#ko)TCx0}tH$+0j9;aFLG>Xnq7?PZgfLK6rW7DR71Xx_GB)3~GI;`X!o?lQ`rm zKUHyS?H+a%tRlH0sd1ow7o1&W?6fK3Jv$Z1O?ceZ74HJnr$br)O>$wW-x9*EfBAPW zuMrF5Ts$T*c#~=PBCogX!KEOiYv`gpt!%ax&=Ok^L{^@IeY9TBlcb+27}0v@L`!tt z>?V-%hx^Ar*klQ;q@qkLfHL!-{pxxankrqmu*SgY!<_pRS^uAKCa7F;1(ASU zEK^21e}Zb^rD>E=3Xw29`&4{U1;ZeViNTwo2zqbMkBFi;>1qe6cC?`&?aM0qQHuN{ z+}*(yMXo@akK(>CJXea3(Ymc!)WRRH4}aV~)-;AtKcXe8Y5b+=ucwFmJ1n!zNm(>s z-x1-p8rHk6{X$elD*;-Sk~+Y5jF!H9VY`&i+6*w*Rr5YJI98Y2lf}1%7q0JG_By5M z!E-}P2dg>`Av5fP>^I`N+|-v!SP0d3D|Is^s@H^7E*r4^ff-fY#SnZa3QJXTOYKKF z@sKdGb5u==YQLyIsH22N5DWD8NsY%;9D*$O@T?s$j_nsEZ_RE->gy}<{3N-Eica>* zP2o_=LhdMx!ft+uw{@k|dq2}Tb$>1pNQggI1wQnuch8Xnk`upB99AL4Ep{`k4~2;5 zB-qj3Bev+Jf06lZCi=-LM3_KTi`I|2o^z?ZTIfYzT2Xo`lGYqKKlCE*zZbS&g-6B5d2s8j z)J1x8=R#DMl?QZ0(viOS?6Quf_4l)nQLRxHW&A=f3TOcbbP3Xsqb34PTCweCbPRzkTGPUVXjpfBV@r zRH<)^Y;P_;^8WW^zwJ5oLRX@NpPz|y(O}vY(A(?E(n$xiD9+9mEw_vE3tS1zYjzGR ztR+5^8~N_Uv!XC!)@uD+4p4qkEm`B9{du++Z7>6Uck@rVu$~%*pb<7`3hH1QQ58v@ zh!@fU^X0u;M9r|lK^`PQleKnpKXXLhVUzw@3^>yAkBg2|g0Od(TKh4n07MrfrvEq{7`$~%Wl5hKOo%6I9Cw=zPT;! zarAfLqMq)bGEPW~zNn$JlV2A-{HUr}RawJIT6`kSS8F)8K;Qo|G0 zZ%^gU`1j?*7ZU7$-f}k;b-NUP`H~%eAAjAcxCRaxPP(+kq?{dm`ovhNq$C?|N|lRt z+>H)=-f^nuDLBOjN2AYQ{f1+ zzq{0Fj<%%V`zWH4_$Ogm+%Ix~O%MhF5eF4B0>5KRay8v>NJ?@eMn0Dq2|%1#+oL`#GTZK-^ zGxfFIwo-4KS_jnT^JA~4u?+{G=JG4Y%e{mv;3w$;J zQmm`4K9$`SURw8G?_byro}aHyx!}Iu62~tiufHE3(SeZ!G2Dytd z5M#~SQ{5M9&(#B>B%E-ZYVc9PhyjDAFhX{xtupPj>2U*nEWJ*wzlu;)+ zQCjuOlwbwgB5S1+=J^{PzgxY&T=6YUdU09w9Dhr5Wu;bAsyE5q&Rb2?!7b7{SWYe( z?C)BXtJoId+`qj=w7|6pX6hR6{n{eiK(~lnghzD2rft!`$9WYzOQ8}=A>47S(UVARq%LjuU8V&-jRt9QR8!18ss7AI*y#ak2 zS#!SB`(98_YP1_E^r!8b;!Vy_wr|GF+Qr@)GxξA<`i;adbvdE!!52w;&8)Snx!C(!ooYjf=*lP@ zRq}OYn`jxgqfNGg9U`2^`WPZyU|WP!@3|Jq4Amr-+mtrx6~HFRO8Ai`)f%=**cn3g zCe%%u8LUMvL^x>?ihwo=(V2MB^3aAA0dpm6N}Xv6V1IDb&(adr?xk@cY=5i;HA$6` zS(*eZ&^Fm5m`j^v3cEzE7W?HA?P{HNL(wdm5e-r9c|YvA zycKf0&$w-A{Gukk0BH6v#xc@BM@>pO?hOQy`w$rE4HP}FMN*D1Q5Ux;h4Ll=@5dPp zXwPk8HEf%(DCr5~*xMI3yO;+7Y|g0)%d&t?1D!?9U4YxYEzxyRwhIYWMYo9;5v1CK zQ9@f}3&-IW(Gu7unOGXO38t_nxfs-{Ny{wQPw$#!jx+x4V$UAzWO>bXbXgqK z6S~A;Dy0BweQYKRZT73cwFtJHv|2OL#5Wtr9jBX=3t*dM#gn>CwgzsJZiE(VQg7i0 z8c0Ku4N%U2Et1B4u0_m3T4cP`I)*!I5i5ZgND8kpbPaie0X9r7hEp5vpusf>Ho~tp z3Agag2AsQi9=5GXzX88MUSBFU+S>*CCH_JKj;m~6{azCgU>C^sHr#J}%zNUEN|&07 z5$P@riiusR zheX2$Ehh6~j4t-%mj)xjUg~qg>RcF(1bd0_B_U%!4gvQ@g4QeJ;!yO*%m1k7>K1Zo zkR7PmXA^CrNy%cGgjgSW=*1?%8usmk>qa>8^eO%38U{IaFb19eS=gShqU*NO;5XR# zkb@(W09z#M0VP{>8|W7CL??9N2&!T)5w?LvT7B*bC)l?U?!#TajdVa?Ant->UZCkg zmq@+oboV2W@hKNb_fC@+`Wavs$T{|>xgUHNd(;JDwHTil`dO{gY^L|^bgsEg(iyBp z&V=P?k+P5~8A5Ja*>!y&3s8$xW=BxF2BDRqn#9tWrqxdrY8k9W4mofV0<}f2z_kd9 zWXK&py=QrgWChtGngm&G(Mv%sQoZ-D_^e1qljhu(z!u5=%(E_`txi_4mk7JV)H!tz z9qi0|Prp{>LNjF&aiJF{Kj6Vp7zz(Rs2LBy?3~) zJ*e5o%=VzQjxtz_TpAg;)wK-OCT2DKjh-dJhMOan1s!g7OichnY~lfOwHU>1s#SFJ zvrjRyahs&Uvlidd-{`sJ9T~ZSJCHH$U059KnO6>$V@QRq#Kv773p@EQqMV z2K%hCyZ%{Fm!k)oId+h6DR5~XO1czk_*Mhry=>!%x8|_GwFt(z<1JDK(InEpa{BNI z%?}RmoQNDCng)MscF>q$JD-HNkW7S%jg@MxcoO_u8W?y<$hxw$duWU7n=FKcXbEhR z!~~`{J{JA4CZ}%i0`b1C!H38@`A6MmMmrma+Z1z?yaV}fg$Qm+aS?Vqkz;JH| ztZV|o9y8cO2dc&3Y7VV@*g&!@aV3VZA3JDxQa|!#9 zL%pJI4kQSLF-9)QjDX2**%T3XwmgCw4xpp*{MVnMW zTqH7deZ=G!a>raI<*$OqxJPOiu8dyDm#5Tdf3EOxW!}nmkDX^A*5I`87aDNKW0w2l!e`X$G#hf(Jwbrf`hX19B5IB;xxad=nl~u7 zEnKYZzc%cws<=zN?cbw~Mc#L_hg~8^Ln1bFys!yKt7K#CTiEv`;(iqFWs|of3 z;od%Dm}HN-KrE*8x$x}<*dnQnL6QTgMYDn&ASzj4P1c|RqB*ifG|w~CB3a;S1pACb z%8+mthP*^Is%`KPX_V_?`r9i?Dl^~H&5$*s%QF2@t*13uja)lhQjO{Wx<$O-BWg$C zaxAqd*PvChwX{rCqE%pvq-9A>9;X)J7Q98?h;rX5m5}UGm#S5p)AUdxARFQw%N$cx zrrjr!g3GtLrmCY-%}O;y^!Tg+OC|2GOBgahw#2qSz2_DBj8<*31+qqTC~ zfa+zd+-c0LRUJzymPeRQkGnXC`>E>sCb=fQ)jRueuN+{~2Mei^DUx_q$F4-xh_zCF z)krq6O~RPX+caTKqB*WfkSkMeH_3+HBxW%+LX8w;HF_;*i)@lssIK>|BsZ(B#%7YU zRzIs5(VC=H9TYR8wTR}h`iEB%snrSAfDMutGp{vTxLmK%pqR5g$cR*h?UlVsROI10 z|34byz>%zPjc*%juCIBi(V?5neo?@+2&SfWA(vsR>n(VLd^J5?gLWO;B5YIIwFoAd zCZQtzU6WjiY!fXK=C!Go(6^KAbL_pHdZ_U~Xrz*z?|;x>t#-3<6R4)XS=AV=cLN+E z)3#|#1EDt#*IMGh#z$9D3^s`xyPnqhaM?DA5AYhtA-A9ksxe;91O|JRS28ZNK2myq z={QkBNy5V+YALYMHzR zA}pdoq_oYcUmYc`Nid02 zxhk|lwurt`pQi%WAScguwV8WE_(P_s32%~5lAbocpFC_fHEQePcbZOBxEryLP`FY7Nr!_B$elNZIUa14U#qyY=c+=X_EO$7H!Q! z*yoIGQY(>fCfbrZRC3lfEZ$h~{tz0DTvNq0`dKEjZG3wL*dpny4ZOBhGvBsoR*(Zk zMaN)r|Bm&5i64wH&$Yz?qNKIHN8O8DO$bdflqIIfqJ#d za5H{uW|@(P+iBDpZYVrG>Wj<|P(ZbaC27K1-AqAEQpZ1^PR}pB?MkCxZ*bb@WDr{g zCDx~RZgwrl)p{psdV>>kb-ibZ7Lius=vwcDWD`H!K;{Np8OcaI!wwS;NvelC9APbT z*2%HaJqu}(vBI0^xYZz72e(LD6>D$y(;!@fw#e3k&o;=`pe?fKTYD*8gPK9KiKHPj zo0L*mi=1bOEZCb5u9WKsjU#_06~Q}9L7 zYE9Q1!$8!-E|Civ&Rb*H6O6!1BrBn-VoLN&%?ww*)O6E&%}!w3dQDIXKX75YSFzPT z+U)H0xl0ijiCnbEs4Y6%#zg|PE@(n^uOpOP@wM43Fik>PUil`m9M>eM`E5TF#F+!L z-M19=CSrAVRKL_xYw*d6vsXh%Mc@47I=b0cZ*P&*I=U-O~vNTDNWAeYG8 ze7S!>wpiE9SYi>_Ao*`n(UbAIH5Z|{SzRR1PxnuC{TN;O_f14JiG0yCZq8}0-IWy8 zCdS$)L;3N!zA?2=vhsV(Afd1d>kI4Oq>ld@*GZdHuUIlDl{n%)ER2% z`|-a|r|$#9D9R8AX_C4B`fxfqUDcP{yMf6qfK8I$pN?Pa`Hyu*d~vfni~%NZlESJV zxf^^>97Egw*5O*s#=HkFmr2XeLHnG++T`%IeLQ`?zkRs*(r|ru^fFwN;QxKS<=i`- zzqP;IK$>Kpk6(n-!i@Oo;r4N0mJ48$AAU@-%Po;eeoq|XO;Y)`_Q-&=eStQaO8H!l)nuSGG%H2TOItMks%h?Z3= z{<`}&ve!ly5d;j>4fBvH= za93ufz}0x)s!=I$HLhAUDg~~_hgOYBfvfSaR*g!59cLM$o8K3ko2%(YBDFprPqI;8 zo==s4tu0)YprpJOL!aC8`E+;B8?zSjUMN<9b&>=z_e!1Tgm7T8}am1AGr+DB4hQXwY3i!3u%%0e3WD4(~%?WsEfDRsS2`1 zRPVn1)6=!P%UCQNnf8&ukE3?kQSNbh2pJA8dFe% zHp!-T6D^7vI&zF2ucp@q*DZIW z#cHtvH^rOcXEE}bJsiKYc+LU0yIzfE-FQ5n1A|mSXLP+=EY^qpVdns~wno?M{dnB1 z_d;ZZxcJ8rQX=&T?Ti=Kv&EWGneV|&9`5Ny1G&6j%nz&aY%~_6&!cqw+;{Gs`ADG4 z&0)QscU9>76uMZ-upO#UJ9O*o*<{=umMiV5?LhzWwhy33^ZjhKUFL*)wCx7y@oGDn z9!4#+?MZjNJ&bmn!(juOr%*W>ae$ZC)9re*n;j-#H>carzlfQfB+=R4ioL>T3*E1F zo5fQ4P(gmN$lYYU8qEc{C3fBr&FNvhJxq4edafxMm7!8%^XY1~Sr;GhJ{hyw zVm{xG_Z3t^Y_l94CacLT|A6<&n9b(9@pRr56Y%~^LTox(EvNH+F&giaF`MnX-Ey*# zBO>|C_t}_@HtX$S+Ap{;0q>JBn;)jz`HaEKiJg<4b+f}}GG56+lC*i1jM-toUv-PF zAa?aRA+}j;ce82P=2bFghuvZ~pX`g(c$JOWcs`#WcH5$7$(S7$Q%>exF&J0bn2nd+ zdOnf^DE-W2%=XJ}G@UMsrE!&w*?2RXF1cqiVjq$*TTG|>&3?KrQR$dXyUBdMD%$*z zj2T+$^+HeSzGbGgux&-{>#*vfFUn zLqq{Hgzq9uiI~~-hNG$L_Hr>PW{!6Dqfdt#ag*!CY_gbdq}%h;S3Oz};+%1e4Q{XJ zqseS@SjejBL2-(A*X#9uI@(WVQbKW@+wJvYGM?;qdgb@!aZ;(i;<{bWWr2j^SbfYL zFdmIzWy0DP9%UqfYRm-8xc{c})oK&Y7C{wE4Aka}{eCu;anTPw^u9W=OKjXtHyW>Z zQyG>FmG*3MSRA^8oEj-CS!bK+e79eZWC3L;Lu`7zolKV80WuCB`#_gE^;e(bgw3vZ zv+amYCzFxG5^}5Aa<^OT<=n_{aqif=yU}bn+8yMu&0z_-^v=hz?ki*bYUW~oJzMVKWjAu|W!-!IWcmju4#zdAOvS7DTF7nS%Eo$Z<>c&<#O5CD z=;EQ)Kl8ow>-l=LUBEz9`e#45yPnOryXi_#i?n53u;wt>U#}Ls^?0+Bwtv@fDTmY9 za2AK_#dtR3_LHwQfH)lc>-B8EU9RS`<{~04BS=iPa0*M=F$Q2sOr}d1n3YU;M8v^_ z#A>x=ZOf+{fF-e#^Wrd*B^VKL_zu_0Zn8Tp_Hv6DKtf_U?v`Uc%>%-442SF8>d;MQ z%Y=kw78nayfbn#Ze5&CSAhBM;+K-d*wk*Q_dNSE8Mu)Xr2eB7+EOz6`XtSIogJl^5 zCUvsfaI47e8%fx)U_RiEx@1x#d(aEaX1$~C!1I4Qoo^<7UwW9?CVT18W9OFE~ z*>$q#0?4*Dzg~Cy!vbl8L->&@7Cy^^wb3DpQ$ikQ-dKn0ZnWPWCcZl!V4GTBPxq_s zY`5`;jh$=HRG1TNcFmUGuC|?=?sVOv?b{mMXvyihuTVAJgRfn3zKjk#KdhFX>E-si z+imu%sj{`*Ip0T{>+N*9;hd23w>xKhXn%d^_OltBC#9SF$3ODwGKx#iNS)j2j4{CT z$#yrHb;^>uaNhNo+Twbv6eq3k=iDw!SqFW&ZGAK1H89cr8H#Q7E!@g()5-ev<%a3nAs~hM z8yVu3&GhoMe4%+jzIyZ0GvK45dliJ7mDSkt`cuZiF0&+4r1$>y2=0q1aZR zt#{+ycq@EsUv3*;am*cdo$!mHI9BJtVPA8O*pYK$-$Yh7y`GFuxeeQY1_F*Yh#oCvw=25MXVTo&W9j;T{v-5;d0nhV)a#)^ZolbFMj!>Hq}FQ$hih4t7G<7S^lHlT;_AtJ_1>P7d>|;~F2cnnq>>MuZpMe* zZkmr(vJx2f!-UmdqLL4sjJXZA`chBYv+qnuZ5BwASF-6X%DkEQz>dAU*iYs1NkPe2 zZDC+IKx7vssN@5?>3X_xN}m*zkV34>dKk%$OHj!Nu2!@CZnMpY-9CbZA3>IKm@Q;; zT2dc&RvrLsi|hkQL;*8LB-D76bC6H+k@&E)qdL8o=g4ZICqmk&l~&BISIGOPNRNs} zGhqed8}98%`3?2~z!lqdBLvfW(qzrr?oE(+F3}AY>*s?V5|+lE1NSh_7pxT~Luz*z z&5@wypOCG6j;;AldE2C8$wS+*5saLL24fc=Yz*S(9R>)35e0@YtFbd1q#!Hq{Hct-e_h7X|HVUk#%o$S;hu`I zj8R)pUplH}HVFoxVzuay!td=iD)miarcVs#eBP}&-t+scWAxL$jS<{V z=5n|up9w8-`;0FOx!S{l&RN$X-XEz3 zoP#qHi^FQc)FblI+n=kek0J{+wZB`T&>wefTz}|0Lg9Y8|IZI*Bqtd3t-4L8>=rj! z=hBV+=ZE~}oQ=05)Gpb0Pf4+Qw#E(cPdg;PFlHdD5_hwkm}Ff>RL=Q_7i>XFd&O( zGEv^&otZPlwlB9YukpU2OLV_mj?@YZ@Z*5l9>V1DdOz8y8d`-Yhy8 zP}xiZ@fU!79ibUrboz!VN-8*Q(;&?;)IMdD!Do`5vtras3uoVBJj&6RqF|(cr~5>I}%%8Z|C#foXZ(v z)8nVtuUo<(V8%Kjn~Jd1_zOie+U)U`LqP2}E!r^~8Fo8cO-G#`c^1oFMAwmFcZbzs zyjO`Qqif+v{S)l^`Y`JlGJS(4D^oY^@v}wqR@g2ki!ruAd|!g@rM7*o_?4VDoJ<%Y z%9aYtwa3}cVcF!C)KOb>yW$bk!g#NH97pv`j z?@qNATmx9eI*59Z2JzmNc{N9p+gjKa+>2Gy`OA+{sKf31u@KmsTPhXDwqMl zb`g7m@dgH%9=A*&FWn54Kn!%m`KcaF||;I1#dkAOh{rCBL@?jNcXh{mlDMEVzlLv ztHKzTjREQbd3=_qdP4hvQUum$qn60kDx%r5RXAKZs6-QSxoqRUy&hhw^Z#UB9O;PwCqqi;Qb{(OA8eLkn_P*lu|Ic&XbbkEnc(KG07 zQHO416oZ}&^}}mQwd3L)(@+1_JfDvb4{9eczZD;UJDc=%GvAK4TV-c|;gagH+tcTi zs>pu2i7*_rJ|@(XIgm!X1rNa9K?9N30aMl4Y%bgHZAU9xdAZ-C;acdv4+fKg#Y~&v zD4J|WVlyG!dV0J2OdeT<4JJeA*PLCFJ?lJ2m%%6KZa7V`HI=Uo=0O>1em%w@9TT{C zSb6iA42Z1-8ajlxGI+g(PKH5cKIsngg_?k2r&FiIk`enXSTHEDmCWfSjBZA=!}w%9 z>PBkgk)dT!>QYoxjc-!e@hUi84 zRquWz4~@<7$MNAj!W1knaWsP~EC##TUgQ#H{pn?xVG*+Ib{(dDa$*YB`YY8c$o|=5 z(WMNKzb*aytssrnFP2}bmCi5N3TZgE9h@dqgbNE5Y8{FLgR}!FB8yI*IPOxLOHh=2 zOhgE64+;le};l?v(Hd{--Joxqb>rqUwGU)1hgRB&h zq-=5r{q^yw0p@#0>nU0`q3b;Be!snc`G}8VMwat>vRRGBBi)Z&=r6|#3g&XUUX4+t zLr)h%1vE!6vf3YzoCD(HgM=Xe>hU#Je+Q^Zn*fDYJ~Wt_ZB~cTbR~B-7CB|lvF{vj zIn(82Y<%3|dbL?>u=H{qU?P3*O_Q?mz`bBPW1;AHc+R4-q7dm|bG$_DA>SYx9e*{7 zw?am8&6$e26Adp=cMKSCei$r~i{J~`Ta^wVk=bKshZsP{yE_|X)`1b%|Bq%ZJ5YH%zz4TAcZ?h*In9 ziZx-1-r-U@nyyD`QxL{PjXu2wBI~(GanKGUFJllnMttYB#=Fl2c)Z0D3E@ly{G|YM zCnL&~&&&wFFA1;E&v3uUV$Q)C;XSs7V^p(h(xghc>GA31TU2=?2EgE*6VfqPl<6Et z06gOsi%WESf{+cUX0r#fg5OK@k~uoe+b9;|&R#CoBVMq=6#UE?aeMai9dG>_U5GFj z#I$d=nahVbvTP1CQt^!JuDdDzFH7gddHjBQ{(F4;j9vEg`0t-JvP;CWb*5`%8p^o` zspuF1l*r=7r@si#642byb4=H{`eeHczn~ZSIk3WG`tAORb?`h{?7H20rGr(I(e|}s zoxO+|cC(R_CAI3vN(yy&QmmF+yhwU8Y8B`$ZzWZz{RVwkU|qjf&poEbA3+r)n{k;yH)`W(0IO_O%cU1Sz999m=<=Y$66g80kg>xe-P*UmDZ_MU`5Pu57{jBK_!hO z{j$x(nL1z(xg4!G&UZ4eQ)>p5>;X4i#5=-qd80Qkk#!Rx!jhaGj>a`;N|x<-=++CobigKS0+n3W>lMtxo&z@*?r#*D(q&Bc zt1;3}eF$_SV_-JO2gex*7a}@^XJp|i9AcP#mm8g+;EJOF=Jrt98#wfZ&NjB$!|pr(khhaXIYyizAKxgZm?8_=YuY`8fu zuZ^12Td>zeSi-!PF@(jbR8|sO!oo!pVX^W;U2GTJW?+RQ^=BPNg}H}>y_`>X?)DXF zlrFaFV`hK7!A)z9ycmL$Z^yeoa%`^U;yJV0ZqUg~1u;!BD>>auYo-ByXQisq99o%; z@oK-rZd1lLqD`-@_0t;9SzK>0!E2(8UK8|Tk77!VLaVf`J{f7)Y=;HuDr~HLOcM3; z9@86!8g5s*V#9`rfTZ7$HgpIz*3-pwrB)fu8a8|gH8z|!$jOG{s#{T&C4|uu~-I&iuegg8C1&-3E&<%!IM5)3qHQp<^85<)Io| zcbvQJZ8WS{BJybIkbMh1^|&(Y!vI&DEi-g>ZdqH`tOL=eB^0m$a{w;z4&TTn=7@Uf zVmzy`s>Bf*V=*}@9L7o*46(5|M&Z@%t{H9Fvug=xGa4@rJ+8{s@DDJC_VUk}UG&zVs~I_WtSn?Nh{VIVuTH&}&MH zt&?7Tuxzu*N{%3>3UkL`E_X@{AhtL2`b8?|6nx1rw6rAr!?v3$cdLXEetn?mh*1B_g`wo*6Mu!u5vd68K4%O?#FNk%7E1IDz zSjwvD+p$YKR0?&tRf*Yw%eG3XsH380H>^%(B?9pXU!i>J=DVeu(O2OHyv56k*SGRX zHLSj2B5gPhw4oT7$Xc%B4RPdPtEsFAS)8E#p37DZc7xm5eBF<{2dSVt42Cr;NAkjv zwCin6t9X08z+l5UZnj%t?P4zi?ZgxlHuHcn!D!XX>YaU01SeNf$8tohga)Ke+IAc4 z8jIbLzRfD#uw7Na2!Sj4Bi@1$9S0Da`Sd#9YXJ=j`Y!zetMFj%xU;rf7d0ydXVu0se zLi@Iu9Ci#|wF0l)=TB(}1Qr~ozr_UVWYr$3N6`MeQGvkG}(>lJ-`Ou&d;9UeWBPUdX$=2Tj z24%^sR*eumFicKz=q*uP9e8c3(7Qk;Cmy1`O~=`*KHfRhNJFvFmpER#gUon=GY1Cx zyzO{CLa$N*nk585K&$oEe0KO6b6BALmPhV#rcXiNvY#CLCIGe}HV7Vyv0V?d95s7` z7$w`4>R(c7@2AG zTt|%>*sck`(ScUD)z&L{&T@9)a=El)ifv zd_FQf{yS{j+^n14xPRto#t{#=4fdF6XDr$r_$U`QC}6SA10JuCb0RB&m0WV!tyGm> zwZptm@Ms0sNRrjWJ%Oh%3{o-TMno;kUU7*9azYaIC2EJsPQ%RwY)TKEFL5Qhk$Nx7 zxA*})%NlmyA67Cv>3Xy8I`^Qq;6(o+wL%?+6vzH4(o_+AN*!J51FcX4BMAI)XDYVO zO@u4`;w8XyWr7!3-$t*M$%TISaIIETLbl1}o_;_MB?zkc{i7TLYFLJN%EoVGG0#zb z;zI-$Hm?egr###kYZJA6A5kK|aVu@0%)nB0yFlnp8|?~-7#E9Z!eF>&WMi3r#m-}j zPMqBpCaMq?l)c9z3>%9P?EO^7II}T}C?p@a)4}M;{iOmu(`GKqL!N?IW2Pb(Z@Us* z3Cw<5NK`;#Fsg%)1KK_sBq!X87^zNeW?HuJ*x4mfh_@&)HN2QX`_tdvB0wkIe1STQ z?<%48A_0njJ|V~CDlMV*Edbvj?@PKJsW2h^>>hv#N*HHqXi!~1F4!sE1{bViQL>=3HT-R|k zz}(FjxSVr8QUN=m_*Ic8C+=dgWED7!r5Qokc5*nuXUPp@Aq6u!zD9P7J)<(<6=dXO zB6X~X5nQ2@mHlTr=@(0K@M6P^P-)I#S;b=OnQ9g=-X<1{KH*Esx(X8V*pqWv?FmKz zd9T@vLz_Uc`$DR@T=z5R(QNZXVLoEfbW^N6Bf%WPnKj!Wr&Sqb(P$i}12^wf!$3ld z`7fkoy`(l)nIrM$wBPk2nvDC3KqB0rH$~JfOhfJnV!s=f3)A*qs#JQe$OI99a;ITP zeX)uBAz?^oYeE>xTQwBNHB0pkw)O<0jpgq@hko+D>kfzMSj`W7bsJHG>R3);5+w`O zmtWcHvnj!9WY2}dq;35AG4U2A&X=3G1}MonQi&WUFO5(ftMedOZGd1K6#?Gw-n#Z+ z`7=Tyj$pKa{bhp=a`$r95GF-em~XK6(A%i2}Pth=5{FWZR zSPQ%eb}Hpb8pey?0%4|!Q-uSKteOOvz>p}Q(q2u}#x#ZH4HHoW4}Mj}Wx(W9W^(=V z>Qe_>wt~lse9|sfh7dlx>q3}3k1Gu(*eH`Ju_nBPwRg!X2;%9Dsm~r}fiI@v9#~TB zt_h z{QC&>F(Q= zI}y+E>Zeza`RrHI1o(F8(Bdl0+yl#*UB3zO+=Q}T;loWDj?3A%pmsQ-O zD*YlrCF@M1gjiHcY$Pv+<<1+cNF)-tnP0?|+FbqzoKw&e3h$u7O44#n9SPmFz*9oH z9RY!XOSL5Uv#-YswFa$Vt)veD=ZcIfTy#qJ@yF@mRa_qDnr_)XWy;q4mpe$^aQ zv4$}5tg#*=l9Vh%u@BHuD`p9?(|Rs>6`c82kISYC+fdlREl#3=SQvtGSV1rL2QD&w z`zpx{ZHJbnB=LovON;W!tfs7e!lrfvjm64}_7hAPC%amJ<6wvZndc8KEEt3#X!y~k z%1NTsv+l;Z-6A<0^K}}KB866a0-li*cie(>z?-#;JtQj69b3@Bm*g}}BiW+Q=!iy& zFe^g@a&{ny7do0^TO~Vz-Uf03Y}zK&0Wp3@$cP;nZ~X7KF%kmSLqx2>EkbQMAm+*g zCEF}e!qJRIsyZs6rcqcvY_3>*YJvgO`DSyDxMdYaUcy6eaI;ZyU-*tt{9k(*GCW#k znDdUKCLC`O1SkiOO{p1&P=7D63uijc)Rs&tK4CjZ-Mbc-CyftRAO*Bz~32-GDoqK&vA zb^^QX$6PN1raEmw6i%(URJa%vvBR;ML z9E=&k)i(!crhMPW!B^3JoK3hllIfVz3oN|}5DYHK9+$u{tikyKjikVw zLtGooOP)y4m`#MfGD?~;2allin3?UT9IPrL)**<%bTvpEI27RvRbZybFBwTpyAU^q zlR8kuS>CoysPi$anxu67@CRh7M8YW+xd4%^WXjW~v!yM0NpPUu>+(sFsrn32-)MjE z&zuaH_i}uIFF+5PH~u~!$|cewyqaXb6Ozc4@(;(jpNp>~Sq$X_3v!Yp6(ozX+_T&X zYbUH++IT*eJdO|#&Skr1z`U0P??A$&7eI>4#}X5+CC&%s=VT`eAv942jgUX)jbG(s zxg$XT1etLO%zKH+B;h4A^ncRJt9&exTW&f6<`*Q3v7Bs4Ml|Z=eo9H^W4V|kYCyD9 z0`p!jPzxTE0Zl39L%GGRj9BGm)5TC?0gVy9+M6UKKjcFx(X4RlEjo#KGFz4#LdY+c zDr!wh=0iD`xDkY{&%c|1sToNOX0b*p2mM1nlxxgQ#D}CHS!{8w0ggx-wWelI4uuplt0@;DE% z9xNSfj*vF(ye2mUdaw|QA%f5WTM>xB{bH$6=|4mU>xA8aB$=Vy@lolg{s1194{ z`ZPq-k(G#&TO1peJA3fl1|8mZeqJSZN$n!7XFyj84P65LE5mte` z)M!;%oA|J?5nlE;zzQHqK`pum1lMU9nPSSaL`1|YWasTBD&kuF(iPtYqDidtZ zdRu2N+EX_A3kovJLGzyD-gsze&ui<(z%6mUOIe_+Ft z8DgNYUQV%FcmCe=xDpsHnLd&*1%+eMc)X;S zZzB82(amHC2^`%tZ&C@%;^E;%Yhh>*iFh|grs`2}^yx_m6G|f2%}hP2rCAW^!3Gn$ z=Mr5g+vE}HZbCSKdAsB#kh@MH`tr9u;gl!76DE#*Cfvt^ULZ zcR5d`DW3ncKBiNkN2JK4Va$AX3nEYVX5Ehmx061;+&_`%F~MTOLn5Zf#5?mYBSgT9`TrPaI56Ubd|rQ=C;{26$D=RxuB!NNP+pI+P+a zJvrSK=BPc#=NA_k7yDwN-a?pd6ad7q)@00c0cPxD z2YJ8q)?AZ)kWZ+ftt<>IA?5LUlea?!Yv^u~(683Zy*`VH!*MIAOrK-3ME6>guLu`6 zNEJOagpi&P#{sdLsxt~?@-66Q;kZyW%axKt6U$wKfE`9IAwq#OgEPaMSGlH?GO9=eyLyU_jZVFw5njwslAIm^=Wh~C*OBFPuG zUo8-F$pP%Vv=W-;dsb+y#tWj;$PwUHV@5WvO4x(RL;{Ms6Z^3Z6iYcy+DM$;UQw&tu-iOM$W7w$SvS3i8WP{v-<`s3FJ?j$K=4=@lw{v9dSp(7?eYAH(;>~lzaqh2dHEEzrG-?H_0 z${xGqdi}?yqt`9CjyOxpugFJ_3~dXNZxuje0L14`aSmB3m#sZwM~+#5B`z5~;$v(NEUOC4^bYYpVj1++j;VP` zFCRVPGZR6(Tr9={iqBn7V7FHq%{HCg#Nda~gCiez6%!ScLrchwF(q@)iHuw}dW8PP z7{Am5EZ>jKSlj(fB`+dMk$J0U0~p+#$KGP5=`e#GU* z|46v`+B{{+Y>1Ui91u)5%iZI9lUl=phcjN+)?dKe{$rzz&&bHB2y6XGMjo`pqpzKq zj(RfgWP>Lu;u!zj#K=A%+YbgDN_*wQ;c`24M(i-FU6yNN45k zWLx$z!;@}I0Q>P?xmYh@a-3uW<1xbZIXkE{!||Jb2~}wFWY`iY!v#dK%xMLS6%+$R zP&JuZ$DLMD`vaNLh)As{$xK^8p=#h-AG*=T|QtdsjCK(f9p)_DAo z`X9bwYG>K@^K;2HtA4DvTQt+Ort?qdr8CN(*N|3yf36A z+~LPBOEf@|FXBOqg+1JyzUDo~T`{~jlJzGU?=X>5RwDs&Q)ED5E})8E%XUkU*(cCA zE;m>^ITQbo{aS!X}M#>rdg)Iu&jCUE(5|jUP^Tf5?@Qxr&m| zlpv)V22V~pN$W1rgb4BeLj0OUzRi_I`0hCx5ibnS(f(_x6z>@^Bsk1@g!v<&Q73)j zZx9kqFpXdY>6HIay>2azgNCQLUc=M;G&QJ~|TN9Z}h!d6b@>8}wDk}I`)ynA>hy>rj7@Gs^69e%5{^fffMsJB8itOty*%G4b0Vs=d$_K4f zJ)QM zH8zU9eMo-bA`yq;|5_b7GXBowes?j5LlGfV5l1h$DJbj14~J4FfgHzVfYS^i2Z@Mh z*n$W{;E&t%0%umJq%gxklKqIFV0^1g72_)5w|vOdK#G9g<0VXup1xq*WF?a+VV7~r z=dN{R93-D zQBFvhC!boP-{LEb9W3R!<7 z@DKJbQ@wJk6|yc7<#>%Z4%0>pEWV^pO{X(mBK7QbZ)!hqR{67e?n!>1C234mlI6tR zX|7E;dDI1Sgh@2o&qE{j1CBb~a?5*4&fy+g59a{8Of-4ao-)xuz00PtS_d)0!y8N7 z1YvAYL7*j`I9K*aBXzhv5ch69Rry)1=P^RfEOkkuMfHIx^n@I zRLLVp>~T@=fIQs3o{s}y?lXK9NH8Y55(|ab??dR>HHm8o3#O8-XxgHDiVa-5zwYE% zbu!oLAaMU4Eq_JKRHE~8Tgp)MrY;3t)L@hO>VOLqsD2H2lwql4p-#6O)W*Q7&G!)? z!l8ytG*;({Y8}_*&SZL%!P{b8ss`I0C{#<@D1@Y}3Xr26IlmODgD;_V{{(Aq$~}Wf*1oyNfT41A}P?%3FW7Mo@M; zBD=(oio65~FYVb(W!8n03d77MLi{B08|0p01{3Lp;>|pwA!WOVBA{d4=Fg z0#{!le6~apWMF`aF|9vHJQtK?ZCv84#R0p1>VCbZKf-mw=Q1>J@ zi8wYenOL|2&12> zuix@mMnd=OT~MHn;peF;dde`bsHfW z2f-e229Yzukx9+4U7d$qRIkzCyBNrbxkhrUH!hMXv072VKt#sgZ6`~G z`6Bp5?9P!Ax?{v)c%@ZfJnhL}t}%-pBkI73B%c;1`;OpTYT<#+ zRSkpQiyV|hC-b5yhY1hzbR;;Q33h_FuBLY9hVy72vN!pZ1qLuYYF%op0IhtDtb!%^ z!}Qkd&W@xdMY3M9qA$<_GjPF4$|5lS=!h!A9qn$^@4Y8g2HKAhN;tWSOj1qWh}{Wt zBwkNK$qlWCrDMC7yf4^c2`Y&NtyiG>_9cxIT}VRkyZntwIOs+Nf|yQ;Gv}^;Ca=+p z9p0jNrFbsbgJzFE!VIQcj%Vs>Jzn83AiI`nsnkgKAf{0WUy*NTHq0VnEh-|)wk5NN8 zQ1-C($62z?S={^W4y~Kq4;eoFJYh!hbJ^g{Swgd~!h(7-N4M3pn6?*bhmiu1VtvND z9iqVuELlX7cV@fA7f&FSnadnBwz!-kONLEr!P5cQkVS=1?IZ`Vp&kiC$$+T5hMAm;I@U8cxa#uZHqeA)xBJA2=#IF{%^&06naKm8kg@uM} z_eO=Z39$(#jWTXYu|{Q$Vl9I@4K_dLXfroCtSad(+^XzgyExuuYYt&JVr!%s1;O-- zh-Xh2dGZIy22TiP(}A51s%XRxIWzh$J?RKkOAfp>PnMiudeyROCfFvfR_e55TYjIu ze#sR>a6&P_&IrPuC(B)o*hefdl`CF!MSij036qomKg?Yf(sWK8^{>dBe2J%tokC$9| zhY8&n#>9nEObF(myx)^gWwe#enc~tO!oZHX`p9{h0YB_g_D`8-(pwW6yg;TWA4swQ zN`}jvd;YM?1{{0c^%mL8JfFc2yVp<2;#uNpf-LK>mBY_|kRa1f!njy+oM6IULbIN7 zoNwTt$>dljsIChEq&BkTuUkYmdBntp|Ss%=gU{Z)i+x&7((|2Mn2#PZy(8 zIQW%1K_mq8MZ}AcP&CE!CfDl{+?)tA>w{`O5`x+Aa0EyIFCuQ_!;`NzT&-5!zSuV( zvOy%3G~ByO>zXv2&ml_)`7$a6^YV0qlX3I1ENPktPX4a?kaP7I0g)9LfkS>!RbE4= z7qDmDaiYrX2zTisF!YMpWPBs3q{ zNqE}{Np+GsSXRM;U0~Tka0$U3(nxGIWk^zjcH|(~5f2;XPDv14BnZ1Yo)KJ0!%*!c7RN&} zgL_=i@R>$VLVK}15}>8S6w@|BEQ0uWygNO9CRS#c>^KQL%?`MsVWwRLMv^E_i3-3y zC?_~N8};)~CzO{jVPm?HN&zgyQaKQAj)?fexdccui(q|0sym!feKy*tvoCB3)+K8`-gP6E$Sx7Qr#5d~T?=Tb3Ah9o~un8=N^_E86vgcAd zIIvh_A|)WqgH#Sn$jwN^2pd}9l2PI=$M1B7;xs1*EFpKmY90@q{1i?W6nmB+^c$qx zIkjZOC?)~Gc1MW39G486P$T9pdgBT#c8*8Dd<@5J_>6=7NS65w*GwY}lww;S2_ErH z)#2R@Y4TN)NJ%VK^&E`lmcU}PT#+>{UiJt3A&9j&ph!><`35PE1Q-x9hje=a5b>p& zUsg3C`sOz<$%sJW+Ld}jMp!47JVrxC1`Dn?f+PE9=k)YSG$pHokS9Cd1DZpFJ7E5B zx_z6|?*&>W6O2tu8pE`n0-NK{_fz>};pA(gU5cwuh0dqP>tkjD11ClppAV;lv^laruQ ztGx-PHZov)6+wnxWt1KDyA2tJHOf{*((6K6m< zDFm&sdQNQo{}_AI_BN6uU3-3#wT#F9WMW4Fh2==@m4|8x!f5Dt|6j zwTlP=yj+gcEz1c6|%#9F3FKNEF%e8`KOIAWZ3ByNr7W*v#do2P()@O*Hj zybb6NA@$fUofuG^&lvp|=n`SG)A#gzI9#2uveIYk!P)@gq*Ll*3e?3-LLxVBDZmDr zwWll&JJGEbvD_B$31QxM!IMheYwF>JGUWwn!4xoi>RVFcPMQ;>zwY&M-WacZEI`|% z~@Zj|&-ki{o^#w0ky(jtjkoI4RcxGd37*AcN`~1vNHMefa9=aHs=_KvZN> zcN;qYej#S#FP-p|mJII-hLh!hl4m9yx{k4)3fd7ibS1+YYZ=&3`pRyEekQ^Q#VQj*^*mk4aDinQG^S)$ zj6HY03ej2tZr1TbH1#tE9T($^#VhB8C_Ooy{5>O(y$x5^)0GTs(xpJY(+lAU%OwP; z4K#F90zF;H5VR};BQmE(nDP5^3GqP^9%(Tcj$!9IrUEoEz?p3zGAx%+LBgOLYhycx zoi&`WXR6G88~C9N`6a9fx_gT*X3^g&{;x~K?jPqD%Kib ztzSbt*FfQPHiMiKIpKtauHk@?+z!KX4av2bkT+HK+qqsh!^vREEm9JeONhmjjJI+5 zkpV9#21tg-fEs@t!g2|T48y6{*{$+ntbEHyDw$DMDfz(1>u0$~hG zXg~wAF47XCO$cFNWT?|N{#^0MxnsUm*_;Il!R1s7vLW~kcyx3O!m9RcRb-25wy7(U zP9akqb_{*%qs5ZE0jrdpIcP@@hy5AV(N2TwnT0|#S`mSmku}Lmj#AatrW-U($?u4t zPiT$L=hK5DqD&wL=NWp8i1N}GjtqY>r8HM-)2%!87aXa49yJANEHabN@mn}+js{a5 z5&M`cB-#A(_|Q*Z?6* z@5q5N!=O7S$p0GotD{#6m*Nl1X41$0=*Wc)0=gTpI#<{qJ$q_jgEOXA!st~DqnPeH zKV94k^I65~tXCj>y`n*}K1)TYv2`tGmP6L*z>S}r-{Amlt;uc3s53KM(FD+0PQ2-i zzJs<&F>BJ!rl2|0b~0&Fz#%&J+}$%Q4O0sRD+r6J;?g8ojzeJg-|;c{7DLRYGyu}nnD=D-)9kIV@|$;i&L zn}G@>4P7x6tOqkf|HwyA{F%re*LuO7*@qp@P zKL<+JsiIS;?gykM%y{j2g(t6k#MS=%+u`g;>6XAia8M*KY)?-!^5dU+=+H`Q%6tN+ zF1nY?_iKbCT9IxnF&{#6cMVT3k9QZ>E3p?=ip^G9?`GpTmr#>aDq{gu7!a#%M|?lr z{$`I0kLHiV*C04N@1I{_pB_Pw|CH_*@D`&r!U877hxL}LH`4Ka8 zn*rIDF1D1=Tgecn*d9|%Nvp0&v9-431q`qko9+He6Tig}{uH#j!G77>OS6X=TRU^w z3`cY%s(Dz??~jX`VetT&xrMc4#xJm3c#Q&iRDDq>-#BvjvbE zTBLpNG?IqC!+(Q1q0Evi^!_VI5+u@vGH_u(*@b&;S5VYt4jQ951LK9;k`}`NOn`(s z5=o>yWVFqwizTdyFIWR5WV(D0d53#Nio_JVeLweNj>^=g059pGkjJ?HaM6I}@r;6H zzI}Jk0CG$ebA^!F+r-OBoEC-be(c}|Alp;dN8jINI9wSzX>J4DA7&Qn(B}i^;E@4K zEWbS)Sxucx--r+lX}c55J{+TP8Q5d?Y$Pvl-UV{wg1Df;%s@JV4 zE~loCu9^kl(1g%JoMhI8M`37BqZ<`pj5*LzY!YHs;;#2%4ekdDz7C023f$YU7RM0Z zFP67a2){@AvDlVgegvJ!8I&s3$0!)bjwx|tQHUybnthjRGBM6MITqQUb21r z8Ie}Jq9{hd@MEkQWg*AoVWWb@z-((7A)o!OWI3Tuc{Q{o0Z-ZKyskG>FgD`KH=VyW1csq63HsslM$Il05pxo*0hrpAjSRSBP^b$2~dUIY<8|+F8u2I6y|9l&jNu>F1nk8atijm`-?g`iUl!Hwn9gUQ_)GXn-L#8Q zo@14L0VBIM<5nMid5j64qTV^cWAWg}LA4$DDZq9`IuFlqcq5x>x8%j}xmIwZti~3p z%y5F^$V_($_aR?bCQQ~NW}>DFPPc{sV8osR*HBf>b)M13?NEMVE+U}}RThKm#}r%m z9tas*1JX!XDW71qf3ls~BW^5+q8(4kiPh40x+o}RiUDR>xmHo^j966wr{|Z;^UDvn z8c3R${3wH{EfXLG1zl3zamgH?y`%|b2>>LZJRl2Ekd)0+Vke2tbtCL zn0X;lm!rhCG5~x@#+5`=ast8_yJe9!Ji9U{aI+KC0N~ZK zt|9Z97ak5`?*l$(#;dsh_#AWxOk>7MB55%$Wo^@?9mP2MuHZ^|Gzkln%EW@EOUTMe zu1BD_4h_XPr}CE?s)E$Ut;>*sSvkqkm;@Q3K>YZNSrV1ABrk(Bxs0sOFvaUiWEsM@ zB*Lw|q(T zutzvk@_% z8t8BLbE!V2vEhvx5^+Z2?A!fhZ8-dZ4OLw8Wj{SCC-@cf$$Ar@g=~%U6WkLafrvMz z2v9(%xz@n0$25rr!ZRjg>}bs-dOGoK2t}FHAf1d2Vli(07?ktQza=ryVRcS zl6Dqgz8$Ehp-xTFe<@BVTOP&PLaaRLhjRX8>4VK@3TjDN&cBi~acT-iL0Zm#Ca^*v zeLExl(3w99go^BScNJNx`QyRKWSbJ3Y0qHMe|P>vZt~H{iXVE~kL3bTW`h5i`=+EU z7XZWstRuly?uu@G^g{(kYej9HnI*RuOgjretuzV{m;h0bb{Bw4vkorv4yhmOS|Mhr zvxceVX@ky0wE(xefS`@JT<50I_cr(m^hnW!iYSzOHHp2y2|yFB2{;4QfNW#)!t^!i z_Mx|hgWo;%VIEd=$n_yXW(UJV~&P;VJY5kd3MFql)pzdK?9D2-mz!-qf zFN;HDo4@LAKMUw)jly7Y{gJp)aSE}YmzPCAiqH5qq{TO*ex=GkkaC@d(2y3NO@Xb% zI0{x`SXYq$kId1UOTz_c9=fwzx6h$RTy?; zuRzwt^z_Y4Ha$&n)vTE*aQ%K%X1njwBRLajLlvMbb;L&1=&h-rR!YMO1~39abCqt8 zY*-;Jr>7He!7A(yBa2$i8hBg}HB6msITDl|0wltB!lp=La#2vs1;k=uxXIp=brb(J zL{A-GkC#*1jWmb#2urA4J6GCNHl@@CIDk2UQ`3!h|CKgj71}nenUK3Fx2N6OY13UZ zBmmVNLq6z7?0+Bx+TqwZi zW=#$ZwHu@nkY;N*^NtUQB3n>dmeDu#*uw<*YDw}J-$I87Pe3Zj;aCBEkIxnrOjCr+ zIt!72#T}yfM+!p$UfiK9FUNr@00TK@>OjNPvt$3l3Ai}zlj_o)BN?(l91wpiyPN$S zq4wSI$sU-Fh=nq5dy2$x>&XgGi+Bn?wr&Z#8dS+4deR&_0mO|kSeqOlgJ1gSFj#Xx zQt(dleh4+`Bje^LwhfdWT?DMd@N^f2VA zFo3(h5nwK&N(q@hIwrko2>wywD&jIFu3DTOy{FU6kVpm=aMei<@U)UPo=N$EKr4*8Xku9q&{+3hfCg3dw0>M zo>I*##G~88aBXmH8$tyqv(X$|r507>A+4ZI;mIe$6*nSA60rG58}TDj8jhn@dI$x` z&}1UHn}Q>)!6pMAdSQXL8in~;?g<*79u9Y3_qV_0BYXqb)Sl8=3qBOZIW^LZ5L}lix@!A~X1AqD5ms>1l%zVoD?(>5fvdo43CwmR*(c zCaVBb(2#kL2)mH6E-+cA3?{Fa#*XhP)P7_v&!{UwFObl_ZhuB|k3qi6IEnz{s zU21;>RR@bY$TJfMdWb!1^1lJWjyQFW+7B4{hhpaxrLi@Qi(#`XR*g4cNhQ|hKpW68 z^ur{nYDvAUp+UWPIzK{SfJp@-%UQ2LLx`GZU%(F%x5bE3;Q^YdLt3&WNE73Xi3ugG zA1ZkuM1T^kqf4qo>e&)^A^=A$B+&9^HROFur6MyxG6fK&lGeZX+%M=>)GfDV&1l<& z@WZI7c!?7-fVlLKd+ysCA~P%G4Sh2kX~(C@_ZN;rfch9d95t~%L5>RupY>`LJj1z? z6t4%ne63tmx`1%?tf)zW>z)2%`d%M%M3Grd38CP06k*;$eh=d4nSqct$EE|zk@6L? z0V_CIsR~)p1urr<2%&yPi{#Rb!IM(O2XiT+t%gxMvNbCRu2ZOWrl|ZAmokr7o06iokAa(kv{%qRYF`Be}DIO9P)>y8{1j z*1*qE@s-t>SWwLo!hCL?Qjo+5GmC{jG?XFi_V@%KOuh(YM$KwPi!|}GS=T9&&P);Q zCgNE_TErm~OEx{{qiC%be%~YI10%JiD!ay0U9xWS;egC1T)t5#1Yccp&W=t76N2-w z8^JE8YMw^F<6sJMuVrmzJ;x927_*xRO4$NB0^=@i@WExf8Nxe;q1Yv@5eG)9V=%U-CRH<~;QWZ9+;*dr4)%5AolC_Zk7MLdU zV3xEcV~X=^z^egKj{X~;O<@Qg63{i64r@z&OEi92*}g>a09U4y9Em_$bd#0jTP?}x z$T|}mqa&iO1;CG^P!=&VDsA(GV{HZHZQ5<3DH&n9Ax+UT^dk|-i>@;mks3Ahg>=gi z@zhtCkjLf{b1VPObK@exjgJDMZCeofu@O~7z!{$T%(N0dCh)dygd7DxSn>L5?|Gix zaRR48=|KBVj`Y3fiN9_!8LsLK{viPQRPT$Afqh^LL`(1>dX}AW&etj&k)d)lJiFsu zPeGKUEJit{59K&P@0$^Qu07>?Fa0{KJa`3^>Fumixpl~C98MY=JycnWNoH>h zd+8&n){Yd*fgFXPG<2ADK4(psAPCU9m;6A>Wg>N$G|h_Kn=WZF)FqXGcwYuqXvT5v z(WQu_nvcN_oj2J5^W)|D^bNVq%?Y664P^&V{^_3UuBB?9fZ_q50r7lbAYP;QUji%W zoZOS<&3|4U!GHVdhJX}9lo+cTB#lUNt$zixQey~2xiEmhu%#}0Uy~kO8@O6Kv%GU` z;42~2hVa$y*pO#|${-bA`X-nU*#hNkRPts-{cPl=hORqNo=zaUiNVy;nY~G-9LI+D zj2yzv(kuf;(n$D@j3@&jNhb3QWhLAeRxs=2bBoDFB};@%M(xGH)6;`;ua!~cSP~qw zoPoY(k8~smx#T+0vC2)f=8p)kui%O{Bv4Q ziS`a6I3X%JyVWHhh~o%;!+J>ug~@C=)wSWGKaym)oY_;@wei5h@#p@g#sDbZT5EPi zqw5`h6#5F9-W(wLP~^`MdR2urCc|(;hL?oEf-tF&eg^~XuB79s`Dk1lui3yHd6)W~ zozWJ>ax;l~fjynmctI?yx?!E>R@Uj zZJ&3@;=(&^ipipL4N%7k;p*!kpK2Uuxw&-w`Vv6o&LsJ2B zLuIgKQ$X%Y<_$vMe6gI3ENecc)b?>CuYs7+IkDl4*sP^r_Fs!#z#})Qh+i>h9~aye zGHSX_K_g!`wzNdnUR#A|0$4m1RkxwWi(}lj@ZtgX=vA3=0 zr(Iy$3}swuGS{v&p`*45F<6^wJd)9fZmu-&woDLv@g4)}BB}6N3;!B`2BB|MS$zMM zCSE}>fnj2QJgp0ID`Nl=HoKoYIsCqLjctX$8sx0E?vjyFr z9{%`tdhB&4^U#fk>>CX>CmTKNe>ejY5NCwC%X250etSOtI6fa=4~Bq3BI5Am}$Uod@T~sL2;6 z2j99f7KuIZWd67ymqoxUE{kX`<+ns!NwAF%$NW97F%DwlGISZkx#J} zjS44yhk)&~n&D+y*<`# zT91;lWC}t)MX>Bd6r}!46P`3C<7;J^eI;ed6iem`sZE=`AoXXM;6>ot$-k3iQc{*o zF|1)^GLL3K>OY|hi&8&VySJqCELD0Dhg_)QTado^??h_LbV(U^L+k92mTb{(CbM9~ zDrx=v3FM+Y2`Fq*^gE;_TQCr)qibpVC9Pip(ks^pPNeAdur1Vb&><@Fv`9DV(Dv!& z1XKVhL_VT9mQC6Ce82?${dD%BEXWABa0WH9B#g0__mfE>p*Sg-9WnT!C2Ozdm*ZbQ z`lSGEK%vCTndzdJwuw7h=nYfQ*nK5DfvioP}-i4?R( zAbXHCWdRCx!lDh_O%Dkj6A2;pTHTQ;p8-d|kC^=ckQmU~daQoA9IjImVY*rls3xgv zGZP1=hv(bx!~L09D6jgP0a`+W?NF}9Ubo^{(8 zW~4m;<^YKLkhg>Zb3iyB9tOkE$;RAi_qlyOnI2|XG!Tm%N}WM0D~xPk|MFvc~?_|PG4zqcpUUzJiz zs6a7k;#h4n6wDNfUV+MMFLSo;ahXEuR&Eg@V zR@Y3Vc0`1yQ>ulK1kEV;*c+yf4tLpNKr}$CUh&vRguKi*p|-GI=Sn3{I`+&8!56#d zGFDqYp3dk1|8D2uxaL7Co}0oO)mAr#n=Dg7IUFE~zA2{^uGXyuDy$+%!evPLOM<)mJ-54{T2xZO+r8)GjI3%+^&&IV37WayU(Yl$S-_ZGwrJ`S0OTgxU zkUbFw7(6<)4{lV1C-Exs6}K}nrml@`=X@aJ(TtcPyWbq)JFoU4tf8H*fPPBM%@;?+bVC+OH7Ey&-I4tp3o*q;vCNOnRa){O$rY*w=8bOf zHbY^m3`^4ugrQSkPH1fmBm}z0a!=PCs^x$s=Kz1ewfMYw1(B$2EN?hU;J_6Jp~W!fUP-Fbj-#aGmRw{yyC@2$ph~K(*Gzd{Me9P23aI`(+ z(2YGG&&Le{edKy&1U31Cq(bQ})9oI-_ngx~j|@KI~g zQvff)O`a3H_XJoPDCuI3iiX99oI?3|h!fHJ`}^_V|1MleAk-5#jo(!3k{Tj_ zWyM|!BO=QA0P85A&1oQI{1K&7@X2F+&t_dJZaB9q;+lf z(Lotq`MTjp#qvPNq8akS#q-aDk{S9QIsAE`5@Q6`7te{k`J3tk;8#yT>o3Xt86W`^ zAdre%0lLBM|Gwa0T^{~8fKLB>_-VF0H`WzNcv#h!_K`m!W+C#wMNhCBIWpKdbaX;3 z+D|xrL!n8>nPd~9R=1#xLmBOZe-sfrIQvn&NR!v(&0zB7aQ<<8+>=5x`$RI!`2S0S z7+sULP9a=kZg)C7t~fl1bSX01w5qbszJ^8M?)<*qEJ$w<}TiX5UMLJj(G#j zvS8sW`ooqTLtd-%v=e6%*`SoG1>o$$#1Zq+E9oYwDpHk!r%}9HGw4m;_ndSA`1HLtIyLEDk19G#N^ZXApBp`?Ctme2c)U6JGGG3{l0z#>d zS-2Ih&u>Tw0%+)Q<3?dJ1ds@qq}_cKA;l>uIA@qjdyb(vIDj7x=bi>aFCL7k4zEim zTHm7!G*HX%;JOf41VJqrAKqy3>Y897#!fU`pO1~ z)V0OFACFJJKVCHTc7cdv7=p`=S6DAzw~g6vL$lNd12TwcgbHiZblbci+aXa$sSVb= z`II0k%Ngp)b!eNUv0QY%J^*PGC*3bT`@WFDsLr1Lp7ey0{J8q5&a zNC_63;T0SkY7?5yH9GW9A}dK9j4H(Rc)mO*;=5w7N_U)*sboG{PVJgg`xZ5^2vZUU zqP#51n7v*--k%EI!odZ)b899nc(;75n48~Ngk{v6J?Uigp%qsIf4ac&_{B@ zDRP(cI3Z*?^8wVSZ;24}UEH`7e~^C!!mO%NB0{7GI{+M{_;CW!_W5k(m0G$DVFXk% z2VfCiy^KI49+J&Gw%76s7t*P>R23#tPFDipyf$_#rquRCv&6p(aNmC4>p*bd$L5sy% zkf9TG{)Pm7pyh+CM#)Z;RGp+OT&E?#;K)J7_GmX_jJZC1Bbq5{l8I84cV{5hs=IKB z@7O$=eZx@BwkgWAE$OrcCLm0}%lQFFkC0)>ep$odj z_H=oF=c(}juCYchEiECVD*6->FU2@4`ZZDAm%P^G5Gps<^?2XqMX^VcDs==Cvt!9@ zw3j-lqiMDNo0_Gn8-S7CQJ=LsonU&^D3DU*TY7!7@5SZvu0#`f*fp^co|iP89A94 zEX?nb$U18_A}M|zY9wb=9cCj15RjLiPxE7U%_up)9xvTAsQ_F~a|Q?$a0t5Z+de;b z*KCD>7yw^S)nP{YPgR$6U-M&k&6dQ|hw9v^%VUSxcspN!N}@+Fk#*M$(-lPx{WLEH zGm>bjeE@Q}4vNWESSIgq3ZIBl3KH!4*Q`*=QhFcJat4cmEc7-t1&dIkw=)wh1{Z|Z z4zjT0t^y;gB~Y4L&X(S^W5PTnyEt;#lk|kR2epaTw?uqK5yRX+ua2B34uUekb;!x( zx>YEDmmcdm>D!bSOF{AC-!$L`vt{}xNbvbZPplV_A9f;td7=Q&-R$W_mLxY6kf-M( zK;%s5uV>p|v@TcYshYGPOs(yUi&_@d^8@8t9aF{EjxjM>ETPEq9F?Bs1KegcQ&j^= zD#6U}g3hD_x(>|ee_r(K=h%ut0er@{t#DqZ6I6)n{3wM!Hy{kAST*W-ARYHGCdy3b4F^JlY&hf<2c$sDflj9%s$6!LVSoBIj@OY>EQC% zR;%r1V6Sbzq?L%tfuG~<55VS#N>9qz+LE<*ydcR9kNfwN@|h)L@B@)S~o`IT&) z*F(sdX^-iBnj&qemu7nI8x4-B0UHoN@~tAtt&^glM7}UnW(orR#&QX}f>4?z8tRN< z$kbsGOI%uKtKoc?GXoA}O=v8rMbKm=o*fbScz}lyN~){Lh%A7uph15Gqr#H9wFjbV zn|B7BH$j=0t~DUhm=u}t?Q&YoeJZhxx*2KH`+dR9c6%s#C*lh0e;ZvE-=CZ#)*50e zR|Ho_j=%n9?`%#pqR7^43Hqd7R^IJjf8*7-)v5JVbD7_R>K7!tUw@k(7*tNBKn@%^ z)K`O7L)B&;H8D57yiHh*&}kz6zpVhH~mZI5npU>9U1qtLDCsoDSn5rNmIvZOa}6 z6K31Yt@MCXCG4e+$IJI}FJfP$HuG{EKip%72_aB(dI}~d=4b?N8PI$e1ler;CkDSk=tucG@8WvB1rOr%`b>G&BTsI4KaU9 zzA|K;5`xQz(G$Xeqi|;`T>H82+~*+%1H9DjaQ#*j|3&rqO#z0sq^RC5KDuiNAS}RM zHze*esw?zvOvEQ6plk!IQGWxc(vd7b07j6iX;(Y&GXP3a7kp*%SAn^gttVK~q_g0W zH!(5ajxka^ZTj|o!SF~}*8o?lF3UgHMj1AEw<%+&D=JPnc(ZCH*k(gw#B3@4V^V_k zFMC3d18b>1Z0E0Q_noww5;Xr=71_24A(fr$al07{n+(IBsIeCw1CN&|6 z9JfG(o@j^k#$%17Mgk&$P^l7^W}8`+!-YafRoe?PFgGk|UnGTO6X!G(@$>oIQHi#s zcoTc^Mw@((BFcbNr7hR0`Wl(?~}Sx*O)J@N}kl)?~DtBqxE^f%~q zK`m5LLoMVWwy>DJ_698$iIi)+q!U6R)0jF9+%lo$qczP(1~+%53%^jn_X2uV&#WTV z)fTQ3)fB+m6Q0T5Cgo!3=#Yyrp-|qnnb4$IE^I`k2~RfW184t7rQf!GW$o@l93kUC0GF{I12+PXuIPb zR+BN|aNW6qVOT7La{3XL5m-A5@u4$bGSG(;1LyTa5M?o3HV(FEODZX7yTjcQmO@ld zcK|)3<$;+@Ea26%{n!~SJCM5Kx>~!GUq zi3K4vMBOn_ng~CO z(hQKurol1*^A~i*2qzdDhCGKQL$~%Y#FIY7iPH+t%?SNRps*lw5+Hy^YgjuT0MT9oE@&j1)Ja10HdFc7$@ z5TCWI32rmXbo0As05;NK0orlfgPR4i@EoMQjrr*V1HavH_>IvwhUB!g9D=RPe_v4S zuxn0&kQNvjM_9}kggWf9Nc}qfj32Tcr5Gc5_S9Rf1`o1EWEq1*U@dZ@~vdhbTRJACWD*;zj@_z?wM! z^=t>TIbU&q`#nIYWXuWCtblkPQ7k(!4-_FjaePpl1N96pr@ zN*|~rWHw^zv(pQ+E8wKru-G_+W)g2<#YMPzuCb;H2BCy8Z4x^9e6G;Sj4NVV-cl z-X`k?BNwqyGXibYB+5Lb*Pf3*->aggCtVYoSQE$7B?UF#lOpvGK-$->>bP1#OixPq z7d{1ZeHNr$t`uydvQ8!uhp}2cOV5>Bu=rlf?mw23LIoxI0ZmQwH`m?f_V(dLzBRK< zQ5IY)m4}@2 zD(ZUV$U53T{9&a&1I3hx(+PYF+QMRh33EuE{n8-jtBdEGj}{qWjG@*Un!`=dnqn@1 z;ABm(U{GwOQjRl&j=Ei^NiiO*G2`_VwOG&pl{RkEk=cd8ytX)LSua5ba`z`?pC~{i zlsg!jv3`1d5Ps12rbLvpkE6&DB(gMR&rxR+Bg$hrMi0i9(C{S5?eyE>Dpy`X%5P}> zx(#y1D6NP-RH4(h40}yH^9_ape?BO{1W6Uy|Fi26LD=h3JM0JS|Ei9~<6eY66j`VD^NTfQ2;b7?E9lc>LzSFsQf#FbtMWl0TtIUXuOVj@Rw7&%fB_HENJ_`Z( zWu5a7b-o@h*##+Tv!-sKrXA>fw?HgSd5vdHNJczV;SIhm9E1{whEukxZg7(eo=)I? z+Ro0GsK!%GaY=B^sLO zsjLUZlbW$(p(sYqdrUyvnv}lCXZG;N6E`%tIh|VpQFjJ9?btGl)MujYIq+*7Py^uQ za=s-QD8$tY+>1>!3*(sYclyG|Jp#Q@-eGkb$!8ip@y#5Tsn5f>E&w^(w6tAhZqMa+;X~NtKwFn zKFr8M*~BZ{e>oeL4fjzUu+{Az8a$jHzlk^_<6W!4Pr!4a&Vu(sB#o25dVG4ppXd%7 zCO?v^XJn$&ra?-4OSB;Ki^?~Y!_u8uG|0w+b^}yC=tsf$^Gq1S5%M?X3ngz4Yi?w1 z^T;|i$(SP(5`2TX-4x?U`Q`iJ(aAa{872J!#~}3=$XL_fzt$%2q`Cn!hcF;h`pX7s zTy&EZ)(z4I5O3odP^C1e?L8J3_UfK^plL5W`d9A0k$Oiv%zb?c0{dbw!NXbVMEY zCNIy}^msGKp!3~i_E8R%YKaBY+ht=oKfZ3(F2;?sWVk``>qwZW)Lv;}7bHlCz+l$}khKX*op;pUGqfR8m>HXd zd%X=Er8ctt5nZ!vf|a|oZ~DsHEQy}OXQZ7%KYyYP`<`@JQc6wDY8H*?<8R2{Dnv>q zjnh7$qgL$w<)`Z3Rq_Wt2vtD_R1zc=?)C zNp5LpX<6pv{WfdPdUwIQvVHdzB3 zPEXt+S|-Jugj&@@-!mj~0tlh4*?*os3}|yEiDUF~c|QF}cLRw_AW9-U)xoy)K5bVava{hC)IT8r(~)?FCfKhs@d&C z1KIEm5hmk|Ig^){gf`8zf2@FFaRA9^(=;3xrwnTTP$=P|nH8yah>fwhYiS9O`gi3O_j~BPM_%>%eDfpX%%fvOdKa z&>Ie_%i7)cZ)S=RSK9wG6Wl3;p2JG^m=osVCg9>q=~;T<#tJ5}d?$YM7Bgr@j~!aanpBfY zE?3J*CdIX!ZO)i*ZY|`(Vq3QRmrH_r>)WI&LQ=tFSev-T)A{n_O?p)j8v@N|m*lUA z(Z3*UIyoQv01-W_Abc2w9-No+J(V4tNKIVCW-uF)nZg%0!V0L{d@5tgHYyWCTQd+` zBBPuN6F(1C1^jA5Mv_aUbE`;}#E9B2rkoqQPvEj#5OjkK-@_UY(GvRzY3>c{rim$_ zJuPr{PS{{9P}3q34Q_9X3`$I&3-b_Y1KW5EajS3S>^B-Gr@&S^hX(SQkNl_XflHhLX_e8yRnM0 z7%L#ZsNYtk#FKW%%1K*Lu(mU;ZlEx)I!X!gU0TWU{H?S zP$`C8ir-rhk-+Tka_w1G(%)9=k;RNVwq*n-W5pIZ2{|qu%5tm&tjaU91Y_BO-vXphX5j6|AH#((mwh-vpC8Br{nd{W;GNZ7=)$9`ExuYN%J|Ojq@Mm$S zT{4*r!0Ma?;NR@qbxCmo;Urxz^UKaIg{n(Sn0LJf2P+F2>k<*SB$sqRKc^B*)H2&j zFn$pyh==vYoF@`mB5_WGc1JGna1iQ~T4H3w(vy(_L`-A|7x{U(1^l;%8=({=m4Yb{ zKJa57E9#4@G|0$ekl6&0rnN};TtnU#a(^kHs!!5G?F>zrTqyNY^L1p$P1M-(3vnFl z5~YbNVmuw86EehYE})eb2o(hR-+~j=6RvOyDAu=$RLhUP*~-at&sS3rlseCb2*faR zdOv+xwCdr6BDrClIi;UEXN&wbf{OH}6g=H%2?-UPphW`U$qrtmd~`&=0!2&MsFqxw z>mC}80HA+Mn?U&ieI_R^Qvy|Hp`>z`)UAuECr*eq9Z0O{&=!{F5fMA2P-~D~QpXkx z32}ks#pnqwX)hpf<+CS~2iN_SkKae@*BmB;M?%yno_f$1{|ZP5|dS7XYL%bhMr*xn_3|r9nJ94E)McG)Xb1bIYl)dq8KW za}$IeS;4MGr(O-rFp_V^cW$D1l~AuJDq0FS?=A&90w4&aGNVk+?tL*?oE=-x6D44J zvVt8*(gci}2j9^ZlO<}M@Xro6|8-SIY_O)*kM0P^t(falm2m(P>X4O#Be;EK%5u)_ zLoro_H4lhxDYyZy=f5l3BH>+zUFFynQ!=%fz2a;}&}*I=fWbNx`v70WZ9%p6*- z*Ydj(_Rce4=AE3*-wi+zS5(F(u&dkB9mn^6uVSUDhQhunRfx;`vg_>tP|Q%@&vW$q3vV=H203Hp{c?yL~c6le?(VJtM7Bs zRbxUogXgxtO|+c0Z3wX-)R?kImQjacG4Ced&nt`|nwF>;A93Jr+k4#V+#3t$PL z7C9coEDB6yVP2- zTQ(yKGs{HacHwBVrIrU0$$w~b|C+a%Bk`=TC~Biz??lo3JKW_rG8J-1(**`4Eq1I2l^guP(Hu|^0C|hw1IBUwGchsbA`<%8 zpekGGAFnBriPUIrKf;LxTz*O4ktDf@)% zW2%O(xqUKbk<8uU8syGC7cp7IbCPy*vYv(1*O}sjYrbfJ4s8fs$4GKD zK4*fgvYtPOqCMF}IESP)fPHE4*I*`@E9J}n{Oy1Ui^6^W8c;l*Pic(^>c;Uur)DX< zeVcgT-&1cll@4abfp#Jq!w}I8if{72FJ{00e0U;O;Q8Rl323HFB7n7edW>9wd%dI* z35cdfhiXV0&WPsxh2S};i>tTG=Q71{Q?%*iRfBEBRLv^Kq)^?pOPP%W0wyeL=0d^ zfZ)r{UH&`YcS$Z6|EGPKPL-oUP5=&k#zmvS9v|;AZ>A#@fE8I#0a8qa`Tla0=+Trg z9OI~h<>>q2_P30u;O$;6jvn6zAirc)Xdc1Ok~Q$Oc(!IFhZBF;(&ppv#GnIV^jii+ zEn}Ita3dkoYba=U%L~jJ^dAeQ{Z$-MQ;&$(%o_M{;8&)a^e~hOfH3dhQxc93=*l>h zaEB5fErq0xPe1lg`9Q&uAUdKYL9&g-`SFVsL#TioR6Y?vyQKM zKT4Eb0a&oKYY3F96u{%i1munt)UaGCj9BU7ab&mx>hTCQR(ma{il9o4Sd~a9O3+#v zqbAPI!!7G58RTS%EzKnN>twhh2W#>}br_g_kcS$(PR9}0xZ~bb$kqQ6)}**5n@LhqpaYwgI_{Mymv$xb7f^Fg3ySLPuqw6 zYm}KkiQ_mPu5=jh2P1fvn}o`y;TM$%p+Wal|r404N_5IqBwFKJ80nEHU> zsZn)d{GUdRB^n@}5jhoo#3gGqZ7P}(V5npE)_}<>TFXdcu^W!CU`ZMRU?tlifJxc4imuxknfhKlJeQL)^dXhr2xfSn#& zqMweF3PKVmLM?zWDs`0)he{^|fPqyJcUfmBWJ8jxOa8F#b7l@fDZ#APQ=<80Q;WYB zBOq3u095-Q&_Llw z66_rj5BnHY(YXmQrWprgl^o%YPzL~5oS6ZP2FWFA{v!2HJ8lTV-2jTveZ)##B?MMW zIBgUshmb0y{e7eI&&hb3Y%F}Vd#hMx_N!)=A~Ff3LggnR!$PUb$XeD{s}UL|v4J`; zbq$iO-HccIxu{-RiX}tv#7s1*Faa=yfe`d10so&7hrcaIR%4)AQgYgyJW;$IpFt6B z(Dgm}QbC!NG_kuT=!b7m6H9~}b3h7=EjA#`8ROtb^6YWWa@$NNQ=L%Gi)(Q4v^9CN zHIbwuo%|H?UpUW=Ea9nzn1P|1bn1e<;7aBsxosN|BwM;{wF_bjKww_kgo+?x47ohz zsgeBTzBHApKsZ20zP%p6C!xBEn5D{%wh6zf$A1939mXTTk959NSJ=^n0# zP$}E^0bvIKKA+Tq^lc;_9nJ;WLI9bhp9D?o=X2|D3(~0TTnCd#bPx=5ezQ+FCFIhS zW-x;9kKf!Rm6wAw5zrI++O*%PT^NF$ret@8)X%)h;raG^j0x=wY&B5uR=lqDf!aZ} z9cb#Q6SfXeT)0K_jwq7w_<#@A@g;O}sOmrqbFlIy&(A$noXC-Y-OXLoUI{T%A zy&ZHoIx-Q|Vi|G*;G@^Wpj9UsH4*%sgevNnSlWcO{g{5kTS~g!U}UmuGK(dGzfRb~ z+l3WhBJv^q@IQDm2i3+xT=YY-&vAii%ac)T-#N&!?R;tgWU)h6=4y{pZsH2WR!v3f zpt4v^dL>sqBm%NnNz%k`txF~&NZtR9YD=n-qFrVLsqx<#FM;=_oP?iJGmHjfkiiks zt=;3{pU1oB@2M@)`Fb?i23wZg#z9p{1b}K&m__j7FyP0-`MA#pjtseEP54mxYZ z#gBnaq=u<}C#AXMuSi^;KY~?s;O#Zyny?s-?1R=|PmWC0fGEOar7`|(JwO>9S!730 z4chPWH{wg#hMK+ok{Th+RIB-HWRjuX<)5iYmVQTesKA^W4i~ziwr$btClymztUZ z?~2X@Y-5y!^kZ6eUSx1yCN%}{V9R>8$31btEJ#-8U=zea1(+%qKmVN<9UV1*U$i<| zyRw#|O35+HYi@P6)SfYrYl3EHw?D6DOLO1yfQGt@;1AVN2We>%A8h{w0Z@Hi-w-xa ziWS_YsiMi@#sdI6KKL}@fOwqCUa>A zCT>X+BR)B2jR-{x#I#M-v+~OFl$1=0eH8^RVX$c&1XMRCo7S|$vD*f&-No-e`EZ{-Jwq%A0w+K%NHzYMbx z_R~=lH_P*^%8c29+W?E9tyg-TbaS%>s23P&y?xyMU0yu(BtL={q{~iQv7ZR_lw#dx z1`4NMw%*TfRN#^$GLSe7qd-GOICtx#Bg2h^x`Qp;%*KY8K^coz%YV^pZnq?8^Ow(A zd1p$$57*REHlN*RV#98=pL2582QtxUi_-)AbB!gZ_jJ_%8c@EG5c!g>jZXIscsWST z#dD@jX%~CY8xSg0E1sG?o}QSah5YuG`^@Shnw_5xkG)@2DjS7;s92@Jyg`TpNDVM- z$WaI~^UBAu@0rxR#dbqPgQiA*jo4e#3D}AaN3l}q!aYHnF`uowRan)5(t^z~rzu>a z1I(LSdW1^{mR7?q6tic5|4P>+s7nfc2?(G;@yuwoju|lzDq*@S$_cSVIOjspY(tG9 zq0}T@l6Q@Icp$8p7lah~?eQu7%Ka*Nc24e~<_4zL_fUk!^}>~3lO4cSr`^FJwfwAN zm2mZe3BoRl7LzMvSYIj}R%?Usi{}VZ-=E4DthPi!*r?jt4d&$u0+Xj-qRTIYpRRp` zEdNdBdwaM{EWG#Bh?d*M8e3YbldQ@&wSq@22YrZW`2|fn zm~uYc9dDmc=i&%c=#cy_wxf1>xE0?bCw~KZcS}tH$hq;}qFqq7dW{X&yfdtV(Kfb| za>@93B=&4TP%y@xxLhwVy?~V=mpLbHCg@jVu4hTUb#2W!i2w7le|-M3|N3wscqly( zGmPStkC|IQO?7co^Gq>;P>GL>3%zx3(qT{D;O;cVjjwQ}XFRk3zk)rZ+v)S~`zOb< z_+n&0f!jdQlsI{ky|FL!ZgR~0!fY5vD7xoBdTrOL@c9%gxm_Y}aODLDZ;~NMq<)(v z&uERWcVL&aL9uZCvu)gR$|SB#Z!1VMKHQVp;eMBOXgaCaV*{;|eqG&h*B_t%2*hR} zQuZ3}e`_iw^acMM(JwkKg8dv4(1q6SIP=!d4yL5sr2;3+W-*HpC$;HBYK z%h`Kk>UE-A0UREbTjyo)lvZR7anw?zotweasmdD2#skYE0R85~RzT~#J_N)Q;MYK9 z)LNJ!&aS7ld$cFg=0@NEZFEARsD5($)`=WL2HTg|YE3Y4cPs(Gq!Rg>7*wNq`r`^6 zwl0txR%=6*W-}zRYlGcjcc&)x*6LUHwWWZ{01 z5k^-?KAd(bXoEwZa&=8&%at|^sBMGM7@s)C!B9mAOcePmo->1*?aQeEBeyhFihp!N)!B)hKEjE!rObXxGGlU}ov1y)S5| z)az71p}sL33tEt&s1|I2s-5v(94$4YspbNrY9HGdKQ}z@n+>j|{xQ7xK@f#R(MJ-d zOdcs0?ZuB`iVij;6u}_&gm+~Tt@i0WA@)5G7CdO#|aJ~YBY9&KH2dc0IP zvE?xB(igLnmk$GPz?v*rBR&;u*Q+&-53}%@JzFB=!Ly?rkz`rB$3EPLEBb@qWGGG4ju{dz(IxaOiJqHn zsHJA+W@Aa7hB8$juCV5Ap(GQ>UK{O71K)+BmC33E^Pz3=@-++$9)5LXQd-6j+^D=8gQ zHaOx1xNRoal^^(+f5rCl!H7p*2Y9_^ruma?c(tfSNm!PQ|NU*^r%nBU3#piG>S6u) zHtg*!IG;i2zS2+l6saExkD!)@+N6K74N@dIY2<_S+z=E`%l2sA56Q#iu2>Lyr=Q+7 zfQHs&mg9}-JAg;t5wo|xzaO32e#Q%cSP5%b8+2=@pZ+#O49!cTfh}9&jW+A79|VTQ zbU6hZvhVw(ezG=-8pUbIRn_}VQ=4CtfeqW;n9z?oLi5}GWNi=`a== z*lqz8rNCr~<`hlL?JmLocdZS!Qe5L3LXUg;>A${EB`Lgy!_9){%dw?4Oel>Fe?EAk z1eNQtOl|W0e<&A?STev>24Jnd*(UD?>mh}=7O1&8I;o$&Zx5yy)$RyTF^gN5w)`Ml zVy*!x(SB@*KXL@$SX}Td0bCXU_n&UV1SVi$FEO&aHemuE-L7H+xG6vau{S-9siAcf z;Bf?(eK{H$F(z-BNan}KXSqQBNhWry^$X!{L258rwZF>|^9)Yy`EZ(07M6dph?x(h zAhqPQ+PfME|=5ok$<_1 zjq?@=vB(YB{wWOjMhhh_=Do~u`eIq1s7>Rmc%v7xWXN_U?vLagTA0pc^O$XaA$%>H z0YW{lH`Ki4tf351*4QQj>~D-sohRNDUpQ#?QqkXdn; zK5i`k9B5zVibD1YA1jD({T$IPR28*3a^FuB3oxZAfQqe>FskGKmn!jMmYC131FjvY~=j*q3jQmpuFpwbxYI)011!ba%*vRW8>;wCkns zj2c_Vl8}5<@jmu$;N(jQwpKaBjHFFQ?fD+)H47?=AvC5(G?K0MKiy)tmpyI35n51y z+18~M#O!GbqRr$L8zKj$ZNqi7p{g;N+twyrgjoYOeBlnGJg;%RGW>WMUL&UH!GJd* zzC7^?%ZQtyq_c~5J(~k(GNwGE_=inxf;&*Dep_QSn_(P{;&Is4{gmuhxhg2|;nuvL zn5+hZb|)3CIYwaDb4y6P8Y)MzAd~Z}_V1rRH zi->LeNaKGs_@aSpmg}!em^GXufra65sUqjwNmj($VZML7dvFt?76lo7_!;B8f3a(& zXG)SXNfksF46J{7Y`{gk!yt(Whdr*#pb(JyXj_{YIaM&p2aE)Pmt?V+gayzAIh0HM zphqt!1n2}LmJvr@-G`GnxWC6;gI|1oWGn|m$wIq!OR+Gn< zAG4>Iu`U{I!D_Z4}ej_7RnM?m=G3>PPJGhO7dmaRE@VuPtS)Q8p5Nf zX|vwU+7--^S2|x469lDR7FfsZh-ts2uNeVv;_gci4<4>D`SRnS$>^4Ovk!a@s}%{v zxZ&F^@OA@?_rwzkf>{mX1N3$ig--+dI$PM{7BPToB`9~pKNQF5Crv_{8XJgx0 z7hKuJqQ*6A zv$nHmcDD;m9U*|l_EzJ`A1&}asTJSHXRUvC_h3G!TX#LMwz56hp{%iMx zlpdrPpAU+|hT14{K19NLCxPN{+TCKJJf9vCPdPp3SY4-UBgNvj`}Xv*+ef=3hO9)3 zB(&g#9q}@%f2;+&pn2}}dgYYl%Av=S!VpF(O7)C!ba$_y;qExtZD5 z-JDNf$wGTf-W%Ria5xE8ATFtC!<<9<#)WSnK-G34(rze?LwHu|;XWaL>@J_sESvoR z>+!IjqtBDI#O~y>=b>dr|?Y^FSgx` zB(iz4MMNV**ACI*$No7HQmp}qhz+21ZKpXQpZ=7SV|ie^0YsJhCOVF6(4964=@l(! zJZU6r04#(3v{~0?@h_L%{^{xA7z!Nh@-|p1Ho#0w``TP2!R@~30Zwg%yfh)WZm?N| zHeV_?)nW$Hf&gnFgDY-x$o&lXpSREZ$8XtzBln1NsaPq^gcHvO$Cq+(QTPZS*tn)Z z7Kg22WbQcZ4wv^k?b$S8HY`!YAT%b=9sZ>p9l6hUWMKjWRwLi4c>(M&=Ss ziVdMn+dltJ7N$gt1`1{s(V?S0+81f8iFibWDt2}-W{i0K>u&t79bUh~`Sg^iIE$ny zgL)Jm9Y^&(k&y*P95_M7Va*}CMGM>6loAz2VQkGS%yvzechbOiUrhzuXz*k$aA*8J(@^ zJ9`=+e?_9s*AfHZjNm^Ws)k;Lov`kNJ>(cunu{#8@YxweybZ&h(z(@D%nN8Dl>3J9 zmD|&OSR#K(fSI%twGCqzc^V1m6=;uR{J9NhCPn|dy?{b?#CiG&g6)Le4p?jQeXM8=dF zdUNylo4^0pKa4uK^K!!Ymq7E6-RNfbmk(5Ds0ld*PNGil+TSqT3@D^Hy!mzV=`%=M z>8B4vWUgw2kn?Vrw)}r%M*#~JYdnA5y=!Oof%uOaZJ$3U!`_Fe^(&opmt1dOtNqP4!$1> zFZpfTo9v*rKmQMUIGCBM?agy3xnaw|dcI}3ZsOr%3x=|6i0ixQzrLgu{5ao|2)-tY zTslC@ojtz-?sCL5Zg}D!?{+_qk3aT5cO(zt@=kO_401~l7rMD=`rwiKFdlWJIgGEs zPK+n>g(Dq&=^+(hCGl<4V}R@9g^B>=4ZI$9cB8bNuWv|kpujIwcZaVp-*(*tSraO` z9?eA{`R4Wkm1%d0aGEV6>@{F!3g09lj>bs|@YBD{UvA+RDEx4#m#feb{F zv63aY<-^ar@B4@QuJA@#VSvCmbiI_jdqJ2a&VWk%WR|NC+{|FHvs=P~0ZG#VA9CMrY!v3-gOOlhI8#9>sa@gy`{gItJWc!zq7sT!d#Q)96>j6f+?ahEt` z>=-JUzN0VD4sy;Qv?)h-P*UO#emQjLRdi`h{yHmc2WuzY9Hh&5y|s+DLbj6A4Zh6h za_FwB6)7C*ifRUTYVw=tmhs*lvMG^e50o4UuhaHU{zk=emjCN~T$AiLv2iI-yakzMSWpW-O%S84mx!={B44c}1m#58gOF%BI4kPFko3&0c)>hy z%avk+X*zzqk;Lc>shu~tvFV(-yR`exr{8xcm1=GIZBfYT8pJLr-R09#@ceJbD-wV) zpEUcZd7~u<-2Hq`asb4H__3cj;8%!0csC2UJlnrIKRO$*Ao8~@Vn7`z$qi+IRD`EK4c}CXpB;`b?$^VPw@1$VS`PcD=HM=tBfyRb!b7&(`kg z1^9Dk|5;<>8qP=vu6Z$KDJ%rj|CtXkqfkNo=KSsJ?&JF;TmOA1K^}NX?enjHaDTKD z<7S8Hieg$Lu3~CwJ?ziCG)@ZrNKm)1Y^OKUw^CEm%?RQ^=3lj2@BNsok=S0&-s4mD zu5l661k!AUDb;*~VCdWpXP*Xtu#_2rbaP(HhN^cD zfSN``5hjUEOXoFJtk{4QfYK5VfX21^j%bzoQZD9VMcvr;#ttfPDPmw?B(8fP6xVpO z_o~KAfR~qRLPKT^S#!r6^see+PhaToLttSEiC*9Qar^c5>^|&AOxH*ggptd}oW{!v zE|;iC)FhpJesAgt68=|U@1C82MJx;H;C!6PXY{`7bij#Yj|GQPbXWP2$_bDk+98@c zbh-?CdL2?Z1ifm>T88U+ce*bxYR=Rk8-zk429VR@ zHb~2Woo7433W_uzw5)poJiF2Z*AgkK6iBFV;^{1}rN1FASrwXFWTaButqFS=55Vod zMG|lCqhf1d0$fw_8!UrJRt^>nShD0$4`$)!>-dx~tD(+w@%ektoBx%Iby=v)H^cuTrZ3Njj^0F=KS`fN1P)u0*FDk^ z%O2eU7t*a;j@U0i0-z`t31Ce0&XlzMLu1)GKHBL?@*M%HIDi!U0y)=saq|IUIGzIf zhVh`shNuMT0bv;$+sng4&zr&}y`50{f_E(_vT+;uwMEQEV!>28&(+;DC!!IENCm5V z&F?_92A#U|9i^2Kt-ZwK78EfaK|Hm)y;at2*@3};=>=q}rPG<)-+2h95oRJml%ZM{64}-yzfQ-)o5SPxAYdV}Viic2 zmE@e|29qtm@K$jF1B_y#GCZ>+xkD2awdH6|JoF|JzdRo80`5{1)(2GOT9CC!g9fO> z9fR1$|7XL1Kanf?Txvwllar4?*pi!ojU6&b#BOSn&}(k`ocn9UFXFQ;)nP zvh#5IJ<)>IG$ZS7#0}rl29YY!0BM9wL3JxLcZB&wu`B5H&QOm&gy#*X@exM21BF^b#hCPhgA~im^|rYlMp9o$eTxng31-9JVCzWdMUgV3CC*ZYs#XJ!(Ux zr64Y2V5r;6oUjz6rZbg#A$%1NHl-h!tQCrA+0=MOad{K}5-n1CyW3yE?p)MV#{?|J zRJ`(u>?J5$cRXJ1A%jPxSNUXomzMg(#>qi?^>KKF95NJFgaL_#z*U@eNVr3-39B5X_#0AY6Sa1Ls zF~;Qv#~tUfodb^1EVN)#z=~18o@4b%W`C1WVtEUcwV(!fxv`_o;}TUC%{3-Xy1^AaFN$jZf@rB zUe;?AsYydsnl#he5E-!9f+R>PQ0zR=I*F5yC2?wqlQ9x?)(y#c08(m&SuT>`k-a?% zBsO&hp2TuYz#9sGB#OF1v$4yAE@gHyUK20SHhB3;fXp-ZNX{0w1hqoYA|l)7WsGyN zShVcRA+mzyHe*+p4V#MLl#qA8E_?L|=r z?{b?va84N802~W^9pT6Ke~}`dn3A!-SduYHxJZZV@eyajUA7Vs0}V_q*05fVv)Jb6 z>#tZt<|+zcd^7nAjc!0a<^hkgdc^9n|M67@r*=>q%!M;T9Ko}V7U)8!;IW}92t^b@ z@b)(9>>a_0k8OckwOH%f?8%N@UclU22;ZC`4w__{poD5`W#5!g`#CAzD^Q^tn|Ig+ z`JCnM0GbdO4B0)RAs9aKI%p@z__1kFJcX;b*-Kyf+Q-buDOVCz-ZMaVqf`+ncNnKW_$92S6bqk~jJ<5Zw6TSQ{*BYOnU0=n z>96j9f^kSNCm~14c$CrYzCJx?7A%tXR|{N1oT4743^gal!n^^eN(CZXVmw3sq9z4q ztvGkYhLWf-DN33d6QwP&x*GL@aGeUC8P7MgAc;wMy(=v+J z?fG=M@YU086J`v>wild+?0h4nwJrG&j!fR#55A-&b!eK7PifbB>9$I6Aqas%?AYA zYpG1fW_;%?L{^oz0D77O->`tC2g{ri_Jj*%3$C0_egwn5{)lo@M@T*Cqm6l?N7 zl-4t>J$R<3OVY{O{+d^_*Ovp12(_2V+D+Tw5~_x_p9;e}&n5aZ{<#p>YHEG^J11u~ z;F_fTM2|BryMIU|CN~{yaZZlhA7*@L9es(P9)8kNWnS;nwFb&`bfK$2>yR_IuYuyh zFfaWssXBFnrcET&K-IRb6NGi$FVdwF5g^2fMks=to5on;ZrDVLWHg))=M!*Wg3=nU zpxswg^F)P~x>VEy8H5d0FxdR{Bhp}^!?`;nr&&Smo=!^K|7-6|ek;rFI)008L?;T6 ztjH>QL`~?9=!%EuDFpDF2frz{tGZhljK?acJjKth>Iwp}fdyg%Oa23-EV5;R5XH;}A|Zwq3&Q7ne)kObzUS&nx+8&vyIp?o-gD1Aa=SVHWWPi;f=b z2+mBI|AMV@eh0{5h{mZ0c9E~Btdv2%z?rFr0mhdw_9?a+%_I?7bws4R(YG(J#mt=U zFD}|IM!;B{xTaH(@5O+I57KI>r=CLE7FL<<%P zuQ4^tg_5C$5|I9e5EjY&;Iu0_r&Qud*MRV9$|Svsr_32KNa1-D1)N*JTQWA6=9Pfg zV=^=-MVff0as)-`v1FTN_}C^+!{~-@|6aW%UXTrv_W?m0#yRD%mX8zG009#++#t>} zl+91;tJI9jVMb~!)O~1zi?qePZ}o zaHKK?%PmS4yuO7#xB20t$AlRu({|`=wTdaw?~ubHrMA zg@TDwpL18Z$G!v^?12_dh_n@ZesxZSWzojG(wkrjsN;okbn)_8ay+970nVk4G9Tks z;_wjF)=8fcPC64NDKDxP7kmih;0P+g5Oi;fI8EoVcPuL|OK5kuhtQ5|ohz9e3R}C4 z#eG7k)}>3%)%W53L)>e|oi+wW9=TL6i}oHEN?b8|HP&RL{30|Lk?vv#?PIg)vA0u? zjr1KLIsz$zAyw8qBNxeS&{+tP=ru6H$!Ycc;P51Rpo~yj3e|uJ0lR&1aPusch)H!c z0B}b}rrZ>W8{e^P%hR|+U@n0v-5QZz1{>b==l~m3a&m^o=t#omi&7iM*R$!j+>tTQ z2?xQ5z+)hx@uW>0WD_Wn?9ql~X<33KX7J>i5IPa3-p)8+~~F?x=3C=MAUp3p9G z#b$Zh*b4;JE+kW~nt?2p&L*6U`oM$$Y?k}M6gj?)@le?#3H3O=dSa)3s2jZtk*3ujXuk-1hA zil8@Z%{kSP)BCtplR9d~{1sa%U=Yw>V0E0y$t%z2C_okTMT9+igv2;i4K;0`rbf-% zt8YHVz~F3X;U3EldXB=~dH&+em$UO`D~jg>R+bUYfVhIo>_jn9$WRNK&`}p1JGKD3 zi+thI--QyeT1|osZ~@Fq}u6kFrpi1=H zAv6gdg|Ky{b%jBdLL`621(c?{EIz?O1B{cvlhP;VIUs^CgsvZUW>~h^?H^uU;Zu{S z-?4a&G4Ba6J$LppDqZ$8#CrlvJPaFf#3+psHHy9*P7~Duvmb+)-7h=t;ffCr)DZ4c zZp92xA2kWO8J28%u|_5k zy>xGja0(29c-tv<<51@mG?5R9t^fw51H?LH8Ip91TVM3`i7Nsw5=T1l%6gmE&u?yz zN-@&75)gN)#7CPq4nk-CgkvG@gU?L1&rL;5=W)zMT?0xK=qO=ARAuXbDrqou4eUBH z`GJBy=04{t`_H7sP@>wdH;I#kk16^nG|4W~Af^c04crM_Gd_s&3n|3qJN&c>_2Zv@ zbb=kXeEPHVpn8N|VHG&x>0|k>7kSkUGGc)eA|1Vg0-oYs9~y^;W*d)%8cwj`W`UsT zC>b_DtxO9Pi5bTrajs)<3e*N2AhO$g&&*<5(CfgfpdQA3<6fCuipirWE24};-vChFQ62@s2%Te)na;pPa1jY&^6;N7S}{O|8-N@R*hi?JIEW`GMlVt= z7GC&@em~8)y zdCSUxi9aB)VM7259QSpEq`XZ?Y10r_>8;TJ;Zf$ZZ_lFJCOPrdo`wY%-V4R`OMNF9Y41NlcEu-+b zjsGl3Bjy&KE~kZ2WB^P~=GJH{NPD2d`%|=iablV%%weVgDGk-jPEs=TA*kbJ+3KUq z@GVAX6>EXQq4ycrq*c$=?zyLuBfHXSD_v83fD;n!z@U!Hj(08D#5(gyfBc1rd{X};Zh9A=0n_7Mf)Ch6~t$t4!UjgP=tGVuQ9q((MNyd=RREF0z%n_<6N_xfds8850sq&@bwG z+T)Jw{bwgH8L$fkjfCUEiiiHNH9}a<75>3IS2!hrwgMdzz34}aix$UTvZOD|p&5-R z3}HWNBGseT1jKHHyZlJR{3135_Gf1ty0k8wSdH;!XS+3QH9t(MV7+mq^npn8J7r#Jd4vZ@6RjxFVM*Pf$Zt7ERcVca3J9iD(N$$VCNs=I zNInY$O^0L=mP6oDrXgv=3rK-r)CzpQwq!% zgfS=8NX7t{hptlK(Bp}zXFt<{P zmYF8*(^U>uqFT@m;GL3;Dge_6BLo`dGiC=GR{Iy1#$AN*5)1_p9c+n|3lFz7U2O3E4W70<)Mylqq7}{2I;EJiG*^A^(JY`#h`~CV4%Ylu0ys`=f|il zOi11drqe2VbZ9REQg5`|O3)p6(?H3X2Vle<^4znhh@!dF9;(M~fsUBG)Rbnq$4Gix zC1>9$IlMdQ033Z0ic97d3qMSCT2x7Xg${>pF&w@zw&HY9VN<|G+^8L9>kh3ZUEXqX2!^`=WM+u)cM}WmB4!uJMnr* zJUynk(oGXj&nj97NyV@f-DE=HAo1R5cSv=StKEYwAP@eJvI!y#%r+T1VBSl1178-= zhbZ8aM1_DWQwMPQG4>6nOe2PFU> zLWh%6XU?n=j0z$IwyqID{9(zbo62#YPmdG+2p*#eyfwbQ_djr+Jb+T8hsljo@fE!4 z6cH{F^Qy`Q-Np5BYqwx@B_wf#zl{%!DnZh%lI(`{1;o^_wNooRNN$Seq@Os*Ko*ap zQ{ak@Qnb|eWZcg%2e`}wc*DVyYI08%4H{$DB*YSs1Xiij-yj0Y4iKhD5*Dh%T21S| z5Q&hhCE`(x@{j;A(66L%z$l&jamE5rGxi1s2kb=ooaP*?BW0zi6V%o4vP6@?X5&T< zC=OB-K0$@xVw?|=kjG7O_*hI|dEZu1-=oVzRX2K^j4E!~Bhq6GA@BFDcXyEO$34P; zx`0~nH?-bMp;mFk1S{G{@gXfY&=a}7wP0pusCuMGb;;FLM2f&8`j_l`a;p&9F~QXU zKlx`+dsmk)7~Y1S2U~u(j-kp;4^Dgp*QXZYWfFm)2_jq$;GpmvJXi-j0=V1p=JN4# z=bI~LPR4*_#<23#$D~f98P4|UjKk6fO$BV~d@p5N4b?(NaBLWWqJz!z{QBv^K3-(r zJDzwk2P7b3aTE0@%Sae)On+N4hlZMPPa}VUv}pjlpk8-ziTRYsu*0Py_y&6w7gO?* z;-K=X2T~Od-NP1BtFgI^>P@khCTb`SRYI9z`rs~|SrXq=&OI~{Xh6~<2GWadrH;;u zr2!rpI5gr%VsB))B(*dV4JzOw|MKmWgxi4T4pb;kmljbN!vm2`d>C9ZIT$hOfY<>D zqxD!mGUL0^N)nN!psac2m=(n5M9{?PNRFpXuo>r6iw6x_w97<~!QKK3717284bHS9 zJb*hzXcJ5d{j6a+7q>C{3>sL@8sb7yXg8OjUlm%rm%Jk41Oil4d4K9%6PrY zGI?_CHA0EzL#m}QiRp%@AgmIUVa#U%o35i68ayavNpzSzX8+@e7B){p@JAprH*q5a zI@%0?Wlau_hJA)#dO}y=`Q7=mgUeEs7REaiS(sZ1oSzL{W+4*RUdPcumcv|W=ypSi zYvn8@tdcw!M4_J^YVV1an-|zdoFYM%q;CT6=M3|25U#>Nj+A7POre-~oz6ce=*fL> zPGL>J#gZ{{7GYpOI`2`RTtP|fULXcD^Crz3AdYCvX2Sv#!iXy#9zFz_CY)csm7?)a zy59~?yvmCh_(OkwU0oNA>2SV4-DC3vS-^)wdWjHu5dAh*utdKEdK=sh@n5K848yaq}4_9+fqPa?t+5^IZCn>u>G`G*b^0u>T0wViM?qYvpO zeP2ThUKPv|x-EGplZu1GCoQ0}ayFNpoLQjXa|3I(!-2U@w|R=5f?8XqlbC~+jOW9i#8y%>Iz)A%Bqtqf{UgfGH z2Q2hY_W)K(116joSulfnQpe&!%At!b?E`qg`D0%0lyF%fu!lyA1*u<%_#6yiUY${~ zq{(Ncw($eR!M2m$#~BA^Ei_ps3;38Jyq2rP9gN|wB#u6gU_Hes%5Z7t=B!0oZWDwN z_N-L-KGjU>MB^jcQQ!$|6r3hZ6HFZ@viLSsI}Be9$~~u8Tpuu!WOXML0Uv#$6c`-n zIobp)y@A>n6=7QQKt{q$reThTxtZ@`hba@90(4#%TRL)>*-U4s3w|J=+7op{5T22f zi-YO2eXr#A2S8jKOb0xD2V^=#B@_3dE)Fg3c~VN*Q3%lm0>KMZd4OWkMh{Z}z6TW& z>XFm^v|Jj^O};+#vOv+yl)PSC#bQ=~vtjRd@j)XrJE&0edZD3dt>~#6=yJh1_V3U2 zZUR;d!^o=I+QJ5~6(bri1yv@St(z}LnTgL$15F^FnDB=#o)h&vOU3I66bO9l@Guf) z4H=Y?7&yb775D16)2pjnc3HC8=^lq*oiN5=;N_^)!Y=6{IykYBXKRE~F(2N%-1I4- zT`BN1@gjZFNTO(SC81K#70lA^R0;#Ze4(rY*u@O5iRH6oq2p-ifxipWXwjW%Nn!1! zH4^XDtJf3;%6^l4KHW)F+{`Hsh`s{$5OWzqAswDv91HN* z#8S!ro|m{eVKkhIE0jXN(!X$O@`@w0um4xzeo=cJ|IZmJw(M|%%B`Spk(XqDAlxthjdZSz(_-aEMNgbL`=S?l378`JZ{2VgP&4t zSX`;>JDIoLFdImE83&rEFY*d(2~SVE++h|vU3JoKKnLo;#Q;7Z%alXIs&yIBIXO4S zt(~Yl+8}EIx+zJ~-pf8ND@Z-a6VidkyR&*C$S^S&AjP2s50!*sfFn-NlR-g$kDXHx zX`8}aW8?T>mxS6-5%#Mg(fViy{KndkUe@_Wh%Lp_me9QpdntY3UKh2sE|4*U0c~(> z%~G6@wFW9>7y$f)r6@@JDWyGa01F~TpD{yzJBm8PZAY^gTn|z}i&2TldFEAmS2&aK zHU>n49LGK9LX4h-jXEDAL`(#Z#9J~COBawkij`>;u0gmIlYoj+Ui^hFS-d{3^@(J- zF~sTIC9%2;4kH@sm0Z`vd

      OQ&4q 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 literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/GLEW/x86/glew32.lib b/libultraship/libultraship/Lib/GLEW/x86/glew32.lib new file mode 100644 index 0000000000000000000000000000000000000000..8808935c90c97a9c98612762c4569311e51e62f2 GIT binary patch literal 769106 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®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

      {Cqx{SW_Fgda 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

      2X~wIXYa9Wc6p^F-<@ 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¬mOO;Yzb>epO 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 JtlUf>g_KZ_R<4-9!Ug_+a%mR&{ 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

      1x|ec{zV$Kvmex^@#kcAy$Ie@y(G%$B)R%rm zFQ8x3Q2GrWM!%(Tw3$w#-&2k)w|=5`&|m0M+Dcc_Hp;Qt)?xY#Jwl6UmlU?wXjjUy z(w2knpgkzZG+SQud)kX~?6TE|_L;)-Ae3W_EgyOc^`#e4KC9JrDLsX9%&&DCok$1J z1bRBY{;kIX#Q6qUX}5=wP~z2Gb2Rgl?r5(e3nNT0<|T-_c>Tg$}12>uHUk zJ_$SzLi^E3+MixUhtg~4a2icV(il3Kj;1%!F*KQur_1OBnn`b*kW{y=BZU+8SwM(0wFWwYi{j$yOr(*g8$8b;G8$Cg=lP>w0Hme8qm z8NHciP>%JoGU*Dsims-sX*OL;IabQLn-^3^Y4jNyK%b+R(dQ}078^Fy^EGn zj$N_J>3aG$eTixxJ(Jea z5p*BDlJ2L`^m96menC05!1|KjO245T17J1LyXis7zJBX_%D#E)N6J2VtA%c&t#mj2 zm9nqg`i-)WocG0KeTa6N$@)+tk8iXqbx?omNe9vH^laLTM$+E&YU)j|r#^HBJ&Dey zeW{b4Lf6t$X%6jA**9vPPT7~qdvdZqL$5JV1L;s2NH3x1(&03UhSO{5<#aTSq%-N2lzmrL6kR~0Df^hL>*xdYddj{eYYb)I zk2RLE&&L`^-=a6rIvP*e7h_GL?1QnU(oQ$?d?R(xM9RJqE18}_XV7!#Ei{$h&Bx6?Z)&&gYh=|j{-dG6iHpgdP@t)M(dZmpyhbT!>i*HE6j zw(g=lXKmd>J*M$|2<=Yqqdb>vJxI@@57YB#9=(9()9dIHbPRox#?fc!T>32KxlwB! zy@Rf&Jcnr&(?{qFl;E+Ibf1 zL)3##pj|23`c`+!wz<`lvQ2Jz(Ph+|K1z?LPtp@;A?-^y(|(j~S?grVHmud3Hd23j zkPe_f&_T4<47S@S+kRFc?Ms8`5PBYE+sqnF*(S3tpyTOG@j;A9*eD9nob|0 zJZ4%C(-rhF`Z#@@@>pg)L3s?bo~B!9A>Brwr98G+&(i~R18t_o^e0+Exo@^!p(oOf z^klk;UPxc3+*ev}(97uCl>0QRf=;3DQ0}{|_vm7}jdCAjRna?XH7%e!DYt!V7v(l@ z?V<0{z4Qb65#_dM?W5n)dio>%l(y0@DA#4{E9y%d>8Z4dhSF~-*DdQiI)eU4xei!A zQU3PU&y>Hp^($RU+vrOAJLPX-b(+okB<(_rs0V$4dQyHDs|Vdd`Gj@XZrYoEPy0}o zZ5>a4qbE^LmM=Yp_M`svRC*~rjfPXExgu!*O`vDcBzh*DLC>Mf>A7?jJ&&%XL+Cmh zLO0M0X$c)lw^P1{tA>Wry_E0eYM~?OAv%&CrdQH_sjNrR{`6`(kX}cJ(-=CEj-pX? zEWL@2r^z&q&ZO})lTM~<=oESny@@_g`JG%Z(wpf<%J1gdNmJ+^$|uab>gcWX7dn@= zQ77$mE4MT1NBR7D*8sYZot>osZ=rY6RJw+)rd)=uY?@8) zqdByg-cMhq575`>!}LS?2>pmYO83(z=&!VZ9-&WBk2&1V=xOvh8bFKaS+tl&&==`d z^d)*7-AJd?SLrPJ8l6kupm))7dM|y8=F)fQOY~h@N-OE>w2Ic!59lY9>wxPsx{Ll! zKct=K@;nLcMn9sb(>i)4{e%Y5PwAEPa~e$>=qTDqQ|LGJR(gQWr{B@L>G$-0`U8EK z{!Cw?t#lLRI_D~$YnH9Yjm$8T3_pHm#xO((mYC+CqcrAsRw`=J9w& z`_YSOe|jk$N{7+ml-rDJBppE~(@1(7y^=1X+=g7sXf%D4UPqs#*V95ehQ3S3(a&fc z{fbVYO>`3NHlN!U^`Z&14^5;&^k#ZKoklOBx6n~^CLKp-(TQ{poll)~A)QBE^fvl1 zT}bn3I(>?|XgOU<-=WLsR=SdYLGPsB&{gz1dKc}nfZG@CP4A{Y^gcS6K0rfgE*(nq zXe@n{PN0v`$@EEj8-0o{qEFLhbRB(^7SSgu_c5+Q`U2fdU!s+?guYKpX%pQnomEXPtkp} zoYvEK=%;im{epf$zoOsJM*1CXqCIZo_C*KL@9Ej}2RfMkOs}SgXcGO6&Y;|9x@J@B zR_;G&7y2yiO4m~deTnv?wegV(m*LUPpuf>bYAxh(jGjVy3~>3=XgY|-&~Q4MM$$3#YC4`K(Ft@0y@AfAlj$m&K-bc# zG>0b94RjhUp~>`BnnG*nEV`G@ru*nzdWg=Whv|IUC7s7H+MlM=f%Fa>~gK7YiJg|i{4G|p+z)@zCd|QbGoMxUhC z9c-V`Q|PnQpRS{W=z1DXd5m;L(iiB}l*dX}65U8=&{8^^meE!84Z4=TNpt9Cx`Dn! zOXwE*D&0zJXcgT{->3WN4tj|0qK9b>?XrmNGuoeiLCjFYup$F+2`W?N8Hq!@a3w@FPOgGYBXc_&D?xDZaI(nFXN;}VCeTA|P;OexP z+Z%Pz?sNd{Nzb5O^c?C6yhW4em(0(+Po=oS_{xqBV)BETE`VbvNU#4f$ z*JvPplLpa`=y`NM9ZVbO1@s8Lkb1bdz0vOU5*k3m=vj0aJ&#^auc9OAb(D1&*BBZ_ zXVI(aTzU;nqu0}W=_r~@N7F~>I9f{M=<9R>eVb0ApU^4vGnzoZqKUNg5+2WJH#&`a z(Oc-5bS4d=tTVaJr*mjDb<$CE9vw$-qqow9bUsa|3#p6VPnXh%=`xy6SJF-NPFhY^ z(RV28Vy=3cO~0Ub({Jc~wChqH&u9FHzC|19+w>saLOqwUzDRq~ z_vrETeR?k4PKVHHdNHk`qv>usp6;RX^kce!vX1FWr~Bv<%DSd2k2cW9=@;~A`Zaxv z9-v!j6WvCe>6i2edVu~&o9QpKX9kaJ)SLcFPo#%wFtz5gJxV*#OK4X*maXcAPoR&{6KMfGi9SnDrWMqWzDG}`AJ75xYdVmAO9SYSG>{&*ob^U} z0zHTN(!ulsdOi)ML+CJi5sjmvbP^p(Z=}QM9rQA~l!nulG=e@sub|IR*2!H(^cwmu zy_Qzd>*x+Tnl{l``aK;>f2I>?pB3y^qbJdLdJ0XT7ttH(rSv8mPN&g{bUIC-GiVZ> zMO`$NE~jh*xK`15^eMW4uA^ym15Kw}=_0zFE~Yhf8U2nfr!8~^Jw#VgpOrixLi^D* zv_ECr!ZnoMONY}OI+Etn$@C$56J?vjl}sO_%jn}YlRiP$(5Go3Eu_!WXX%UddHO!x zKzGt&x`&p~A1K=}u3zXz+D6%yarMn){gL|7H|PNRHVvom(24Y2nm{XQ60M>x`T<=| zx6@U07k!F;NY~NbbOZf}Zl!f}JN<;#&`;@i^mE!m8|We0NPX^P`;7LZ2WWr#9UV%4 zps}=tPM|;0$@CDtgSOFJdYC>!kI*M*7bo}Elx;HC+tfkdr9J3p)Qf&ad(kG^hjv@V z?TmU+AKHid(ja;=J)fRJFQTW>QFH(uM^C2{=^1oB4WtX{S=2?(r4Q3!`U)LFH_;1d zIlY+frBj`XHMTb+iDP1G!H8hf5PZQ`UnnXv_X>>fD zMU!se{*d0l*IwK`4IIFIk;MwU)YD?sO6p-f?Vh&IJ?%C3v^U(-wz{W%;GWj#p4Q}^ z=IVX)dt|h$hgIsHR_2~I@U)}nJF{IqtQhySSogFN_cZgqD(3g-VU1ngv}_pPk=uE% z$4!=(JNq7~KG5sPiRP;qJFBag@0{ltQarT0?7mY#3_K&(SO&p!;G1KIbHa+)O`ItCub+F z41fAiXETpE&y}1G_TfMMTe84>s`Hge&d4-p(yY1DXV2nC{9iuS`R_i)*?ioUC-Wc2 zS%|556Uu&?rSDleXPzb%)B%A349f(X&&ugcd~-?wXgL*KS(QSR-#7D z5-!nb55B&kPiGv$ce#|)S$vT2bYE7D&9`?<`O8l~cZ_q+^jXs)<6_;5vVT{HW!~jm zOa1GAuD^Yk@1gqmYIAP$9gnky_UYF?>+trk{oB6|<7@M--#_qmYWp-3bD0-%>d7gQ zllk{`EGzM}iJBYDL29m0&D1Ra2YLqOKrxrOj9Tb<^cOmW{zT2C^D{MnOEcXp=Nzsr z-K@BF^|a#K)x*kiPs?^sD{)UNbx*5wPpfiIt94JSb5Hx(J?&Tbw9C21nV+Di71^#H zR=Rtd%RMd2JuTZkEzdnI-#x9wJ+0I|ZOpjU7xE3w;nn;*vRir5cKa=Lb@iRPan9?_ zt+JcBU$GAKJF@f7w^^NMb@RAJbB1LV9_@3l33JTzWJZsToep#!a%8;OC&r_T`LEqi zxF@VS)o@vbuO?-DJkK+ue4a|Ykr z@q}d+!T;so?=MUJ-}1BmCkt6t@n8Sz{Ga*h|FYEoV8XJBDE%$kXZ`!D@?Vy_tRmpQ z{1^Pc=W_dh`>+1r_0#_+f3N@F=J}f|{(sNi`Tv%0{FjCNWx{`QJO0Z;{xab|S?d2| z*PP>YN9lg_o-+A@@`;6Bco00uJwxLm)*R1+&(Y&7_d&vjfqh_V|Db4!}vgbX5 zMr&SgR^Q&$yeA=h-qVmhdIl=gyyqZ$-XZ8YO}iM4(Ne=?$Mp-H7#WivVW?5=ygr|98J(t8r`GK=mt&e)R{d6T5>mJFWDQ}qkWNi z4Kdp}$X@b5v{};v(L^ofT=(dOC|=X9K-*3?*NtdoFL|tcG#+iyQl=t%$1yo=qVD^Od6nRhj^=e-9V z(X?K#YN4KHQk!H!&$X>EJk9kGE!>U8KYAK((N54jM zH0@VZqa~Z?lI$gSNA{>U@{BY~IT6`QJ{8U7Cx>-E|L@Vfc}DyO4(loRXc6iY zX{Nn^?0H{B^Eo-Jt^8lBd8?5V z7NC!{5}j`FIqhX?@WmEyd40IuH%kXdqgw z(R1CS7b2IYU4i!L`$i-C`;K*w#-kxx%2Z^3-(+;5rp-i4w3IpS(c4g{Mi-%_8eQfd zU5%D$S{~Z3@B0L@zwdMI(HGIBTFORbf8RGzhUTqC^_q7#vgh6J9{myx*SrUiJ@1dm z+#Vd3hbQ;^nzskC=RE=0qbH-wHScN2p7%_&Li2{A&ou9FWY2r0d-OUKp?Sw3d)|p? zrRGgRpKIQE?rGc*^@MT;J^F7kqksI@m#@1s!JL;B5bKUVjYsgcr$)^apIq<%G`^It zyKxTl&n)NGKaF2vCi2v;`S(31^Ef>CPfu8zpUIqU5&hPF5|^)Bddl~zS<{_XZ}+p$ zNomf=_9u^hIZq-d_HKIi;SB!rO>?HFrluq%>KSVDv!rP9nf&mbS&2XTEH=v-^S?Zi zZ9fg&moxR!tmcXBi!^JbXJ@OQHKWrFeJ1er(Wj@)Q`8^uvzl&iZ*_akv>ku2`P!Uz z{$bj#Ke(pdAO2z5?mzhG{D0Ry?dPlg!}<6A!5_8z<3CKR`-4Ae_rCV-Z*P5jKW*=4 z?ftyH=4WYW_ZNSd_T?XJ&hyouzHV&)`s?<7)7}H^ZKC~-{xv(BT^5mPsY!FD&rF)- z1gY-9&xpc6uWHj`GTMR~POC z`q6>Zj}E4%(J1Oqlj%Tec08Rym(#Q8{WOSfpy$%dOXyH~ zDV;!v)0y-#x`vLR57J2bBE5p{q*u{>G@5=#ucu~@*J#>@j-{v5IC?3aNUx-mX&jwO zZ>2ZVyJ-@Air!4$q0{LOnnJ&!GieX5b*c0uI+qTnPI^6EKyRXHbQxVp*V09_kS?Z` zbSbT&%jrS7g7)Ix`%XH5uA-OIHPmdg-bKwC7O(7g-AV7E&(izo>-2v534M@$PamRv zcuaqU4x*3JNcuP(MGNQ*`V?J73+bcuS^5U$odaB3=?3~aEv8*~WP6GBro5AY%b&hV zhtk*R1o}EnqUCfx-Avcg3c7*5OE=R>`Z?W3f1y>>JpOE_=g?|;4c$ej&>CtUZ)&Nz zWu7&_Jl2%9tEW}gt{&EB?rC4Tr*-8TXXfZ>b#GS>E66=9*gY-WJ*QE zJuTlojXl<*R!4e{iMcbft&!i@I=Yj}W0iJf-x=vy+-Vt)<-J!-;gNNQN3uE7nn=%> zHIZ#Gnu8tIJnfZnz8UWN55vyWXYdYBe>3jA!yj%&uMU=RiCM;p9h~VzbEbd%RoZ`=X0FdO`gX9SZRSiT zb#SJq&6)ajaHb{ZOy(7TfA?2)w*O3K?RtiH2WPtY-&vB`7Wn6@Li@Kn$X&*aZXJBP zN^>UjlEr`ZgFk7`bbJSAT4c`D(VxX^s?G54U`ZkW&Y60fGyT);$a!^#Kkjz!plA4Y z@RO`FXZoja(mTUpuG2j_ScZ9KX~xMNoXI@Qba*B6GiUn8JAn4T`Y$|?%{ZZhZ@1H& zsiUjw^X5z)U0pN(oh6wE;|_oD;pR*oU0u!7R2^PjTex5D@WR|~&eYKrf1No~N0-xb zbEbd3lI-KA)!}{GpFr}Z;u>gWgX?D{O_D;wK-Eqm(b1TOg{f`2_1cC zFh}up_~_{O?<~pe3hMBFZKpX?M}L;*&6zs7*UvO(`p1X$Zut!JuCxDqakrl%;va87 zthW5)->QA)Zd$X-DQEp@`2#;6IWlqe7v|VMbHty$OV4a(+Pmt^W?Kw*qdeh=R$pgy z844a?p28o6mPeXtlhOH_W}dIe)U?~s5KX%a-KBXScAxKAbhoCx;y$0*k$1P|t#zO8 zOO&JY{pdcQ*=c8<`gK@6`4g|a!pIldKf&3k=4vy|?3S~Cf|1DHk#{{R(`dYVG#S~u z@62Z51Nv@ecbh%0*~w<_$TPdv9@6O3?$H;K+1PPdZ=gpsYIdX9^O~J!_6|C;%Pe1` z&F;}QWbdHkIU4Ipjh=|?c?TeSSKYa&>y_qvT;d)zyTT^u`;JCWYu+jD(OZzcyKMoo z{~j6cQM0ql-pOWmaXqVfpLLJEjN-NAw@{Hr&F(Dwr!qUSCTY~{y4s-8AKjxzkiDa< zCwIOtYSb6m^O`3J>|JK&DTE~bM#J2rSD^$gc`QoS=#B2tS!k+8Z%2!x%%!ms*?;r< zko~hff$Zx(nI6$M&PAwY(-|FYhoa)f_!}1htpf7umba2BJ+G z4R(*39X(0<`J&Jp8XfB%or>&TW;4-S8ok{;YIfz=yUffEoC=LT<{o_x**niRBKulm zcGlQGmDxozUEkO2n6a-VW_OG|`V*R=(N6qtUrUZd_UOsT-T`(7vaclAc8l!R=vepYR5Vx1 zn~C;n^mg~C+3{iTLNdEM>NNV8d(`aiFi&tetc_^DMl0N-)yUpSREIv(=-2MipOC$y zrxP0|Jvg$$VI7C;-@`mj@rC9vJ0IJ**j7?@#I26wEi;4{(VnI_Rf%j=vOT{ z*gYDCR@i?dv|aO#M)qGd0sXEyW+Hoew;_8M2sc&hCr%NZj{dukQ8V3~%)cD&m-zAY zwdu+~jhm;tj-LB_WX^xlpLSQ6Wtw@{(jR%c+Wu!BUw_ryG4oPWXU}o62jWkM*PExV z&AIg*c#i4s4!1wf8qvor+Wt3?{U%5EYs}&0|KG9%9`URd8b0LN)e5ynSeIH$S*6%w z`CA7#d3W-+F649rr^TEKIK9W|TTUl*_P0VgP2#ka(=(i^IDOywQtSLK{?@oImsth9rhoyTbmr!-EFaC)25SDd`M`djC78pmm2*UPLoX#=P34(8!BhEtm3GOLV! z%E{5q-#Uj=45xXV9^&*Srv^^lJ(-8o7*1)N9^zEyd8zipbYid6Aj|wq?e1e;+x>sO zh#+H)45WTX7N0|eJKvqlsVl`V&6>!Hv4WuISu7>$-k%>`%h0t zm;J}(|0m1(<8uBy|Gygh^LhX7>!b4zJbLZwJY~xGE2AUFPq`o>ddgg9(wwB(Q*N3) z%Q=VlyE9i?bCvYhg*m(XfWMjPinu8==cPEO&z(AxeQ%n@gR`4`XzY#9UKaE9(SLt1 zds%v0J@pNSajDOmI@8SFQ-9P~nPC3N=4?wRE*7 zPjT|%UzkA6{8Op90p3W>Rq7@>m~zWF0D2JxpEH>`qxiJ?V0KCe5TH=qh?8T}`7YZ{XpYM(?I6^d5REy`P#_Q{>XS z>4VhlZh3^hKp&&8(0say7SP@FX=--AJVWd0bM!a*Jmo^P*3+)^MQV1(lu)z%{4zb8 z@`fR00_8&7oVV*?sc?Euq!)Rl0+|K|iE>=^ko! z=hV{AX&pUG_fd1O)_&?qKc@rf7c`K5NzbL<&?wqOucZg+X!<>!Nq?ksXbW9HTj@RY zH~KvNoti_V4%3aa^E`GlQ4hL@cBOT+JN=D%QL`K9IC={0P5tQ!^ip~v4W}p3NP03& zpnf!oo=RuX0dzSXNLSGSYIYk1(slG~x`CcUOXy&_ot{r?=n%S>UPN1HC_O}n(!+EZ z?Z<85GTNVp(}6UC4yRYpk@QL$MX#Y|js99{)|aoNW({>T&7`q(4INAGp%duybRvC` z#?y^7f$pR?(mnJhT1ThRU+8q&MrY7Y+=gdSe|jsul+LB$)Je_mt2CNGZ>LFgAvL?P z7SrW)2{pU3meRF!1zkro=>~cyEum}ZcDk0<&}_Pw=Fk>;KRrYrpoi(h^we(bMx&uL zpAMss(-HJ3I*C3*Z={8E8ZDwr>3X`7ZlGE8CHf3~nHJGk=nM2UT1Cs~4*EJZ2cEn| zzo(n&&$NR6Ml0z_+@Woyr_gQGpKhm@(j7FM?xc})H%*|mG>Pt|Gw3IDIo(fJ(R#X; zHqdqSOS*x6MN8-bx}6@RHS}A$m;OLoXbU|=f1-!!A=;1o<=<$3+D84UHJ_i8cBbL9 z3mrju!ynfq+JmN1-uTCL2kk`{)8pw1YVNnqy4Q((ZFUQuJ;1C~rM1g`F{+u?!+OR& z?YVaKu*{BcGuqR7(>-mQd)jvQw6ERM4!Wo9<=)et_mg(@u*{1V?P=zj2mAX@=3c^{ zX12fWX=X>WJV_cXrQv46)dfn%4zu}k3CC2;H#ICcpfy9AD10>>_a zW0%0OOW@cgaO@H|b_pE21dd$-$1Z_mm%y=0;MgT_>=HP32^_lwj$H!BE`ej0z_Cl< z*d_3%OQ4dY3^>k}sZ|m?rLAho>^H8FILOGVm3)vnPJv_LQN3i2-*1roQKJ-q%<;4i zz0+;86vQ-h+>yfyM&=k>hh^U5*Bs~I;4nS@aYTW`3IiTeIP#Ptke3vNyd@5Nw0xu( z?QZ7o6@=&6bkCLSVlp+1)wG=5H(9ds6`4! ztx^bTlR^=PNLXC|kcSkGJf#TaB}E}`DH{1mG00bnMSfBo@|VnOKmw!$WZnwKVI`s< zDH#PzDJVorMdoN4u74;@N<-mNI*O27C`!se(NZRgk+M*%l#Sw~9276*q68@qB}(}y zSt>v&QXxu}ijY$(Mrl$BN|#EJODaPdQaQ?$Do~bGiL#|Clp|H6T&V`-Nwp|nszU`* zJt~wMP?6M#ilru0A~mB@sRflut*BgTLlu%a!mm>DKvj}?l}xqdg=!>kR4e(QI>{H+ zOMa+9GDiqDN&%=zGH*85ECrz!DHyd%A*f9XMV6Tshs+UE4l5l+ zNG@cKs^|U>MN63|M#@65QZ|Z{a!|aKi_8&M4$HhgC{fBs$x;DIkqS|&RD_&TF-nt4 zP`Xr#Tv8dzkjhb}RDrUjN|Y^Cp&Y3iQSN8fQqC>R4g^25~&%L zN-d~NYDMKz8>)~jj%ccsJW!Qnj^eDAyikqgjcO$yR418NJk?9)C8!OOKWdZ$P?Kbi z0&SLpP>W<<8PzI^u$XAL*eo`DVN3wDK zLjh6(3X~F2kd%zfYa6)!p%5t*g-T9jUhly551Aw3xc;FC$%Ue%3=}P8q8KR)#Y)*I zPRc>?QZ7o6@=&6bkCLSVlp+xiMa-|xSC)J{SsSXuL^{7y4Kt)m`Dwdj1iPVfrr502swW4yV4OK{%2iHHz164_$ zs9N$uHIg@~m3&a0&@{q!j zrxby_B=gEQZz&r2NHNG)ibZ}>9P*dqQGk?y0;NP0BqgI@DFuZ{sVG!(qA)29g-huu zLUN%fDFa1InJ7leLa|adij#6syp)R)q&$=;<)dV&0HsKUC{-##PN^8BNhK&Lg!OFZrPc$saXJ0jNm| zM9oqVYLS9bs}zFTq)=qu1CZ+<@{q!jrxby_q$uPqMI#?62Kh>{$WMwx{!%;&kP=X! zl!$_)WE3o=pb#k)g-T8oCZ(ZpDIG;fE)*qYplB%*#YkBwR?0?kQVxoja#4bmhZ3cH zlq?mX6sZuUN=3*i6{9q%1f@%*$R(Ab45=JtN);$eszljR70QvSQLa>j@}ydnFV&#} zsU8(d4X8+JM8#4QDv_E|snmkXq*hcewV?{hV$Hu&@<3IRC#sgbP>tk`Y9$|3C;6g! z$qzM1{-{w3KuuC0YL^u$XAL* zeo`Frm*P=?lz;-IL=+??qhKiog-EF=RC1y)DGh~7=_o>Sp(rT>MN63|M#@65QZ|Z{ za!|aKixQ+flqlt+WT^n9NQEd>Dnd@F7^O)iC|xQ=E~yMxiM za-|xSC)J{SsSXuL^{7y4Kt)m`Dwdj1iPVfrr502swW4yV4OK`MYyOpz2da`hQMKfS zY9wz|EBT;0$rsg2eyBn6M~zYdYLWs`vlN6{q+rx4g`hSm6!9`fbNxdeQaJLIB9NC9 zg}kL`>96{1wB2sx!GQV?p9f>Em!g4(1|#OrL$ z^$&SS;mA{pKweT5@|L2Jj}(J^rC8)A#UXzw9tB7VC{Rj7K~gdbmQqlNl!`(nCkm6& zP`H$iA|w}zk}^=Vl!;=bEEFqcqc|xC#Y?#;LCQmkQa(zS3Q&qvh*G5@jxwbRlqFT7Y^e(6NYyA;szG^DEy|bbP=QpB3Z({ABsHR9sR@-x&8Spr zL1j`aDwo<&g=DejUnzN@D#;U7OJ1l(@{$WMwx{!%;&kP=X!l!$_)WE3o= zAoKEnhqgD(n*i|qAJf95G!!nSqX@}`qNEHIEoGt@DGS9)*(grRLGe;9N|5qUqLh!4 zr2>>96{1wB2sx!GQV?p9f>Em!g4(1|WIn-%`#p zC*`1cDHkP3c_>lJN6AtFN|6dts#JuWQZY)CN>I8~id<3|%8<%Yrc{Blq)L=6RiPZI z8s$ngC{LaXNC_xVN<=|YG76SbP>7U@LM0~(lhRPQl#U`K7mAWH zP_&eZVx%k-D`lfNDF?+%xhO%(Ly1y8N|p*xid2YFr6S~%icy+Wg3_f@<9qGG8Dl}OE~RBAzGQY$K#+E9gL zvF2YXd7vuE6IDxIs7CTewUQ62lYCLVIq6otH{XyhZsAYUmK`AKoeUy4ToQUVH;5>b$pjDn>U6e6XfP|1nH zq%;&RrK1SRg`%Vk6fI?<7%2YtSr8-m~)uTeG0ToG&s90)3B~mjg zm0D1l)QZZbHdG;5toc_;9;iz4MAecPs*$`=t>lC1Bwti7`Jo2MA2mt=s7VS$%~B9* zk%CdH6oT5MP-OY&`iDHEaO5dPATKEjc}vmAM~XqdQY`Y5;*h@-j{>9w6euO4ASoFI zODQNsN=2cP6NO1>C|pWM5t0iH%475@DIZ-e z6`*URLKH0(p=+gLbe&X!%zJD)w3Qhnl`(CURE|bV6=;l9iDIQHWIim951vBfq#86{ zszq^99hxB3qZ_0KG*N0q@lq3-BsHVSQVW_QwW0*64Na9S*7t9eJkU*&CrXsOP?F@0 zZkBwIdDkP3xhFnrQGVhn_ z&{pPBDT8Utq)e0{Wg+u{8xCz{u8?w=wo=MPnNl9QQ_4rHqyn^BDnwaQ5i;-2>d;o^ zT~Z0t)=H%)TPj25ou?ey%DhLaVA{P>CCZVi(0x)hx?ie64@k8rSE@tiyM%6v#_ zVA{h{Bg&JS&?8badQ@sbk4dd4Uur{-OBU<lPHIA*NX=-U)PnX)t*BmVL!U|( z>-(Qc9_Vw)6E#R)=nKgkeJS~%uOwg8DEXnUC4cmd6o3v$fv8CeLIx zvlNEDm%`BxQUv-@ib5??H2O)3K|f2e=ocvtwMy~mkd%Oal@if!QZj0jQqb>GDmpAV z(Ge*PSsX9KQ7@>I^KWGVfT&{U35jImmoWDv!U&Q_4f#rF_&wDnLD@ zLgXbCp-jXGlIwJ5%ySfs!9OOY%qNy#V>JEOd?(h=QabWZqkwqn^=uQV1F>g`!|7 z44p59qajiRxMkpNwMf+DGr57@o1=&fXsV(bJQuiR7yr+QVJR-rJ~`I z6I~{yp>Qc3T`sxM2q^=Nlrm9-l!eSYB69shS4cVNN+}mbNqOihDIb~lPIPE1^BSp; zY0**hPi*GVPldZ`q}NM&f0RF2I1l{>VRIYz2vTC7xs#!A&_oK%CxOSLFYszVc` zdUS)-fF??fC|+tplcZ)eS!zL3q*jz5wV|n!#rpn@k_Wm;@A^ng^0a-}--pj3|@k{Zy%QX|Tfn$ROsGkR2NL61qTC|_zr zk4t7N^9jjpWj-mHt;_<+Y-K(rnXSyHC9{?JjAXVl3njCa`K)BNGS^9FEAu(YY-JWn zW-Ie~$!uk=m&{h?2FYw?7E5L;^99LlWxgnxt<0Asvz1vQnXSy1C9{?JiWG}BN^z)E zibtfDW#!uDIL8fxzO8E2HGrTq6#Ssy(49#Em978 zSIR||QXYCw%12wJ0<=vkL{(A|dS5C=A4nx=yHtv*r82ZbDn~n|3baeAL^V=zA#~{UAl4 zAEhYNB1NO0q!{$G6pMb5;!vv;j}A!*=vOHb{U#-&HYo-DE~TQwk`o<~(vZdRx~%`9 zPLd0CmNJle_g{yVi9Dn%)K$tx4k-t9lX8)#l!v-Y`KX6ffXruVIIKeCB^9AwQZYJC zDnY%aQsga_p*~VMI$o+kCrFjZN2)?6O4Z1GV4%aQL4BoK1beWWf!liU%J`s!OU(g6C1C5k2 zQG}F*BBg9}g_MJ?lyXs&l!wfxu{f-JbhT7~u8|5+v{Zzym5R}IQVF_VDn&6;85$*( zqtQ|Y8Y5MrSg8t)m8#J=sRoUgYEhh2hbBn%=mx0)O_Ul@ywrpyNzKT-tF6OoK~tnw zlpwXCsgilmck`aNyy_C&BzdAl$qOY(-son@2ThZFQL^NRrc3^4h7^EqkpfYQ6oh6< z!DyBgf@VvhC{+qWw@Tq?jue6BN>RuuMWcCA44N;+q6JbMN|WNzZBhcdT}ng?rDT*Y zrJy^cRJ2HPqQz1ga!KiEiR3~{r3|!8%0wAb7FsT4qZLvPS}EnCOeqiDDdnS8QUO{m z6{0Mu2(6Kd(OpsrS}T>JY^e<0EtR8tqzZJeREct=Ds-PzjqaCf&;wE}%9ZNSgHk{Lwlo06ixKq9Q2>Jud~L^->7hAcdl0$$a?p3sN|GQHnq>Nl~aoibgL>G3XU3 z7HyQ`P^lD;UX>EiYf>WGBqgIVDFwYQrJ^?^Cwfy#L*-IBdP{Plx1|iUS;|BeQWkng z%0^qH9Q3Y~iz=l&^q!QDwn_zPn^cIZq$2dbRE$25O3-$x6je)QXopmec1jg!msE*r zq$>2GRE>5^HE54ii)y7hv{$M}A4v`9W2q6iUrD~GQSw7yOaAB^DF7Xi0#TC`gbqr<=vyfSeJ6#YW+@DP zFNLEYqzLq*6op!(X!Mg5gMOA`(JxXQYL(*AAt?dwl<|^KW>MCU;hm?c5Nx8^V%0u0yd}Kblo9ADU`7AQl|B#nd zgnCKE=s2ka^_EJJw^WAA$IkQoA39#DKqp9*$VaL|CrZ`mB&i0OPd;;4wa8bhL*|o3 zS^q;POAW|;nuNn@M1E2eI#p^${iPOkn$(K?r8YD`viN-Z(fKNKK&p+S;2 zIz#e7XG*>(Q1U}(N&e_;DFB@#1)?A+2%Rehqw}N?G*}8n!BQAHUkXPh zXmp_zgD#R{(Zy063YFr~P$>ajA|)d8=^L#7p)e^04U_ng*GPpZS}H=wl65x=HdxiINvelDyH)k`J0D`J!aW4^5Z+(F`d7-692|6e$Rq z&jaN7XEaL+L9?Y$lq!XxTcvO`M~Xmmr6}Z-qR~7l2F;gZ(E=$BrAhJVHYov_&mrXb zXS7gCM(I)txryIuLvo@wr8HD7rK7hb7kXRDK%1pZ zR3T-dccg5zMan_%O1Y>~%0ur-`Dm+DfVN46s7fkA?@Pt#1E~aUmr7B!REBm)0|ovM%Dw|m%HsTgZLy%S zg`eFRW3OBRu|x#!z>{`zfT-xYce{7DvbVeL-W_*{Ekq3__7c$;8zR<3W9%gw6Fc_a z#n>e#8jUUfzfYNYXWn-f^YmzgVS;YZGG)6J(;dtLsP1&&{WCHnVKnf<(dn*o?NlF z3Jg3ELp;Lhj^2EK4rp&*B?soQg*>7q&{9vilB-s8S(8{DSEuUnfru4I`CYb6IGSz33ObMCllQPvOWU5cfRG*NkJ}FZ} zLZ*hKObrQ{8j>n)P^y?f^HF`7-h8QO!sGgi9c{UCrjqHU2;)j!+!p>kE{juRX*V$hR+)abF^)u#7^g8jD3D0OBmBv>%zHRadwiNP2={ zV}_QhWC-4tsu6Hfrfkva#U3X#y07P5|pyZucCF##It_P0Z*cVdVtqFk(m*xybJ zRu_~Y6N(8qdB|j<1YXSTZzm~Uzzu=xP6MJldh!V5Whjs+2Ggs~aG8-Qd94#zp9JH!KBGVaAw2_h|q-|`u-OgbX_CR56sY-#fBv4Ws50MzPINRo+D@wozN@!I5ZiGl1x$+WaI9vd6B zF(e_E6x`O+aCp`|f7sQ^pVVW_4Xlk;UuG}T1LW=pZ!n<;kW zXy$YcP8V;ju4m7C31U}}sl^%Z+b1aemSwd^yrm2(|= z=q+<2D`1*bDoue6P2*-Fl_u14*CaRt;j$Q;DHLcr9zCfkMv?g9Ix&)rnS`2XQ`dZx5L zOmtr3s-69|8XP9uR~<47xFVi7Lyer=UT*WrixjqVh!+Ue$9*S8G!7x3EVdsBQ8h&> zI-!;-1%%?5yH+zLRU%7TvCTqktxGOpWa#?b((>YB~!OWmNx2>G1RJF!+J`7N- z5eHkP&vL`dUnsD%U|godw!$>>{wqGIlvVCAg*@pmX6hY1dHlp?Oa$LEK9tLysB{%D z3HXy#jOg}aovTf}$T?&X={?lz;O8-*arT&S@vwfNx)As zt|XYK;|hJ%ZaCY@Idw8}c?|V?I=Pk#3wx>1?=B_ocu^)asYqm}MDz%yDWR{@l_SrX z4^J}7vV~B0SIB0BAYuv;)%q8Gs#Ido(=U)$5t`UEF*HK}k5I=Gj!gGcplVmd@GQpl01EfsKGD#gmi zzF0M-Oit)vni*5;vb6}EH3;>!V$|ChY}YpB%Dvs>f8ZZnDhg2(vwyG^x?;Wx>w6pw z?F=c5Q?UwVs;UgCf0*`|gdZ&j+Y-S^xt>yGa7?CxIkqxpa4IZz-mtQY`xq#or1Op` z4UC>T1~CFt{}^Osw0`B#xut60?ElIm^%>)){!RPj`)7(-j3bsq`YX+pVN~>}N{r|> z*F>4=IklFmlK}>PK1*BaO47bBN%_P{nb|of=Hyawh4duROFJ0d z1g}Ny7jlhQ30T>^nuGmsa!KMEA>`yy%^sZu&4<~PJwOZslDS-!9fWn)0&~{5N~vco zEr_N~9A}Si5;;h;ZNnfd*pfE!HqV?!X_I%!p=cb3h-&ACHOvTuDT4CwR26$Gr2;b; z$CXqqW}0%Qx1*cJT_11u#t@@}BW{c$iYClBNr@B!trxo=Mi|Qx71XuGtYIg^)iwD< zV3pA!sAXrym75w_c8pVVYF9)Tp(%zmNUlO>S)|J7&UMU=4HokdYgR63fTNuvx@=DJsTz z^%MSY>+erewDeBT)+G+!$(pnPg`t*WzwSJ8?{S)5XUWhwJ{n-7?g;_ztV z4ic@wE@&4Z23_gwF#u#&n@AHuoEkMufH*amQR^*8q+O@gXFAEU=E`ejn^3EQ;3(B zI20_WM&NbFkI>K*j-XnTm#bo4w(eor#7L9sCA)yi7$3btHI>Z=Yq(u)qc{Up&Y+Mw zBd+`e$=Xl}N=t3h#1Kg{iFPHN6xBisNhn<3N1@?F#+dL`RZF8&h-P=gc+B$wnu~dx z9}X|!%IEl>s?-P~qDl}n_B;-58N=qqw+^Qu)ipN7sh!Bu!p?-`%_>+Of+U@u;}b^| zw_mJ*+6+QhJI6RuAs`{{v_X*XZ3V(=vLl$)kk!E!xn{Ycb94sIO_We4x=ZpYI!Jl= zIS~}*5txK|cqieBI%$$8&leDgD*{PplrdKeb7HMP^Knyh+5>6AV;JSjVV4(x8;oZ1 z0P4?GPO4flG7geBJnL$kC23qe64B_{=G3i@BXmZkpp%FTrbaj_H&LWbkj+#a znW*s{L6HjrsD;nlj{2L=G}+%YGBi+6ySw(cLuhaaa%fb!_a z2^dh0b$grvzJ`H7iVXvS$RQ{c8OK`8c|FaXl;(KtIld!QsoBc)I1T8qYFlf%bzt{; zi-T*1u?UgdB|r#9sjra-;o%6i^1$hb8c`Z*Eqr#93VUjTq6B(NrR-Qm= zNt#J+|9rLA90*6oHke2xNij*_AWTn&&hH?;{7yuU!6v4tqUc1@@<_twg5Ne>xVIh2 zKw-d=W2ta;TLqH$F|py`oQsh$Z8?mJ8Q^ghO|xe${!`~Fjor+UbXA#WpOx9nHZD}! zj;r7-Bss#cA+L=cLop4Zh>=k*nta067dW!;qX>=$;w1#$S|sQR#zzyS0}xRR?zq?_ zYhzczli&km`zjUoTtPYQ)f;TYZ zZzKjmQ$HSSXNVO?OQb42R@FnffT#qy4ry!MV^x#VXElxCq1eVuW(B=0gob3rG2{?y zNLHNG46%k}#Xk2z!*(H?7I~D4n^{$ii&G z=DZCPCuIg?XWMLbPwU2>NLHobDJWX1B)u4@xwMuFgI%TKl+I49M0_9}0~->lzRfdu zCrm&yr7Mngimw&5=mFO#hM_p;+-nnSM<*|YCy7ay1%VX(rP=UjS+5K72pmwgHHkB- zMoDwA_*HS2W;F|0!XuJh$s-6Wh3Tabq==yDi5fJG$U)XBqR6fJfgE|Q-6#fgdqdHJ zrbAL{+JJ4n`EuDgD^QH-4pDZP1$n`U5LJ!c5-8+~q>x(@g{+X|z!oXBBRZ?HEEc9$ z(1}v+$Z>B|4K}DmLZM!dc9+P`LWjPh2Z#6&Y(*V15=le78nPq9ZnPu_;+RJL#wli_ zC605q#EB!x-7b!mSYGjHEs{|jCe=TIk@6G=N###q#3<{q%n>?ffl`HO$n1y$b+1b* zm6DM9jInFI22nFsC`oV~^F@iIYJU0fz;AEB%4E@GwExlOVnRPUY(v#!^`V+ROz4!6;S-L7h8 z8Arqz#nBT)ay|KNbX%3jCs!zEHOd5ux0Hi8YR&SAo87ucXr#*tK( zRms+7GhsirwbPW`;K#OBlp*`Et>vWTMn5)2i6={=AKTh88e1ogSR|b;f@qY1y%+9w zqS)Z@s$K3MjVY8mX462BJ!aeM;AX*1l3tv=iWGWPO)N#F{$2(iY)Dy0Jr7-jMfo@; zMFeUVrnAYYRxsj{Whwzz1@}g5OR=NShpQ#rLu4GXCaYIwOeg;y%yenFb(D1@Ct}Kk z(@HnlNXYY5Sh~PD6W!@GM@%%x{$Zr1 zL33oqQXMg*JuG8_!bdS>XnSJG5ddwfP;`%BMm{$OIiUtzw}-faeUSHZz{-5O#3D#D zO5*SfaOuhk3K=Kl*-j9E!xxi)iNB?qfPuDV`l`7Q0d9!Co**Ui4)GLZ?+GVT!7$J9 zGd0Fp6!Du%QG{o=V1cY_zE+7P6PGRY+MM*z07cgy>K81(^Fp1(2~ac+wV8};J-rkG zW~if>vIyv0%d1Cx{+n)hPWh)^}mI;YvwjBbKl!Q3m%@cYRfF8t_ zSPV%p>8=LiMin8g93@8uj8kPk(A0^+%}8r^g*m=yBHYNa7xvGu=h@c9or2ZLwZaTRy${L+_Og~P<0^_HJvMA78?6)N~4Hl-F z28^hrvtl`-Q()L)O~&@=$@s2P8Kvsfw>u!UyQ#GSc9-bn?ZQr$E^KmWsd|+js1dX4 z6C|l9A)2l?L6RTMucKIgapDT2`gz8pnwn6F+?sc52G=IJH~E-m>w%h^kA)bu_j-(G zyt`n1AZxpC=`jYfwid9*7|7agM7oS-AJWGHg)x@1$7rh70|QyxeMOg%p5aPXc_Uup z3ZbETYn7Zt9kphuRX zS+bVOhNVDm(2Fg_uw*TP*XUBoafnj!Fp(n;CD=qBj}1_QP2}>}JlR^^>?jbWptUM- zDd3RYWLq`C=z2P93B(;iuqbi^YzCrVHbRNhU&chH-#+ zDrRA@EcS3pgv4dB?$n4SE{k=kMl5kz>|#MCwozE8wNN8Qr{F~Wv#2{QS;kP!QdDn~gqtUPA|V*cwGUTC_SQ_bYGxoojBl;1LAiHN zl_S~Ulqnr}>=iPM261#t^9#tPLlSPCJgt()2MY?hYNs$dNM5r`K1}NoqE~1I<}ReJ zcCPbrm0T{FH7$%Z)`jBqA_p}c0=#Yl4zmk8+<0~o#j24(l4xSKRNeHXIFoa8lHl}m z7W-OBJejm4f&#dcw^Kx?EHyZca5c!1fqNiP7{yzrW#A=PkcRdUrXy9BXJyO=7-2AR zn|h4eb$l$us6EPKG{y5k9ST0CDN6C!tpFob^Y%f_$E^rhC@i>-c}YsKvBQ>RG_B;t z4&`D><1uP!d@PVPmas(DWXdGLfQ)3yBpCxT(zafbF(4z^JPAfDZ2>IA7?6?HxMb{r zjI`1v83QuXdY52?H5|Y~i~$+R)JVn-$Vgk1NydPTWPUJX^Z1Ffsh+`eQnZljZi6`I z5>#iyLO5s%=cyz7CQrl^9czoJJa8gOMHD%5DX7OR z5RX}2J)Lm;rmK>4ohBcgF{o7S69!~Tt0&PJx2Sq5%-KpWvXiZQVb+0-Gzv*cWz$F? z-o%uZ)oVR|l>|-74J@n%G8=0Kwa?BdK*u=2!xvTz6ua0WFv>Dp+F!!ci-j1HxNlO| zWKxWs{j5(CB9$%?CnD*MS|=k*%h!&Ux6uMuZXy{2L?b8K+sRYTuS$MC#Y)quS=JyM zi9n7WE0t7Zpb-Q5qnNYe%N5>f^vNf@{^4Tr7k*6L@ar$SLz~1*HWZuY2fLZ;u^PAr zcY|r#zJlvz)g)ZdsUy*4CT7}m1!3f$f(n5718>JR(+f_MGL_l6iomU)S4-qtZOE27;2_(7@{o7gI?7}Nyi9L zk`ckA7K&tOD~jhz;Z}f~o{PI_DQ>a}L@}fl#4-Ztev4@2IMLIKm6yFH(o2(Moj3h` z8ZwQ1B#Is5eB`4=jnX?Ewr&_Qcn->%!?}Nq-k#rhx zqD{50#Yi-m$ov+R=~eO!flt%6^GVLh6%*H4n0ZMsgVpU5CS`SPX}d)WiS>9{Ms|87 z_>3zoVvEXe7bs^1GBT1q6XoWh0bbNiHpvS#kOI&^3Vw~4+~SWt*)oI~0_oZk;x0lW zc0`0HvNknP2piLh=XAvHBkSg?&C-dA!A*LkPjb4YoGXnz@a1!>)=AoCwC1|y=j_5< zZbj5)a~iuglT&Rj6D(UCVhlO)&feG(CaF>B9a^Anl2nZe?;W?Cm>80ik2y20oPQlx>8tkk z^%!2X^#C1zYN7W}^Sy&{+#Y_))}(aCDG64OgJy!m4>muedZsL#ZR$HQge2fp3(EoyinFnxT~YbnLtuR>}XN}(w}iI~QZ zm~^2wlP;o}UTGj&0Q{7kCBb2eW#_CA4pS^UXTdN`o-XZyMkn$>qYW7_Ibf3%J6sc_ zSQ%_$W)LSL#L8nM#4FLA?)=I$8lO=HO%?`^m)hW_;La$H78eKf79GaP=u^*vyC5;m zS&fn+$2oL9Gm_UJn*!7zd*yJl*Tki=YQ&`nmR88XuPiwn!G*C=yEkW2gF^?-3Rtx3 ztcc@#6TvrpzE4=N{13_W{SWEbQBYgtDx8$xCs6f&kqAt|>|BL`#c(^F=l7~b<>4ad z!_8|7j>LiFoCw0GEv|mVI&H@|s`U_qwVLB-nAtQ+jN4X>kJkqUf%iQmb$w6}c;JJ~ zVL@m&Kg8Y;6a+5zAahUiuVL|BZK#09DD2VN%e)XA=6i34;hXslHte=X#BovZT ziF93YMdTV{+nYwUfk_9MPTj7;qL8<^yO>!d zT+FNtirKZ*s^STP?Kp9Y_M8N)O%%tq6DMGw-JM*dRy2ZHqRqk>gJWei+@`qkCrKq~ zN0H~94R;H~p*3f_a^nh_t{PWzFr~_j%M)n90@_|^{DU@ zMVH77i+ArwJ02K08F81}-fmzsZR&F;k`hPIYe9lUPBZn4afhNSRcdW3n|#dK!^CCh zLC9Rcb*XS9s}{<~?MEiPRAig|s6IZ?D0?EkIUR-`&BffkwK%R}TQm);^HW1o91U2( z3~O|d$$7^%s>0yrr*y1{$vyLwNQH-#b6zUJ5ZH)~l1}6wk-S_Zm@P|sX3TtFbp<4| zi>tb^+6%fvIUp~VNp#lCRzNp%j<;=PKuz8Twey&;&f7L<$a-c=TNl#cdxjznMkgQV znn+hb=o4lIlSYydOD&3`Js_Eu8DSnJlz~}-J;qS7@f4u|aA{(RS~w=N!DC5VSlKa1 zJxPpsaokAb;3la+6hktxxB|(8AWac_$XGyk(NqOLp^@w1x!5e5_g_kuF9cHmiHvZtnf*SS>&+F=ED}Xw^dC!!>`x{7 ze(#8Ej$69NINX}@J|ArfYVx`3sH+%QJrlL<;WmP?8IAc6g>~F10Mkk`jlwXa)6YGyuaQjDV^W@BG^yw<$*(O|lfap^HPgygl>qR$#kH>xO) z8J|a%>hjT0Zq}dTvsQx%;4Vif-JobSnuxxc97w}k9ns zQyxXN2}#g0I;q4cCJCFkB;h89<4*}$8FQIf(<5a~;&aff9Rj&^@7*LFjhETzgi3U7 zLj$tb@GA$3_$fNO$fBEg+ZpcTq#}W*z~BuULFIWbd6GtyZf^|<5U9HOLwUk(YuVH# z=+leUd{+@)n;e9S>+EB>xOS12s+*X|^%h`HPX^Uw>+di$EhajVz~a$P%n@ABqK19 zs#{xywp1d0Jq8+GJqDXYmhuj9jA-IuxbQccg>25~S7*CnJS##fxj@M^Iq(jJV+8Ve zG<#L(pYaXI=(L2#$;!8Lm=G~n2-&{sOgK>lOLYbcKiX)G7R%wpufbu`s6kfUx)xQ( zUJbIYA+@L`G93emB$kHZIX(g{tMiPgVRRsVSyb^#9?#e0`*Y5xHVwsl)l)#@5QiDm zC*OLWJOej$k}$U-)3_1)p>N{5=r&eFo|>tmpGhCIN~`^(fzvSNg9fH0s1ND$mLeNF zP1-u3+e#Q75+~&QiW=I5Cyr_b#$X-DaWu@VT_MJ73KE00>EmcPWv!kVvswFNa9_BD zR^5oRhb6IkX`DSQi&aE?c25%#Td6JAlPPzXDmmNccq26q;e4w?wu|%AG}3l>49Sp9 zW3GU^4GUxj*EW?!V(>FcJ|wfXtnw6?$JzZb5kjJck!R zof&vs4i7%*OHNV@vQ^j*jun%ZC_!Zv@)-GCH_tO{_UPhmbWJCZ1W%iLX8wO;gfRX~ zSR$6n7$QkE>DT2W>yGq**l}V9a@KakWmateX)NvGh{|XwDWdCNG(qyr*NO zAR$^bUif{fK&(V^HVSeVl~I!Cw&K;SMJ0C-(`1kV(d_7O?Mn}LGf8rXSw~mQmn>nv z%QuNdGU{%K67@70(h5Zb+6VBolN$%$crI12^31iFc-=$%{ua`n>L_@MxUDa)MANRC zTQa7j#5u7YG?oJ0-4#Jl+m5rGKI9U@ohgc!B&%-tK2oYhX>Yo*A_+y9yGszEj>Uo1 ztwzGsCn~YepyGDlpgl)di>fUrM|9;vkR@t?EH&rsR<$ zG2T2rssxs-EoTnR^9*XS0s1Pi^hAT%uIM>i@Wzt}ttKKJB6h9CiEiC{ggR9OVxXU# zypB*GV#SR(FK1zG2(jYYb%52JEAa%tQxpMKzw+>9^`bh~Xj~H0gWqy@HbB+K!ra0)5A;?t9emun zRK$5hNeHEA8|-N>6>Q(}>dm4sY5FBM-Kx?yz~HkKK1&_I)f$Q@ycnCS(24XsYAj8U zmPl7?E0Ln&v9uJem5O#Km0GUU&?}2h<>7HPsS{}qt2RefB9)9G>}l!D^0JpNA}%H6285tigUf4#8{KhKAI$X$xxpMR9Z?K&B1kn%&EZq>)i4cg+0vY; zxei>gr)%;OL-kv{J1SvTf2QRsJ@_IZ7SQoin)X>Tw&DwilS<+?B=1(yU3x^GG-Fw^$6BM!X$Uun~3jMNrc!^ z7ZJ>sqPB5FaM!^I_13}&4q8qTIksFz1nD`6yh#}lwM)ECEtAGeBPputs7q99M7Ifq zLOP8^twrq@a*bFCSlN@xcYRY+X-=`q>a!%7>uNq0_gd1TtV*`#DxIu>nv}(xoPcE& zO~B9@6Bs(kxO}DB8xgW5agZjX?}RCY>KPDvmE4JA`T2&kRv^-{cnkd0WE+R#xM`t+ z^tB!G^c(I7H3*;PP&;?R{!`IhO}X~Iu1R=|m>y`(6bkK`j@fazRP3#k3NcicHGq)U zO=M!JOF;3#^9@rMXzi^S%;!*_eMH7p08W@MnIef+9DDPCS|1aVl0h!x2;;|#ov?Xn z)zD${A$`Y9hLCPtKpiX3$OOebE&)nX{;&0;X{**ka!~RfIHcH!z)HJ4{@=H*k6N)&c*^C z#20LYX?hutgk{H<`$(}9XyW+R>G8|*5ry>VN&&ANM3B3c=1MLGi|34_1y>@*9G4NH z7C*AhmF&>#WG6g)YA%>(ke{WRRx-}}rhIRAu7Wn9d65~oMjeGow~febgg#mId93cV zLN2a%`<+aa5-%kGTXGRACKK)iqM>kXK)NCaK~LG?2rX473FGBbikFf{o0OTIbK*@d z;gF3u$fOKDIYILh4n_7Dyy&&GFV43X5#1c)Eun&iQDJtMROVyAb}H#VW-P^r3o@fc zm%faUAqPXXmy>Y9Z8<(sCq0Oa$b5l6q~Ni$d&h~S+zj*ObOB`XO7IEn@?kwwuIlJ) zwqiOk^>2f-oGu{oYq2}2qvvTN`(sJWRX8PpVCj-u^o+Dr9YGc0RQNYlRWf&(9hiYx z$7agpQemLh1Y2`{1p$+0nLcvYTFK$DL(I!#@)^?-^iW1WeKIyD`*OC$Wf~zLMGXe& z5`kHpdIPS9`SUe_uv{zrvPPDR;ykk90POM9uvJL3;Sn~|NfkD3M=s)vCZjk-$ChM? z6lTn3$vBMmnlT%rsDm1u5t)2v%;pbtc!=HVVU*_L8MA$?xj#c65)@&PG=9so2vMcV zU<=anE=?z8w(i{Y!YNr)(?G__1OQsTPRYxKob2fsg4koqC)22Nx|^#273*48jL9J6 z$`i52<%{`hcT}5jw>eZ)1cx+poFvSlRi)aMq*+ykkwefZc{VZY7@J^BL3%nT^2%$= zo3(WtBx^B)v_|P;HE5D9GmxURummZl}~0Z4Eidg(pXkWL}h4&yGKxQyOEj0B(Dqk(fU>p&&U->l&@3P z%2BRSx>WYe+MyB?HbL~njZ=MrlhhSNP6+MCcEm>Ws%k?Ua$J%KirP~vMp^4vy^h+) zfjyxNE?RezzgGJ7;q(a(rH`|$r0yruXFL?4AQIy zafx7R(l9zfgG#rUEYy~PuRC5N1%i+|Ove-&;!k!#awHS^_ z4ql}iy1CKyx5VW@qeE!y7J~6F3(1Cr$nz$aVD>212}=wMFxCec>oq$swh9`<0x7EC z9-}FMxIr~36Oc4~ueY+qL1B#*G79=+Et(;lQkk%35e5C&S`0%rC6IMflQsc~DIrbP z1YD9PDI`BZQ46)zguy^=3W9mL8z{-amXlC4@7h+8$4>LyqX(Hvco#cPNn;G3Ir^vOh$ka%L7azxK%VO8@d z)2n9TbbK?3G{9Wr3^r$hUXq9cjEuAdPUamP)7{hHMXF+Bh|l42DjtOq9z-5&B1BG* z+B}?u&O6x5$J09Xbb~wu!}XVh`BHcY4s!EHV3XW@znfvURHt;{Lycr|vckr=m4fcr05u{p)*Vv0Voe>3a7^AnFR~l5O zN{0$`(Wv?aWoM2_OgT%HtcNsZs@-govkaQx#9XmU%dE(x9J*r%oAxfFz+Qs31$-GT z>>@?nEDF~F{N~YkpE+?62SOILSO0YjCZW`Kz zv(fyPCPpYEsAw?5wOvB(Y($749lS24 zwv-1&Y_tNQ}q{Di-xif6hse-AL2Ab471b3dT)v1(Wz50c;`>A1C7+ zIMEu?6E&zHsZ+k6#Rr#ZPsr&?!TfeCCzKAS69JIDgU zZ-SAYA0e6|9M3py#_o-#zD$8;4^A5HSWDouK8ou749rfwnF^*GjHn=m!Dv60gXo3r z_}X)Ydya=p>FY&j@}OwA)PSV`CQZvO)t7{Y9Ui|7Z3V>SK(%eXe`n_DVcoq6{JYnGj;eDz? z=~ig-0P9`-Ii546Vd5libTms$_3?T#t%+T^iibIhvn_kXV7>|o`7myZ(&O|C+me$< zp`A5>L;GSiA~+I+VmV|lFW)0XB6AfaVW}@wr7fQm76#hPqywhVK&C=z@U|7=cq^WA z#Qi!`=MLF-c4`lE=$x$Urj66wq#c^1JEelXsj+x;v(#e-dF-Rz4NXZxbgx2b-V^T{ z!|9@G{O~a?jsbw>R#pUKNoowYTqcfpipz6m8xHRtW}JhpFwT30>4dqA?3Vh!<>Ya3 z8gj7(=SJxeJ|k=n*)`4F3=k6fk@R%B7!ZRTWrX^hjtF|ipBY290+@h-ofHCKLIhVx z&^1WjS8~2{T8TKYa`AycS%nisO+lz6bAp2t6@w)~lW1fFCrDbZz=y<{68MxjajV4fJ$tEG4|DrlOBk)=QXVF4>t-~emVF&P?!43hd02@{gTeqQ}eW@1EO2;(Q`UPq3>kZ%kp; ztc?RQ&R(sR4!!Eb8BEO`1ilW{TH5lWfUM@s+d$TSGEaoM=t5B};02%dQ{|$xLxzHIbTj3pb`| zN)JnBY8uvKOJ<4_smVtE)6rK3u4yFWqM>Ck!V2%H3OIfs;rv= zV>Dlp`$e;oRJ9s|G-vKg#B=6Hho-2T4QK5FlCPbF(qK-6}cZJxi$YaZ&0K)3P)4Zmb4G*Mj~ zo4xAdZdyukSY4{ba)`0Uf%4-JH7$T{8WHNeN+=0qP&?6OH#PP(8_Vb>X~$;1U+CVe zga&eB2<9SQ4}>79Ex?3@9WU$w2#hk#8AVGtVe|NgLlpEz4~D(~t4^cE ziB*%_0G)M}u3%=D0Lf=}islpCsm`aMj{J{Y<@>#CKsO^Vj#J$_iGfp&-C*kjA00;p zRiFapy;$BH+Qx@+LUbop8p`}ufP+~(RHkQ5!72Q>Qa>JCf(sKz;XCuDszVHR8ZgPb zOwQX&nuqo%n|>lX`DF8jsCiKrm0l0AU1|XRDSG9{hIoSJ5PfjBk$y#UHih73G5^q= zPcwfEJvvEs1NA#2nR`)62e zJ@rTNWDPMt2;n|W4^2tHd9aQE`63qmk~!8m`Wc~5W6=*}hBMR7FA@r%Z4@R|@H!5i z>!3iiw7CJIpqqI_H>~t=*jmm~7NAKDYQR>IhE=X86bVEampp=!h-ISc@zemXaKzSJ zso*|o>9IN6oj?#hZUd4wMcJ?m;LSwGv<>tG&j9InIoq7%iH@ zI%`wziPnJo5ltbm>O(t^GC=7F@))?}u(~@4tr}U=gi~{! zxHFFXcWf#uS6i9hHnJ;~>Bn){bmJIqdT|^!?9(z`GVzO!t9haxXJGa%;b|!H4`2;b zLKwy7jbkR*4IGUVvqBV2njtoCeg2Exai(QGLqs{F_YB?KmB{`c?r~AoQK8ZK0wnIn z9?7tl2P1aDP&pBlNIXn6>3dY0oOCTxk*Gt3lB~gDlC43ezJfy4qH1;2AXCq&9XXt{ zM3E&>SDUu!lWAETUnsR_3Zix63Aj?F9fS~`t$}ye!1FcmY7M-vR>pm`QtH#B=%63F zq`AT@ST0}=CI{JAoLE#nQSzRe^JpgL1l%8HS9#*>sCllrI35-VFQf@OciDzc87U1~ zn=#O3ZR}LTArvJ^^rH5)OE&dxHrT!}Xpq^H$ueViMdS}l6GxRfUN`wzLBll|=UQQ6 z$tqY;qDk%*CvNJ>R7$u&$y!SA#Ve?Wka4zJ(qT}ul3$O9sK_p^(Mb|wd~dw(&oC}x zjgmw;#Up%w7XIK^K_Ludtt1V-hKz=+(Ib(A-Lxh-9KBYX#F9y})krSh731kd^h5&j z7Le+Q5{T0i37CqCM>KdWLSwjBHtIBFGOo#%NKW!e#y7Y|fSpDv>HgRkAfxr5mdU9( z@R`73g=v{9HRH}dey~HXp=lz~=-B~!AOaSd&{^U{WRs{{ICZY`qiCb2 zj-gVE$N>V5jzC|~Gs<*au2j@0ZE#EkB1rw2TGM)wOi+SmA&2(^!S6 zM4FN*hoq#>0Jig647LbW+!q^c^*|)7fK8OI;`v|X&fZ-}IgV<515MEN!E7>e#|MC9a^nc~C$4$a0j2&8XG zfh>HQmy1u*jO=*=zi`~06rvX>6FJ$Lln1L!bj|&+G)&FQ9OO_nL+#K>f_7Jj;H9VS z!YdMvpZhHnM{TL%1TL2a;bF$wr-JdxB_{FFKWxw_0UI_U7#)w{>GZ0ovPQ|r(rB7F zwt&g9Dc7Ip7mR34nMuWv{V+PB#*hT<$!)>lSN0>CbJ@ae;-X(;IpUTg$8*lUdB>?t z=iU^{E;{?|CKW&Yq8U(E9z$-W91U#&RUPQ;glD;TuxYGi#g!)$YA*Km;0+upf|gXV z>bOd&XLKyKp-Ecop`n9PZWRy<9}eMp#7mi*K$k;Z9HWFt@aR$r>g52OmmrXzUlqQn z4b8QB@G(dO!SHH17`LD#fJV@+;UvHwP$*3HDFP%qu9EY@wy1iZt#*k$1{H;RlY1)7 zjm=`#BI>}aMYdA$$dn?Y?>jZ`W2ADKis0AC6P#{_PNHo%?xpM8v=T?M2~VoxdN_8B zC$WNx-01;kx!0x`w=C;BRWLgs?=r~zSHFtb!m}L6O!ft$K_W)bV31p$A%MxID6zVu$|y^1Se`Pe9BE7{J(;MOE{F;$IV8BCaV9WL zRfp{&n@m)cbOs-E#6w`@7*6ML3zC0@7^^f%rn@SozH*##T1&c?3?TV3AgE93b0*M! z&}{HORC#BNItN2ugQj!U`n20RL6!tZHdpTLb}EEoWkuhWJk!0TyI48Gtx2(htx1G% zYceI)nuNKn$>Dfw#=$fyWp*wbD?=5tsy75EnhT=6Gt$ek(4xq!L#F#_S@7Z!wTm=F zt^y8;7G=YE`dWbwNegmTTqS8zxk7j!t@2EmJR{vSGYxY(S1FZ~NWFnN@VZBuvolDR zR?u`iFQHsKL*Op%3WYp)Hqn*Q@bP3s1f4uQTqY@y`uXE}hDP@}p_WNy8Blw$^e1;L zA>$SHZqT{1c+{BGkRj4YXXqSO8aoA1MQIDk3#FEwo2|q*&KbjOou)l$+mskHsTs{v z+ghefPN(Y9_4FrQhrb)}rxAaKr|Q$g@TV@-fPWkK-+KJpkZMG@5#dI}YUFSu{vD1# zBT_t}r`#F6S7#%w0tnE<_g`u57&miTU5e)Q6oynWo5mM0dNKoP>}tZ|PZ>`1<%XuQ zc0O|8(bHTwdMGu`wVuk-oAha|1!;(m0uGp^tGP1lqTXC8i(8J`DXM9fA>|HRryS`_ zwx1t7^%%56;MEX*y}Fv}>L{i$>0$m%Q74k0>25rqq~kG&raS47lN$qlzivbf7}1#G zAt47c(l~iR+YVK!?KBq!#(AFR%2W|I;?rHZB5DHHo^z>^d3Ps$R9~(#n9h+Mk;3jC zFALamO!t(aUZU2^`651Ro9^N7-=;8u(nBrjc0PieKBRHju#}{rOKz$CNXjo!5mj71 zpckvLY_-$p{?f?HHlbDvzJAh^r!Lt?BRyRzS5r#CUQwZhRJkV8xdB>k@)%$;3aIh; z!oOjV83&747E3CWXG}3!LxUz!?8p}=5gfgVqp+p>axoe$$~bSVy)lJFrc%vCvTJ%J zvo(s?fU>!4%5?EAJdlC%wBwOqmc-!tZ)2+0?De7Hb6NUSLPHw6*12jLdCR9`0z8c= zEx%R^W;%2;AL~Vx=L%Sm(ULxe4ro#hU|Pk!ztrf-O;e||VC2~ajMojUnhkXsP{&Vf zPGbPkVyI$!9lsq8Ob>8|3VLZ(9tW2Bs+yt|36mZKLPb_ebJBS42BQ0&%T}Km;50*I z2YTyj5gKX{hFgLxDZP1EGScy-TInPjx{CBJG3QdFTU)8fnZ5y;JxB$mj+5#rSLw>J<{?^>&Z?EJ_H<)?eTpiz9iO7c2rA<`WFb?*VBuMmW_?>9^-bt!a7Ux` z#WDt%kx!Jv^qBEeM~}pR7N^;mWw(e|MiX5Yq^MVSW1ceIPnIm5CbUbs%a}r@FXU)M zQunQ<20Pk2DqK3!YE#W^^}KjM*=)z*&fY;FSe61to|6q5z0rc0fshqmM1KSqYO zDrP%=Zr^r&S)Mv^1UVY*+DcKs&`Gs}UfDKnsO1*S3?%MC#lqv02j$(z*REYY! z%m`X^k=9vQF=60LHmbQ_>?-=&i!4YOK4ffV_`bZi>`K5aW@&B+=@UY+OPVflI<=&7 z#cp1Y)0hUa#A9%oRRTvC@iqdfnPQh%LSHdY9X+C8t><^F(T6Z2;cwJMk*WtH(U5qS zg=#0WXM}5qO#s{sr8yBU(@Z=p+AXWXuEqg#6XN5&L|NKhl6EB*Vk5CDSHfb5^-3~o zOm*dY$*ghKZH7$esrI$2&fHZ6D_}F$C{?X zN}>yNRWug+e56jotj5H^daz>b=d;vLAS3?Gq)2hl&IVFfk!r;SW#WNdi~Bmrm0x&K zeTc@e{4~QZrUS)wqIxV-73dwXm33vHkwmtA8HX-udFD=xnLpoA)q=QlaatRwO!tG_ zDiEN`=eSaM-fpl93tOqP6E3VY>!Sdxy}IgH+rqRU*A<=fGg(&jBjKtIVd^IrgRLeW zVX%O@GyVA7t5Vqk@x2DT!+;tH81Aa&nURIXhOcXIeNhLHAT&8v3PE<2K-j%yAXLeA zvWhrmE%r6SNF9XkhsCl)5B(Sou7k&pwiM3|POno~91r~^D8P!uHANriIZ`=o8ALMJ zEb{3F6GLZTQ}5dN8X5f;K964X8N+Typ9mloWy@!Xj@oJ_9Gc#syzqj>X`u>$6}$S# z$gYDrPFZ?jWBo8%rIUnw5pPmuMI;@3ZhB0o%KZ>EEZ%}q#1QVG!6Brp*~7R zVyLzv?k!dyV84@?meDM^BwBm9H`1S6LZ!fx<`> zlU2^<&RC^Xt)dz{Fk9-4bY6HJ$!N;pxOoZts^xqnrIN&&wkgPJZ3Gb;#S(k+#|y z5!zsmYlzTuqv$2He5H(bqU)VbD6+&#FG{y#O}BcrXgMPq+hK_rF2QK&qamiK_%%$x z8#M|VT}FdC8a32ASf+`lGhJ6Fe_+U&q?raE(J=j=NygBWIcpAtL7`F7)aa>`(pbF< z`M7$*nB=OSh7_7QGm>W_bR}2k5m$*aCkQdy%`|jhu}JRk0(4+f^Dv#j#3yTM^t6_l zX{^7rWXlR&wY|X^o6)c%kf!#WsRETmyi6!2r$o9ol7@9%>=zxTr%cNq{g#F`nl}6_ zdF( zE2-LT@U&&&WWq@t*k#p@42&LU2oZK9cVO3J;`&JIJ=0BGNpO5I3oomYSCX;hG|2uY z?ii|1@Umoluca;-oop@1SdI)Q7y#W+sk#U;k1@ELhe!l^B1(nYhQ*^+kuxGKrUQt~ z9;0SE%41{=!TN!^&z2M!H`W0!?h-O?2qU+E{=`(yw=^|qnusO04JNKtGyJ?zx)U}F zdtS{nf$0+(Ob;513`5wpH1+UWCLUkzPU-_L!`Rm>6;b`1dRyfDa8^QE(oqI@W=kff zBrXvHWXM9RKCP4@fHb4#$FQf_#p^tZZKf|r94BqJ2gVGybbF};A4`$liWorBw~f2b zb5LnOy=!V9T0aU5JK7nwoirXsUnK9IjAP$$gYQyb35GNnROpuYF+eWOUijT0m2HS} zf2FrW_H!$I7{=|hDca4|y;)h_wLz-1V1dfr8N1N5dZpOjr@t_(!ifj@(QBb`sMnqh4rjuO=&b+Z@S7PlvWl3HPNgPj78gnl zJ+1>I1hz9e2>!AutcZye?LBjm8{OrF?>tg5Ttc;B1%z}JN!q;0x`di^fx0@`Jl1L(cR)--OphNswrxsk z{M6=2%}ocVWr4<^sX)i#ttdI@VrHoQp+vu6BvaPW8gt&<59iR@q21?TBw&*Q|R{O?<@;wH@0t;ynUY zQ`vYWjhTlaeH^kr1z$NGK=M#26&(nWZBLwXN#Q+3{u(Y#PNdk2g^0NVZe!AI=xOK* zdlAWCNM#D;?hI+F#z&5ADc)$O{yLsTncc0^0qe4Y6uyM20YwiuR|2BzU3I z)gqJ!svYxLVAI%!=r|HWY|vJrvtbtl#)?>%FeXKZ=DNj919LG~HcAh)4xvH;qg@a< zB_%8dA7(E)Q)8?^)63ZW>+dVf&fth39SBP~JG*vA&ei=p+o@$~p7VCV@Uad|Y3BH! zT8r$&N_E0qv^(*3QnS6omd28_mFgp#Qjx|40zU!Qj*Y7g3ZLvCv~5^o9ljmPbGa-R zyn7h5P>pObPw|Zq+6U>$lVeEC18XZ;sVt(omvQ*Dw;TSaE;%h^2OST|C|YFL%7&g& zhSRa0Xb0Q1e`9-nDOrXiLsz^xMl+LbADQ*VxTTWulr{ z7xRLY2t9{~t5CgEFUE6e3`N$q>8KleiyjS(j7A!Oc#}%cQX#~53Seq>iLRj(eiy}P3%cbeyA#^YT?|{$F|=Ga!X9oB^HKS+ z7Dn7!Yjh~gBv7O?TV&pHL0OMNW63P2c^Gwp_HTRnq(o%Enx(w6RO&@b($1J`GB*-x}oh?2WrF|r_8|gGWdsm`P>RXMn;mDIMy2Rn)PGBh?oRItnD$ctd=%gdD_qvS8%YVt=-r>5~%{aQAwldSe2y z7Ar$I!esx%=v3a`iuR{?PI@9yYQGMrV%4(H8P_Il!e(9Z*&1TeaMX`a@OJ32UTS$h zyvI@_Q4_A}4i?^a#0e?mjgNluWY5}@C0Yn){i=nA6dfBwOBfe3=_#gF9N)CIk4sFr z(|B5{Zxr$Imy~)PESROHlJ#jnZ^u!M}3hL zqv-^L9cs80l8jGs%8|Fy9FaoOGHutHADHR{ff(`)6FEXF_KqDCjvvUhm2vf09`ATx zU=K81pVd0ip6KjgD54vGy0urIqBG=hY-27W>l5pS8poJ3^%ouhRa=}oXynaxoyJa` z1>DQ2*74XiV|O<#|5Y48uy4MnfTzj85B03I6yufsa04S ze8P> z>}^hV(1{W8iga+%%7wuctWjv*a3pub5p8Bgu5(O#i8ze%eg*`h zy({j|G>PCbPk5ejZWv5<=aJ59YD{y!rDG8FP2M`xBee)A!gM|kP1<2BN}2b`R&k1* z%J#!zVvmh@qqx<%RMP%@>4VIBt^vmQ>=Udh*m-hZj(oZo?1!HBn$-E;rO5IENMrL zT3Ig>=G_iaCtVya2RhX(gN2+6SUqrpj}AJ+yzZ*wzw6=PQY##`j_ilh)e4!iQ$={O zt2l=YZ%O1gjdEwp3FBjg92NJ3g!zKr>O(XV6oFF-R2*I`;?4$kRywhT1c^!Is&->7 z(3k7du!iW+8*Re!{RbZUaFq4npjfGwMaGqoUNk2F+Qg!LkZism3O8MWfdQnOFXn)R znHVt!;5m&p38IN7wv(V1b?9Ie51x3!a4J0d$F7W1cX;AAk4f`ynik_!XJ@ou;Ed%I-p9f8 zM9v;)88}HwM`wYh@xU5ylgWr;8(cPy*j^D8liL@n2>CL3y!T+EK`x<)i%YxKj23w8 z@U#t1%XH(bxophSisSA*(hh^&KE$X^@kKW70(40ex5Mz48Z%~nCMSe@rPsfIoAQHL zVRZz>a4b-m#^E$W$yl8g4{>C^%39Bxj%J}t-orF1r1W`lcIW_5&xe?)s*;*H#}8sP zHr^_3Bbk3qD!06PqG6@aQ9LsH@dlb$)l1Gk{2^3W)ogv zJo7U#VV8%T1l3tk*yrq8zgzuo!`z?kefdImR)0s`@L9b*Wu~A5 zL9ObTrI+ky9Ykj|T*_|cYjPzbJqFgu#Im zf0$qY#eZ#o*qL+hdgqaB^Zc{7yy~glf7W>WtYhz-v)xr|58SoN$IJh4)%kyUbLq^P z7wxh1_4Tj&e7jAbzh~ZOL(cu_o18Xa#Ov}okwFMjyXtBb#0{qK)2{=?p_3(ikXTIKh}6EcmG zI{nwbA2;gFdyoFAdEFaR59fx>S?ieBAN}y?g_Tpc`^)fSQ~RBN{|T$EGjZFS{;}Ep z&rQ1ay_q{qxa*OZZaU-Gmk(Qd;6AS(`{Sv1Uv}F@mrwc69=Yki*rH?kpC{)2y6Rb5 zUw-`Z2M+w~qg5yUcJ*VP`*zt~YggBA+GBeEto7&r_~|bScQp4dKj+b5o4(%uyY7Lm ziw|4#@OPIVnB8mHE{l$yy4A(K=S}|T!B0Q^;9slVvFwT|d%bqrV{ab1*B4*h{{F;U z-+J--+?3rHAJW{KUb_1`%PPZCg~QirF4T{CC*r{dd1~-FKsQJ9@-U z|H^Ot*{vHt_tH}v+|hCRvunOJY5Pn2*7$sf|9kR;V;Z+!`q~Tsy7umK7e9OLY1@^z z8+GxNzkc=Q)~8*2$dOl{u-n&_|7^Q^^|LSTJK+Z>t~vhm<;Q_a+~oIB}J;&-wfPN8j`I#q(dp*W-g@g-b;n%t;meJGz3=41{_)!4>_%JddigIe+5EF} zmzI9pbjb3b-f}?i59%J-{p5*L);jEr(^~$v<(1Fv|I#h@ob;oQMvf?N`@)@XZ+_k5 zw=9_V=EI*~`^EF`w&#|-^8Dr}PXBbt&8x3^=nj`}|MruIY}0=DR)1SK;rS)wXLStU z`l-^mAEaOSzil4*D!1>1)%UpitSJY)fAM#>ZNBW<*7F-S+^KNlk8XS5=ezEC@I@CN ze*R%^oYD7s%e0Ke7wp(xMI`h7mJ!SS5hwgLy+Na+4&-o4aT(Bg2+Jd!y zJn79pef;Y6?``zN3lFclakX^I%XL?sw#udDW3QRN>PG)uXSeOPoYm90`-vN$zU`lO z7`y6K$Gm;p+b{mNev?t{ZKu8Y(#bzM=*DF?{PWV|{(0p68}7RN)Jr~F>Aq{uzWnS1 z)_dUj%?giy@Wz<&cOF&Q_UbFrA1*jG{rU7S&pdp~_1@oU-{E6#KXu^xnYUei$KKB@ zoin~zIrf2j=lx>i4Tj`jdbn%Zv|s#o$7$!h_s$!8R2F9@|9pJ?X;-v7b=b%o&%5ue z-ESNIi^U6Ge(H}K9I@nvk-zEObM{WF-P5+tReQbh#K+(5_+90uOQ+4MKj+B#M?dgH z;Xmc$Ke=`Nu9h!{Y_|TADgQp}qx2E8R{rJiRqna{j32Hw>Z$(O-EZahNH5y%*y|@f zwD6phX8xgg^0cjn+a_%c87s#|Zo>cYlD=T6)5gpKAO z^T5;Be|*WJb1(gN)%ADF@4v&lH{I}9b>~gD%8okizh@79@V&=Iv>yMnOTXTCkMS>W zIpqFF^M!_n_aEAK$!~jJKKQ$q32h(WdHxm$?EBKar*!`7s;dt;>#Hl8r?>q3^gn)j z<~Mgt+5fd&N8aB5*S4*e&E5LO&KnMR_tke_I`Ok>=ASrp&+=mrpM3Aw!ehE=oAJX`E?uAF!Xn*VX&sX3!FF)V6 z^UBt3a?kBIs`|jlVaGiG_qkiYxp;2#jiYAI8`$~%o9BKrZ|NF;K5WlRAKh^3=T}{| z-b1fe2W~jD@#Yu*d+YD6-fFMYx4Gm`oBiy)h5O7I{=mwIuD8Xu%gUplY}xPQyBeR{ z?WLCo-gxuNE&g-j50`#3ZtO#^KYQ=EV;|VM`CJ0S8vo7Q2aY^;S?5g?P8hxIZaSv2?eM-TjIuhzbY_uu#M1Lw^A&yI`l8#(ojKaKnByWgF$-GlkJ z7PcPs&^wu}KRax*TQg@LfAE>}t{gG(Z!2GL@cj9UR^Ry#kN)X`-A-F_>GXN4T)Sic z{=a^+a$w<;Cs*05?)mRtYAx;ZTK{@Szdn4|Z$El=lXKVm>AanXq|V!=W8w01+U9Mu z(S*W%AI?1dn^U*>ddDko=|6nL8q<&5`RR@8<}F!s&#T{?`t-cYE`6sg-)iIKJI;Lg zsx7yjv&IMMHGco~l7Zg+Hh6pCOEWG!@BQBGhV0YPc=5m$=dZKbteKB)_09h0FIj#- z_f5k$U-rrWpuYSTj(t$V|kKVP)T-M7E^uLI_PJ?_+9?%3(`yM|wM zY(jm(}h|B0t=>^N}!-OhMy;p@A1?fTJ+S6uq$ z0pDEz$~qU`d-E~hPW*Vt!X=kYn*Hw0BTM(3wE8|DWdCvNC5s;X**)LAf8ynD?^1nY z+GZ>N?8>*sUiHwvhdlV*|2?&M)mg*#Tx*YMgD-5o$*FgYe`lv>&fo8eu4gvi^}{9m zAM*RY%z+agy8eorpWoo=-yFOC_HUhhL*JuY-?VJsuL?U>=I#3UKi_|H=_j3ky7{?{ z=S;osjl0&*HebBxqUUa2d+AT^KY88FGego3FL-v~-0i3D*?RsJ{qNjdf6Zs}hMjW3 zu3tXeu;CSt-+kh4|2S&M^t+$F>BINWJ>%31M?Ajtp*QwEV#!xGewkkF!z=#y^Jl-C zQ9S!c+n4t|d;XE5{`$_E6Sh0*j)~>nU%m0D1$EoM{@e|R{duotJ8n4q?7jcIYyXT} zFSuumi!Z&q=WkoT|LUXpTW{L;CnN9uUa8XrCH0L-0j~(_ef_(v|Qi+ z@KbAi^XFU79=Fb;J)>qE`{vR&I!?&1{KO&u*<{Qb`&~G5!Ou^5W#ff+9@g{4A1C~` zxY{Li`qs_8d+I&Q#+|kJj4x*`-SM@%zItT#vx}d(=82x^zgzjx_jld(@EKo}w_jz* z9Xp@@&7qt8WYXUjee=~$i(k2Q#06cWwwrm}V-Ju1y!ny;e)im^6W+LQ!O#y*T50c9 zzTB~C$ip-4e<1VSkB=OF!;ZV&``|0vUBCKErM-UExzStawLg(tz8Af6%}E!{8@}Iy8Hs^h7`VOu$&2QX z-SF`T_x$}&{=QP{LCcS*KjXa_7o=W(W82$O7dL!&;CDy;=#GPb`|ulMp1kAWpKQ?g z-}%R${qC0STim|J-&5Z{d;d9GJbwDSORu~5`G#|sUUJZ;H|=`Mk0)I<;>t&_++dd} zSN!BR*M741gF839cgpV$e`x#d&P=tQws@nKzg_c(LRatQA5R(G_K$Bq+Wpg;E*iJt z+*@ut?$c3MEx7vG;foKs@VP5?`0W<`TW@>MJKHvH^x;igKYQ7dMTfm{Koto}gzV>6yO z>Ym4bP&#JM)rb6a{Jn2}aObvr|7~*m()IUQXT1}ic;Z@-@Z?neVH`xE+)Al>`(Ra?iZ~fG2YYi!%l{s~bZI1s#*M`5^ z_|xxZv_AjEW`FGdZ2v_co>iQ8_aR$f{^NVTICk*n6MO2fS@(^>b9epnXCF;VUBAiE zeaGE4_|);sURd(GwTEv0&0Yr&KK;d|d;H`lM}Pjo@o(&N&A4Ol8#{BI-bG99U9i^W z$8B}%CevQHwDiN~W#?S{#?P*3J*4m4jrL!9=EHX!eazZ-esSOW9}WNd+uNR6_3ATT zyubaWO}AWs?`gT;<)6Rf^3*DOJ@@oFH*L0Z&%Zx?X!H-)IPBZak34YBhlj5HRmb{2 z>-f6v@%#4v<&T#gd++;GZaclQc$;m1bK-A)@@4V;6Z?N%y7g~2EZlSX_-kHYb-j0{ zAF%Jx!F^xrIPt~TE_ra%KfHO|kb{bYr~dwfpYL|fxf?yT!8;4OP8<2vbMM^Tv-`JC z?t1e&??143;LNu#{&2}k_Z~FlsGpv`-nv7VZ(2I&#xK6ww)x8GXD+Hff9t3@Gw$2} z(JMx-vEyNxCyxHdNslkv`@Sb{ZT`Po$Nyr^UgN+0`mXEWn)>1IZ|(SCmAQwHufF%E zb%y=mgpTjFTxt3$D<9hV-lbE1Jo2!*n{Rsk*PkBntKt9Ha>SS`J5N6CtRH?c`^%w6 zXMVKS@vF{0be}Um-u?V@?p$=`@kh6PedL{6emU%`gNNTe;kaWiIB|<_3acM{_*ah} zaprzk{jKr1>;5q?dz&jaId=U;|M=~bzZyLGj3@rI=nsoeobmLTv*usE*3m;QJR{S6 z!ZD+Yr|$LCo?W}VcNekMpxU;li=q8Ws+w;IN zrQ2F}o;Ulhd}-M$XD_P1yyer$Pc*#xz#Z4TwxIgfPagX7)49Eh7oBn8=x6rse!cza z?}nbZ_R3$~vd6^jZ~Lh0q8;|SY;5!9a~H1qWY0?{zyI@1mfU#UD?>BSeSP5;Pdzm= zfA(7kA9>)L<3E@;?6nX2N4|T+v^RGv9sG-l+dX*2qhF05diRePzg+zH#1VDdZ@S|K zL-!co`q+f~4tjIt-|zP9gO^SE;P9>Yy79L1{H42WaMtK;wwij^(dSP4vj5UUHf!Jc z;IR!aw_d(YX872}*Z*SO3pN;a$Fy~3Trz#Nrst}KU-bR+s^u;7KAJLo%2O}C_{jqo zzq!GM4}W;xXC?aBYXx9`-=Hh8SEXLaFfONVT@>e$QI`@x4F z9N&7~!+%+L^V{j^M=g5u{$E|U?`qe*Q60J9zuW%j2crhNzy9Hzm9BYav-2M7YkX_> zx&uyX{Nw!ncUrhh`%KqR;pWXR6}LddYOBtA92sK_g{9+MXR0jugVU`elz0TCw?(&+}ID# z{B+@$FN{hJJ^jU#=4RJ=@3N!+xaGmGT>JV{P5W=K!F5Ocbe|>bZ1u;3wz&FcpI|BqwVJM`yQthVN#E_v>Te_gul$^5%t z)z3Tj!~<9VcFrExf7SKyBZFrjdhyG1M*L&^g@2ni;n0l_-|$DfuYP62O2a;Xa=)j3 zdftei{HAZ#DW&cI`s>{nJ$dU^-~H~5O$VRp+vEOW7v8b#mSy9fI{5tmy!D@tmfZ8V z_b)s4myd4ygDck^e#`S;p3<|~&?|17-tdDX_uXZWxgUJ8-<7+3JvnpY&<}3UukvuQ zaqV+%xcAcaju^VhK9fdnI_1wd?)=uoV;22>^#f;oH8sEZ@0%U*@~3MqKVr3$Ha~F7 z6PB*@RMWRJW*sxQbk`$4eSX@+HP-&}^waiUYvS$~ZF2dJhoAAp+P}QysjJ>SXU(hM z>3{No>_6YUbIaZ4{QJwh7Vfj!%=AX*@A}g@Yo_--Y55Jm=(zBtleQkd_S~BmKUuf= z;XmH#?VBEY`Oabg+-%#9_g?tyyWd{%$-tYL!PQ?lX6hR|?=f?|g}1ERc>MBdn`HNS z@}FD0w%WvBe?IGh{om_8@s0_FO+MM{=u>V_J+<}cGyWe>*BD;c76s!pHku}lZL3LR z+in^+wrv}YZQHhO+qU2PbNX|>nLTT5t-a5=_a@AG(3%d(s-MYlupwPjrlCJw3!*;m zwst8?^KygdVbppa8DBbQMwK|#UJZE8Hg6faiBce^=Yz$;eBY&+!cQoQ{he6UYg*9pel+Ip3Z;z9dDa)FNpwwf@OSnr0<6)ExSTY|z0^4w z2nzAIaRw{rOL3oeRq(_EZZJgg0@mK;d4An?nK7%)ZwOCZsJY@0Pxq+*I&r>9W}k#msa7fa7D>+g+HOMJ>Vxn8nS zosGPKDLYEHDqUa@IS=vTlP60{{Wz)rmd=_4F*1~O5ycA1^Mds|Yucm;95DJsYEP}66)Z^d%hM9l_UYV9Qk`cJ1L_XjKcO4DSD+*@9R4Lc6>F% z+upGpJ|FhzhmBJT=8gEVK;6v?FYc|H)9urWpO}?)g5{)BW02hQZ3Ze43AIn5rzdN5 z$+qM&)&>qGNn6~lT@{zYgOkF8eQJlfGR!8@dgP<2{$r_GJQ+Hcl;DY!pS~N;eHghs z^njhrU*0v}h(w~J%Yz{CQN1I9hn%4L{GiB{rDUC&u#dpKRkaTgm0WDB-QOm~}S^Sp`gbHC0$Hx_U#uasb zs`;YwHjbDcZ`UZLmOCUK9X{&#%T>2?_FQ7&;643z9>qWMN6}*a^G4Vv8LY}xF0{x} z@@27zp0@e z+z_ouj509>S(+nQEOr{4OGokRH@hA1An*>%VsuM~Ia$b}aIi8ZiZV(TJd;M?YI~X5 z$J3R%{EOJQAp_Y zZ8W2~)={}FUUS6^qF7{;K|<9Q28Pg|_D5!oB3L&;#A$}rR z;GXYnMN&I0e~V`8#>v~IZI#)&R%JcuDL9f~DPy#n8S zaThVeZwbC=@Ws3?PNtrr>kNzdt66+djgg&^ZgIxk=96OB!}2)hbT>I79u?``2=S|C zyjZ&;WICm=%CZ$Ab!k)?pmumtSzNoJ)wsNo&}RRNpsolthfmZ)kSaK!WvzN9byz90 z3-UVUK3j^Ae1r=5IBwI=vW>bQPI{qoni2bQa@Yx zDw;vnOr7Z29~2#hLzN_0^EkNQA5^*oTswz@E+dyBk}L#Y;$&-g%c`t1Et>4#P|)1* z!Z4=z$`9Pj)ysdupMw}Dictiorz)U+YDWr|sEJy{{aW6!tMDv&r_}#GpRsjp8hiu| zE*-3l5E_1MmQul~jj__!ZZDFB!V4#7Xd;6AD_e47p3C7V7rec`ZNY+y8=lr?)e%4E z_BcFy84ZgwB|_m=6d&|1K{vWI)bB>GISp^K8{Gd}wl)&t^6M`bQED`gi7LFTBMOAr z=x&u|1+nuL#9$CV>kXvXj@PKjb40uQf=>8$&8Ssj(euWvy~5AScyoqZ3pFcZvNj=Les$eYij#pUR;pq46V=j(Ouv(`>v+b)0VC~ z47SrgjCm#Ply9qgspn{Zc=Ip+=&Y4KHCRr+bmO`TCL_Vw&?thWW4>QeO( z63W3pSdxh4uMXA!^<~%bbek^-(JlBTXgL(RP-@u!^o488(%sS=%eM243Z7;;P(*@T zp)R1azh~FXZ1{T$2C^@Vm7k2B8P&c?6BVX^GIasNOIV@H!Te#PXAUDP-;*KWFNedP<5Bb#>zzQg&e%kn3viLjw+@+kacQP0uT z>0or;^>_rPYUl`(&jucrnu7`v^E*b-tuQP*~Vn-J)V^U}W zcU>O+$?q@plgIO0>IDNy{@T`ml|SdMyq|CewXmdAOnZ*~#hV+IUAe)JD5zTOV{?{vG**rsoF&-)7>{7Fr2Vyd7^Je$ETHX{JO`i9Adqhtsi}}5gMKg zV!4)(GIedZw$ie3E+MIDb=F<;TSg%Gr^(R&FFuIIoyaqzSs@s2El{&wd+~=7Bo^1j zapdbuA4)6pp@+yiG*-;dMICVU_vd?%C$+Fy4DZeQ9MqCJ!waEDZ8WmX)S_4TvBCoL z7dswmk?Mp-@M#Z5jIin+x>3@i1A__Da~o)+C`EqOfDEReaKF^RD0PdIj*t=C+a{=f zZ)t^ZzcSio_QXNDV}9Elr!M&to|l(Q$^ek=Nk)5wET&S?JN?(|>(RdW-9snI z2z_*BI+M4m?YHR&#qSpD_c27`NCYwxBvRwToV+rY9Y34y?jIW&7(MsnE@uv@dtEZq zfT7=3s9;<8$aaqIJxGH*z^WG|NGMu#*i0dU(?nXp7{E3g*UDh4 zGUebUU9ltYvDS#T zM_8{{r=}KJf2@{1@&h(=CP^09(IHRCcuvjxQ->ZRbT*q?q*zL z7eW}E058OCayg;>iVg6f^)4pMPFmmqKO?zT(rca?1z<@*ap$NT#tI-G^vksiebWX5 zAU-nKyVc}sPbi>=YUUK){c&#!U^}X}R>NZwSPhpmu?|8{%Z1Uk8cq+kxQ;gh7ReK+ zDI8zll|CT_av-0v$DXUICp3xUL4t0*A91UwDRrW_qe zAb&Uevj6|x$*4MjH_JgNPLIvj0ly;Sm-$N2k!*Gq>g*UN=W<4mSxX+x!|XcuWoOx5uDoq}naYKz#kU zo20(Q^eCBpZ~wN&-S@QY-jkp`P9i{$XzE9mIi0Bw=v!NkV=T|)4gnnB40#Y@MsN${ zLnFaF`}TxL4DbRyC;CcO1R|?WTJ5WaEHGjC&c3e{3a)M|blv5u>h z)My?wL<>1f9lvVJx5fDKmSMmzBHyp1u6jiph}YVH01XK;F$4IEK!0Fbg8BX1A4g57 z@N0kei1Ds|oCFT`Mx(#&u%JsywE})`5VW{h*W~lSdJ?;C=O?&{z6bOV+@ilR+a#O- zeF}R%sCjQdG7!(noxPs%Y%MBktU}K7a+#Qq(|!V9Ihh^UFT(H1cH;kk1_tQy;jfgT zT}8$KKdD?Q%p`s^7=V9{80T3+3%Ug22WGk#($8eE1N;th?wiYYITSD-ehx*mre;|uwHL?2E<8LqS1i$ z!=|C*6EBgd4)8YjRiwP&c_Dy5r6N*Ii~vI?pl`p&(B4!aPXzptq{3|fqF`GA?U@zF zw=cCXw}E^>_B*k$3;TotJ_}kx!#_v$rFllJIYa>d zxM0k7!;pS3BEg_Of(gowhQ5TzHr7`P;C;pg1xzcHc!2ue!Qn;11qWe>p@RxDyXkex z&aiLpSuEQNg|XFaan`)@%kfZw7c{v)Gh`BxzS?xYPLMIk0TV7+mqLO#G%U}*#65kc4goU5g2 z2;e^HcDyVOYI6X~Y{IsmFtl_4{aue!=@ae-{RYI73_9jmrQsX2qn<@g8Dy<1mPoL# zmacIF+6&*gzvZub-vN4#i=T9>zZOXVjB4hQN+=}rub$#Y-hufz*-HTZ3(H@nJ=29c z1oS5;J~bm3GG_q)IBx3ZI94MDV8U7#1#sByb0EIwb_br1HTJ*yu8k0f2NBd%0qD!m z^yBtU?JNL&26F|>N00&-fIHR+!veT_9gDuWNMxBt)T}<^3{1#HZ~;7skZ8T_0^b_o z_k!O5-%?jF4Ad_w`RrqFIy4kOKV-ve{j2iy8o*|w5YhTbGN3^Ja&D0|a~!Ut0lyGL zXB{l{UO zy4-fT@Vf^#%p1aT#E15F!7lf_%NQ^|vX(nLQT5B6K)goyAGR0_ZzDjx|K>n#%-&1f z4~)k{94VZYPF)@l45S#qGh;wGC=?qC8+IDU#~j?;@w15RNxj}umSP1 zvvMdJPH@j3Y^%ppFNGc*!s`-WAbs(H_VhaJyX$VVS%5xTtZfU~GV0%b>{?}pXRIdz z2jI03BD`R(P-_8$ zlFq9k9HF2%;HMokjY|V3R}c8r_|raeXM`pK_<`;dPh!2$0>E(!QLcMEKaT-i*o}sy zC)|Go#A{KnRI3?y^aApU#t-9VJm|Lu;@NGYHZ9nELjmS5)ACY6uxBC-sLwLdTk}`J zA+UhIJN^?S^8m;o(4Jl7ny1L~y%q4U4ngrhtK``O^vfnC7lYpNbb!9Djf}kLkK;L@ z4|NT3o~5-V1NfQI1M$!B;T51g+ToL~btGdFpts`n+20tx_6PVjDrBh3vi?#4M?}D| zW*w{l1u#n8Z#z;Y*mqz&$UtVQj!ub=0KSkXngW$@-MORWwQU z*6)BG`oo$~05;7D;LF@r&ojy>y#d}c9bGc@cmNdW&o;zvngA>|A26PMCinx0N;zoJa3u*P3kmtlz&JA=c)Q_V@ z1o}s%5&N07#3BRq=a=7~(F!?KP#}Mz66levEe~oye~nlet4SU+1?aoAwm(h~{QuR{ z7t3E4L6zC)K>nhoNKv~8xJFNRH{PNH zcP#aX>pOscpiJf`44(48`zxf`mf`F(#th(Je!6;8113}g)Vmi#dJ3e?s16`sSn;Dl zDE`(?U_8DGgc0vY_sIy1 zP~9a(QBdG~JBD&2Z+x%Y0rbql8;cTwod3?tg73=mE1dpGPKKTs}>06gm%SZeYLeFtD)UYaqCEUyUwH_W9T!&pB4 zyKg`&5WUje+>8VK6aP7`Hc~D$kZ)AIK{~`K*ciYw!pGf4iw3;_^OKQt!Etan`#KEL zRurofCbTk{Zu|pG^e-@;SI)x*?|;?yf&CTaH%=F6@%RAvJs+;boqaS-0rR8gtHV|L zoahAbaf-3EsaB)^`p*S|{c_i2%LnjQw&UHeKja+%92!{ILDf550Nk&ls-KVFE*IMX z{FHI5CPg)*4V-T_9oX88D73WSzw5vg4J*m*_z-c*^Q|%geh4!bll_kP^Z=IP762v6 z3n&HhdT<ktg$M8j0c~)jnl&Q;)_7YBG-C<-_dHoQBbc%% zuwn}E2Sk3-U>>+0K)r@;#<*CQv`bgyHxi08j?G$7z~7pI*ZOxKv_@#M{cC8b2h2~p z;H()x}jqDn+vSP292`|w5Y-cLt` z2mFOs;+a&&U-JQfwo*&1QNd~-z>l(6C-H~fnjL@#$+&fBeVhLR`V0KUEzp~c?XKqs zgy6tsimhwjq9*9#pTPRgjjI~0-V1&O+Hcy1lJXqsXaMcsg}~hhxof!re$GZfL4C1q z3&6q>LpzLQ+`@p~X-U!f^39zaz(f6-vn0xkRRErH2`>5lLH6(c)hcNC9qH3gNx<*A zl+z*Tqwy2ai(M0b*$^l+05EjAZwfEg92S6AAE5kJ8+Sy3`HsmOq0(DGD*$-i2CF$< zF5!RqlXg|iyUf)5^GEyZav!;agAK$_(36g3r@z<+&MO!n=+F21?hAmQt>0M3RDJsQ zzNG*v;wvYMx-+o9VR3sFb){>Ufcg7sZ@1`#KXeGRhbR1yDnfih0Px@cZe_+w!Yzyv)R^0>zq_kiC*!ybBznS&d!9_c?SvO@e#838_`!Y$V= zxE>#9pVlKekz2TUppI#v8S3X#G$W8X>9UTb3FOP+6!~~p_~#FB{@@40AZlI*=tnIc zL^3fj305bOwAqnZ7yNV_XJJwX+8r+Gn>cD#mD*<5sS00B#CWq_Oh?|=L6CjuV3 z4JX0`aK49}=xwv*fh+>~I{W0naEm z8r6N^JbA*3NA`~O`?p?E`EJ?}Kx%n618A%L+Bf~Rt8Iro9})_K@(N`X4~ z@A=Cj*D99L&&a-@!fP6y7?A(HXbY7-8{5C<5yHa@wiTHYQeeG|MTup2O(-M* z`A3eNixtyQ8v*TYZsa04Kz!N(eY#>qmPZNf3V`#jwc9VuM-HoaNJ$O zr~dhHi!E@~#ZrCZkqN#Qthi30nY$o4ecGB>ef5)q1*ODKL|GlRLg9#UrNhYeu)G`e z3uEK_%|+Yg@?k?Lko5mYjY>9G5I+bdyjz?8y7Ls&irlqB=2riCbM_unHVKS^P6-d> zLmvvf$)Tkq?iB1Hb>?#Zb`IB(t)U_nZ{_xVg5Cl5dLgs^*hm-)#W;Xw1IhivekU(t zYPwI{y~DIHYt0tMFBMaKwkI39T3x4w`B@@_7=Ca-13_E9+F`n!e2}_QT@wnc!`fHh zWK$XW3V}BxXDoLMK{V;*%u~)jpP*)(30Kci8*xS7JYSA(g-}$W0rWZCXV8WZc1SH9 zo4cH~D^5AFc0rnS5w^bUSn)F3gxUS(cRk`+hbRO) zVo4-Nk*DV3{Q2h`>R0Z($t)Q>|xHzQgOBg7_&rdElZl@8Rg0-FC^TtixDsdh3NIwOW zw!-pS#34GON4y6~TTQ(dHNHvnaKNh7X08dq zSzXP_ALhf)O_S>ck#KfolPf8-vhrdCrx$V`i7F$CQa7-O=?twK)%4$g?pXHiBI zR$`Uqwk2%0PyLqv!~gLjvE63Zu_KOvj^r&#T*Z83VVwp90f|OuR)?{@67wQLjx?f= z;-Gt4`NZ=7-&|yFJ*D2)QUoh}!8=Kkn-G)?zhkHta);>8kka>+9=zcxFx=&XD*uAR zeM0Usg5sbx`Oyo1}O)Ik#~f_zZqo%G(n3s ztdGp9*RlevTlvt@AG}+k$Hn%!`=+Mis~2)9e5x{>Nh2cp)ZXNPyKR!@mmn(_-qx&roI%Z&8yae4o)>CXYwTVgF2 z9Ft+)?vO(^aFk#G2uA64&?CxA;@hbf(tz=V9-n zSN6kAZr;`thfA~?ke*RGaI^kkeW|(r6!@TuhHJ9L5p6*HbqCGGL43R6m+G|Qun83! zz#JQT1PWp!F2vCl6F$iat&!{N$78Gcat)>pmG?=bfwXQndKiu*z2F&i+xqKIDjMVm zB}6;hN;3wiH2vMnaYmbkX)ntx^rw z5aO3wE1gNoY6|{-g#WEU{QT9%Tzf&Cv&n4mR+Y^k@cifNPtcF4y}jL@N&(^vFKD8n zTQtxBBoK;CX`O8c4}L!Eq8(W9Cu$eYnnYq4Eq8IB4u6-Y#?V+{U#sdc$zDSa9nJQj z;M7+TS_n+5)*bxiQXLYj*Io=bw;AMtahV3g0_}tm{vENa#&S6-Lgs49hna{>?jrs`!T?E=H@rSwkbA>#>QhuhGifzk~@hT6_N1 z%f$AF7F0CJo>ou9Xo*dL+G{r3|3%=uBQyf9KI}u@%}n#gbLlrD@u`&xh$S7_50R)F zHuj9XJ0xwuaCr`G)2LEJiAg)G^0H18XgEjSOJg=y(lJHYy<@^t|7ckr3XCpv{K`f^ z(8F;h1HGMzqQLqn!$wg+hiJq09ZSPi#PX08f9#8mz$(lDgVQnx_Qn?SX?2W!gvPePwu!aPl<_Y`fcSV$ZhD=-6+aeyL5}3l@tYwlO4>+;B%o2X!HDK)RbZZBA zI@>E;Gtr3UinsU95QQs!Zu}t_bP30fl&l)((kwdlkif&zmeb&dX{gW}(sU`3niof?)Uug;G%~GA(L7jhPllCwwc@mU z0n}0Qs@EiAy!NV&wzt5>s7V2O6U`z&%puNX@(u5 zHOeA=N~L-JL}+7$h$t3hi|3d|sqmj%ge=zmSoh?wa%``rE}sDsuvdf)et326eOP#S z^qCoYcnsaV=<8Fy&>Mlat9EXq^3>(e7IK@J9+;WN;29)-AY#;ejbT3Oze@*DVc`uH zaH;L+pMSKWrD-TN9iFmogv%AImF!-Gd8t^zO3-iU!6AojCb;hkOUnLCu4y-y(ez~E zx;%t{JbI8-)Ez3JABfde$i3E}(xs{mWZhM?5Ec^*Rpy$vXK9`a;n)c@O2=>6b>U#3oOdu(Di; z@cFakx<(Yv5B6QVB|VI`Ed$-y2}q;eZu*!;+nBMBMk@KHh|DApQac~PM)dwiwkH@R z|EP+#7K`JY4RjTAK3rKo*{LMb2?`g)6q3nM*^CC_{BBBwo)0-9rrEF6Y#9L;LWNSI zvbwDt0hw*v71Xxk`NK6zffvv*ryj;CBzp4JV9%JgDwEtj? zQ%SARE@S3cXZ_XxtgPEiLBp%y^m41c(EV<;_@j8GZSMmuTuz0%BA2SBFv&l%7UUR| z3l*k{xo1;Hu}tDCDC6-~-B8$I4=5j;?oshNHp3m6-ctvrr`cWWSChA%dNpQmIAZUt z?C1fjb&MUV(McbluHrxloEFh?#FtdfR#juW)#&UY4(wklDx~Csmce$K0(V;%L7z*n z#p-5qe2`^yjOWx{*FUlSGoo;}1;#U(e=?>T1yi%vetclDogKGPTAZ2m-;V6SH`S_a zEo{Sf3|PEAvp&fSvzv(*ZaQBdA#7+)qV!>OhDFH?ly*#2WWBfIaZ@8*TX1(+G^p}c zE(ggbLD}*1=0$F(U&SGQr@b|)8BM$*a{k2-{HP=50goE=XSMY4sm+2q5FX>UgBe+8 z9}e$EVMh-8Gd`y-ZVtpuTPTQc?0e+AC8K@HXDDR~>pD{e0q=`Nlrf&iP$%q_2pAQ- z^#@NP-)ZIm?XPE1ci|yubpkT%2HKdQK0dlDcr87M2?eWs*O2-5y)JJggJC*ulHWx> zw4qB*jg*!447+H8h$)oW%c35cH6$(_!c~#JU$c!_69ru!dM(x@qfOu+T2!lBxSj9w zVO}HnWcKXYC*wJ{K2C`J@&|EV2s7-gw^u87eY~sLBNd5b4Dyb1%U3%z!v4?c9!SWz&uw8r=qK5CPF99R#QYfu^5xV>5S3>@q;4T-0n&yluYZttqNlF^VBb4?>~~{JWYzq zrre#>LhZx*>`{*@hlw1U)>v~7+0$6)c?%043#z`$el>a&dPh2t84WNBPL~o}P z4nwd8+f{A9q!e%CnVPlb?G>(+cSvpo)`RAEC*n*Yrs0<6{vOw(X#i>et3}8qPARyj z2yIRg5*3w?9EkgNigPJPy$c5F=n28xe)tb{v)Hz)*d^h(Y&a8d&58SU7iFEkI`{7& zb&_jlqsW8*|6z$3>&$ci>;8M*P+G-&7)*BK<7mji6z!?YKd(p>4F5rG9*fmKL|$Ng*uU4uuhs2m}n;?u>Iu?z9*0)y84mYRuak z+|}1AZ%og$cC7MIQ41_m={FNQ!Or+YP;wWVbPoPPxN$@0haQ#o2!vV@#r7t9WGfo*YEp zvq`*R1UXSt37rX7GdU5ccXWIdOce;5MU;mTzho&d<=I6_e{MN&X9k*aL%`Kz#%Pp> z{fI@BBJbtCj!22vJ*(BQYYl~58gE24JQaTkVKSgtMoWt$&4tDHlBFd1D=H(n>%SoX z&B(sv>(6QbQLQa5mA5SsQjW5zn+SJYsFMJGoi<1;1a_i&DrBxEAGVNlrqH~Gm+@b$ zS=+R2_!OV!2f^C1M;;AV9rloAO$5peOh1I@stXgED{ZOsV|Y{k0WQ zPj!Fbf++8=3SkIpe3c?#w3H$E;6UHmQCu~IcSH1dq*g#85kEb5X4?za`0BMe!hy=J zdG-fBYd1bv9?s(b-(cTZjcK;{lzZjMqmwnHzI`h*Y<#s`z2Vr_&-umuiBewH*$=&T zxevRXH%X1QscCAPE{|C+b+~))J&kmQ)N}ml@a6sV*G1lvR@DM(Ucv^U|8D=zt7L># ziE1aGf%=UL%{ug&8~MX`?Ukq@6a5%2m0As%n1!d&4(P9%55$?3Ds!y+C@Iobh=%K~ zkHg_C0!eHmRL@b8*a9dmlS!=ElRIt7BvzuxnMqOJ;TuLf{iP@!?_eG3VgrpZoL25! zmD|)MV8gEUVJCeH65r{T<_x9pjM!Jlj6H}&VGZ@%aS}vxC|&r2UYavkDOdGymef&c zR6cAab=J|Q5Qk%bS}r=FDp?^pvmM)6=h%}ie=Mx~;#|L}_<3|FR{yp|zKm`cbcx7? z?RTjwM}6UP(~h?jm_bga=?+KGvvfFrw{yL5sAg_vKom$uWQB{Vq9s#H^}X^>4*``I z2$w#{fh)Zzk)zUqDKJ``QfZ^>P)O}{%ey=O2{q4p^$ib|NkWuWh29&D77>cvFbQ2l zpb6q?>CwxlGSszsWdwOt{IJR!jjsGRxYAXtdn1#GXO3|bY6+j0>J+1A^Tv|S<6ytm z*hoOy>n7X_oh-Wk8RSwF)!em=6OtR`%q0T72?6RVRshdt>;@CU{RNS*0V?NWDXtOx z@=IT-nJUcN$^%0-0+L^`;c>(&StJ4Hh`*u&YDaCw@1p)pmA3C9-F!u3G)3gliCe|l zFH*nx-5VjYPqpst-Ap}DX?t1>CWk&P%D3~9Sf6{I(A5?|@$3>EAjOU;6(toTu2?H& zmUJOB=~i%sz94(_me3WOx%|=^XRvMJGv6=a-gzL;YBZ9^lN*7o)fsEnk7#p7$dlwW zfUKZ=FaO0_9NnSVhOov!+f86`A)Mp*hsP~H)Af{i7c7~Q=llKcTI>#A4~@Vvy~Dcj zlQ6j`qCKJBc$$T8fc-9y0h=@`REwe zGe723ndeFy4(tf?7Pt7~i!aP4d%C(z>fE9biX<=>zB<4|YYSM@8?Qd-elXXL;8(|5 zHCk5j$UigFztzmkGhn~{%V~2I1KE3UbX1lIVX8msejXAwK z?oZkD(;ci=L?ZVq#UHElLUptp=#k#OrAP^gd#Nv%aE~yTtd<^J6Ms0NJ>&GbY=5Jp z-Rr|(l#+a#>p%Jlm;AAtfRj39EisyFq+2FR&DZ=|Uu|kybuyK*6((|U0WXQn_ZgVS zdWA*^*BZARY{X^7xNnVa_;+vQnhKZ7K`zUY!Ch?+A4HJu@c-}V`whlwogGG8jl0;o z9gghCN2;L^i9M^=;7Etp`26M}E#f-g;c~In+{T>{{+o+T-A1mD8|fp7gFa^>=yosl zyysAiY$k4sLsYn!o$R%FaqLV4%I6uh<79VsaB_mXNKrt72>&WM`HAGT{;9=h=vO#u z7C}WwY_r=$xiO0&MjGqQIXT=wKn34~d1Hj^e!K`3TIXpt0vlaEa@43D{>6v3ZWEbx z%S@NBKiH^O=lm<_c9aFLV;aWpw*{wNg{~13{Xs2*iUJR7%O%6jEdhDq&2^!ZyTL#c zAuE{}lX8^4ebh|p&D2ddU@~q5uUK0sf&Cnq6VkKHi5fl zmWhRK&Cdr`bAKo}m*R)0S}*S+PnUeZz+L|IA7syNrx75!R@Z6-eK0j=sqZ3WEEXQx zCcm>#3lWE_gQho{#hs+~GS8i%0;k!@67bSy`vte|`vjN}@;$_^=uxV9%xZ@G-G8&e-d}-lkQ*4#z>{pVM2&8iI zg53x)XSDGPRBv-Ofp_0=EMMgXd#Ew}fQe2c#|m7^SJxOz^Bk~t284XmNM2Ki6?JY_ z*fOF4y=xr*$J{jHNSD4S$h-r5QzWhb{|!s^QL{t9l}7ae29*P3+%BU#Y~4#fN&sYY z+T@w@)&7DctK6;O9n-h5%;Y9_ce61@2HE*d`-UKpbDRV)TD@#D^e+MSn*3a9?DNc8q2sas!ZVVU*yvX5jo^zD zrjg-XMJdFcJhlQA9H|VZ?wEvHz!Xf=#_bEWefw(V5kr=rYL4pn! zAt?|=}ukauH{EIi!-)RWDhp>mmAYM!OEkf!)4&mZTR-kSU8>U$gu$OpVA&nYzco;dmWDH(44BpA2-Nv=ObzEE3e8yM${U6EO4d8~mX zPIy|Mo|s6?|BpQ`dmUB9sg}lS!AEV$mE0fhVp3<{wd;!weD)> zgKhVQbUU^1YeTL_J*;hmvZd@CWx{iPy(yd{=Qu@D3BR=O|EH>JGdvfC+ZvA!(3IH~ z`|oZts#y9M5oM>T=nbh@P#|+LT!u?8dV%p_?6~n&;D2o_w(x+ad2l!erE<(k25tv8>s!nhnu9A_Qwn@{(m2MPNT;>AK_5iq1Z>g@GqQu&@;f1 z3aniv--C_e>?s{hd#_!*ODSZmNkod}9!RZsYUr7L1cDn7!L}xJMWs^Ww8QS`Fwh}% z(e_%8Hi?a^$xA^w`sS1I8JA2U>^n0gYhUjQRpu;8(fd3)2$zdmjTN2Sse77_s%?= zM0HLy=9p+^>dpP?h5t74H+Y2 zWQM*DdLNZU9LPA>)zc5$=b*f|0|E-KVVuEKq>$RgY2J9W4T$*^+Pd#be-uPtzbk0h zyVg-E!n|AOJIL+yW0qD* z+ql>Kl*x-?!WcT=@C>tWURu!CanN{Mn2(OrPS*roM#+m{Ys@t3`PssxlcAb8eoZw54&zG zI?lrWvR;C{`TCcEpbPg9=2Ee>VEyPVg;@&nwo2JCB6>yKO)gM%dM#?QN5jeHWefqe zJn#riY$&Z8tuMDCK8GicBd`61X#;|vYGP(Ggw!)JuDg%AhGfl`(9HtYy2lU><(`t7W~Fl zY>e|S-E+1IeKPu~ic&4TDc*Ftu+mU%6MDGxQ7@_a4X)*&%O<++O_l)(Qj_90@rUSV z|H(M*(}@&xG3Gt{+f<~eWYn>Z0)3sSE*1Sn57OL8-M5YK=@L`Hws{cB^aNc)PNas> z1nROF5s?N-pMg*#@@{Y35IG$=Q}2H0Su|gqUGMm#f!mr66uck}386w8uOZ_VL9&KE z&F>Ub5MDfvAn6w+y*@-WC!pZ`Ulh)*azCNzu%ml-HFWUKazuNoPWSSC@kUWFA3{`U)#zu+ zM#YlBWUFvtG$6=j_6OOF!vBQ7(F`htYF-9N1g2qVL>Ly^i7n&&T0gMvb1JvJe8?V-W$ z7yDD1xjPWu{w@gZNZgM74aihma}DJi_FHA5-!NA0Lp54|OfGF!G4wfS!n32dAn`ki z4ZaMfi7D6Y6)`6bcyPBikBce?dfQyupoGyo4{>}c;ChFO*?7pxaLyMc;$2BtmX+=d z!Br-RH*inV1j~iZmQXfysdCRD&-dqSm6ktN?4y;U{Zn-qSD1X?u@CiaH=RcZ*C2!j zViR=F>4}}sctcJ)^AS$LoXz>-bwkS0Ik*Zl+&5@5Xc$7Aks<(mwyU3M|7S**J;!IV z0yU}-dcdyXi$+YbS}&WyTbl3J2?LJrWz|D462*tu6ctesSG-19&dd1_ZsVsqbm&k9 z_nz{*rjc`%2Mx#;SOWVjunk=S(gX~29ay&^U0p|Q%i|OhMNM-QNo7_%Q=xG&OQ-?G z<3!C}<_z{DlXf`@pwT@~FGH{>#o=7mgxa>$VBr~lHHY!2 zFUCvdsCPS^_Uzw*_3PANvp zsy54LCI~W;PGU=3!!xw<=kdb=sWMk1U6{m3Gp-L}Y4=2{ii5101o0h*Tt}$P6Zr0i zI2JWPe0yMXV$xrLupUQ6YTT3#Q!jue%l39@pUv#~VV{~vF~C5Oc4t1v^P zD96Uu;sN}hb>(c;h*SB z#o9MKc_;o@Z^-)hv@F_LLbKA2x1E4Ac~|0hocRWAsTuwuM8^pvmjfiFgEYuI=XY~x zh(kdK!iI{h^8D`UaU|tKjVz;}2bAL+=SiLa04qS$zZq)>KPP+JooHlP9X@PC41cHn z84(evOp?7*Z@TQibo#wH+JlkM2uTu9pxBlzIgY7SP>T}y8tnhm7eZGS8t~Eu!o|h( z0JH_?JgHWQsq6*v(@JR^eQuM_kM5BNSJ)!XiDQn+v;s0qV+YDat3i+JCyZPlf*pXj zhlS*%$L6oI^;XbcbC+9y#fRYXmEe?ao|gJ!AcKOf(B>?8$HbHuNCU5xZFs?~$Y~Wo z$Og%>w+f{V6ENC{v*cIqNyWLU1JMBx1ify*HwV@anE#ZZTqvO`W){2t#f_dh03)sz zEy*v-n+{25IcO`Zgt$VG-QpJOl;9TZSp`dwL-30Pnbll!tWCdSR8he*JJZnFOO1Wa z+p6b`=RETT_l_)U>|Oe^d=V(^H0ZCgICkAhesccGJO%cNGFOSJtjtIo(KA(-R+9F$ z97<-gm=hO0OJp0VwYsWVM9SodK$ueSMw14LPLnrizTY}IbBNDC*3BAn4X%N=g+y5O zMi^|Q2qW~r&jp!^Okrcm1E3O-!HD1?ykK`j6Kzt$gRgPy8ztnoxt@x&)JX z{d}337$ZPE9?ehTJ$ReEbWB+A-kjr~=l0bzD?<}rIbU^|g2b=63D>0rh zt1oc_Ac!Qv51JRXTa>4ZOiG@b zzs3NXW}?=dP8$bb*#UQk`kJuFqJf|2J0Ohh3Rq7=Do!|OhLN{{%rMt#HB(Gh!`)2g zxSnuKmk(HM{O4E|#={qQWK0y#Ht(ca?iU3RvOIOEHj&pi3G>Jzac}Rxq#ks@8Wr`H zckQ2j%sk;yC}0EeAmW#}J%rsPay+%ab>D-0V1nVN@$1Ap+182!&Tb!vDEtb{22tLV z(4y5Z^hg@$ow-4aOl?c9U^lCVot6-bX|dga8x|yG>oLyX~(hx`{tS(8F;5h zuAG&#G-v}DmVHQOGEOZhTh+%{;4-I9A(_OWgvo#??y_Jcm%tg5KOzD|dr!w>37Z)o zY8IK?AhdmCzJQ1qnm;h`lU>p&95##krTdatuvuNzG$r{E{9 z{Q&gnc4LcC+uTZMM0Q{1?nEoWy}RM9o@{-66I%koinJo(Vd3euy0e7uZcj>z~4)m*>}gLn?(pgi^5 ziG>7&yb8z0s?dPQMLEsVjYW|Z2e^oc;&Uhl5I9=5C>a2|le4qA&u=(v_}Ww*-?Vy5 z%3Ik5VdMt0p%Snfe+PBZNt!5w_kY#v44}CKHWz{+pdxb(BiQ1SuWF`U0=%OB$2ATO zc)fL`Q#JJ|7iv|-rP!P9m)Ujz35IcQX@EKR%JIy%wLUS_^B=f|<{S38L54K^F{IuL zx^YLVBbs=!W|KAp4%GU%tvPPSJTMWrCLqyK{M~6Ol5@okEN?*Z*wnEPY7#b}N+Yfc zfCLx%eYWaQ%(PjZN+YB1NkH@0C=!Mi0R7AogtQ*h*!K)~e#}uyK8m=w0WXUac9f2UY@IV(aRqJ#1q3eo2z|xu!s|7Gh4qvp9`d zMVB?i6W3q`NT5VRkfh{fR5e;+iNImgP{JeDwCSrQ#F_pgB_(>z9voC^ZP)Ljt;6W50 zjcp37a8K*gFMNj_Fn7vFKL2rG*{9&q9%Bv>%!$)a7lncE+ZVgbc~ub)*poN_^fS(P zIi34Uw%q^ua`Vxxw)3#YN3;`eJ z*FvsBCWX5D1bgQ%a|=ZlQ4yb?&-bQu(98ObP_r#l+$$w2s{1JGB}w%B@#o`s^Na)H z3g{ZLTzN$aUcMo@dAeK_w6Fzd88Uwv+N;n92$+ zjUVqOwh%}ez=&3-UP3WfA8mn^@4X7BY7UKFP1VOFj376GO3~u0`h#v`0)H88lsJ{7 zjU6XT^rmt5xSgr%!6EY@%1MM^`A9vSC(T<%Nuq`u-E7v&!oN}|D>-s#ZYCwS5Dm63 z(5cZJSBHf8PVLRkCT_*pWKz5wrLC33W*|3jp zC9kD^1KNIX$#&Olo%xIOs*0WCAG0@M61{tPSo9on7 zsq371C9;J`dv|lR&e}m502Byu8p?vaqM{}}wD=26s}lL1uSPbEwO(Y@_WVoJjF#^n#&T9o|7BTeE>mk*ktPx z3iMpn!}jUkMYw)k6s|u~%Y(L!(WaLMCjUESr5T+c1BO_c#*KYde3UP}(--KgGoyPY z%?JoaiZzmMqco&0htiW@=5u;zDXBY7GIm# z3U>HivJs`Cz^1FOvB(Cq!W{`_tUX4pB+*yI0 z0W;}kSoy%M`od}L7BR`%r4D%!eb1qwa4n}?uK8kPI`A1e{?L7Ql8O$NDUWFlI;s6Q zC^5R6XRc%X8r9;UP}&@y;FGi-XnBaK!Tdz9t*14PLI$=+% z7bh`aIKV0`R)^gF9VaXvZH(S~zIB)%F+W-FOAO`6d_3ba$Jv8*d7CqF>hGv_+dhZG zlm#WWxzdAX!az2MQVGNJ{kF_cd&SG1%>qfqX2gDUMdkeM3BbPF!-mF1Hmcga$PC;R zCs*+#{}s|~EGPNB_p|38T;_)E>)_SX#EiXey&u9`S#Ubqp9$4PmQ;8^J5%f3risL_ z7%bGBR0sO7JryCRl>RgDgYpYQkOQlQ8pWjl_v9UCsYsMRT8<_+FAc{ET45VnP)Fil zlOpV8fEF`hQhg~Q;S|lX@0?6b4&xVRat??hTb{cvJI3L)t5R z>Ui3FA4qfn=qGF%A|r z<0f}?eCg!k%@vQ?$7;N1s1-aX-#Yyp%VnWH$5$!oxv>~ znm1AgMqzErYrCzHl30+h$Q%BICTRLA3X@+@^q`5=o>fmz2iqOkQ@^ONzF;I*qPH!A zz>XtT6LiMqB!CP_ApXPI1C*Rt(JNUt%0gAK-{%APiECmQVghD|u!g)s{EM;O;IhwdS`Df6dbOVREriw^36X<|_pBcWabEm%ySI zq#he$XZ1O}G6cmZ$Zhz-S=ajt|A^xh(%cQu$MKV=R(9ZgdOGKV>R~{aHZ?m|i|seG zVc81chFWNP?v(6jMnX(Fm4#%e$u%99Pd>SlJdHOBj}kQ=V*B30f!(#FIr-!Yi~G3Z z66y^@=dJ|nZ8FV)tK<7A4nGGE)XcMg%2ZzThHL=E4|63A+EE! z#~i2>XXv}A>f$J)T)RI6w3tez2Y(rwhWfk~R~~Ceb}G`Ca7POkG2W~aL0uSK^m+-R zmvip151PWlTLCt>q5RWxVFb}nTEUtL4Nh7gUMgnvE=5EJgL!7E3Mp9qT<6Hu?khL~ zFOoA@_Ati$bjIhj1H)N=hsoA$;X9p#wn5Ail#IvHbUQO)@5rml#~naDRJ2Px zIw039)`@ZW491z!7lWippCH?fBo8+Eo_lsQm1t3en%1|gUqw)L;$ouyYR z2%L4n65qCwime8Ur|-IN5FXzSf-1mhgNh(70=d^w6A;@R)9~bq5d?&~f;NAvmwwn#rYx z^-Mon1^luGq~yj`7Lcdg0_o06p$aRwR1;Np9x>IPm9)$Yo>}W5+{1Y@G#q}HJv|z& z*TI^9vv8m3wii`gtJm*)y`_^O)&}cIu#d|+Z#1GVVy3@d`}Vz|6sZ+0EF56;)4e;u z3qkKt6A;KtmeS0i)eDnG2vhA38T zoif@&#sM6_lxV;)fRr0T6v#;81_y9U9u%cdR+7UHr)^H?PZ)LCioJJ$MqIz9~jkj2D9Up#lb8(``=@_!%+tj&dv~ zM5M9UpCAFHODW4_pQ&!-i2p|!np08}aQ`X9+1|;47!`oU3Vwwbo`2zLYhLLB0}O%z z7-1Trmn88;6qBePZkoyJ+jhI^85&mMtFuUUvX5b+#<$ISdTmgr{S|YfszFiq!ptgOC0di?Xrx!KcN`yXk*`q%VkG@Y&pOBX|-%px9_6|VIWwbQwG#j zGJ-`=l-WRn&x%R}d4yPw=#zkF7p`dlYA4^f|3@>d?`R~lAVKS0L{+w8WLz`TuBzno zLxEj8`Cmxt2cp=R4zfMSWp&Z|mN)wybY-8}Fvo~u;x}1%LqB#IU37A0Gfq!c7csAuB z=q|~qDTjW(2Un|RSKh+^9RN5uw*$l{t=wDYG0E9*NzU_bT%zEQUf~qjz#j@mD`j0L zn%%*qHcnngA3JmymJS=fNLqN33-QmzE0rbil@KFoN1o1y-8K9+xRErtKZxM zoJSnn=ekRqObwf`SvNln&>%v(w{_tv)Hv_UQ})}VJJxmY;ZM$~p*W=uywPK<-0ghM z^a1}B6s0LFgDPYF02&Kj_QkqgqTX2MqIU;_lj5Wr?p%r9nyoORUaGylUf9Lz*BRL# zOJD(he7cTrF6sKtGf36QERbwREvS~n*1Dd&xVeRc9*_6;UF+im9?4p+N9gGIaSNld z*A^bD^<8bn_f^-aCXPs!E|~^8$W_aa41CCv{J=nb58RqU{d>j1i@Ndwd}vOnguvN2 z#Ri@!t5$;?8A2a7IZ5YToe0x4Cn@pk8^}J;bSCtL16<=gV260&`RntL@7EIPIwVEU zhxAaT7l-yHY38C%HXgbQNU!FVb9{@c+3l=JQ8gAqVbAV8{@DVkjub>V)FOc$kD(tD zp{eV$nI?+hrD`idlP(fCz)_0`xaFjZx@Y|e9ihU1ruu!U8Gsl%{ zWVz>?P^d#Qr8_lTV1Q&0gZk+{s?ewNNf!csr(pzxQ5CQ+IDx@Ec>Wc!B+nZ9f;gVX zqk{sX_(gmw2hECRJ&hrG@rQlXJ*3dL#FJ8+_PW6&9r#mmAOiq}Qq#crI_Gqy<m^yH&74T~~B zgl4{2B^&0~!(FS%Rbk(XIZ#-Rkjk|~sTOAW{-S*sNP{8`_-^OJxac@hQhTl2UDix6 zs#cHj*`Gr9HsPc^70n>0=ye*P_)f@ZYe|=A{s}i=F3N2-Bl>7Iq=N6o4DiFBy^?Tnkgs%H9QuYn3GRw96oTIbAqIX1{8^ZCr^aDi-BZWCo3?aT0MX?wyUK zY?Vk{OcS(rq(mQlym~#q)UK06?I;;D%}yt?-~Gx=j{+HDtMk^&kuiCPFH3)@h2etY zFYj|S$W$WF{sPO=d_h~|<>iVD%borp40~JWGDKN4J!Q|SQoP5Z-twE}Z7Mpa$S8R7 z(_<~rn$3h(k4nxGAmC9E=|UZ_n^0L((Ue=fo*$G^kQ&f+d!0^3KETvc*$;f`$sxTIK%;{a^^3o26S5xwii=A-T6^!&B2 zBf$f@^A%F`^9QB~lAn)1zxJkdF0ueQo_-U&z@f-rxEk3Nh5U_d@DzRFZK5xk!gsQ) z8`Da;-w?$%IRP=j+P#zPY1G!Fg?_>*;om`+!d20#f-I* zEQa9l7vgXC^*>c$EW1cslw|<)XI36JGSs?#Tz47iV(QIwC4V|6R5#%%7l?8mY@8>52+&J+X_dY_sIt31R_u3UZNxh)SWGY^7 zc%z5ZP7F2sQ{Ti_vUZs^a)6Gd0 zs^x0kqGw~BLm}vta)Jc1Bi!)1z$l6s^D#TRx4U>Fl|-*g5htG6%nY>mpL5j?qRn`m z`L^GAdg`R=0aQ}p)P{Bk(L1`FT7lB()&?1d7Q=4DFdUH>PQ`aTV3`9%;Eq{l29F|y`w6_zV#SV8}YUQ&EVf^Zmqgx%G>zhY*hn%yh{aR>u(l?Z?eYxo*FKVAedA9JfYUNkaA=#Zg!Jcr7hC&oa$Jr> zie;aZ`j?mF5?GcMP^80I8lIP+UUHDCu-(RRw9=G+Z(qV-D1R&?BSccbk#p|rZRC{Z z$P!@02x-E+pJ1zFah``ir0lEnm;h$K93?{P#Gif`w%nXZ4ZBl?$HARUimrM?ms|k0 zO(pkzwOTGk(A{CU15ApeXqW2#zcr)F3?sH~L^Qp%kxbF$-_v+4R3WiFf2(hT8{te~ zh;57!a*;loaNG&zVAH9fxj4{OGaLj88>}!U+AHb z35^{)@!5_IvNWbZ((dHNO3mvG-BJ23RfVCigX=50Ii zm!7!=gTq)RAjn;mu?~E;;upjP)3Eu8a#vBco{vbVOB2j&@2}d~1lFh((?ThWa33%? z6bjycQ*0-miD``uMIQif>@fDt8|och4+7@!qhI?KUQ-($TH(`LPh%d8DSAk-G1CuG z4UAdCp4%7Y$y-4-+EK3(pJ-1pnVCpR)E~Q;k`;c4O>zzh1C!8XKhlS@#801jm1A{Q zBfqcMQ~b0>OHF7aNEkvnUSMl_SbnYRSTZG?3^&EF{HYlzD#-a7I9|lgfaH2qOTRac zdrLm~y%_lDm3NfR4_(IQ@bWPnT%=HIh}=K30P;s5_XdQuD#Jak#O#xo)lst=6+OeF zM<2G(TNcQ&972T3v8t(=GdppklgxDmcPqUj z?@U{I9@v6|b_{wh<%xpqp^r5q5u@DI_83We5=%WA`~4n8)E}L_%{=5Q>PUJ@SY(&& z8o}^0_t4L2AW44Z8E5e>p)o-CE4&~~*D)dKc|8&}B@Q-$&WA=u5X3VO*)=!GDW97T z`{(vB;DwCUmcAuXc&q~mwLj?19!a)qls>GNZ<#Z`lI`OER*ltBl&MPp9j-n7DMVErRHkopc6o$+1ap|@&m^~*v zjUvz0yv!ML2j(Gaq7H;0v_lYz(W8?+6xlY-Vs*T&Ma%tGk(Y4`T1iuQi>DZy3U{Zg z81A5+w2D2%;XV5kl6*$ZaLC!we;+I-{VepyV?nFn0@k)FBfc^>!y2;Lbbs(}Z?aLQm%Q1Ngjy_ek}Qr43J%k<#q2^YCArN1Xl1 znQUU)0CgJ`5UbeVCWR8^JP$Rt%X=?C2W9!>0y~=k%8a;XcYV_K7pwB>p-_=sDZVSD=s#{cdwwuAw7Be0aPJJ zbNZXb^s}5;8-qOvz-n&@}$(-aEZQhX(!T++HqHb49tkd45&i4Tpz`VMk73V8-m_w z@&8`}rX9e^e50d23EDL4HKBM=V3CLZ}}ty40J+ZgMi!Di;~O zs^r>bRrFwz0ta79_CWL8v%;3QmSdfp0FME5QuXvdsr-0HaC!C+OYM57B;IeJva2GF z7|g!8R9RiM5|~mh^CbEJQKi^a7-n5(vy7wFD4{@X=3dvGQzlr0SBas&)p=7*a+Bo? z7e|J}lDU{;aO_4E2ML;(RUUGISm&L*ReeMQFQ3$6T~RhAPM zCAZhRU)b%GtV*N`38eWWj+wDQLatVqt?w8 z5Wk(NQkmb^WGgo6f>>)oh47lDA^9zmkY3%uNQ#DE02*~(>>^+V%C@PsN_vpwGrVB% zES#25I1Frj?%h3$*DQyS%l*5;596Vh2a@#Hr5 zVjm9Oj4|t#d4d-mLXObP0Dhb{boan|2W7WXuyXd$=tpyY*?22nhA%2x956t5 zaoz=2d>tlV9;|WHgl%jDd=^3itLR zn^iCgPRWvmozUEcolI3fXwIe3&7@KF`OfIKG-lXdzkV5c58|KAsrP@R-m`>|yjODO zQgQUBfhq6!fsPVcYS`qd81BWc(o7xw7)$8J#>=N8SZm9iAS?iz1JaEn7uXl1vQ|u4 zGEd?-B^4<^DNC=>`J%U~6tj*PTygU(kP#$K>}i$wFCYklsvJ~v`^T~9No;}D3W_U3 z^8PRt&LIa)Ubd15^swd#Rl-l{fE^Aa23!&HpJdInHBAO?%^Q5}DqiDBvVRBpdth9AhNsk4`@`+- zc=A29PzIC#tHpqLBeP7*P~z>yQkzOh9c|CAd7^kOT!5Yr8I{+G@u2nN-;p zzJj+sLMWwU=93tX6bVa`Gja=>Z5+6=B3q+IJ^Q>^+^LMMD1d%|A=T>^vw}fry7CNM zpY~Rx)gb9j+Dx{*?B4!^e%(X`*|RwhB!}cAX4^J0f>Q@8j{Oe+N_Wi(oo6P}wGJCe zzjeuVmx7r9?@u&Jv4|Pb$|{q7OZ`uRoK(Y|FBJJY09~7lcKIXjJO)y#TrMq{ z7rHmf;^3ab4r~0bDT$ERdqvaV0{7mvJ4l0QqZtpTNS!46o-dnQOO+F*fs=C+PUpQ; z_|2hY?;U^pddjf~x}gc{2In|ZQ|R-JvWB9Qxx+HIoDztC8MLFsIE-^RI5)PtP%KaZC#Wuse8=#9w2r98(`2(oZ);! zu?81HP-%%yH}g{uIa>jBU+_!ojNLR~gqRS&dk7Wsb+Un|I0TlPL*p!xVLjL#`+q;c zTWGyr3sr+uUxuUAYqiyMSAJAX)ptAR3raV3!XYj|&m4ehIwVX_UX@ia)rqzFI6Ja- z8rEhS5*N=*tl~InZordNyVKyqMUx+3PZ%4B4lOp%gW_S>SA@y~PHvj&;MS||JqlaV zZSuCO*SYrDem3pyyaFzL%wTMXF*c)kaIowT34RDiCG6bfrpZGvOHioi1F21DH!5~4 zva?U`)%RQa3$JQ$A5?rwZ&SbxV-x!ESuV$i;XDNMI7~qb(zdl|4=m4mSz(qDOMJkWEt1%Nw`m=8(x ztuSsCMkP%cFlBFxeSn%jMGW_IJ_jZ|i}rs`-8m1#PnUe97>Y~bbtHY`Lh0ZwW!C#@9_ z*x4X{E|Lc*^zvRxk4~4y82?fbMYmq5i@YVDgxY&{{JoJ9dsa=PbQN!L;;JjVUf6%zZcn>RmeVE`-om_m(ub ziJ$k>6dI)iV`0xmcxAIIwEp-GXDq*bJKwA>JTg#y?wc>^QSzhl*rpEpso%e)P5;S; z{2Q-N@oS`|yl)`-l>rl}KBX4h5aYe_N!s*M2|uN=KJps5Ne<2i#1;#HI>{F)q&@$H z4x4;roc*8$;+na#s#g^GbV%6#l4vqP^1@%GqT!({!I=@lt=$zE-4mR>IbJ7}sC9>5E7dso1$m=afjKSFXpoy7aZhN)iE_U~&uHsZ>bUBpDWQ_SjE_dg}(rTW^0=eq;drH-zOI=O$uUz(S$=a@*oJN1($D%> zmS9Ga!AX+pV1(0b>50p;#n|-FQ-2vJ+9txT&D$Hz@Ri3W?3oL7^#N6~nbD6}yvSiS zOhT6w61BWXJ2mtQZr{VrB+JlvE$eNw(NqfoOl*lLhTD7c3tMhW3dyyaU{&0kj@mx@ z9z3pO>E#aq2qCa0Cg>0#dYw|GyM|u&>b?H=xZqd5@d?A4VpqrCH>fmP5X1rxYI6X< z^1*?A*T#tATuTIn%Oe^O12r~!%C~eXlB|xITn-ci?{ulOC5gRo33np7!)=di+H-I{ zns*YG?i?xYWNWSn+-Z^-(05+BGcpJZ_ct=jru;PEsTZ`xb_Vw$g&3;@T;ds88O@HO zke{%DUBR~c5~4A@SD@BRlM4frFN<^R8={-7r?$2hE$=W4_1=^hP{ zuFY?aa8d=g=4?JrIV`y{44wcG7TqF0&w%^#Lj5p6kq9{IF4bz@`FZmmo@&|;gP&LH z7kGH}yhZ|(jFPQN(1*QhR|d|Sn<6Y?IbPsSV4&aph?PhxatTJRdu=8@F2 z=P3?bv(Ef$5$%A2uz-Nq1nCeP*{8ryndcEotGQh+5tWP2%bVa$0ex%A;CCy;3EQ?M zxQG$wM0>}QVKBRusp(+P0qqh@Ui(OCG}!i43uJQ2bQJ@WwJhqv>N(Sx_zbgh&a_cz zh!Bn`k(QDVUA4dN^!Q&;wGnQW_VIL?`Sf|2B}2Ydhz3b5F5)3w^WB@uqkmVc^lbGe zMQwoL`!JR5|8q?^f@r-m9GD0G>SfJB~hALRx=J`o*4Mn$?MewN}I0$qZ~fA0`) ziLN{YsJHb=$VW_ra&(%mre%_c_@l>(V}aNgiG1gF9i8}YC-+eBLt-)GuHZx5cY(NYO;4 znPF#IX|^X|Q$ZutPOGMO=}RgPL;<|Lk#q z5Qas1ke8k$CO>2VXM2*W(Q#O%n|0g%GNGc@Y^tIsM;Ng|p2!+*Zhy?a-h(ai?;>A?scnDX5zJD5JYYX|yxC)bU2>gXdcv#~QF6hS?^Tm>&-fVB`v z(k1r!6E{XVV?;bkhM2;=W~ynSbISAOOm5+mhV6!{rvUTuSOpb z^*2~&Fx}B2Yql^|f!YyN_7!;K6(ZE4La>d1?m)8VAz$e~w+LhBKlj$dQMeqzLkCy< zIadA#YWsCXU&O+}ufa=9@!H4*T6Kg#5kxe7w|hH_{FW%Z$SgKeONJ?iL^T%046750 z$Rwfw!a7{8dE$a8#Y^4%kcd9bFo2O3NjkP^9;F%q9C$l=+`p0jebK3Zuat4#XAwr- zN4`st(-#mswggZ?+N%5U;vH-3Y*Vv|GQ~we^z#!`q z>Zo`XDQ<15JHOh0A@pKmAx_(c1{ra`jn3{&?^cLhL)UzDUj0b@QM)|om3O%pfL%B& zqC4fIv_-FOb^exh9Y^%A-plj>ypfPXAO%PWCuiqU?DZ)9`DROs{eOpII!p6WPUYzw zrgO_v`|8m;&tA1=O3PPuZl@ygQ=?U9N9b>PbniTz^R~2%>|N~vD)_Cf z4mV%GJB}ddo^J^?`TDdLpOlcTKNr-q^_1=NQ`n0=hycZi_HSe4_q03GAyu|+@8c)5 zwQ>;+v<Ok$s02izGP%V63 z&G5z7?#`K4!pHLh-Cj@egUM$86&D_J&IEA7Xg{7+6!ur`rfn&kyjJ7AT)y0fG3U~AKIpzZuV~<%9Ty|ZOaU(To3N+kba+5Tv>5P8KM#DuSsk%mk z;UCi@*Yf{-T`TRog?Iql&%?R#X|6&fUKcP&EWK>Qb!NAsr?s!z$_18_Alh(60A7yB ztB=ruW@IcSG(!PtbI4AvMLRn|EXp#LJPwMtIouQ=v*OYo)(A^Wb6t*8wD*f4F;chC zdhm7m9!y-cA4dQ6IdC#VH|KE!qipG;R`^8V2yI&Ls_-%-z$<~@Xmmerrs*zE#v1NMh z${PANu+Q(f@@%}u5=~_Np&WSvO?>HuoQ`?_aTH|GG4vLix|uyd9fFTdA_(XEQal9m zE=@a_LkrtE24_?Ea{bf90I7j{|-LGJ)ry=W`-=YKKx+Y)SuA zI;Ky2ZZ05qVcw~UssqgRw}&h=kM675FCrda1>xh=nWtXsnzsBybZ=HF*SVq@*NcPx z*3cBCm5Y30hj$CR6??Aw^rCH>yr^DI4qt3;5Oder{jIJ_DC}aJgN#fPWuOC2|N5p# zrLu8HP$W|LEf44ysntQt8AOp zMnGw=-d>Ccd$ocgK9uYy7`K-VV(9J}*sr}q=wmKM#BQX-u2_%Vc7T|t;b%JX&UFl% z*m&{VoFS*>Kl>Uul+F z$<6X-i9x0hk8?~PY1sL_?WFu4vb&1mGx@9-b-DYlNz2uvNs;>c)>S2u#c4`ccC=w~xH3e-l>qpkumJIoE4W|)kDGd=F+d9qo^-X3&Z z3qer;51^u(Z+K%OHBzM}?@D#I%yQY;pK$dMOFP$}PJMf4-e?=UOTD2w#S_jW=e2!Z?{AbefU$Wf`||kNxeI2)rfz5=m^0)TO7WjoiiACQt1=OFMA&l& zrNh8s@*n5wDteEtV;O8S`M#I@QVVr{m}enYbtuPrOr`)8`JVMC)@3SwTO+rLUOCoh zWQjtzz7CIqKagLmpcQm!Z^oCfcOAm36a&Xo3tW-gy%JEcyopNg_mG7VBPHJR7mENC zNs)5Bg|T@j!>w?_K1uYc2{dq3;zK(mXw>6oCV+9DL+afD>2$pn?rUm+n6w|V^Eq)c z$F)YLR93a9*EQT3kYJd{FJrLIX7iu;@i^LL!8lcgq)9hHEv8jmcoqqSN``wG#}ComRky z2Rt(r8soSMA^hHDQJIwUhh`w&(?$8QYE!lQceq9}+We>Bh&N5ZAc*8ytxcHtyl=kA zLSXKy5e0--Bkj*TbJ0T3?-R#L&iktSsWc7$KuSSNWm%fDbD z?`WyO1XPO9Nt{lfb$$=V;R-)UFj-mSzz}$9mcWyuL5eB*B1M&DTW>&Q?^k1Vg9)_H zBd;a1$UEWYsw4VqC;jUBzr{=gTRi3qKm{8mGg_tBXK-K4`{N2)5DL(Y=ce1e|Hbn7 zq95WKSZ}AD)|Hr=0j^GGN6I`cx;e~ceoqtR`BM(PMx;y(kjJe^lyhlmgc5(%FR?oW zAoY#RQr(~f7~rV`)iIW++~Gq82a-|Y`xiLqDjQA#149iMJpn$%0mjrF#Zb^CMZ(D1E= z8-iS-j9)a0TZtJSO9mQ>z!<9HfD}Suc}%bQ&_k<4+3MlmN1GZ<`;^x`aS}EeND)Hy zMBR-Om1Si{M((&gMt5}Jh30YUdX+_F@V<)v@qwlrh;;_PF$zUx@{a87)~l%YR0)rx!}c=g$6zIc zt$E_rPW4sJ>tX}XIDAB?5n!VDfM5&%mg)WS%^7x?S?qY{y0jj`s?`zmH?rwpNev+u zyZ3e6;XAazL6%?198ySDuiz5_+(=C%XvnIGD6tLR78y|u@W8L>A@G2hoE&HoiAG?i za3VdlF;?p@Se@h1y7%?wq9I2Qh;) zwR@hBf+UYD=bH3q1hUpP?hS*;K+UAO6A{3jolnDTy2|_2X)gNw#YWkyHR;y+uD-yz zv}KvFmC4^Mv)6-a^er$f@1HAx@Z2!l(>I2T$~h9~CIcdj-wTbZKWWJm59TWhI+)K| zHs`{~G$#g@+0kpI8H0HXmnK?NQ32Kx+91nO`XGXF9EH$}>w%Q&dcJT2=nA$Od1>qkJm7=B>2HVVGSI8PjR zEO?Dv(bKv|UJ+?aZ=3Efk}1;lltEaFknEb0Rqfpn@jYHFHU@q$IQLZ5J*Dji-tCsk zs1t_m)CCT3(v>O+wjBnx(jVx^XWMu{IOnGbGj{GT($O(bp4qC4ewd-PU<>CK6Y5t~?aXX-6m$4Q6diVe3um7SMak z!c!HHs)v^Dl0Z;v%}Wb4N4t;7`7uPLFQC;)zFNf%WiSj7vp4Ss{A}LNsey*3j?k%AOx3uw$#qK2gbIu|mJ#WC|BL+k{)0_y2ZDHrY_ z02`Ic;!c!)Iw6tYc}eka2s?Z^bC2F^26Y&0_HX^#Ju~>%OeI&*7O}=%!?;f7fKnD^Lr3Iezx1xg-?ze z=(6GyFvtvq|S@iZP74t7mTU? z;0`Z8dhz}Nah;?Qf%R20b+k$_GrRN@RP6Qu7NUkjkrg@JaMng!`$7^Srx(f2H{gk< zB@@-k!1OC?W)u?_>Ig4Q5JBEx0c#5|)f$=szV&dENUf+Mf>cS4Y6==j-02^E*L%u2 zk}H8ygQmh2u)e=H2KOZKQvTPmDn8KE3!fT4C}V1z6ko}wyZ+}mjlCJw1PM<|ApQ>3r8aQJni!*$Gv+}2M2L2~e2PYVj}TSw8OZ!- zGr0EP;y|^*xx}^wIP~QGqm(ejP6gvY-N}lf)tBix@(NQQCt4#_q?XH#EcDz(;(4Oh za{mw^ihht~uc543#Q^vsX?|Gi=>ts`F6=(h_T- zAVQ}KQzEws;VXthgn>SgmxW|~ZNQ^)7y>CE|Kwm#+3`saAFAK#Jiub zDX{>F3`TaTtP|aKQaVZk;pe2~(&1DANIt&z#L)I5LR*2bTuP|kKs(7>Jvtx?ttP?9 zHy^E$7l4#BGM%CQkvNZZ;A47&ht0y5DP~JiUSOX5AQ;p>Xi@r;EPmK16SVQ}h>uM^{T3y1=k3D( z>Dhu$jZ2+0tW=#+C0Con6!8=-956X~w0)wTY~2Z1OrNf5(0O_qsmE*U$6Z?-}-9d!KcN zK3DVZQ#^M?~xwq%)f_LhE9vjv_ zW=|7uzojl^?{kn_6Ud!LSrDaays%MoQ#uo2h^4RmF z=#y@`3YX^Ecpa`)^HX-lEc-m}eQrc{Y+o+%?$Fr{ z+TMILG-m(j{f*C9Cw9&kerctL!;8$aO<$TZ<}H68mHiuQzn`w(-^M9234@yAU;eZsd>)Bl-`Gx5;1Rbc0vht=r^} z`!jCO?-~apuG#g>SZ3qbaCx<$9aWpXI&oye#tkMbcJ^*?+-ZJdL7y=f7G}KlTUGw( z`r*A(;sR2uEH-t=@88*TVSJnGN4-W}nG&2YDB?rQoHOUX{MXmfrtz9nRW}@MyKMdR z-izDsTK0Ux@2(xaM_oR5+&q3#Li2Km=HI!pE2wv+uwGMIKTPd6`RLL96P`}{(zWFM z3cC}IZ60erv(!kdF*{CYghf4CS-qjcxqM~l`m`>}6b|C-l5 zMwWXq{%Ypx2G57w8PGUqO{<_K%RcY3?-iFF=QQo!-VgN zkxxc`-5&X+eSmxJmO8&yfBjVYPMIrSOFRGE=wX#wyPJ3MXE)=6Z*6$;x8;(*O>zcb z*yJ=Ma(A`O%@adQv^evj+VHe9jjN1)G5CGc9={H}UOH?@l124St98yUz9om+J*je} z_~F3lolUNp4RYyXmXyye;%epV;}^BN`?|%K9*f_`Wqki+H$4B356&LvHnv)P-PLxK z)9SyDe+syCv97;pvt6fS{@2Y9Zo9Gn&6DsP(Vt{x6gHy0>b?$*PIS(9eAc;bZ#LZb zNNkJW_-pQRX#DO^*N?2YTIcq*8G8@=zB|%naLI;lMR%s{s?vO5)tvGEPdlx9vT#Pq z@e(bjoP8FSTS9lO_};co&-_=+DZDtOThySMd-H6%Hum6dolDUoc|SEMyRuoqwmJQ} z_$_+Yqnzd6-))v91soW$_0rsiZ5I6+wR*jGh2Iga=8miT^-s{RU03U_s#&t&m76Jl z53f%>ICAXTdvh})M)o$ox3XRH<`(X=cYk=YXrzhT#*C>YUNlH+7T#@~?fu@Hf7qTo z{q|Ma@_+4o`Z&-R5U&?qGa>@y8mk5^wcu`~67GB?C9kFK|#-q~zr- zr#1xlwK5v|c|)OvV~g+H;1X_krt+xl$_YD%pIP;?NAz{wfM3SZ*V@i&bMWNi0tb7P z{Zpsll19_3Ofo94*GOzbi{$@82|zxVB)F88Q+a`v{74}5&9B(|*hW7g0? ze))|`xP)G=lea*DRqt|>=8S%MI{nDhes*8)l}n7RnK)^C$_Q(VEAv}a{(1ELLF-JH zY@cQ4Ue0oEvchY8i`u0^yH|;Au=CQvmwf^bf0{h^iAUdcYY%$nE-$#D`NlH|=id~L zD0d@oYQpVb$@|+}jmmJn++~)Bd+ZU9h7WwKgB#ax+R<*d+g-;>{nO)<`j_!_oVC6A znDyV678+Ty&6#gA#|4&c_kHI+(;eXxx308rIe%EiyfYlL7nKSwF#G6-J$D^0ug+H} zWPQRY(=P?>7nu4aEzUSLcaPb}d3IM?E;1=H>u0-8qnBA89@e@4iNQ}Zwz%%_&)&WI zeEr^~|Et{VyR-GAlHR?3ySHw(KJxOswu37BzVW(0}MSK97c^>plt4c@;(%ug9@ zo%^tOpYLJc`kWp4Hss(iAN!Zz_Ih{n88mu!%Lku#Px}<%zp!=FW;OeNvMaFf;e$5! zY-W!s(Cyc{ZnN{OOSv|xR`*2{YCnD3Y3sKcM{XZ#xifaHM=kH8t%8QnIBoQFY=xy~ zV;ydqmMqhwu;tm*;LT>i!%B__@p0X2YFByNm&*lgc69oje1GYZU(1`F%=~Kl?a%

      IPHeh`}y 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˜n`J8?r((M_dzQqY5GfqhE)8xU1BhLVKi& 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

    1. EzMNxyQ2rFFy0(YOeYARZ2cMhpRRg{%JrQE1} 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 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as 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 + *************************************************************************/ + +/*! @file glfw3.h + * @brief The header of the GLFW 3 API. + * + * This is the header file of the GLFW 3 API. It defines all its types and + * declares all its functions. + * + * For more information about how to use this file, see @ref build_include. + */ +/*! @defgroup context Context reference + * @brief Functions and types related to OpenGL and OpenGL ES contexts. + * + * This is the reference documentation for OpenGL and OpenGL ES context related + * functions. For more task-oriented information, see the @ref context_guide. + */ +/*! @defgroup vulkan Vulkan reference + * @brief Functions and types related to Vulkan. + * + * This is the reference documentation for Vulkan related functions and types. + * For more task-oriented information, see the @ref vulkan_guide. + */ +/*! @defgroup init Initialization, version and error reference + * @brief Functions and types related to initialization and error handling. + * + * This is the reference documentation for initialization and termination of + * the library, version management and error handling. For more task-oriented + * information, see the @ref intro_guide. + */ +/*! @defgroup input Input reference + * @brief Functions and types related to input handling. + * + * This is the reference documentation for input related functions and types. + * For more task-oriented information, see the @ref input_guide. + */ +/*! @defgroup monitor Monitor reference + * @brief Functions and types related to monitors. + * + * This is the reference documentation for monitor related functions and types. + * For more task-oriented information, see the @ref monitor_guide. + */ +/*! @defgroup window Window reference + * @brief Functions and types related to windows. + * + * This is the reference documentation for window related functions and types, + * including creation, deletion and event polling. For more task-oriented + * information, see the @ref window_guide. + */ + + +/************************************************************************* + * Compiler- and platform-specific preprocessor work + *************************************************************************/ + +/* If we are we on Windows, we want a single define for it. + */ +#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) + #define _WIN32 +#endif /* _WIN32 */ + +/* Include because most Windows GLU headers need wchar_t and + * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include + +/* Include because it is needed by Vulkan and related functions. + * Include it unconditionally to avoid surprising side-effects. + */ +#include + +#if defined(GLFW_INCLUDE_VULKAN) + #include +#endif /* Vulkan header */ + +/* The Vulkan header may have indirectly included windows.h (because of + * VK_USE_PLATFORM_WIN32_KHR) so we offer our replacement symbols after it. + */ + +/* It is customary to use APIENTRY for OpenGL function pointer declarations on + * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. + */ +#if !defined(APIENTRY) + #if defined(_WIN32) + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif + #define GLFW_APIENTRY_DEFINED +#endif /* APIENTRY */ + +/* Some Windows OpenGL headers need this. + */ +#if !defined(WINGDIAPI) && defined(_WIN32) + #define WINGDIAPI __declspec(dllimport) + #define GLFW_WINGDIAPI_DEFINED +#endif /* WINGDIAPI */ + +/* Some Windows GLU headers need this. + */ +#if !defined(CALLBACK) && defined(_WIN32) + #define CALLBACK __stdcall + #define GLFW_CALLBACK_DEFINED +#endif /* CALLBACK */ + +/* Include the chosen OpenGL or OpenGL ES headers. + */ +#if 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_ES32) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + +#elif defined(GLFW_INCLUDE_GLCOREARB) + + #if defined(__APPLE__) + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif /*GLFW_INCLUDE_GLEXT*/ + + #else /*__APPLE__*/ + + #include + + #endif /*__APPLE__*/ + +#elif !defined(GLFW_INCLUDE_NONE) + + #if defined(__APPLE__) + + #if !defined(GLFW_INCLUDE_GLEXT) + #define GL_GLEXT_LEGACY + #endif + #include + #if defined(GLFW_INCLUDE_GLU) + #include + #endif + + #else /*__APPLE__*/ + + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #if defined(GLFW_INCLUDE_GLU) + #include + #endif + + #endif /*__APPLE__*/ + +#endif /* OpenGL and OpenGL ES headers */ + +#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 */ + #define GLFWAPI __declspec(dllimport) +#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 + + +/************************************************************************* + * 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 3 +/*! @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 2 +/*! @} */ + +/*! @brief One. + * + * This is only semantic sugar for the number 1. You can instead use `1` or + * `true` or `_True` or `GL_TRUE` or `VK_TRUE` or anything else that is equal + * to one. + * + * @ingroup init + */ +#define GLFW_TRUE 1 +/*! @brief Zero. + * + * This is only semantic sugar for the number 0. You can instead use `0` or + * `false` or `_False` or `GL_FALSE` or `VK_FALSE` or anything else that is + * equal to zero. + * + * @ingroup init + */ +#define GLFW_FALSE 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 hat_state Joystick hat states + * @brief Joystick hat states. + * + * See [joystick hat input](@ref joystick_hat) for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_HAT_CENTERED 0 +#define GLFW_HAT_UP 1 +#define GLFW_HAT_RIGHT 2 +#define GLFW_HAT_DOWN 4 +#define GLFW_HAT_LEFT 8 +#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP) +#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) +#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) +#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) +/*! @} */ + +/*! @defgroup keys Keyboard keys + * @brief Keyboard key IDs. + * + * 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 + * @brief 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. + * + * 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. + * + * 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. + * + * 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. + * + * If this bit is set one or more Super keys were held down. + */ +#define GLFW_MOD_SUPER 0x0008 +/*! @brief If this bit is set the Caps Lock key is enabled. + * + * If this bit is set the Caps Lock key is enabled and the @ref + * GLFW_LOCK_KEY_MODS input mode is set. + */ +#define GLFW_MOD_CAPS_LOCK 0x0010 +/*! @brief If this bit is set the Num Lock key is enabled. + * + * If this bit is set the Num Lock key is enabled and the @ref + * GLFW_LOCK_KEY_MODS input mode is set. + */ +#define GLFW_MOD_NUM_LOCK 0x0020 + +/*! @} */ + +/*! @defgroup buttons Mouse buttons + * @brief Mouse button IDs. + * + * 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 + * @brief Joystick IDs. + * + * 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 gamepad_buttons Gamepad buttons + * @brief Gamepad buttons. + * + * See @ref gamepad for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_GAMEPAD_BUTTON_A 0 +#define GLFW_GAMEPAD_BUTTON_B 1 +#define GLFW_GAMEPAD_BUTTON_X 2 +#define GLFW_GAMEPAD_BUTTON_Y 3 +#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4 +#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5 +#define GLFW_GAMEPAD_BUTTON_BACK 6 +#define GLFW_GAMEPAD_BUTTON_START 7 +#define GLFW_GAMEPAD_BUTTON_GUIDE 8 +#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9 +#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10 +#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11 +#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12 +#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13 +#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14 +#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT + +#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A +#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B +#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X +#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y +/*! @} */ + +/*! @defgroup gamepad_axes Gamepad axes + * @brief Gamepad axes. + * + * See @ref gamepad for how these are used. + * + * @ingroup input + * @{ */ +#define GLFW_GAMEPAD_AXIS_LEFT_X 0 +#define GLFW_GAMEPAD_AXIS_LEFT_Y 1 +#define GLFW_GAMEPAD_AXIS_RIGHT_X 2 +#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3 +#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4 +#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5 +#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER +/*! @} */ + +/*! @defgroup errors Error codes + * @brief Error codes. + * + * See [error handling](@ref error_handling) for how these are used. + * + * @ingroup init + * @{ */ +/*! @brief No error has occurred. + * + * No error has occurred. + * + * @analysis Yay. + */ +#define GLFW_NO_ERROR 0 +/*! @brief GLFW has not been initialized. + * + * This occurs if a GLFW function was called that must not be called unless the + * library is [initialized](@ref intro_init). + * + * @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. + * + * @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 @ref GLFW_RED_BITS with @ref glfwGetWindowAttrib. + * + * @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. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_VALUE 0x00010004 +/*! @brief A memory allocation failed. + * + * A memory allocation failed. + * + * @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 API on the system. + * + * GLFW could not find support for the requested API on the system. + * + * @analysis The installed graphics driver does not support the requested + * 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 support it via + * a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa + * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary + * driver. Older graphics drivers do not support Vulkan. + */ +#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 context + * or framebuffer hints) is not available on this machine. + * + * @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. + * + * @analysis A bug or configuration error in GLFW, the underlying operating + * system or its drivers, or a lack of required resources. Report the issue 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. + * + * @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 +/*! @brief The specified window does not have an OpenGL or OpenGL ES context. + * + * A window that does not have an OpenGL or OpenGL ES context was passed to + * a function that requires it to have one. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_NO_WINDOW_CONTEXT 0x0001000A +/*! @} */ + +/*! @addtogroup window + * @{ */ +/*! @brief Input focus window hint and attribute + * + * Input focus [window hint](@ref GLFW_FOCUSED_hint) or + * [window attribute](@ref GLFW_FOCUSED_attrib). + */ +#define GLFW_FOCUSED 0x00020001 +/*! @brief Window iconification window attribute + * + * Window iconification [window attribute](@ref GLFW_ICONIFIED_attrib). + */ +#define GLFW_ICONIFIED 0x00020002 +/*! @brief Window resize-ability window hint and attribute + * + * Window resize-ability [window hint](@ref GLFW_RESIZABLE_hint) and + * [window attribute](@ref GLFW_RESIZABLE_attrib). + */ +#define GLFW_RESIZABLE 0x00020003 +/*! @brief Window visibility window hint and attribute + * + * Window visibility [window hint](@ref GLFW_VISIBLE_hint) and + * [window attribute](@ref GLFW_VISIBLE_attrib). + */ +#define GLFW_VISIBLE 0x00020004 +/*! @brief Window decoration window hint and attribute + * + * Window decoration [window hint](@ref GLFW_DECORATED_hint) and + * [window attribute](@ref GLFW_DECORATED_attrib). + */ +#define GLFW_DECORATED 0x00020005 +/*! @brief Window auto-iconification window hint and attribute + * + * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and + * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib). + */ +#define GLFW_AUTO_ICONIFY 0x00020006 +/*! @brief Window decoration window hint and attribute + * + * Window decoration [window hint](@ref GLFW_FLOATING_hint) and + * [window attribute](@ref GLFW_FLOATING_attrib). + */ +#define GLFW_FLOATING 0x00020007 +/*! @brief Window maximization window hint and attribute + * + * Window maximization [window hint](@ref GLFW_MAXIMIZED_hint) and + * [window attribute](@ref GLFW_MAXIMIZED_attrib). + */ +#define GLFW_MAXIMIZED 0x00020008 +/*! @brief Cursor centering window hint + * + * Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint). + */ +#define GLFW_CENTER_CURSOR 0x00020009 +/*! @brief Window framebuffer transparency hint and attribute + * + * Window framebuffer transparency + * [window hint](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) and + * [window attribute](@ref GLFW_TRANSPARENT_FRAMEBUFFER_attrib). + */ +#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A +/*! @brief Mouse cursor hover window attribute. + * + * Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib). + */ +#define GLFW_HOVERED 0x0002000B +/*! @brief Input focus on calling show window hint and attribute + * + * Input focus [window hint](@ref GLFW_FOCUS_ON_SHOW_hint) or + * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib). + */ +#define GLFW_FOCUS_ON_SHOW 0x0002000C + +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_RED_BITS). + */ +#define GLFW_RED_BITS 0x00021001 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_GREEN_BITS). + */ +#define GLFW_GREEN_BITS 0x00021002 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_BLUE_BITS). + */ +#define GLFW_BLUE_BITS 0x00021003 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ALPHA_BITS). + */ +#define GLFW_ALPHA_BITS 0x00021004 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_DEPTH_BITS). + */ +#define GLFW_DEPTH_BITS 0x00021005 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_STENCIL_BITS). + */ +#define GLFW_STENCIL_BITS 0x00021006 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_RED_BITS). + */ +#define GLFW_ACCUM_RED_BITS 0x00021007 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_GREEN_BITS). + */ +#define GLFW_ACCUM_GREEN_BITS 0x00021008 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_BLUE_BITS). + */ +#define GLFW_ACCUM_BLUE_BITS 0x00021009 +/*! @brief Framebuffer bit depth hint. + * + * Framebuffer bit depth [hint](@ref GLFW_ACCUM_ALPHA_BITS). + */ +#define GLFW_ACCUM_ALPHA_BITS 0x0002100A +/*! @brief Framebuffer auxiliary buffer hint. + * + * Framebuffer auxiliary buffer [hint](@ref GLFW_AUX_BUFFERS). + */ +#define GLFW_AUX_BUFFERS 0x0002100B +/*! @brief OpenGL stereoscopic rendering hint. + * + * OpenGL stereoscopic rendering [hint](@ref GLFW_STEREO). + */ +#define GLFW_STEREO 0x0002100C +/*! @brief Framebuffer MSAA samples hint. + * + * Framebuffer MSAA samples [hint](@ref GLFW_SAMPLES). + */ +#define GLFW_SAMPLES 0x0002100D +/*! @brief Framebuffer sRGB hint. + * + * Framebuffer sRGB [hint](@ref GLFW_SRGB_CAPABLE). + */ +#define GLFW_SRGB_CAPABLE 0x0002100E +/*! @brief Monitor refresh rate hint. + * + * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE). + */ +#define GLFW_REFRESH_RATE 0x0002100F +/*! @brief Framebuffer double buffering hint. + * + * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER). + */ +#define GLFW_DOUBLEBUFFER 0x00021010 + +/*! @brief Context client API hint and attribute. + * + * Context client API [hint](@ref GLFW_CLIENT_API_hint) and + * [attribute](@ref GLFW_CLIENT_API_attrib). + */ +#define GLFW_CLIENT_API 0x00022001 +/*! @brief Context client API major version hint and attribute. + * + * Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib). + */ +#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 +/*! @brief Context client API minor version hint and attribute. + * + * Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint) + * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). + */ +#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 +/*! @brief Context client API revision number hint and attribute. + * + * Context client API revision number + * [attribute](@ref GLFW_CONTEXT_REVISION_attrib). + */ +#define GLFW_CONTEXT_REVISION 0x00022004 +/*! @brief Context robustness hint and attribute. + * + * Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint) + * and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib). + */ +#define GLFW_CONTEXT_ROBUSTNESS 0x00022005 +/*! @brief OpenGL forward-compatibility hint and attribute. + * + * OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) + * and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib). + */ +#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 +/*! @brief OpenGL debug context hint and attribute. + * + * OpenGL debug context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and + * [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib). + */ +#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 +/*! @brief OpenGL profile hint and attribute. + * + * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and + * [attribute](@ref GLFW_OPENGL_PROFILE_attrib). + */ +#define GLFW_OPENGL_PROFILE 0x00022008 +/*! @brief Context flush-on-release hint and attribute. + * + * Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and + * [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib). + */ +#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 +/*! @brief Context error suppression hint and attribute. + * + * Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and + * [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib). + */ +#define GLFW_CONTEXT_NO_ERROR 0x0002200A +/*! @brief Context creation API hint and attribute. + * + * Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and + * [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib). + */ +#define GLFW_CONTEXT_CREATION_API 0x0002200B +/*! @brief Window content area scaling window + * [window hint](@ref GLFW_SCALE_TO_MONITOR). + */ +#define GLFW_SCALE_TO_MONITOR 0x0002200C +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint). + */ +#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). + */ +#define GLFW_COCOA_FRAME_NAME 0x00023002 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint). + */ +#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003 +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ +#define GLFW_X11_CLASS_NAME 0x00024001 +/*! @brief X11 specific + * [window hint](@ref GLFW_X11_CLASS_NAME_hint). + */ +#define GLFW_X11_INSTANCE_NAME 0x00024002 +/*! @} */ + +#define GLFW_NO_API 0 +#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_LOCK_KEY_MODS 0x00033004 +#define GLFW_RAW_MOUSE_MOTION 0x00033005 + +#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 + +#define GLFW_NATIVE_CONTEXT_API 0x00036001 +#define GLFW_EGL_CONTEXT_API 0x00036002 +#define GLFW_OSMESA_CONTEXT_API 0x00036003 + +/*! @defgroup shapes Standard cursor shapes + * @brief Standard system 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 + +/*! @addtogroup init + * @{ */ +/*! @brief Joystick hat buttons init hint. + * + * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). + */ +#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). + */ +#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). + */ +#define GLFW_COCOA_MENUBAR 0x00051002 +/*! @} */ + +#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. + * + * @sa @ref context_glext + * @sa @ref glfwGetProcAddress + * + * @since Added in version 3.0. + * + * @ingroup context + */ +typedef void (*GLFWglproc)(void); + +/*! @brief Vulkan API function pointer type. + * + * Generic function pointer used for returning Vulkan API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref vulkan_proc + * @sa @ref glfwGetInstanceProcAddress + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +typedef void (*GLFWvkproc)(void); + +/*! @brief Opaque monitor object. + * + * Opaque monitor object. + * + * @see @ref monitor_object + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef struct GLFWmonitor GLFWmonitor; + +/*! @brief Opaque window object. + * + * Opaque window object. + * + * @see @ref window_object + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef struct GLFWwindow GLFWwindow; + +/*! @brief Opaque cursor object. + * + * Opaque cursor object. + * + * @see @ref cursor_object + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef struct GLFWcursor GLFWcursor; + +/*! @brief The function pointer type for error callbacks. + * + * This is the function pointer type for error callbacks. An error callback + * function has the following signature: + * @code + * void callback_name(int error_code, const char* description) + * @endcode + * + * @param[in] error_code An [error code](@ref errors). Future releases may add + * more error codes. + * @param[in] description A UTF-8 encoded string describing the error. + * + * @pointer_lifetime The error description string is valid until the callback + * function returns. + * + * @sa @ref error_handling + * @sa @ref glfwSetErrorCallback + * + * @since Added in version 3.0. + * + * @ingroup init + */ +typedef void (* GLFWerrorfun)(int,const char*); + +/*! @brief The function pointer type for window position callbacks. + * + * This is the function pointer type for window position callbacks. A window + * position callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int xpos, int ypos) + * @endcode + * + * @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 content area of the window. + * @param[in] ypos The new y-coordinate, in screen coordinates, of the + * upper-left corner of the content area of the window. + * + * @sa @ref window_pos + * @sa @ref glfwSetWindowPosCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); + +/*! @brief The function pointer type for window size callbacks. + * + * This is the function pointer type for window size callbacks. A window size + * callback function has the following signature: + * @code + * void callback_name(GLFWwindow* window, int width, int height) + * @endcode + * + * @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 @ref window_size + * @sa @ref glfwSetWindowSizeCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); + +/*! @brief The function pointer type for window close callbacks. + * + * This is the function pointer type for window close callbacks. A window + * close callback function has the following signature: + * @code + * void function_name(GLFWwindow* window) + * @endcode + * + * @param[in] window The window that the user attempted to close. + * + * @sa @ref window_close + * @sa @ref glfwSetWindowCloseCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowclosefun)(GLFWwindow*); + +/*! @brief The function pointer type for window content refresh callbacks. + * + * This is the function pointer type for window content refresh callbacks. + * A window content refresh callback function has the following signature: + * @code + * void function_name(GLFWwindow* window); + * @endcode + * + * @param[in] window The window whose content needs to be refreshed. + * + * @sa @ref window_refresh + * @sa @ref glfwSetWindowRefreshCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); + +/*! @brief The function pointer type for window focus callbacks. + * + * This is the function pointer type for window focus callbacks. A window + * focus callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode + * + * @param[in] window The window that gained or lost input focus. + * @param[in] focused `GLFW_TRUE` if the window was given input focus, or + * `GLFW_FALSE` if it lost it. + * + * @sa @ref window_focus + * @sa @ref glfwSetWindowFocusCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); + +/*! @brief The function pointer type for window iconify callbacks. + * + * This is the function pointer type for window iconify callbacks. A window + * iconify callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode + * + * @param[in] window The window that was iconified or restored. + * @param[in] iconified `GLFW_TRUE` if the window was iconified, or + * `GLFW_FALSE` if it was restored. + * + * @sa @ref window_iconify + * @sa @ref glfwSetWindowIconifyCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); + +/*! @brief The function pointer type for window maximize callbacks. + * + * This is the function pointer type for window maximize callbacks. A window + * maximize callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode + * + * @param[in] window The window that was maximized or restored. + * @param[in] iconified `GLFW_TRUE` if the window was maximized, or + * `GLFW_FALSE` if it was restored. + * + * @sa @ref window_maximize + * @sa glfwSetWindowMaximizeCallback + * + * @since Added in version 3.3. + * + * @ingroup window + */ +typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int); + +/*! @brief The function pointer type for framebuffer size callbacks. + * + * This is the function pointer type for framebuffer size callbacks. + * A framebuffer size callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * + * @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 @ref window_fbsize + * @sa @ref glfwSetFramebufferSizeCallback + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); + +/*! @brief The function pointer type for window content scale callbacks. + * + * This is the function pointer type for window content scale callbacks. + * A window content scale callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode + * + * @param[in] window The window whose content scale changed. + * @param[in] xscale The new x-axis content scale of the window. + * @param[in] yscale The new y-axis content scale of the window. + * + * @sa @ref window_scale + * @sa @ref glfwSetWindowContentScaleCallback + * + * @since Added in version 3.3. + * + * @ingroup window + */ +typedef void (* GLFWwindowcontentscalefun)(GLFWwindow*,float,float); + +/*! @brief The function pointer type for mouse button callbacks. + * + * This is the function pointer type for mouse button callback functions. + * A mouse button callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode + * + * @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`. Future releases + * may add more actions. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa @ref input_mouse_button + * @sa @ref glfwSetMouseButtonCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle and modifier mask parameters. + * + * @ingroup input + */ +typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); + +/*! @brief The function pointer type for cursor position callbacks. + * + * This is the function pointer type for cursor position callbacks. A cursor + * position callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] xpos The new cursor x-coordinate, relative to the left edge of + * the content area. + * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the + * content area. + * + * @sa @ref cursor_pos + * @sa @ref glfwSetCursorPosCallback + * + * @since Added in version 3.0. Replaces `GLFWmouseposfun`. + * + * @ingroup input + */ +typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); + +/*! @brief The function pointer type for cursor enter/leave callbacks. + * + * This is the function pointer type for cursor enter/leave callbacks. + * A cursor enter/leave callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content + * area, or `GLFW_FALSE` if it left it. + * + * @sa @ref cursor_enter + * @sa @ref glfwSetCursorEnterCallback + * + * @since Added in version 3.0. + * + * @ingroup input + */ +typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); + +/*! @brief The function pointer type for scroll callbacks. + * + * This is the function pointer type for scroll callbacks. A scroll callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode + * + * @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 @ref scrolling + * @sa @ref glfwSetScrollCallback + * + * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. + * + * @ingroup input + */ +typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); + +/*! @brief The function pointer type for keyboard key callbacks. + * + * This is the function pointer type for keyboard key callbacks. A keyboard + * key callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode + * + * @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`. Future + * releases may add more actions. + * @param[in] mods Bit field describing which [modifier keys](@ref mods) were + * held down. + * + * @sa @ref input_key + * @sa @ref glfwSetKeyCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle, scancode and modifier mask parameters. + * + * @ingroup input + */ +typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); + +/*! @brief The function pointer type for Unicode character callbacks. + * + * This is the function pointer type for Unicode character callbacks. + * A Unicode character callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] codepoint The Unicode code point of the character. + * + * @sa @ref input_char + * @sa @ref glfwSetCharCallback + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter. + * + * @ingroup input + */ +typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); + +/*! @brief The function pointer type for Unicode character with modifiers + * callbacks. + * + * This is the function pointer type for Unicode character with modifiers + * callbacks. It is called for each input character, regardless of what + * modifier keys are held down. A Unicode character with modifiers callback + * function has the following signature: + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode + * + * @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 @ref input_char + * @sa @ref glfwSetCharModsCallback + * + * @deprecated Scheduled for removal in version 4.0. + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); + +/*! @brief The function pointer type for path drop callbacks. + * + * This is the function pointer type for path drop callbacks. A path drop + * callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] path_count The number of dropped paths. + * @param[in] paths The UTF-8 encoded file and/or directory path names. + * + * @pointer_lifetime The path array and its strings are valid until the + * callback function returns. + * + * @sa @ref path_drop + * @sa @ref glfwSetDropCallback + * + * @since Added in version 3.1. + * + * @ingroup input + */ +typedef void (* GLFWdropfun)(GLFWwindow*,int,const char*[]); + +/*! @brief The function pointer type for monitor configuration callbacks. + * + * This is the function pointer type for monitor configuration callbacks. + * A monitor callback function has the following signature: + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode + * + * @param[in] monitor The monitor that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. + * + * @sa @ref monitor_event + * @sa @ref glfwSetMonitorCallback + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); + +/*! @brief The function pointer type for joystick configuration callbacks. + * + * This is the function pointer type for joystick configuration callbacks. + * A joystick configuration callback function has the following signature: + * @code + * void function_name(int jid, int event) + * @endcode + * + * @param[in] jid The joystick that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future + * releases may add more events. + * + * @sa @ref joystick_event + * @sa @ref glfwSetJoystickCallback + * + * @since Added in version 3.2. + * + * @ingroup input + */ +typedef void (* GLFWjoystickfun)(int,int); + +/*! @brief Video mode type. + * + * This describes a single video mode. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoMode + * @sa @ref glfwGetVideoModes + * + * @since Added in version 1.0. + * @glfw3 Added refresh rate member. + * + * @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 @ref monitor_gamma + * @sa @ref glfwGetGammaRamp + * @sa @ref glfwSetGammaRamp + * + * @since Added in version 3.0. + * + * @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. + * + * This describes a single 2D image. See the documentation for each related + * function what the expected pixel format is. + * + * @sa @ref cursor_custom + * @sa @ref window_icon + * + * @since Added in version 2.1. + * @glfw3 Removed format and bytes-per-pixel members. + * + * @ingroup window + */ +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; + +/*! @brief Gamepad input state + * + * This describes the input state of a gamepad. + * + * @sa @ref gamepad + * @sa @ref glfwGetGamepadState + * + * @since Added in version 3.3. + * + * @ingroup input + */ +typedef struct GLFWgamepadstate +{ + /*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS` + * or `GLFW_RELEASE`. + */ + unsigned char buttons[15]; + /*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0 + * to 1.0 inclusive. + */ + float axes[6]; +} GLFWgamepadstate; + + +/************************************************************************* + * 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 `GLFW_TRUE` immediately. + * + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark @macos 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 the @ref + * GLFW_COCOA_CHDIR_RESOURCES init hint. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa @ref glfwTerminate + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark This function may be called before @ref glfwInit. + * + * @warning The contexts of any remaining windows must not be current on any + * other thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa @ref glfwInit + * + * @since Added in version 1.0. + * + * @ingroup init + */ +GLFWAPI void glfwTerminate(void); + +/*! @brief Sets the specified init hint to the desired value. + * + * This function sets hints for the next initialization of GLFW. + * + * The values you set hints to are never reset by GLFW, but they only take + * effect during initialization. Once GLFW has been initialized, any values + * you set will be ignored until the library is terminated and initialized + * again. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [init hint](@ref init_hints) to set. + * @param[in] value The new value of the init hint. + * + * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref + * GLFW_INVALID_VALUE. + * + * @remarks This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa init_hints + * @sa glfwInit + * + * @since Added in version 3.3. + * + * @ingroup init + */ +GLFWAPI void glfwInitHint(int hint, int value); + +/*! @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`. + * + * @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`. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa @ref glfwGetVersionString + * + * @since Added in version 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. It should not be confused with the OpenGL or OpenGL + * ES version string, queried with `glGetString`. + * + * __Do not use the version string__ to parse the GLFW library version. The + * @ref glfwGetVersion function provides the version of the running library + * binary in numerical format. + * + * @return The ASCII encoded GLFW version string. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @pointer_lifetime The returned string is static and compile-time generated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa @ref glfwGetVersion + * + * @since Added in version 3.0. + * + * @ingroup init + */ +GLFWAPI const char* glfwGetVersionString(void); + +/*! @brief Returns and clears the last error for the calling thread. + * + * This function returns and clears the [error code](@ref errors) of the last + * error that occurred on the calling thread, and optionally a UTF-8 encoded + * human-readable description of it. If no error has occurred since the last + * call, it returns @ref GLFW_NO_ERROR (zero) and the description pointer is + * set to `NULL`. + * + * @param[in] description Where to store the error description pointer, or `NULL`. + * @return The last error code for the calling thread, or @ref GLFW_NO_ERROR + * (zero). + * + * @errors None. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * next error occurs or the library is terminated. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref error_handling + * @sa @ref glfwSetErrorCallback + * + * @since Added in version 3.3. + * + * @ingroup init + */ +GLFWAPI int glfwGetError(const char** description); + +/*! @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 code is set before the callback is called. Calling @ref + * glfwGetError from the error callback will return the same value as the error + * code argument. + * + * 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] callback The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set. + * + * @callback_signature + * @code + * void callback_name(int error_code, const char* description) + * @endcode + * For more information about the callback parameters, see the + * [callback pointer type](@ref GLFWerrorfun). + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref error_handling + * @sa @ref glfwGetError + * + * @since Added in version 3.0. + * + * @ingroup init + */ +GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); + +/*! @brief Returns the currently connected monitors. + * + * This function returns an array of handles for all currently connected + * monitors. The primary monitor is always first in the returned array. If no + * monitors were found, this function returns `NULL`. + * + * @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 no monitors were found or + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_monitors + * @sa @ref monitor_event + * @sa @ref glfwGetPrimaryMonitor + * + * @since Added in version 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 task bar or global menu bar are located. + * + * @return The primary monitor, or `NULL` if no monitors were found or if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @remark The primary monitor is always first in the array returned by @ref + * glfwGetMonitors. + * + * @sa @ref monitor_monitors + * @sa @ref glfwGetMonitors + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); + +/*! @brief Retrieves the work area of the monitor. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the work area of the specified monitor along with the work area + * size in screen coordinates. The work area is defined as the area of the + * monitor not occluded by the operating system task bar where present. If no + * task bar exists then the work area is the monitor resolution in screen + * coordinates. + * + * Any or all of the position and size arguments may be `NULL`. If an error + * occurs, all non-`NULL` position and size 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`. + * @param[out] width Where to store the monitor width, or `NULL`. + * @param[out] height Where to store the monitor height, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_workarea + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); + +/*! @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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @win32 calculates the returned physical size from the + * current resolution and system DPI instead of querying the monitor EDID data. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); + +/*! @brief Retrieves the content scale for the specified monitor. + * + * This function retrieves the content scale for the specified monitor. The + * content scale is the ratio between the current DPI and the platform's + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. + * + * The content scale may depend on both the monitor resolution and pixel + * density and on user settings. It may be very different from the raw DPI + * calculated from the physical size and current resolution. + * + * @param[in] monitor The monitor to query. + * @param[out] xscale Where to store the x-axis content scale, or `NULL`. + * @param[out] yscale Where to store the y-axis content scale, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_scale + * @sa @ref glfwGetWindowContentScale + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); + +/*! @brief Sets the user pointer of the specified monitor. + * + * This function sets the user-defined pointer of the specified monitor. The + * current value is retained until the monitor is disconnected. The initial + * value is `NULL`. + * + * This function may be called from the monitor callback, even for a monitor + * that is being disconnected. + * + * @param[in] monitor The monitor whose pointer to set. + * @param[in] pointer The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref monitor_userptr + * @sa @ref glfwGetMonitorUserPointer + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer); + +/*! @brief Returns the user pointer of the specified monitor. + * + * This function returns the current value of the user-defined pointer of the + * specified monitor. The initial value is `NULL`. + * + * This function may be called from the monitor callback, even for a monitor + * that is being disconnected. + * + * @param[in] monitor The monitor whose pointer to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref monitor_userptr + * @sa @ref glfwSetMonitorUserPointer + * + * @since Added in version 3.3. + * + * @ingroup monitor + */ +GLFWAPI void* glfwGetMonitorUserPointer(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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWmonitor* monitor, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmonitorfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_event + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoMode + * + * @since Added in version 1.0. + * @glfw3 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa @ref glfwGetVideoModes + * + * @since Added in version 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 an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. + * + * The software controlled gamma ramp is applied _in addition_ to the hardware + * gamma correction, which today is usually an approximation of sRGB gamma. + * This means that setting a perfectly linear ramp, or gamma 1.0, will produce + * the default (usually sRGB-like) behavior. + * + * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref + * GLFW_SRGB_CAPABLE hint. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] gamma The desired exponent. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while + * returning `NULL`. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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. + * + * The software controlled gamma ramp is applied _in addition_ to the hardware + * gamma correction, which today is usually an approximation of sRGB gamma. + * This means that setting a perfectly linear ramp, or gamma 1.0, will produce + * the default (usually sRGB-like) behavior. + * + * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref + * GLFW_SRGB_CAPABLE hint. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] ramp The gamma ramp to use. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. + * + * @remark @win32 The gamma ramp size must be 256. + * + * @remark @wayland Gamma handling is a privileged protocol, this function + * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified gamma ramp is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHint + * @sa @ref glfwWindowHintString + * + * @since Added in version 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 this + * function or @ref glfwDefaultWindowHints, or until the library is terminated. + * + * Only integer value hints can be set with this function. String value hints + * are set with @ref glfwWindowHintString. + * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHintString + * @sa @ref glfwDefaultWindowHints + * + * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHint(int hint, int value); + +/*! @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 this + * function or @ref glfwDefaultWindowHints, or until the library is terminated. + * + * Only string type hints can be set with this function. Integer value hints + * are set with @ref glfwWindowHint. + * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * + * Some hints are platform specific. These may be set on any platform but they + * will only affect their specific platform. Other platforms will ignore them. + * Setting these hints requires no platform specific headers or functions. + * + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa @ref glfwWindowHint + * @sa @ref glfwDefaultWindowHints + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHintString(int hint, const char* value); + +/*! @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, see @ref + * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. + * + * To create a full screen window, you need to specify the monitor the window + * will cover. If no monitor is specified, the window will be windowed mode. + * 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 is not + * iconified, 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. + * + * Once you have created the window, you can switch it between windowed and + * full screen mode with @ref glfwSetWindowMonitor. This will not affect its + * OpenGL or OpenGL ES context. + * + * 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 GLFW_VISIBLE_hint) window + * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) + * it. + * + * As long as at least one full screen window is not iconified, 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` for + * 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @win32 Window creation will fail if the Microsoft GDI software + * OpenGL implementation is the only one available. + * + * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it + * will be set as the initial icon for the window. If no such icon is present, + * the `IDI_APPLICATION` icon will be used instead. To set a different icon, + * see @ref glfwSetWindowIcon. + * + * @remark @win32 The context to share resources with must not be current on + * any other thread. + * + * @remark @macos The OS only supports forward-compatible core profile contexts + * for OpenGL versions 3.2 and later. Before creating an OpenGL context of + * version 3.2 or later you must set the + * [GLFW_OPENGL_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and + * [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly. + * OpenGL 3.0 and 3.1 contexts are not supported at all on macOS. + * + * @remark @macos 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. + * + * @remark @macos The first time a window is created the menu bar is created. + * If GLFW finds a `MainMenu.nib` it is loaded and assumed to contain a menu + * bar. Otherwise a minimal menu bar is created manually with common commands + * like Hide, Quit and About. The About entry opens a minimal about dialog + * with information from the application's bundle. Menu bar creation can be + * disabled entirely with the @ref GLFW_COCOA_MENUBAR init hint. + * + * @remark @macos On OS X 10.10 and later the window frame will not be rendered + * at full resolution on Retina displays unless the + * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint) + * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the + * application bundle's `Info.plist`. For more information, see + * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) + * in the Mac Developer Library. The GLFW test and example programs use + * a custom `Info.plist` template for this, which can be found as + * `CMake/MacOSXBundleInfo.plist.in` in the source tree. + * + * @remark @macos When activating frame autosaving with + * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified + * window size and position may be overridden by previously saved values. + * + * @remark @x11 Some window managers will not respect the placement of + * initially hidden windows. + * + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * a window to reach its requested state. This means you may not be able to + * query the final size, position or other attributes directly after window + * creation. + * + * @remark @x11 The class part of the `WM_CLASS` window property will by + * default be set to the window title passed to this function. The instance + * part will use the contents of the `RESOURCE_NAME` environment variable, if + * present and not empty, or fall back to the window title. Set the + * [GLFW_X11_CLASS_NAME](@ref GLFW_X11_CLASS_NAME_hint) and + * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to + * override this. + * + * @remark @wayland Compositors should implement the xdg-decoration protocol + * for GLFW to decorate the window properly. If this protocol isn't + * supported, or if the compositor prefers client-side decorations, a very + * simple fallback frame will be drawn using the wp_viewporter protocol. A + * compositor can still emit close, maximize or fullscreen events, using for + * instance a keybind mechanism. If neither of these protocols is supported, + * the window won't be decorated. + * + * @remark @wayland A full screen window will not attempt to change the mode, + * no matter what the requested size or refresh rate. + * + * @remark @wayland Screensaver inhibition requires the idle-inhibit protocol + * to be implemented in the user's compositor. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa @ref glfwDestroyWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @note The context of the specified window must not be current on any other + * thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa @ref glfwCreateWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos The window title will not be updated until the next time you + * process events. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); + +/*! @brief Sets the icon for the specified window. + * + * This function sets the icon of the specified window. If passed an array of + * candidate images, those of or closest to the sizes desired by the system are + * selected. If no images are specified, the window reverts to its default + * icon. + * + * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight + * bits per channel with the red channel first. They are arranged canonically + * as packed sequential rows, starting from the top-left corner. + * + * The desired image sizes varies depending on platform and system settings. + * The selected images will be rescaled as needed. Good sizes include 16x16, + * 32x32 and 48x48. + * + * @param[in] window The window whose icon to set. + * @param[in] count The number of images in the specified array, or zero to + * revert to the default window icon. + * @param[in] images The images to create the icon from. This is ignored if + * count is zero. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @remark @macos The GLFW window has no icon, as it is not a document + * window, so this function does nothing. 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. + * + * @remark @wayland There is no existing protocol to change an icon, the + * window will thus inherit the one defined in the application's desktop file. + * This function always emits @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_icon + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); + +/*! @brief Retrieves the position of the content area of the specified window. + * + * This function retrieves the position, in screen coordinates, of the + * upper-left corner of the content 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 content area, or `NULL`. + * @param[out] ypos Where to store the y-coordinate of the upper-left corner of + * the content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland There is no way for an application to retrieve the global + * position of its windows, this function will always emit @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa @ref glfwSetWindowPos + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); + +/*! @brief Sets the position of the content area of the specified window. + * + * This function sets the position, in screen coordinates, of the upper-left + * corner of the content 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 content area. + * @param[in] ypos The y-coordinate of the upper-left corner of the content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland There is no way for an application to set the global + * position of its windows, this function will always emit @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa @ref glfwGetWindowPos + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); + +/*! @brief Retrieves the size of the content area of the specified window. + * + * This function retrieves the size, in screen coordinates, of the content 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 + * content area, or `NULL`. + * @param[out] height Where to store the height, in screen coordinates, of the + * content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa @ref glfwSetWindowSize + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Sets the size limits of the specified window. + * + * This function sets the size limits of the content area of the specified + * window. If the window is full screen, the size limits only take effect + * once it is made windowed. If the window is not resizable, this function + * does nothing. + * + * The size limits are applied immediately to a windowed mode window and may + * cause it to be resized. + * + * The maximum dimensions must be greater than or equal to the minimum + * dimensions and all must be greater than or equal to zero. + * + * @param[in] window The window to set limits for. + * @param[in] minwidth The minimum width, in screen coordinates, of the content + * area, or `GLFW_DONT_CARE`. + * @param[in] minheight The minimum height, in screen coordinates, of the + * content area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the content + * area, or `GLFW_DONT_CARE`. + * @param[in] maxheight The maximum height, in screen coordinates, of the + * content area, or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @remark @wayland The size limits will not be applied until the window is + * actually resized, either by the user or by the compositor. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa @ref glfwSetWindowAspectRatio + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); + +/*! @brief Sets the aspect ratio of the specified window. + * + * This function sets the required aspect ratio of the content area of the + * specified window. If the window is full screen, the aspect ratio only takes + * effect once it is made windowed. If the window is not resizable, this + * function does nothing. + * + * The aspect ratio is specified as a numerator and a denominator and both + * values must be greater than zero. For example, the common 16:9 aspect ratio + * is specified as 16 and 9, respectively. + * + * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect + * ratio limit is disabled. + * + * The aspect ratio is applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] numer The numerator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * @param[in] denom The denominator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @remark @wayland The aspect ratio will not be applied until the window is + * actually resized, either by the user or by the compositor. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa @ref glfwSetWindowSizeLimits + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); + +/*! @brief Sets the size of the content area of the specified window. + * + * This function sets the size, in screen coordinates, of the content area of + * the specified window. + * + * For full screen windows, this function updates the resolution of its desired + * video mode and switches to the video mode closest to it, without affecting + * the window's context. As the context is unaffected, the bit depths of the + * framebuffer remain unchanged. + * + * If you wish to update the refresh rate of the desired video mode in addition + * to its resolution, see @ref glfwSetWindowMonitor. + * + * 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, in screen coordinates, of the window + * content area. + * @param[in] height The desired height, in screen coordinates, of the window + * content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland A full screen window will not attempt to change the mode, + * no matter what the requested size. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa @ref glfwGetWindowSize + * @sa @ref glfwSetWindowMonitor + * + * @since Added in version 1.0. + * @glfw3 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * @sa @ref glfwSetFramebufferSizeCallback + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 3.1. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); + +/*! @brief Retrieves the content scale for the specified window. + * + * This function retrieves the content scale for the specified window. The + * content scale is the ratio between the current DPI and the platform's + * default DPI. This is especially important for text and any UI elements. If + * the pixel dimensions of your UI scaled by this look appropriate on your + * machine then it should appear at a reasonable size on other machines + * regardless of their DPI and scaling settings. This relies on the system DPI + * and scaling settings being somewhat correct. + * + * On systems where each monitors can have its own content scale, the window + * content scale will depend on which monitor the system considers the window + * to be on. + * + * @param[in] window The window to query. + * @param[out] xscale Where to store the x-axis content scale, or `NULL`. + * @param[out] yscale Where to store the y-axis content scale, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_scale + * @sa @ref glfwSetWindowContentScaleCallback + * @sa @ref glfwGetMonitorContentScale + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale); + +/*! @brief Returns the opacity of the whole window. + * + * This function returns the opacity of the window, including any decorations. + * + * The opacity (or alpha) value is a positive finite number between zero and + * one, where zero is fully transparent and one is fully opaque. If the system + * does not support whole window transparency, this function always returns one. + * + * The initial opacity value for newly created windows is one. + * + * @param[in] window The window to query. + * @return The opacity value of the specified window. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_transparency + * @sa @ref glfwSetWindowOpacity + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window); + +/*! @brief Sets the opacity of the whole window. + * + * This function sets the opacity of the window, including any decorations. + * + * The opacity (or alpha) value is a positive finite number between zero and + * one, where zero is fully transparent and one is fully opaque. + * + * The initial opacity value for newly created windows is one. + * + * A window created with framebuffer transparency may not use whole window + * transparency. The results of doing this are undefined. + * + * @param[in] window The window to set the opacity for. + * @param[in] opacity The desired opacity of the specified window. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_transparency + * @sa @ref glfwGetWindowOpacity + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland There is no concept of iconification in wl_shell, this + * function will emit @ref GLFW_PLATFORM_ERROR when using this deprecated + * protocol. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwRestoreWindow + * @sa @ref glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 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) or maximized. 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwIconifyWindow + * @sa @ref glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwRestoreWindow(GLFWwindow* window); + +/*! @brief Maximizes the specified window. + * + * This function maximizes the specified window if it was previously not + * maximized. If the window is already maximized, this function does nothing. + * + * If the specified window is a full screen window, this function does nothing. + * + * @param[in] window The window to maximize. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * @sa @ref glfwIconifyWindow + * @sa @ref glfwRestoreWindow + * + * @since Added in GLFW 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwMaximizeWindow(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. + * + * By default, windowed mode windows are focused when shown + * Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint + * to change this behavior for all newly created windows, or change the + * behavior for an existing window with @ref glfwSetWindowAttrib. + * + * @param[in] window The window to make visible. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa @ref glfwHideWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa @ref glfwShowWindow + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwHideWindow(GLFWwindow* window); + +/*! @brief Brings the specified window to front and sets input focus. + * + * This function brings the specified window to front and sets input focus. + * The window should already be visible and not iconified. + * + * By default, both windowed and full screen mode windows are focused when + * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to + * disable this behavior. + * + * Also by default, windowed mode windows are focused when shown + * with @ref glfwShowWindow. Set the + * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) to disable this behavior. + * + * __Do not use this function__ to steal focus from other applications unless + * you are certain that is what the user wants. Focus stealing can be + * extremely disruptive. + * + * For a less disruptive way of getting the user's attention, see + * [attention requests](@ref window_attention). + * + * @param[in] window The window to give input focus. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland It is not possible for an application to bring its windows + * to front, this function will always emit @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * @sa @ref window_attention + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwFocusWindow(GLFWwindow* window); + +/*! @brief Requests user attention to the specified window. + * + * This function requests user attention to the specified window. On + * platforms where this is not supported, attention is requested to the + * application as a whole. + * + * Once the user has given attention, usually by focusing the window or + * application, the system will end the request automatically. + * + * @param[in] window The window to request attention to. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @macos Attention is requested to the application as a whole, not the + * specific window. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attention + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwRequestWindowAttention(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](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref glfwSetWindowMonitor + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); + +/*! @brief Sets the mode, monitor, video mode and placement of a window. + * + * This function sets the monitor that the window uses for full screen mode or, + * if the monitor is `NULL`, makes it windowed mode. + * + * When setting a monitor, this function updates the width, height and refresh + * rate of the desired video mode and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * + * When the monitor is `NULL`, the position, width and height are used to + * place the window content area. The refresh rate is ignored when no monitor + * is specified. + * + * If you only wish to update the resolution of a full screen window or the + * size of a windowed mode window, see @ref glfwSetWindowSize. + * + * When a window transitions from full screen to windowed mode, this function + * restores any previous window settings such as whether it is decorated, + * floating, resizable, has size or aspect ratio limits, etc. + * + * @param[in] window The window whose monitor, size or video mode to set. + * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. + * @param[in] xpos The desired x-coordinate of the upper-left corner of the + * content area. + * @param[in] ypos The desired y-coordinate of the upper-left corner of the + * content area. + * @param[in] width The desired with, in screen coordinates, of the content + * area or video mode. + * @param[in] height The desired height, in screen coordinates, of the content + * area or video mode. + * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, + * or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark The OpenGL or OpenGL ES context will not be destroyed or otherwise + * affected by any resizing or mode switching, although you may need to update + * your viewport if the framebuffer size has changed. + * + * @remark @wayland The desired window position is ignored, as there is no way + * for an application to set this property. + * + * @remark @wayland Setting the window to full screen will not attempt to + * change the mode, no matter what the requested size or refresh rate. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref window_full_screen + * @sa @ref glfwGetWindowMonitor + * @sa @ref glfwSetWindowSize + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @remark Framebuffer related hints are not window attributes. See @ref + * window_attribs_fb for more information. + * + * @remark Zero is a valid value for many window and context related + * attributes so you cannot use a return value of zero as an indication of + * errors. However, this function should not fail as long as it is passed + * valid arguments and the library has been [initialized](@ref intro_init). + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attribs + * @sa @ref glfwSetWindowAttrib + * + * @since Added in version 3.0. Replaces `glfwGetWindowParam` and + * `glfwGetGLVersion`. + * + * @ingroup window + */ +GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); + +/*! @brief Sets an attribute of the specified window. + * + * This function sets the value of an attribute of the specified window. + * + * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), + * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), + * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib), + * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and + * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib). + * + * Some of these attributes are ignored for full screen windows. The new + * value will take effect if the window is later made windowed. + * + * Some of these attributes are ignored for windowed mode windows. The new + * value will take effect if the window is later made full screen. + * + * @param[in] window The window to set the attribute for. + * @param[in] attrib A supported window attribute. + * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark Calling @ref glfwGetWindowAttrib will always return the latest + * value, even if that value is ignored by the current mode of the window. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attribs + * @sa @ref glfwGetWindowAttrib + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa @ref glfwGetWindowUserPointer + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa @ref glfwSetWindowUserPointer + * + * @since Added in version 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 + * position, in screen coordinates, of the upper-left corner of the content + * area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int xpos, int ypos) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowposfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @wayland This callback will never be called, as there is no way for + * an application to know its global position. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback); + +/*! @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 content area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowsizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowclosefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @macos Selecting Quit from the application menu will trigger the + * close callback for all windows. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_close + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback); + +/*! @brief Sets the refresh callback for the specified window. + * + * This function sets the refresh callback of the specified window, which is + * called when the content 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, Aqua or Wayland, 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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowrefreshfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_refresh + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup window + */ +GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int focused) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowfocusfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int iconified) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowiconifyfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @wayland The wl_shell protocol has no concept of iconification, + * this callback will never be called when using this deprecated protocol. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun callback); + +/*! @brief Sets the maximize callback for the specified window. + * + * This function sets the maximization callback of the specified window, which + * is called when the window is maximized or restored. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int maximized) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowmaximizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_maximize + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int width, int height) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWframebuffersizefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun callback); + +/*! @brief Sets the window content scale callback for the specified window. + * + * This function sets the window content scale callback of the specified window, + * which is called when the content scale of the specified window changes. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, float xscale, float yscale) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWwindowcontentscalefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_scale + * @sa @ref glfwGetWindowContentScale + * + * @since Added in version 3.3. + * + * @ingroup window + */ +GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun callback); + +/*! @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. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwWaitEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 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. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwPollEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 2.5. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEvents(void); + +/*! @brief Waits with timeout 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, or until the specified timeout is reached. If + * 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. + * + * The timeout value must be a positive finite number. + * + * 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. + * + * Do not assume that callbacks you set will _only_ be called in response to + * event processing functions like this one. While it is necessary to poll for + * events, window systems that require GLFW to register callbacks of its own + * can pass events to GLFW in response to many window system function calls. + * GLFW will pass those events on to the application callbacks before + * returning. + * + * Event processing is not required for joystick input to work. + * + * @param[in] timeout The maximum amount of time, in seconds, to wait. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa @ref glfwPollEvents + * @sa @ref glfwWaitEvents + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEventsTimeout(double timeout); + +/*! @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 or @ref glfwWaitEventsTimeout to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref events + * @sa @ref glfwWaitEvents + * @sa @ref glfwWaitEventsTimeout + * + * @since Added in version 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 @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. + * + * @param[in] window The window to query. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref glfwSetInputMode + * + * @since Added in version 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 @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or + * @ref GLFW_RAW_MOUSE_MOTION. + * + * 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 + * content 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 `GLFW_TRUE` to + * enable sticky keys, or `GLFW_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 + * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_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. + * + * If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to + * enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled, + * callbacks that receive modifier bits will also have the @ref + * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, + * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. + * + * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` + * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is + * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, + * attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref + * glfwRawMouseMotionSupported to check for support. + * + * @param[in] window The window whose input mode to set. + * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or + * `GLFW_RAW_MOUSE_MOTION`. + * @param[in] value The new value of the specified input mode. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref glfwGetInputMode + * + * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. + * + * @ingroup input + */ +GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); + +/*! @brief Returns whether raw mouse motion is supported. + * + * This function returns whether raw mouse motion is supported on the current + * system. This status does not change after GLFW has been initialized so you + * only need to check this once. If you attempt to enable raw motion on + * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. + * + * Raw mouse motion is closer to the actual motion of the mouse across + * a surface. It is not affected by the scaling and acceleration applied to + * the motion of the desktop cursor. That processing is suitable for a cursor + * while raw motion is better for controlling for example a 3D camera. Because + * of this, raw mouse motion is only provided when the cursor is disabled. + * + * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref raw_mouse_motion + * @sa @ref glfwSetInputMode + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwRawMouseMotionSupported(void); + +/*! @brief Returns the layout-specific name of the specified printable key. + * + * This function returns the name of the specified printable key, encoded as + * UTF-8. This is typically the character that key would produce without any + * modifier keys, intended for displaying key bindings to the user. For dead + * keys, it is typically the diacritic it would add to a character. + * + * __Do not use this function__ for [text input](@ref input_char). You will + * break text input for many languages even if it happens to work for yours. + * + * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used to identify the key, + * otherwise the scancode is ignored. If you specify a non-printable key, or + * `GLFW_KEY_UNKNOWN` and a scancode that maps to a non-printable key, this + * function returns `NULL` but does not emit an error. + * + * This behavior allows you to always pass in the arguments in the + * [key callback](@ref input_key) without modification. + * + * The printable keys are: + * - `GLFW_KEY_APOSTROPHE` + * - `GLFW_KEY_COMMA` + * - `GLFW_KEY_MINUS` + * - `GLFW_KEY_PERIOD` + * - `GLFW_KEY_SLASH` + * - `GLFW_KEY_SEMICOLON` + * - `GLFW_KEY_EQUAL` + * - `GLFW_KEY_LEFT_BRACKET` + * - `GLFW_KEY_RIGHT_BRACKET` + * - `GLFW_KEY_BACKSLASH` + * - `GLFW_KEY_WORLD_1` + * - `GLFW_KEY_WORLD_2` + * - `GLFW_KEY_0` to `GLFW_KEY_9` + * - `GLFW_KEY_A` to `GLFW_KEY_Z` + * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` + * - `GLFW_KEY_KP_DECIMAL` + * - `GLFW_KEY_KP_DIVIDE` + * - `GLFW_KEY_KP_MULTIPLY` + * - `GLFW_KEY_KP_SUBTRACT` + * - `GLFW_KEY_KP_ADD` + * - `GLFW_KEY_KP_EQUAL` + * + * Names for printable keys depend on keyboard layout, while names for + * non-printable keys are the same across layouts but depend on the application + * language and should be localized along with other user interface text. + * + * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. + * @param[in] scancode The scancode of the key to query. + * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark The contents of the returned string may change when a keyboard + * layout change event is received. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key_name + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetKeyName(int key, int scancode); + +/*! @brief Returns the platform-specific scancode of the specified key. + * + * This function returns the platform-specific scancode of the specified key. + * + * If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this + * method will return `-1`. + * + * @param[in] key Any [named key](@ref keys). + * @return The platform-specific scancode for the key, or `-1` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref input_key + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwGetKeyScancode(int key); + +/*! @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 @ref 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. + * + * __Do not use this function__ to implement [text input](@ref input_char). + * + * @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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 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 @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function + * returns `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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup input + */ +GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); + +/*! @brief Retrieves the position of the cursor relative to the content area of + * the window. + * + * This function returns the position of the cursor, in screen coordinates, + * relative to the upper-left corner of the content 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 content area, or `NULL`. + * @param[out] ypos Where to store the cursor y-coordinate, relative to the to + * top edge of the content area, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa @ref glfwSetCursorPos + * + * @since Added in version 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 content area of the + * window. + * + * This function sets the position, in screen coordinates, of the cursor + * relative to the upper-left corner of the content 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 + * content area. + * @param[in] ypos The desired y-coordinate, relative to the top edge of the + * content area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @wayland This function will only work when the cursor mode is + * `GLFW_CURSOR_DISABLED`, otherwise it will do nothing. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa @ref glfwGetCursorPos + * + * @since Added in version 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, non-premultiplied RGBA, i.e. eight + * bits per channel with the red channel first. 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa @ref glfwDestroyCursor + * @sa @ref glfwCreateStandardCursor + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa @ref glfwCreateCursor + * + * @since Added in version 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. + * + * If the specified cursor is current for any window, that window will be + * reverted to the default cursor. This does not affect the cursor mode. + * + * @param[in] cursor The cursor object to destroy. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa @ref glfwCreateCursor + * + * @since Added in version 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 + * content 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * + * @since Added in version 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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWkeyfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback); + +/*! @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 macOS or Alt key + * on Windows. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback); + +/*! @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] callback 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](@ref error_handling) occurred. + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcharmodsfun). + * + * @deprecated Scheduled for removal in version 4.0. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int button, int action, int mods) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWmousebuttonfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @ingroup input + */ +GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback); + +/*! @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 + * content area of the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xpos, double ypos); + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorposfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * + * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback); + +/*! @brief Sets the cursor enter/leave callback. + * + * This function sets the cursor boundary crossing callback of the specified + * window, which is called when the cursor enters or leaves the content area of + * the window. + * + * @param[in] window The window whose callback to set. + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int entered) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWcursorenterfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_enter + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun callback); + +/*! @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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double xoffset, double yoffset) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWscrollfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref scrolling + * + * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. + * + * @ingroup input + */ +GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback); + +/*! @brief Sets the path drop callback. + * + * This function sets the path drop callback of the specified window, which is + * called when one or more dragged paths 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] callback 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). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, int path_count, const char* paths[]) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWdropfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @wayland File drop is currently unimplemented. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref path_drop + * + * @since Added in version 3.1. + * + * @ingroup input + */ +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback); + +/*! @brief Returns whether the specified joystick is present. + * + * This function returns whether the specified joystick is present. + * + * There is no need to call this function before other functions that accept + * a joystick ID, as they all check for presence before performing any other + * work. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick + * + * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. + * + * @ingroup input + */ +GLFWAPI int glfwJoystickPresent(int jid); + +/*! @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. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid 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 the joystick is not present or an error + * occurred. + * @return An array of axis values, or `NULL` if the joystick is not present or + * an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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 or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_axis + * + * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. + * + * @ingroup input + */ +GLFWAPI const float* glfwGetJoystickAxes(int jid, 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`. + * + * For backward compatibility with earlier versions that did not have @ref + * glfwGetJoystickHats, the button array also includes all hats, each + * represented as four buttons. The hats are in the same order as returned by + * __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and + * _left_. To disable these extra buttons, set the @ref + * GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid 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 the joystick is not present or an error + * occurred. + * @return An array of button states, or `NULL` if the joystick is not present + * or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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 or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_button + * + * @since Added in version 2.2. + * @glfw3 Changed to return a dynamic array. + * + * @ingroup input + */ +GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count); + +/*! @brief Returns the state of all hats of the specified joystick. + * + * This function returns the state of all hats of the specified joystick. + * Each element in the array is one of the following values: + * + * Name | Value + * ---- | ----- + * `GLFW_HAT_CENTERED` | 0 + * `GLFW_HAT_UP` | 1 + * `GLFW_HAT_RIGHT` | 2 + * `GLFW_HAT_DOWN` | 4 + * `GLFW_HAT_LEFT` | 8 + * `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP` + * `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN` + * `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP` + * `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN` + * + * The diagonal directions are bitwise combinations of the primary (up, right, + * down and left) directions and you can test for these individually by ANDing + * it with the corresponding direction. + * + * @code + * if (hats[2] & GLFW_HAT_RIGHT) + * { + * // State of hat 2 could be right-up, right or right-down + * } + * @endcode + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] count Where to store the number of hat states in the returned + * array. This is set to zero if the joystick is not present or an error + * occurred. + * @return An array of hat states, or `NULL` if the joystick is not present + * or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_hat + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, 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. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick + * is not present or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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 or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_name + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickName(int jid); + +/*! @brief Returns the SDL compatible GUID of the specified joystick. + * + * This function returns the SDL compatible GUID, as a UTF-8 encoded + * hexadecimal string, of the specified joystick. The returned string is + * allocated and freed by GLFW. You should not free it yourself. + * + * The GUID is what connects a joystick to a gamepad mapping. A connected + * joystick will always have a GUID even if there is no gamepad mapping + * assigned to it. + * + * If the specified joystick is not present this function will return `NULL` + * but will not generate an error. This can be used instead of first calling + * @ref glfwJoystickPresent. + * + * The GUID uses the format introduced in SDL 2.0.5. This GUID tries to + * uniquely identify the make and model of a joystick but does not identify + * a specific unit, e.g. all wired Xbox 360 controllers will have the same + * GUID on that platform. The GUID for a unit may vary between platforms + * depending on what hardware information the platform specific APIs provide. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick + * is not present or an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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 or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickGUID(int jid); + +/*! @brief Sets the user pointer of the specified joystick. + * + * This function sets the user-defined pointer of the specified joystick. The + * current value is retained until the joystick is disconnected. The initial + * value is `NULL`. + * + * This function may be called from the joystick callback, even for a joystick + * that is being disconnected. + * + * @param[in] jid The joystick whose pointer to set. + * @param[in] pointer The new value. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref joystick_userptr + * @sa @ref glfwGetJoystickUserPointer + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer); + +/*! @brief Returns the user pointer of the specified joystick. + * + * This function returns the current value of the user-defined pointer of the + * specified joystick. The initial value is `NULL`. + * + * This function may be called from the joystick callback, even for a joystick + * that is being disconnected. + * + * @param[in] jid The joystick whose pointer to return. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref joystick_userptr + * @sa @ref glfwSetJoystickUserPointer + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI void* glfwGetJoystickUserPointer(int jid); + +/*! @brief Returns whether the specified joystick has a gamepad mapping. + * + * This function returns whether the specified joystick is both present and has + * a gamepad mapping. + * + * If the specified joystick is present but does not have a gamepad mapping + * this function will return `GLFW_FALSE` but will not generate an error. Call + * @ref glfwJoystickPresent to check if a joystick is present regardless of + * whether it has a mapping. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwGetGamepadState + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwJoystickIsGamepad(int jid); + +/*! @brief Sets the joystick configuration callback. + * + * This function sets the joystick configuration callback, or removes the + * currently set callback. This is called when a joystick is connected to or + * disconnected from the system. + * + * For joystick connection and disconnection events to be delivered on all + * platforms, you need to call one of the [event processing](@ref events) + * functions. Joystick disconnection may also be detected and the callback + * called by joystick functions. The function will then return whatever it + * returns if the joystick is not present. + * + * @param[in] callback 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). + * + * @callback_signature + * @code + * void function_name(int jid, int event) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWjoystickfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_event + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback); + +/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings. + * + * This function parses the specified ASCII encoded string and updates the + * internal list with any gamepad mappings it finds. This string may + * contain either a single gamepad mapping or many mappings separated by + * newlines. The parser supports the full format of the `gamecontrollerdb.txt` + * source file including empty lines and comments. + * + * See @ref gamepad_mapping for a description of the format. + * + * If there is already a gamepad mapping for a given GUID in the internal list, + * it will be replaced by the one passed to this function. If the library is + * terminated and re-initialized the internal list will revert to the built-in + * default. + * + * @param[in] string The string containing the gamepad mappings. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwJoystickIsGamepad + * @sa @ref glfwGetGamepadName + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwUpdateGamepadMappings(const char* string); + +/*! @brief Returns the human-readable gamepad name for the specified joystick. + * + * This function returns the human-readable name of the gamepad from the + * gamepad mapping assigned to the specified joystick. + * + * If the specified joystick is not present or does not have a gamepad mapping + * this function will return `NULL` but will not generate an error. Call + * @ref glfwJoystickPresent to check whether it is present regardless of + * whether it has a mapping. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @return The UTF-8 encoded name of the gamepad, or `NULL` if the + * joystick is not present, does not have a mapping or an + * [error](@ref error_handling) occurred. + * + * @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, the gamepad mappings are updated or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwJoystickIsGamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetGamepadName(int jid); + +/*! @brief Retrieves the state of the specified joystick remapped as a gamepad. + * + * This function retrieves the state of the specified joystick remapped to + * an Xbox-like gamepad. + * + * If the specified joystick is not present or does not have a gamepad mapping + * this function will return `GLFW_FALSE` but will not generate an error. Call + * @ref glfwJoystickPresent to check whether it is present regardless of + * whether it has a mapping. + * + * The Guide button may not be available for input as it is often hooked by the + * system or the Steam client. + * + * Not all devices have all the buttons or axes provided by @ref + * GLFWgamepadstate. Unavailable buttons and axes will always report + * `GLFW_RELEASE` and 0.0 respectively. + * + * @param[in] jid The [joystick](@ref joysticks) to query. + * @param[out] state The gamepad input state of the joystick. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is + * connected, it has no gamepad mapping or an [error](@ref error_handling) + * occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref gamepad + * @sa @ref glfwUpdateGamepadMappings + * @sa @ref glfwJoystickIsGamepad + * + * @since Added in version 3.3. + * + * @ingroup input + */ +GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); + +/*! @brief Sets the clipboard to the specified string. + * + * This function sets the system clipboard to the specified, UTF-8 encoded + * string. + * + * @param[in] window Deprecated. Any valid window or `NULL`. + * @param[in] string A UTF-8 encoded string. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa @ref glfwGetClipboardString + * + * @since Added in version 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. If the clipboard is empty or + * if its contents cannot be converted, `NULL` is returned and a @ref + * GLFW_FORMAT_UNAVAILABLE error is generated. + * + * @param[in] window Deprecated. Any valid window or `NULL`. + * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa @ref glfwSetClipboardString + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); + +/*! @brief Returns the GLFW time. + * + * This function returns the current GLFW time, in seconds. Unless the time + * has been set using @ref glfwSetTime it measures time elapsed since GLFW was + * initialized. + * + * This function and @ref glfwSetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. + * + * 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 time, in seconds, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Reading and + * writing of the internal base time is not atomic, so it needs to be + * externally synchronized with calls to @ref glfwSetTime. + * + * @sa @ref time + * + * @since Added in version 1.0. + * + * @ingroup input + */ +GLFWAPI double glfwGetTime(void); + +/*! @brief Sets the GLFW time. + * + * This function sets the current GLFW time, in seconds. The value must be + * a positive finite number less than or equal to 18446744073.0, which is + * approximately 584.5 years. + * + * This function and @ref glfwGetTime are helper functions on top of @ref + * glfwGetTimerFrequency and @ref glfwGetTimerValue. + * + * @param[in] time The new value, in seconds. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @remark The upper limit of GLFW time is calculated as + * floor((264 - 1) / 109) and is due to implementations + * storing nanoseconds in 64 bits. The limit may be increased in the future. + * + * @thread_safety This function may be called from any thread. Reading and + * writing of the internal base time is not atomic, so it needs to be + * externally synchronized with calls to @ref glfwGetTime. + * + * @sa @ref time + * + * @since Added in version 2.2. + * + * @ingroup input + */ +GLFWAPI void glfwSetTime(double time); + +/*! @brief Returns the current value of the raw timer. + * + * This function returns the current value of the raw timer, measured in + * 1 / frequency seconds. To get the frequency, call @ref + * glfwGetTimerFrequency. + * + * @return The value of the timer, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa @ref glfwGetTimerFrequency + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerValue(void); + +/*! @brief Returns the frequency, in Hz, of the raw timer. + * + * This function returns the frequency, in Hz, of the raw timer. + * + * @return The frequency of the timer, in Hz, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa @ref glfwGetTimerValue + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerFrequency(void); + +/*! @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 must only be made current on + * a single thread at a time and each thread can have only a single current + * context at a time. + * + * When moving a context between threads, you must make it non-current on the + * old thread before making it current on the new one. + * + * 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 GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) + * hint. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * @param[in] window The window whose context to make current, or `NULL` to + * detach the current context. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa @ref glfwGetCurrentContext + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa @ref glfwMakeContextCurrent + * + * @since Added in version 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 when + * rendering with OpenGL or OpenGL ES. If the swap interval is greater than + * zero, the GPU driver waits the specified number of screen updates before + * swapping the buffers. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see `vkQueuePresentKHR` instead. + * + * @param[in] window The window whose buffers to swap. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark __EGL:__ The context of the specified window must be current on the + * calling thread. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa @ref glfwSwapInterval + * + * @since Added in version 1.0. + * @glfw3 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 OpenGL or OpenGL ES + * 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_. + * + * A context that supports either of the `WGL_EXT_swap_control_tear` and + * `GLX_EXT_swap_control_tear` extensions also accepts _negative_ swap + * intervals, which allows the driver to swap immediately even if a frame + * arrives a little bit late. You can check for these extensions with @ref + * glfwExtensionSupported. + * + * 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. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see the present mode of your swapchain instead. + * + * @param[in] interval The minimum number of screen updates to wait for + * until the buffers are swapped by @ref glfwSwapBuffers. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark This function is not called during context 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. + * + * @remark Some GPU drivers do not honor the requested swap interval, either + * because of a user setting that overrides the application's request or due to + * bugs in the driver. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa @ref glfwSwapBuffers + * + * @since Added in version 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 client API extension and 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. + * + * This function does not apply to Vulkan. If you are using Vulkan, see @ref + * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` + * and `vkEnumerateDeviceExtensionProperties` instead. + * + * @param[in] extension The ASCII encoded name of the extension. + * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` + * otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa @ref glfwGetProcAddress + * + * @since Added in version 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 OpenGL or OpenGL ES + * [core 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. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and + * `vkGetDeviceProcAddr` instead. + * + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark The address of a given function is not guaranteed to be the same + * between contexts. + * + * @remark This function may return a non-`NULL` address despite the + * associated version or extension not being available. Always check the + * context version or extension string first. + * + * @pointer_lifetime The returned function pointer is valid until the context + * is destroyed or the library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa @ref glfwExtensionSupported + * + * @since Added in version 1.0. + * + * @ingroup context + */ +GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); + +/*! @brief Returns whether the Vulkan loader and an ICD have been found. + * + * This function returns whether the Vulkan loader and any minimally functional + * ICD have been found. + * + * The availability of a Vulkan loader and even an ICD does not by itself + * guarantee that surface creation or even instance creation is possible. + * For example, on Fermi systems Nvidia will install an ICD that provides no + * actual Vulkan support. Call @ref glfwGetRequiredInstanceExtensions to check + * whether the extensions necessary for Vulkan surface creation are available + * and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue + * family of a physical device supports image presentation. + * + * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE` + * otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_support + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwVulkanSupported(void); + +/*! @brief Returns the Vulkan instance extensions required by GLFW. + * + * This function returns an array of names of Vulkan instance extensions required + * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the + * list will always contain `VK_KHR_surface`, so if you don't require any + * additional extensions you can pass this list directly to the + * `VkInstanceCreateInfo` struct. + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available. + * + * If Vulkan is available but no set of extensions allowing window surface + * creation was found, this function returns `NULL`. You may still use Vulkan + * for off-screen rendering and compute work. + * + * @param[out] count Where to store the number of extensions in the returned + * array. This is set to zero if an error occurred. + * @return An array of ASCII encoded extension names, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @remark Additional extensions may be required by future versions of GLFW. + * You should check if any extensions you wish to enable are already in the + * returned array, as it is an error to specify an extension more than once in + * the `VkInstanceCreateInfo` struct. + * + * @remark @macos This function currently supports either the + * `VK_MVK_macos_surface` extension from MoltenVK or `VK_EXT_metal_surface` + * extension. + * + * @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 + * library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_ext + * @sa @ref glfwCreateWindowSurface + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); + +#if defined(VK_VERSION_1_0) + +/*! @brief Returns the address of the specified Vulkan instance function. + * + * This function returns the address of the specified Vulkan core or extension + * function for the specified instance. If instance is set to `NULL` it can + * return any function exported from the Vulkan loader, including at least the + * following functions: + * + * - `vkEnumerateInstanceExtensionProperties` + * - `vkEnumerateInstanceLayerProperties` + * - `vkCreateInstance` + * - `vkGetInstanceProcAddr` + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available. + * + * This function is equivalent to calling `vkGetInstanceProcAddr` with + * a platform-specific query of the Vulkan loader as a fallback. + * + * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve + * functions related to instance creation. + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @pointer_lifetime The returned function pointer is valid until the library + * is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_proc + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); + +/*! @brief Returns whether the specified queue family can present images. + * + * This function returns whether the specified queue family of the specified + * physical device supports presentation to the platform GLFW was built for. + * + * If Vulkan or the required window surface creation instance extensions are + * not available on the machine, or if the specified instance was not created + * with the required extensions, this function returns `GLFW_FALSE` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is at least minimally available and @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * @param[in] instance The instance that the physical device belongs to. + * @param[in] device The physical device that the queue family belongs to. + * @param[in] queuefamily The index of the queue family to query. + * @return `GLFW_TRUE` if the queue family supports presentation, or + * `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remark @macos This function currently always returns `GLFW_TRUE`, as the + * `VK_MVK_macos_surface` extension does not provide + * a `vkGetPhysicalDevice*PresentationSupport` type function. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_present + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @brief Creates a Vulkan surface for the specified window. + * + * This function creates a Vulkan surface for the specified window. + * + * If the Vulkan loader or at least one minimally functional ICD were not found, + * this function returns `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref + * GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported to check whether + * Vulkan is at least minimally available. + * + * If the required window surface creation instance extensions are not + * available or if the specified instance was not created with these extensions + * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * The window surface cannot be shared with another API so the window must + * have been created with the [client api hint](@ref GLFW_CLIENT_API_attrib) + * set to `GLFW_NO_API` otherwise it generates a @ref GLFW_INVALID_VALUE error + * and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`. + * + * The window surface must be destroyed before the specified Vulkan instance. + * It is the responsibility of the caller to destroy the window surface. GLFW + * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the + * surface. + * + * @param[in] instance The Vulkan instance to create the surface in. + * @param[in] window The window to create the surface for. + * @param[in] allocator The allocator to use, or `NULL` to use the default + * allocator. + * @param[out] surface Where to store the handle of the surface. This is set + * to `VK_NULL_HANDLE` if an error occurred. + * @return `VK_SUCCESS` if successful, or a Vulkan error code if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE, @ref GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE + * + * @remark If an error occurs before the creation call is made, GLFW returns + * the Vulkan error code most appropriate for the error. Appropriate use of + * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should + * eliminate almost all occurrences of these errors. + * + * @remark @macos This function currently only supports the + * `VK_MVK_macos_surface` extension from MoltenVK. + * + * @remark @macos This function creates and sets a `CAMetalLayer` instance for + * the window content view, which is required for MoltenVK to function. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_surface + * @sa @ref glfwGetRequiredInstanceExtensions + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +#endif /*VK_VERSION_1_0*/ + + +/************************************************************************* + * 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 + +/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally + * defined by some gl.h variants (OpenBSD) so define it after if needed. + */ +#ifndef GLAPIENTRY + #define GLAPIENTRY APIENTRY +#endif + +/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_h_ */ + diff --git a/libultraship/libultraship/Lib/GLFW/GLFW/glfw3native.h b/libultraship/libultraship/Lib/GLFW/GLFW/glfw3native.h new file mode 100644 index 000000000..267e75ca9 --- /dev/null +++ b/libultraship/libultraship/Lib/GLFW/GLFW/glfw3native.h @@ -0,0 +1,525 @@ +/************************************************************************* + * GLFW 3.3 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2018 Camilla Löwy + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as 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 + *************************************************************************/ + +/*! @file glfw3native.h + * @brief The header of the native access functions. + * + * This is the header file of the native access functions. See @ref native for + * more information. + */ +/*! @defgroup native Native access + * @brief Functions related to accessing native handles. + * + * **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 may define zero or more + * window system API macro and zero or more context creation API macros. + * + * The chosen backends must match those the library was compiled for. Failure + * to do this will cause a link-time error. + * + * The available window API macros are: + * * `GLFW_EXPOSE_NATIVE_WIN32` + * * `GLFW_EXPOSE_NATIVE_COCOA` + * * `GLFW_EXPOSE_NATIVE_X11` + * * `GLFW_EXPOSE_NATIVE_WAYLAND` + * + * The available context API macros are: + * * `GLFW_EXPOSE_NATIVE_WGL` + * * `GLFW_EXPOSE_NATIVE_NSGL` + * * `GLFW_EXPOSE_NATIVE_GLX` + * * `GLFW_EXPOSE_NATIVE_EGL` + * * `GLFW_EXPOSE_NATIVE_OSMESA` + * + * 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) || defined(GLFW_EXPOSE_NATIVE_WGL) + // 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 + #if defined(GLFW_APIENTRY_DEFINED) + #undef APIENTRY + #undef GLFW_APIENTRY_DEFINED + #endif + #include +#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) + #if defined(__OBJC__) + #import + #else + #include + typedef void* id; + #endif +#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) + #include + #include +#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ +#endif +#if defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ +#endif +#if defined(GLFW_EXPOSE_NATIVE_GLX) + #include +#endif +#if defined(GLFW_EXPOSE_NATIVE_EGL) + #include +#endif +#if defined(GLFW_EXPOSE_NATIVE_OSMESA) + #include +#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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI Window glfwGetX11Window(GLFWwindow* window); + +/*! @brief Sets the current primary selection to the specified string. + * + * @param[in] string A UTF-8 encoded string. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwGetX11SelectionString + * @sa glfwSetClipboardString + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI void glfwSetX11SelectionString(const char* string); + +/*! @brief Returns the contents of the current primary selection as a string. + * + * If the selection is empty or if its contents cannot be converted, `NULL` + * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated. + * + * @return The contents of the selection as a UTF-8 encoded string, or `NULL` + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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 + * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the + * library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwSetX11SelectionString + * @sa glfwGetClipboardString + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI const char* glfwGetX11SelectionString(void); +#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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); + +/*! @brief Returns the `GLXWindow` of the specified window. + * + * @return The `GLXWindow` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) +/*! @brief Returns the `struct wl_display*` used by GLFW. + * + * @return The `struct wl_display*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); + +/*! @brief Returns the `struct wl_output*` of the specified monitor. + * + * @return The `struct wl_output*` of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the main `struct wl_surface*` of the specified window. + * + * @return The main `struct wl_surface*` of the specified window, or `NULL` if + * an [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_surface* glfwGetWaylandWindow(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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_OSMESA) +/*! @brief Retrieves the color buffer associated with the specified window. + * + * @param[in] window The window whose color buffer to retrieve. + * @param[out] width Where to store the width of the color buffer, or `NULL`. + * @param[out] height Where to store the height of the color buffer, or `NULL`. + * @param[out] format Where to store the OSMesa pixel format of the color + * buffer, or `NULL`. + * @param[out] buffer Where to store the address of the color buffer, or + * `NULL`. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer); + +/*! @brief Retrieves the depth buffer associated with the specified window. + * + * @param[in] window The window whose depth buffer to retrieve. + * @param[out] width Where to store the width of the depth buffer, or `NULL`. + * @param[out] height Where to store the height of the depth buffer, or `NULL`. + * @param[out] bytesPerValue Where to store the number of bytes per depth + * buffer element, or `NULL`. + * @param[out] buffer Where to store the address of the depth buffer, or + * `NULL`. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer); + +/*! @brief Returns the `OSMesaContext` of the specified window. + * + * @return The `OSMesaContext` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.3. + * + * @ingroup native + */ +GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_native_h_ */ + diff --git a/libultraship/libultraship/Lib/GLFW/GLFW/glfw_config.h b/libultraship/libultraship/Lib/GLFW/GLFW/glfw_config.h new file mode 100644 index 000000000..78e671e60 --- /dev/null +++ b/libultraship/libultraship/Lib/GLFW/GLFW/glfw_config.h @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2010-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as 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 +/* #undef _GLFW_X11 */ +// Define this to 1 if building GLFW for Win32 +#define _GLFW_WIN32 +// Define this to 1 if building GLFW for Cocoa +/* #undef _GLFW_COCOA */ +// Define this to 1 if building GLFW for Wayland +/* #undef _GLFW_WAYLAND */ +// Define this to 1 if building GLFW for OSMesa +/* #undef _GLFW_OSMESA */ + +// Define this to 1 if building as a shared library / dynamic library / DLL +#define _GLFW_BUILD_DLL +// Define this to 1 to use Vulkan loader linked statically into application +/* #undef _GLFW_VULKAN_STATIC */ + +// Define this to 1 to force use of high-performance GPU on hybrid systems +/* #undef _GLFW_USE_HYBRID_HPG */ + +// Define this to 1 if xkbcommon supports the compose key +/* #undef HAVE_XKBCOMMON_COMPOSE_H */ +// Define this to 1 if the libc supports memfd_create() +/* #undef HAVE_MEMFD_CREATE */ + diff --git a/libultraship/libultraship/Lib/GLFW/glfw3.dll b/libultraship/libultraship/Lib/GLFW/glfw3.dll new file mode 100644 index 0000000000000000000000000000000000000000..a5a9eb971b80f567490378d5396277ac3e504c79 GIT binary patch literal 196608 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 literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/GLFW/glfw3dll.exp b/libultraship/libultraship/Lib/GLFW/glfw3dll.exp new file mode 100644 index 0000000000000000000000000000000000000000..4a7f4e9faeb79c26b6b370bfd15e56250d5fcc32 GIT binary patch literal 18558 zcmeI3jei`)dB-0agAEw4@hjMXFvi#*q|=>VPR4+3$?ukJBw02fz-QgbI(*U{_hL)n z5EBT61R6qULx>Y-LkMkXfIu2Ikd{yg1ZW@$ZGq61fN4ofS|~IjEot(5o@ZxocIKSF zfcwDcx8LX4-I>|h+1=+EZ>XCpCx33M1u zq{Hb5nnaW7NIHs+rYUp`9ZSd2RGLP|({!3aGieshra5#1ok(+O9-Txd(r_y{n zjTX@9w2;oAMYNdCq_e1j&Zb6cq8K$(oD$SRt<*;Cl%x(?Lg&y@I+xC)^D(zArxnym zU9^%`(P~;lYiS*=rw!Ci8)*}5rVFTtdZ~}LP(N*@ZFC`BL>JQlT|$@AWwf1Aw1WmQ zXJ%-KcG56q>2lgdIU1o+%2R=^pdyv1OcmNqduWWt=}Nka_R`1bYWg_sqn){-J&DG2 zE+?w9m`Rm0ot0uKU$j7PIW?M271N$!Yj!l9-(z_y=&cloQiB=cU74X&C0AC%n(Sz~ z6yQ?1m>;)}*p(4t9dhMZIWty zj_wpU#+70*Gg|J_=WQwnRpEX9ssJAIo@bMWtNMk9v6ZmbG2xRA%=zso=_>+J@QnHf&2N zgTBLc%;*S#`}$1SO_26Z*z6rdy{(pX=SQ>Ud{H`lvmaX~Xt`vs2X?uXf{^`zFN*V1loF@^q?T zjT>Q3ONB*mZrxg5#;v`>R7_c|L8KPBAMMei*gqMjuT6#2V744~ih5epg986x?l@b6 zeoM$CUdq6ow?gJ zL%Rx(#H90KOn3!OW2`BKI`rn=jAWo-|6g4Z_jT@yWfa39rn?@sC1KZI4E zHPPeQw|m$eYd~ouY78hf^kjxGdk@z>VefFhl1oe9L{A#d9^o089O59bY``5I+`Qo) zec5vGtPGJi5Qg)6w3>SQJ*k2|hjbq3#r9ght9GaKeXlQ59LbKFH<2v`e2r&@1e6`kC)GT~fT-LxJl3hl1L`#0g8obX0I59Q&a z>QNpcYJrq&T?BQbY&A?EyuCAPK=~R)BxBFRVe>h)ON6$s!)DjR2poSDwMa28U~xK3gs6><-q2s zLV1U%0@w+vP<~NV8H@ujlkiPJv|rR1*j!a8za(le7+N_| zPF98TE>SmtouUfmpNP5%tX>t$KNWQg*r}>eenr%6VDnX>yj#@mV5g}<`BhQ-!E_vP z8}1Qy7ue~lP<~C+-Czq#9}@KoKuHz(n2`r%s<+nt=3f7_uK@iW3!Om9&_B~Nkz?P{3dtB61u;r@2{#MisuobGno)9$$tWy=( zlcMHw!!=d_Kc_)*jiO!&x&dR zTc--_IZ;Wl^{T-BPSjGc4XVI?C~6s4w<@sbMRkE~R0Z~es5M}lRDu0S)CRE4s=$6M zYBSgcs=$6Cst>G371)cSwt@Ak0{eSW17Lls!2UthcCam~!2VHG8mwOx*h`{@!M3Ub zds$QtY?~^uS40)SE>s2fQ&DBGi&TNVDryYuVpU-OBx*0%fGV(m7PSxT5>;UTBI-J@ zOI3lrCh7*T%T$5=Ow>(a+f{+RF6tJrlq#?{MBN6qLlxLTQMZE)ssejc)PAtEDzJYQ zbr)Dh71+Otx*Kdr71&#%?giVa3hd{i?gJZE1@`Zv9stX#0{ah94})E<3hZrB2f%iz z0{exiN5OKc!2VOzV_+ky!2V0r6JVpNz}^w{G+160*t?>h11qQk`)^S%fL);q>^)I0 zf)!PPy)Wt|u#zgU{}J^nSXmX=FGaluR#64^D^Ul*cB=yWK-61cdsKn_TGZQMW2(UZ zSJXRTU0P}B!tSE&N~ji?X7_NoH=e^LBO^)XcwkS7r}5$tMJU_37( z3JUgdVUxk?giQh4Cu|DX1YuLbt`RmB>@Z<7z&;^t2G~SlbHJ_@HV5o*Ve`PQ6E+Ww z^E{KN9_*9C>cJ)nTL5;wumxa~g)IX617VB6juh4ac7reox#p{;^6XMK4V%=tq={dZ zOHJ$WiQ3eK0OAOL95=1TcX(w-69+-hPBbPO<4t&RjW?BwgH7GpQGP}5$>hYGK!~(4 zGgiQZdg(L{6r+EG-?4Zhx*lVzJBtskQhumhzo=(%{f4z0*W-D7?lcJ^^3-mZHou0XX?+EDydw3Z@H4r z<_F@j=8l2R{K!ZJ0fzB`{?38Ed_Gqi=LWwG7~h z1G((zF0>9e{~StALx<93T%|}jxE>aCw{3Ca!n`kci?wg?F>(qld|f_^-7 zXrP%pVoKB;M4Y*@$5<9C^vtGXqb3uBX47#|lj*n_Fkzr;&!VOpmFD{Mz?c38bwV5% zu*qr1TlV0aPa>~#VVmyTG+@mwn-Mhzk!!Zhv@F%Y$b494MJ#?Sn@>91@-fj832Jj| z=F~8n=r-?sLJhlwx!HJP4Wq=n**Ld`Q96R_J+Fq*{^&j)J||f|915QWc5;--@wn4Z ziSjTw&gZJPY$pE0nF|vo=lxIheZsoV_iZNZEa3+pMW@y9K>+)PWN5H zkUHN>3w?V@#@ZPXLnREd^PIBCviZ^WdGJ_V!$ZUFy#JY=)sDZ%;Bl7aVS41yfq1^R z8|*!z5qZ7}XGhG{(EMW98ZF!JiP2AoYm?v^8l1QEFh&-bhxP2_G`=2_%M zJ5p*SXij(S!#Ntv=6(hZc{Y zEwwCRJeeESZ+S#=Av~hDTE=KnWFf5EEUWYC5T1fZ*M*j!rb)Qc7r9jOC2YCavQ*y> zxRVDgiy4&RskpZ;so`MXF+7YewS4TH3SXqlESq__nv@mKA=`bseR!@yD&i78#KLOw zowdXAaq=!a;}2S9neq8jrY)#b-f}Aw!IgVKkDVxGOUlJZ5F`9-}b%4Ar^AcC_M={2B8NvQ2LK$mAfv-p z4h2N5_N>f7fvDBoIvg7CEMfJy5e3h~&HC_lyTbFba~RxDMc)ITl=8M!s%Z*q!S@7* z7ozp#r$>+(;_=S0hNy$4h`4ebbBNmP;mngUMznc%E(v|YAPH}wcs!wrefiIL~4h&JR2JB+Uo=ru}5wVGeEZ7*subGyH$59fe zZiggj$RRDX$04os8HcpdJq~H70}e^jGY;vXpG8S?jNWxfGfl=Z#txne&vvM;uwq7 z(nOLLIi!PW~(C#38NpBZsunL5H-{5s3R(b#6)0@eb*r zMN!fkqa_Y$rnL@<)1?kcP~IUebd5t=>2nTgqpvxnogQ&Wl78rr4thOG+G6yfLz-zi zLR(hb+v2pyAqhIyAuY7gA+5CCA#F77kaoJkAxXN!AszIUC~3z%=#XamzC+^libE3g zu0vXAB7$^QOWRv%xJ?MoBV8*E*z`zUYuRebXTcddwj$^izkl z(%TMcqr(whwAz(yrxP5Kq(+ByP=~h zfS_%)&dsq7njIy04mLQXna*`cocbM-pprvc=q87>(w805Mh6_yPA@nlNpCo$gFcKB zJO__P#Mx?ByqV@YBu)(uNzf99v{0WzT4~rJZM4TB?R2w4lC<9;9rR#G_#FzbN8yj( zw{+c$K}tBdW`0Umm`(gu!XK&Tr-a|t%}>eoW)pvve8D3RdgO7ByyB5}J;Hf4^V4(9 z^2lP3EcM7bkL>WsZjXH0BVY2!{T_MNBd>Yn1CJb|&6CEeobQo#kMw%vGLPgva;-=1 z^vFXVdEO(hd*nABnaN49;HSog9$Dg%K95}Pk?TD24UatOk(WKf*<$n48XjrgPD(gC zYko=+9_jSRg&x`Ek*huOS&!V~kw-l8yhjdt5&5-dC?i4uvWs5Y7V4I{IwCrX7VDkCc=egEriQu4TKA2?Sl&?Ht9k; zXl!h}#=+8&{a_2%G#DR~Zm}{B;r@Xwa*TkPOueK`onvt*-$Au%8XPHHqu}gfA0tfX zgva&QBADHcMb{uislE2VSWHU}z2+eFjIK4P;_4a$!+y`&0^=eXCVRtLOAx`jhQJ`R zcEH&VV&x$X*9v%~+OO8y0ON&ep!yF1BQUsH;RO&+d)C0srkg?b%i0?Y0wOv8sHvLk zkMbI4wEjI{)Yl$zT8qfQROAgpD|au4i{|VVajrg8lC6*}bGuh_^AT)v@&aq*;sYMZ z!3(o;@4O2CxLun4&c*~aLz728adsNF@WbaVM;EgEkWaqZcp@X699Vg(m z4pZx&44T6^xod-~GYYB^+>2JO+PL|5Y3Lr!O-FaI?_jSXddz4pI=Z{$pnYWLo}*ST z=j@n+TyvC~9CMV~LrrT6a)>s#x#Z}P?8KvE;oPy04sjMMR~+3(bHq{R507e2SUs&= ra0tR2u#jr*S2k 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 E1%>#79RL6T literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/ImGui/.editorconfig b/libultraship/libultraship/Lib/ImGui/.editorconfig new file mode 100644 index 000000000..c6dc600aa --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/.editorconfig @@ -0,0 +1,24 @@ +# See http://editorconfig.org to read about the EditorConfig format. +# - In theory automatically supported by VS2017+ and most common IDE or text editors. +# - In practice VS2019 stills gets trailing whitespaces wrong :( +# - Suggest install to trim whitespaces: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespaceVisualizer +# - Alternative for older VS2010 to VS2015: https://marketplace.visualstudio.com/items?itemName=EditorConfigTeam.EditorConfig + +# top-most EditorConfig file +root = true + +# Default settings: +# Use 4 spaces as indentation +[*] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[imstb_*] +indent_size = 3 +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab +indent_size = 4 diff --git a/libultraship/libultraship/Lib/ImGui/.gitattributes b/libultraship/libultraship/Lib/ImGui/.gitattributes new file mode 100644 index 000000000..d48470eef --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/.gitattributes @@ -0,0 +1,30 @@ +* text=auto + +*.c text +*.cpp text +*.h text +*.m text +*.mm text +*.md text +*.txt text +*.html text +*.bat text +*.frag text +*.vert text +*.mkb text +*.icf text + +*.sln text eol=crlf +*.vcxproj text eol=crlf +*.vcxproj.filters text eol=crlf +*.natvis text eol=crlf + +Makefile text eol=lf +*.sh text eol=lf +*.pbxproj text eol=lf +*.storyboard text eol=lf +*.plist text eol=lf + +*.png binary +*.ttf binary +*.lib binary diff --git a/libultraship/libultraship/Lib/ImGui/.gitignore b/libultraship/libultraship/Lib/ImGui/.gitignore new file mode 100644 index 000000000..86bed609c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/.gitignore @@ -0,0 +1,53 @@ +## OSX artifacts +.DS_Store + +## Dear ImGui artifacts +imgui.ini + +## General build artifacts +*.o +*.obj +*.exe +examples/build/* +examples/*/Debug/* +examples/*/Release/* +examples/*/x64/* + +## Visual Studio artifacts +.vs +ipch +*.opensdf +*.log +*.pdb +*.ilk +*.user +*.sdf +*.suo +*.VC.db +*.VC.VC.opendb + +## Commonly used CMake directories +/build*/ + +## Xcode artifacts +project.xcworkspace +xcuserdata + +## Emscripten artifacts +examples/*.o.tmp +examples/*.out.js +examples/*.out.wasm +examples/example_emscripten_opengl3/web/* +examples/example_emscripten_wgpu/web/* + +## JetBrains IDE artifacts +.idea +cmake-build-* + +## Unix executables from our example Makefiles +examples/example_glfw_opengl2/example_glfw_opengl2 +examples/example_glfw_opengl3/example_glfw_opengl3 +examples/example_glut_opengl2/example_glut_opengl2 +examples/example_null/example_null +examples/example_sdl_opengl2/example_sdl_opengl2 +examples/example_sdl_opengl3/example_sdl_opengl3 diff --git a/libultraship/libultraship/Lib/ImGui/LICENSE.txt b/libultraship/libultraship/Lib/ImGui/LICENSE.txt new file mode 100644 index 000000000..4023e0caa --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2022 Omar Cornut + +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/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.cpp new file mode 100644 index 000000000..dcc806a66 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.cpp @@ -0,0 +1,580 @@ +// dear imgui: Renderer + Platform Backend for Allegro 5 +// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Clipboard support (from Allegro 5.1.12) +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// Issues: +// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually. +// [ ] Platform: Missing gamepad support. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. +// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-02-18: Change blending equation to preserve alpha in output buffer. +// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction. +// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. +// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. +// 2019-05-11: Inputs: Don't filter character value from ALLEGRO_EVENT_KEY_CHAR before calling AddInputCharacter(). +// 2019-04-30: Renderer: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2018-11-30: Platform: Added touchscreen support. +// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window. +// 2018-06-13: Platform: Added clipboard support (from Allegro 5.1.12). +// 2018-06-13: Renderer: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-06-13: Renderer: Backup/restore transform and clipping rectangle. +// 2018-06-11: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. +// 2018-04-18: Misc: Renamed file from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp. +// 2018-04-18: Misc: Added support for 32-bit vertex indices to avoid conversion at runtime. Added imconfig_allegro5.h to enforce 32-bit indices when included from imgui.h. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplAllegro5_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. + +#include // uint64_t +#include // memcpy +#include "imgui.h" +#include "imgui_impl_allegro5.h" + +// Allegro +#include +#include +#ifdef _WIN32 +#include +#endif +#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12 + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#endif + +// Allegro Data +struct ImGui_ImplAllegro5_Data +{ + ALLEGRO_DISPLAY* Display; + ALLEGRO_BITMAP* Texture; + double Time; + ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible; + ALLEGRO_VERTEX_DECL* VertexDecl; + char* ClipboardTextData; + + ImGui_ImplAllegro5_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplAllegro5_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; } + +struct ImDrawVertAllegro +{ + ImVec2 pos; + ImVec2 uv; + ALLEGRO_COLOR col; +}; + +static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data) +{ + // Setup blending + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + // Setup orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). + { + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + ALLEGRO_TRANSFORM transform; + al_identity_transform(&transform); + al_use_transform(&transform); + al_orthographic_transform(&transform, L, T, 1.0f, R, B, -1.0f); + al_use_projection_transform(&transform); + } +} + +// Render function. +void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + // Backup Allegro state that will be modified + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + ALLEGRO_TRANSFORM last_transform = *al_get_current_transform(); + ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform(); + int last_clip_x, last_clip_y, last_clip_w, last_clip_h; + al_get_clipping_rectangle(&last_clip_x, &last_clip_y, &last_clip_w, &last_clip_h); + int last_blender_op, last_blender_src, last_blender_dst; + al_get_blender(&last_blender_op, &last_blender_src, &last_blender_dst); + + // Setup desired render state + ImGui_ImplAllegro5_SetupRenderState(draw_data); + + // Render command lists + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + + // Allegro's implementation of al_draw_indexed_prim() for DX9 is completely broken. Unindex our buffers ourselves. + // FIXME-OPT: Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 float as well.. + static ImVector vertices; + vertices.resize(cmd_list->IdxBuffer.Size); + for (int i = 0; i < cmd_list->IdxBuffer.Size; i++) + { + const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]]; + ImDrawVertAllegro* dst_v = &vertices[i]; + dst_v->pos = src_v->pos; + dst_v->uv = src_v->uv; + unsigned char* c = (unsigned char*)&src_v->col; + dst_v->col = al_map_rgba(c[0], c[1], c[2], c[3]); + } + + const int* indices = NULL; + if (sizeof(ImDrawIdx) == 2) + { + // FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices.. You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices. + // Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful. + static ImVector indices_converted; + indices_converted.resize(cmd_list->IdxBuffer.Size); + for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i) + indices_converted[i] = (int)cmd_list->IdxBuffer.Data[i]; + indices = indices_converted.Data; + } + else if (sizeof(ImDrawIdx) == 4) + { + indices = (const int*)cmd_list->IdxBuffer.Data; + } + + // Render command lists + ImVec2 clip_off = draw_data->DisplayPos; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplAllegro5_SetupRenderState(draw_data); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle, Draw + ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID(); + al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x - clip_min.x, clip_max.y - clip_min.y); + al_draw_prim(&vertices[0], bd->VertexDecl, texture, pcmd->IdxOffset, pcmd->IdxOffset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); + } + } + } + + // Restore modified Allegro state + al_set_blender(last_blender_op, last_blender_src, last_blender_dst); + al_set_clipping_rectangle(last_clip_x, last_clip_y, last_clip_w, last_clip_h); + al_use_transform(&last_transform); + al_use_projection_transform(&last_projection_transform); +} + +bool ImGui_ImplAllegro5_CreateDeviceObjects() +{ + // Build texture atlas + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Create texture + int flags = al_get_new_bitmap_flags(); + int fmt = al_get_new_bitmap_format(); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE); + ALLEGRO_BITMAP* img = al_create_bitmap(width, height); + al_set_new_bitmap_flags(flags); + al_set_new_bitmap_format(fmt); + if (!img) + return false; + + ALLEGRO_LOCKED_REGION* locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY); + if (!locked_img) + { + al_destroy_bitmap(img); + return false; + } + memcpy(locked_img->data, pixels, sizeof(int) * width * height); + al_unlock_bitmap(img); + + // Convert software texture to hardware texture. + ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img); + al_destroy_bitmap(img); + if (!cloned_img) + return false; + + // Store our identifier + io.Fonts->SetTexID((void*)cloned_img); + bd->Texture = cloned_img; + + // Create an invisible mouse cursor + // Because al_hide_mouse_cursor() seems to mess up with the actual inputs.. + ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap(8, 8); + bd->MouseCursorInvisible = al_create_mouse_cursor(mouse_cursor, 0, 0); + al_destroy_bitmap(mouse_cursor); + + return true; +} + +void ImGui_ImplAllegro5_InvalidateDeviceObjects() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + if (bd->Texture) + { + io.Fonts->SetTexID(NULL); + al_destroy_bitmap(bd->Texture); + bd->Texture = NULL; + } + if (bd->MouseCursorInvisible) + { + al_destroy_mouse_cursor(bd->MouseCursorInvisible); + bd->MouseCursorInvisible = NULL; + } +} + +#if ALLEGRO_HAS_CLIPBOARD +static const char* ImGui_ImplAllegro5_GetClipboardText(void*) +{ + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + if (bd->ClipboardTextData) + al_free(bd->ClipboardTextData); + bd->ClipboardTextData = al_get_clipboard_text(bd->Display); + return bd->ClipboardTextData; +} + +static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text) +{ + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + al_set_clipboard_text(bd->Display, text); +} +#endif + +static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code) +{ + switch (key_code) + { + case ALLEGRO_KEY_TAB: return ImGuiKey_Tab; + case ALLEGRO_KEY_LEFT: return ImGuiKey_LeftArrow; + case ALLEGRO_KEY_RIGHT: return ImGuiKey_RightArrow; + case ALLEGRO_KEY_UP: return ImGuiKey_UpArrow; + case ALLEGRO_KEY_DOWN: return ImGuiKey_DownArrow; + case ALLEGRO_KEY_PGUP: return ImGuiKey_PageUp; + case ALLEGRO_KEY_PGDN: return ImGuiKey_PageDown; + case ALLEGRO_KEY_HOME: return ImGuiKey_Home; + case ALLEGRO_KEY_END: return ImGuiKey_End; + case ALLEGRO_KEY_INSERT: return ImGuiKey_Insert; + case ALLEGRO_KEY_DELETE: return ImGuiKey_Delete; + case ALLEGRO_KEY_BACKSPACE: return ImGuiKey_Backspace; + case ALLEGRO_KEY_SPACE: return ImGuiKey_Space; + case ALLEGRO_KEY_ENTER: return ImGuiKey_Enter; + case ALLEGRO_KEY_ESCAPE: return ImGuiKey_Escape; + case ALLEGRO_KEY_QUOTE: return ImGuiKey_Apostrophe; + case ALLEGRO_KEY_COMMA: return ImGuiKey_Comma; + case ALLEGRO_KEY_MINUS: return ImGuiKey_Minus; + case ALLEGRO_KEY_FULLSTOP: return ImGuiKey_Period; + case ALLEGRO_KEY_SLASH: return ImGuiKey_Slash; + case ALLEGRO_KEY_SEMICOLON: return ImGuiKey_Semicolon; + case ALLEGRO_KEY_EQUALS: return ImGuiKey_Equal; + case ALLEGRO_KEY_OPENBRACE: return ImGuiKey_LeftBracket; + case ALLEGRO_KEY_BACKSLASH: return ImGuiKey_Backslash; + case ALLEGRO_KEY_CLOSEBRACE: return ImGuiKey_RightBracket; + case ALLEGRO_KEY_TILDE: return ImGuiKey_GraveAccent; + case ALLEGRO_KEY_CAPSLOCK: return ImGuiKey_CapsLock; + case ALLEGRO_KEY_SCROLLLOCK: return ImGuiKey_ScrollLock; + case ALLEGRO_KEY_NUMLOCK: return ImGuiKey_NumLock; + case ALLEGRO_KEY_PRINTSCREEN: return ImGuiKey_PrintScreen; + case ALLEGRO_KEY_PAUSE: return ImGuiKey_Pause; + case ALLEGRO_KEY_PAD_0: return ImGuiKey_Keypad0; + case ALLEGRO_KEY_PAD_1: return ImGuiKey_Keypad1; + case ALLEGRO_KEY_PAD_2: return ImGuiKey_Keypad2; + case ALLEGRO_KEY_PAD_3: return ImGuiKey_Keypad3; + case ALLEGRO_KEY_PAD_4: return ImGuiKey_Keypad4; + case ALLEGRO_KEY_PAD_5: return ImGuiKey_Keypad5; + case ALLEGRO_KEY_PAD_6: return ImGuiKey_Keypad6; + case ALLEGRO_KEY_PAD_7: return ImGuiKey_Keypad7; + case ALLEGRO_KEY_PAD_8: return ImGuiKey_Keypad8; + case ALLEGRO_KEY_PAD_9: return ImGuiKey_Keypad9; + case ALLEGRO_KEY_PAD_DELETE: return ImGuiKey_KeypadDecimal; + case ALLEGRO_KEY_PAD_SLASH: return ImGuiKey_KeypadDivide; + case ALLEGRO_KEY_PAD_ASTERISK: return ImGuiKey_KeypadMultiply; + case ALLEGRO_KEY_PAD_MINUS: return ImGuiKey_KeypadSubtract; + case ALLEGRO_KEY_PAD_PLUS: return ImGuiKey_KeypadAdd; + case ALLEGRO_KEY_PAD_ENTER: return ImGuiKey_KeypadEnter; + case ALLEGRO_KEY_PAD_EQUALS: return ImGuiKey_KeypadEqual; + case ALLEGRO_KEY_LCTRL: return ImGuiKey_LeftCtrl; + case ALLEGRO_KEY_LSHIFT: return ImGuiKey_LeftShift; + case ALLEGRO_KEY_ALT: return ImGuiKey_LeftAlt; + case ALLEGRO_KEY_LWIN: return ImGuiKey_LeftSuper; + case ALLEGRO_KEY_RCTRL: return ImGuiKey_RightCtrl; + case ALLEGRO_KEY_RSHIFT: return ImGuiKey_RightShift; + case ALLEGRO_KEY_ALTGR: return ImGuiKey_RightAlt; + case ALLEGRO_KEY_RWIN: return ImGuiKey_RightSuper; + case ALLEGRO_KEY_MENU: return ImGuiKey_Menu; + case ALLEGRO_KEY_0: return ImGuiKey_0; + case ALLEGRO_KEY_1: return ImGuiKey_1; + case ALLEGRO_KEY_2: return ImGuiKey_2; + case ALLEGRO_KEY_3: return ImGuiKey_3; + case ALLEGRO_KEY_4: return ImGuiKey_4; + case ALLEGRO_KEY_5: return ImGuiKey_5; + case ALLEGRO_KEY_6: return ImGuiKey_6; + case ALLEGRO_KEY_7: return ImGuiKey_7; + case ALLEGRO_KEY_8: return ImGuiKey_8; + case ALLEGRO_KEY_9: return ImGuiKey_9; + case ALLEGRO_KEY_A: return ImGuiKey_A; + case ALLEGRO_KEY_B: return ImGuiKey_B; + case ALLEGRO_KEY_C: return ImGuiKey_C; + case ALLEGRO_KEY_D: return ImGuiKey_D; + case ALLEGRO_KEY_E: return ImGuiKey_E; + case ALLEGRO_KEY_F: return ImGuiKey_F; + case ALLEGRO_KEY_G: return ImGuiKey_G; + case ALLEGRO_KEY_H: return ImGuiKey_H; + case ALLEGRO_KEY_I: return ImGuiKey_I; + case ALLEGRO_KEY_J: return ImGuiKey_J; + case ALLEGRO_KEY_K: return ImGuiKey_K; + case ALLEGRO_KEY_L: return ImGuiKey_L; + case ALLEGRO_KEY_M: return ImGuiKey_M; + case ALLEGRO_KEY_N: return ImGuiKey_N; + case ALLEGRO_KEY_O: return ImGuiKey_O; + case ALLEGRO_KEY_P: return ImGuiKey_P; + case ALLEGRO_KEY_Q: return ImGuiKey_Q; + case ALLEGRO_KEY_R: return ImGuiKey_R; + case ALLEGRO_KEY_S: return ImGuiKey_S; + case ALLEGRO_KEY_T: return ImGuiKey_T; + case ALLEGRO_KEY_U: return ImGuiKey_U; + case ALLEGRO_KEY_V: return ImGuiKey_V; + case ALLEGRO_KEY_W: return ImGuiKey_W; + case ALLEGRO_KEY_X: return ImGuiKey_X; + case ALLEGRO_KEY_Y: return ImGuiKey_Y; + case ALLEGRO_KEY_Z: return ImGuiKey_Z; + case ALLEGRO_KEY_F1: return ImGuiKey_F1; + case ALLEGRO_KEY_F2: return ImGuiKey_F2; + case ALLEGRO_KEY_F3: return ImGuiKey_F3; + case ALLEGRO_KEY_F4: return ImGuiKey_F4; + case ALLEGRO_KEY_F5: return ImGuiKey_F5; + case ALLEGRO_KEY_F6: return ImGuiKey_F6; + case ALLEGRO_KEY_F7: return ImGuiKey_F7; + case ALLEGRO_KEY_F8: return ImGuiKey_F8; + case ALLEGRO_KEY_F9: return ImGuiKey_F9; + case ALLEGRO_KEY_F10: return ImGuiKey_F10; + case ALLEGRO_KEY_F11: return ImGuiKey_F11; + case ALLEGRO_KEY_F12: return ImGuiKey_F12; + default: return ImGuiKey_None; + } +} + +bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); + + // Setup backend capabilities flags + ImGui_ImplAllegro5_Data* bd = IM_NEW(ImGui_ImplAllegro5_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + + bd->Display = display; + + // Create custom vertex declaration. + // Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats. + // We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion. + ALLEGRO_VERTEX_ELEMENT elems[] = + { + { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, pos) }, + { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, uv) }, + { ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) }, + { 0, 0, 0 } + }; + bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro)); + +#if ALLEGRO_HAS_CLIPBOARD + io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText; + io.ClipboardUserData = NULL; +#endif + + return true; +} + +void ImGui_ImplAllegro5_Shutdown() +{ + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplAllegro5_InvalidateDeviceObjects(); + if (bd->VertexDecl) + al_destroy_vertex_decl(bd->VertexDecl); + if (bd->ClipboardTextData) + al_free(bd->ClipboardTextData); + + io.BackendPlatformUserData = NULL; + io.BackendPlatformName = io.BackendRendererName = NULL; + IM_DELETE(bd); +} + +// ev->keyboard.modifiers seems always zero so using that... +static void ImGui_ImplAllegro5_UpdateKeyModifiers() +{ + ImGuiIO& io = ImGui::GetIO(); + ALLEGRO_KEYBOARD_STATE keys; + al_get_keyboard_state(&keys); + io.AddKeyEvent(ImGuiKey_ModCtrl, al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL)); + io.AddKeyEvent(ImGuiKey_ModShift, al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT)); + io.AddKeyEvent(ImGuiKey_ModAlt, al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR)); + io.AddKeyEvent(ImGuiKey_ModSuper, al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN)); +} + +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + + switch (ev->type) + { + case ALLEGRO_EVENT_MOUSE_AXES: + if (ev->mouse.display == bd->Display) + { + io.AddMousePosEvent(ev->mouse.x, ev->mouse.y); + io.AddMouseWheelEvent(-ev->mouse.dw, ev->mouse.dz); + } + return true; + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + if (ev->mouse.display == bd->Display && ev->mouse.button > 0 && ev->mouse.button <= 5) + io.AddMouseButtonEvent(ev->mouse.button - 1, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN); + return true; + case ALLEGRO_EVENT_TOUCH_MOVE: + if (ev->touch.display == bd->Display) + io.AddMousePosEvent(ev->touch.x, ev->touch.y); + return true; + case ALLEGRO_EVENT_TOUCH_BEGIN: + case ALLEGRO_EVENT_TOUCH_END: + case ALLEGRO_EVENT_TOUCH_CANCEL: + if (ev->touch.display == bd->Display && ev->touch.primary) + io.AddMouseButtonEvent(0, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN); + return true; + case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: + if (ev->mouse.display == bd->Display) + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + return true; + case ALLEGRO_EVENT_KEY_CHAR: + if (ev->keyboard.display == bd->Display) + if (ev->keyboard.unichar != 0) + io.AddInputCharacter((unsigned int)ev->keyboard.unichar); + return true; + case ALLEGRO_EVENT_KEY_DOWN: + case ALLEGRO_EVENT_KEY_UP: + if (ev->keyboard.display == bd->Display) + { + ImGui_ImplAllegro5_UpdateKeyModifiers(); + ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode); + io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN)); + io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code) + } + return true; + case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: + if (ev->display.source == bd->Display) + io.AddFocusEvent(false); + return true; + case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: + if (ev->display.source == bd->Display) + { + io.AddFocusEvent(true); +#if defined(ALLEGRO_UNSTABLE) + al_clear_keyboard_state(bd->Display); +#endif + } + return true; + } + return false; +} + +static void ImGui_ImplAllegro5_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible); + } + else + { + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT; + switch (imgui_cursor) + { + case ImGuiMouseCursor_TextInput: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT; break; + case ImGuiMouseCursor_ResizeAll: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE; break; + case ImGuiMouseCursor_ResizeNS: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N; break; + case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break; + case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break; + case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break; + case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break; + } + al_set_system_mouse_cursor(bd->Display, cursor_id); + } +} + +void ImGui_ImplAllegro5_NewFrame() +{ + ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplAllegro5_Init()?"); + + if (!bd->Texture) + ImGui_ImplAllegro5_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + w = al_get_display_width(bd->Display); + h = al_get_display_height(bd->Display); + io.DisplaySize = ImVec2((float)w, (float)h); + + // Setup time step + double current_time = al_get_time(); + io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); + bd->Time = current_time; + + // Setup mouse cursor shape + ImGui_ImplAllegro5_UpdateMouseCursor(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.h new file mode 100644 index 000000000..7e97969e5 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_allegro5.h @@ -0,0 +1,32 @@ +// dear imgui: Renderer + Platform Backend for Allegro 5 +// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Clipboard support (from Allegro 5.1.12) +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// Issues: +// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually. +// [ ] Platform: Missing gamepad support. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct ALLEGRO_DISPLAY; +union ALLEGRO_EVENT; + +IMGUI_IMPL_API bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display); +IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data); +IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.cpp new file mode 100644 index 000000000..bb8de8114 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.cpp @@ -0,0 +1,276 @@ +// dear imgui: Platform Binding for Android native app +// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3) + +// Implemented features: +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// Missing features: +// [ ] Platform: Clipboard support. +// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android. +// Important: +// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this. +// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446) +// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446) + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-03-04: Initial version. + +#include "imgui.h" +#include "imgui_impl_android.h" +#include +#include +#include +#include +#include + +// Android data +static double g_Time = 0.0; +static ANativeWindow* g_Window; +static char g_LogTag[] = "ImGuiExample"; + +static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code) +{ + switch (key_code) + { + case AKEYCODE_TAB: return ImGuiKey_Tab; + case AKEYCODE_DPAD_LEFT: return ImGuiKey_LeftArrow; + case AKEYCODE_DPAD_RIGHT: return ImGuiKey_RightArrow; + case AKEYCODE_DPAD_UP: return ImGuiKey_UpArrow; + case AKEYCODE_DPAD_DOWN: return ImGuiKey_DownArrow; + case AKEYCODE_PAGE_UP: return ImGuiKey_PageUp; + case AKEYCODE_PAGE_DOWN: return ImGuiKey_PageDown; + case AKEYCODE_MOVE_HOME: return ImGuiKey_Home; + case AKEYCODE_MOVE_END: return ImGuiKey_End; + case AKEYCODE_INSERT: return ImGuiKey_Insert; + case AKEYCODE_FORWARD_DEL: return ImGuiKey_Delete; + case AKEYCODE_DEL: return ImGuiKey_Backspace; + case AKEYCODE_SPACE: return ImGuiKey_Space; + case AKEYCODE_ENTER: return ImGuiKey_Enter; + case AKEYCODE_ESCAPE: return ImGuiKey_Escape; + case AKEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe; + case AKEYCODE_COMMA: return ImGuiKey_Comma; + case AKEYCODE_MINUS: return ImGuiKey_Minus; + case AKEYCODE_PERIOD: return ImGuiKey_Period; + case AKEYCODE_SLASH: return ImGuiKey_Slash; + case AKEYCODE_SEMICOLON: return ImGuiKey_Semicolon; + case AKEYCODE_EQUALS: return ImGuiKey_Equal; + case AKEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket; + case AKEYCODE_BACKSLASH: return ImGuiKey_Backslash; + case AKEYCODE_RIGHT_BRACKET: return ImGuiKey_RightBracket; + case AKEYCODE_GRAVE: return ImGuiKey_GraveAccent; + case AKEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock; + case AKEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock; + case AKEYCODE_NUM_LOCK: return ImGuiKey_NumLock; + case AKEYCODE_SYSRQ: return ImGuiKey_PrintScreen; + case AKEYCODE_BREAK: return ImGuiKey_Pause; + case AKEYCODE_NUMPAD_0: return ImGuiKey_Keypad0; + case AKEYCODE_NUMPAD_1: return ImGuiKey_Keypad1; + case AKEYCODE_NUMPAD_2: return ImGuiKey_Keypad2; + case AKEYCODE_NUMPAD_3: return ImGuiKey_Keypad3; + case AKEYCODE_NUMPAD_4: return ImGuiKey_Keypad4; + case AKEYCODE_NUMPAD_5: return ImGuiKey_Keypad5; + case AKEYCODE_NUMPAD_6: return ImGuiKey_Keypad6; + case AKEYCODE_NUMPAD_7: return ImGuiKey_Keypad7; + case AKEYCODE_NUMPAD_8: return ImGuiKey_Keypad8; + case AKEYCODE_NUMPAD_9: return ImGuiKey_Keypad9; + case AKEYCODE_NUMPAD_DOT: return ImGuiKey_KeypadDecimal; + case AKEYCODE_NUMPAD_DIVIDE: return ImGuiKey_KeypadDivide; + case AKEYCODE_NUMPAD_MULTIPLY: return ImGuiKey_KeypadMultiply; + case AKEYCODE_NUMPAD_SUBTRACT: return ImGuiKey_KeypadSubtract; + case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd; + case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter; + case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual; + case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftCtrl; + case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift; + case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt; + case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper; + case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightCtrl; + case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift; + case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt; + case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper; + case AKEYCODE_MENU: return ImGuiKey_Menu; + case AKEYCODE_0: return ImGuiKey_0; + case AKEYCODE_1: return ImGuiKey_1; + case AKEYCODE_2: return ImGuiKey_2; + case AKEYCODE_3: return ImGuiKey_3; + case AKEYCODE_4: return ImGuiKey_4; + case AKEYCODE_5: return ImGuiKey_5; + case AKEYCODE_6: return ImGuiKey_6; + case AKEYCODE_7: return ImGuiKey_7; + case AKEYCODE_8: return ImGuiKey_8; + case AKEYCODE_9: return ImGuiKey_9; + case AKEYCODE_A: return ImGuiKey_A; + case AKEYCODE_B: return ImGuiKey_B; + case AKEYCODE_C: return ImGuiKey_C; + case AKEYCODE_D: return ImGuiKey_D; + case AKEYCODE_E: return ImGuiKey_E; + case AKEYCODE_F: return ImGuiKey_F; + case AKEYCODE_G: return ImGuiKey_G; + case AKEYCODE_H: return ImGuiKey_H; + case AKEYCODE_I: return ImGuiKey_I; + case AKEYCODE_J: return ImGuiKey_J; + case AKEYCODE_K: return ImGuiKey_K; + case AKEYCODE_L: return ImGuiKey_L; + case AKEYCODE_M: return ImGuiKey_M; + case AKEYCODE_N: return ImGuiKey_N; + case AKEYCODE_O: return ImGuiKey_O; + case AKEYCODE_P: return ImGuiKey_P; + case AKEYCODE_Q: return ImGuiKey_Q; + case AKEYCODE_R: return ImGuiKey_R; + case AKEYCODE_S: return ImGuiKey_S; + case AKEYCODE_T: return ImGuiKey_T; + case AKEYCODE_U: return ImGuiKey_U; + case AKEYCODE_V: return ImGuiKey_V; + case AKEYCODE_W: return ImGuiKey_W; + case AKEYCODE_X: return ImGuiKey_X; + case AKEYCODE_Y: return ImGuiKey_Y; + case AKEYCODE_Z: return ImGuiKey_Z; + case AKEYCODE_F1: return ImGuiKey_F1; + case AKEYCODE_F2: return ImGuiKey_F2; + case AKEYCODE_F3: return ImGuiKey_F3; + case AKEYCODE_F4: return ImGuiKey_F4; + case AKEYCODE_F5: return ImGuiKey_F5; + case AKEYCODE_F6: return ImGuiKey_F6; + case AKEYCODE_F7: return ImGuiKey_F7; + case AKEYCODE_F8: return ImGuiKey_F8; + case AKEYCODE_F9: return ImGuiKey_F9; + case AKEYCODE_F10: return ImGuiKey_F10; + case AKEYCODE_F11: return ImGuiKey_F11; + case AKEYCODE_F12: return ImGuiKey_F12; + default: return ImGuiKey_None; + } +} + +int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event) +{ + ImGuiIO& io = ImGui::GetIO(); + int32_t event_type = AInputEvent_getType(input_event); + switch (event_type) + { + case AINPUT_EVENT_TYPE_KEY: + { + int32_t event_key_code = AKeyEvent_getKeyCode(input_event); + int32_t event_scan_code = AKeyEvent_getScanCode(input_event); + int32_t event_action = AKeyEvent_getAction(input_event); + int32_t event_meta_state = AKeyEvent_getMetaState(input_event); + + io.AddKeyEvent(ImGuiKey_ModCtrl, (event_meta_state & AMETA_CTRL_ON) != 0); + io.AddKeyEvent(ImGuiKey_ModShift, (event_meta_state & AMETA_SHIFT_ON) != 0); + io.AddKeyEvent(ImGuiKey_ModAlt, (event_meta_state & AMETA_ALT_ON) != 0); + io.AddKeyEvent(ImGuiKey_ModSuper, (event_meta_state & AMETA_META_ON) != 0); + + switch (event_action) + { + // FIXME: AKEY_EVENT_ACTION_DOWN and AKEY_EVENT_ACTION_UP occur at once as soon as a touch pointer + // goes up from a key. We use a simple key event queue/ and process one event per key per frame in + // ImGui_ImplAndroid_NewFrame()...or consider using IO queue, if suitable: https://github.com/ocornut/imgui/issues/2787 + case AKEY_EVENT_ACTION_DOWN: + case AKEY_EVENT_ACTION_UP: + { + ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code); + if (key != ImGuiKey_None && (event_action == AKEY_EVENT_ACTION_DOWN || event_action == AKEY_EVENT_ACTION_UP)) + { + io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN); + io.SetKeyEventNativeData(key, event_key_code, event_scan_code); + } + + break; + } + default: + break; + } + break; + } + case AINPUT_EVENT_TYPE_MOTION: + { + int32_t event_action = AMotionEvent_getAction(input_event); + int32_t event_pointer_index = (event_action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; + event_action &= AMOTION_EVENT_ACTION_MASK; + switch (event_action) + { + case AMOTION_EVENT_ACTION_DOWN: + case AMOTION_EVENT_ACTION_UP: + // Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP, + // but we have to process them separately to identify the actual button pressed. This is done below via + // AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback). + if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER) + || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)) + { + io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); + io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN); + } + break; + case AMOTION_EVENT_ACTION_BUTTON_PRESS: + case AMOTION_EVENT_ACTION_BUTTON_RELEASE: + { + int32_t button_state = AMotionEvent_getButtonState(input_event); + io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); + io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); + io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); + } + break; + case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse) + case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN + io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); + break; + case AMOTION_EVENT_ACTION_SCROLL: + io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index)); + break; + default: + break; + } + } + return 1; + default: + break; + } + + return 0; +} + +bool ImGui_ImplAndroid_Init(ANativeWindow* window) +{ + g_Window = window; + g_Time = 0.0; + + // Setup backend capabilities flags + ImGuiIO& io = ImGui::GetIO(); + io.BackendPlatformName = "imgui_impl_android"; + + return true; +} + +void ImGui_ImplAndroid_Shutdown() +{ +} + +void ImGui_ImplAndroid_NewFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int32_t window_width = ANativeWindow_getWidth(g_Window); + int32_t window_height = ANativeWindow_getHeight(g_Window); + int display_width = window_width; + int display_height = window_height; + + io.DisplaySize = ImVec2((float)window_width, (float)window_height); + if (window_width > 0 && window_height > 0) + io.DisplayFramebufferScale = ImVec2((float)display_width / window_width, (float)display_height / window_height); + + // Setup time step + struct timespec current_timespec; + clock_gettime(CLOCK_MONOTONIC, ¤t_timespec); + double current_time = (double)(current_timespec.tv_sec) + (current_timespec.tv_nsec / 1000000000.0); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); + g_Time = current_time; +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.h new file mode 100644 index 000000000..8bfa18606 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_android.h @@ -0,0 +1,28 @@ +// dear imgui: Platform Binding for Android native app +// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3) + +// Implemented features: +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// Missing features: +// [ ] Platform: Clipboard support. +// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android. +// Important: +// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this. +// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446) +// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446) + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once + +struct ANativeWindow; +struct AInputEvent; + +IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window); +IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event); +IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.cpp new file mode 100644 index 000000000..b19643581 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.cpp @@ -0,0 +1,712 @@ +// dear imgui: Renderer Backend for DirectX10 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer. +// 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData(). +// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-07-13: DirectX10: Fixed unreleased resources in Init and Shutdown functions. +// 2018-06-08: Misc: Extracted imgui_impl_dx10.cpp/.h away from the old combined DX10+Win32 example. +// 2018-06-08: DirectX10: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-04-09: Misc: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) on other backends. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2016-05-07: DirectX10: Disabling depth-write. + +#include "imgui.h" +#include "imgui_impl_dx10.h" + +// DirectX +#include +#include +#include +#include +#ifdef _MSC_VER +#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. +#endif + +// DirectX data +struct ImGui_ImplDX10_Data +{ + ID3D10Device* pd3dDevice; + IDXGIFactory* pFactory; + ID3D10Buffer* pVB; + ID3D10Buffer* pIB; + ID3D10VertexShader* pVertexShader; + ID3D10InputLayout* pInputLayout; + ID3D10Buffer* pVertexConstantBuffer; + ID3D10PixelShader* pPixelShader; + ID3D10SamplerState* pFontSampler; + ID3D10ShaderResourceView* pFontTextureView; + ID3D10RasterizerState* pRasterizerState; + ID3D10BlendState* pBlendState; + ID3D10DepthStencilState* pDepthStencilState; + int VertexBufferSize; + int IndexBufferSize; + + ImGui_ImplDX10_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } +}; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplDX10_InitPlatformInterface(); +static void ImGui_ImplDX10_ShutdownPlatformInterface(); + +// Functions +static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx) +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + + // Setup viewport + D3D10_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D10_VIEWPORT)); + vp.Width = (UINT)draw_data->DisplaySize.x; + vp.Height = (UINT)draw_data->DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0; + ctx->RSSetViewports(1, &vp); + + // Bind shader and vertex buffers + unsigned int stride = sizeof(ImDrawVert); + unsigned int offset = 0; + ctx->IASetInputLayout(bd->pInputLayout); + ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset); + ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); + ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->VSSetShader(bd->pVertexShader); + ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer); + ctx->PSSetShader(bd->pPixelShader); + ctx->PSSetSamplers(0, 1, &bd->pFontSampler); + ctx->GSSetShader(NULL); + + // Setup render state + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff); + ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0); + ctx->RSSetState(bd->pRasterizerState); +} + +// Render function +void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + ID3D10Device* ctx = bd->pd3dDevice; + + // Create and grow vertex/index buffers if needed + if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) + { + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; + D3D10_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert); + desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + if (ctx->CreateBuffer(&desc, NULL, &bd->pVB) < 0) + return; + } + + if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) + { + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; + D3D10_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx); + desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + if (ctx->CreateBuffer(&desc, NULL, &bd->pIB) < 0) + return; + } + + // Copy and convert all vertices into a single contiguous buffer + ImDrawVert* vtx_dst = NULL; + ImDrawIdx* idx_dst = NULL; + bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst); + bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + bd->pVB->Unmap(); + bd->pIB->Unmap(); + + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + { + void* mapped_resource; + if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) + return; + VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource; + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); + bd->pVertexConstantBuffer->Unmap(); + } + + // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) + struct BACKUP_DX10_STATE + { + UINT ScissorRectsCount, ViewportsCount; + D3D10_RECT ScissorRects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D10_VIEWPORT Viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D10RasterizerState* RS; + ID3D10BlendState* BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + UINT StencilRef; + ID3D10DepthStencilState* DepthStencilState; + ID3D10ShaderResourceView* PSShaderResource; + ID3D10SamplerState* PSSampler; + ID3D10PixelShader* PS; + ID3D10VertexShader* VS; + ID3D10GeometryShader* GS; + D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology; + ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; + UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; + DXGI_FORMAT IndexBufferFormat; + ID3D10InputLayout* InputLayout; + }; + BACKUP_DX10_STATE old = {}; + old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); + ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); + ctx->RSGetState(&old.RS); + ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); + ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); + ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); + ctx->PSGetSamplers(0, 1, &old.PSSampler); + ctx->PSGetShader(&old.PS); + ctx->VSGetShader(&old.VS); + ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); + ctx->GSGetShader(&old.GS); + ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); + ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); + ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); + ctx->IAGetInputLayout(&old.InputLayout); + + // Setup desired DX state + ImGui_ImplDX10_SetupRenderState(draw_data, ctx); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDX10_SetupRenderState(draw_data, ctx); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle + const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; + ctx->RSSetScissorRects(1, &r); + + // Bind texture, Draw + ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID(); + ctx->PSSetShaderResources(0, 1, &texture_srv); + ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } + + // Restore modified DX state + ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); + ctx->RSSetViewports(old.ViewportsCount, old.Viewports); + ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); + ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); + ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); + ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); + ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); + ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release(); + ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release(); + ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release(); + ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); + ctx->IASetPrimitiveTopology(old.PrimitiveTopology); + ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); + ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); + ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); +} + +static void ImGui_ImplDX10_CreateFontsTexture() +{ + // Build texture atlas + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D10_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D10_USAGE_DEFAULT; + desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + + ID3D10Texture2D* pTexture = NULL; + D3D10_SUBRESOURCE_DATA subResource; + subResource.pSysMem = pixels; + subResource.SysMemPitch = desc.Width * 4; + subResource.SysMemSlicePitch = 0; + bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); + IM_ASSERT(pTexture != NULL); + + // Create texture view + D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc; + ZeroMemory(&srv_desc, sizeof(srv_desc)); + srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MipLevels = desc.MipLevels; + srv_desc.Texture2D.MostDetailedMip = 0; + bd->pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &bd->pFontTextureView); + pTexture->Release(); + } + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView); + + // Create texture sampler + { + D3D10_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; + desc.MipLODBias = 0.f; + desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; + desc.MinLOD = 0.f; + desc.MaxLOD = 0.f; + bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler); + } +} + +bool ImGui_ImplDX10_CreateDeviceObjects() +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + if (!bd->pd3dDevice) + return false; + if (bd->pFontSampler) + ImGui_ImplDX10_InvalidateDeviceObjects(); + + // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) + // If you would like to use this DX10 sample code but remove this dependency you can: + // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] + // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. + // See https://github.com/ocornut/imgui/pull/638 for sources and details. + + // Create the vertex shader + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + ID3DBlob* vertexShaderBlob; + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pVertexShader) != S_OK) + { + vertexShaderBlob->Release(); + return false; + } + + // Create the input layout + D3D10_INPUT_ELEMENT_DESC local_layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; + if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) + { + vertexShaderBlob->Release(); + return false; + } + vertexShaderBlob->Release(); + + // Create the constant buffer + { + D3D10_BUFFER_DESC desc; + desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer); + } + } + + // Create the pixel shader + { + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + sampler sampler0;\ + Texture2D texture0;\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + ID3DBlob* pixelShaderBlob; + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), &bd->pPixelShader) != S_OK) + { + pixelShaderBlob->Release(); + return false; + } + pixelShaderBlob->Release(); + } + + // Create the blending setup + { + D3D10_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.AlphaToCoverageEnable = false; + desc.BlendEnable[0] = true; + desc.SrcBlend = D3D10_BLEND_SRC_ALPHA; + desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; + desc.BlendOp = D3D10_BLEND_OP_ADD; + desc.SrcBlendAlpha = D3D10_BLEND_ONE; + desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; + desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; + desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; + bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState); + } + + // Create the rasterizer state + { + D3D10_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.FillMode = D3D10_FILL_SOLID; + desc.CullMode = D3D10_CULL_NONE; + desc.ScissorEnable = true; + desc.DepthClipEnable = true; + bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState); + } + + // Create depth-stencil State + { + D3D10_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.DepthEnable = false; + desc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D10_COMPARISON_ALWAYS; + desc.StencilEnable = false; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; + desc.BackFace = desc.FrontFace; + bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState); + } + + ImGui_ImplDX10_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplDX10_InvalidateDeviceObjects() +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + if (!bd->pd3dDevice) + return; + + if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; } + if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; } + if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; } + if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; } + if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; } + if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; } + if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; } + if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; } +} + +bool ImGui_ImplDX10_Init(ID3D10Device* device) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplDX10_Data* bd = IM_NEW(ImGui_ImplDX10_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_dx10"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + // Get factory from device + IDXGIDevice* pDXGIDevice = NULL; + IDXGIAdapter* pDXGIAdapter = NULL; + IDXGIFactory* pFactory = NULL; + if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK) + if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK) + if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK) + { + bd->pd3dDevice = device; + bd->pFactory = pFactory; + } + if (pDXGIDevice) pDXGIDevice->Release(); + if (pDXGIAdapter) pDXGIAdapter->Release(); + bd->pd3dDevice->AddRef(); + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplDX10_InitPlatformInterface(); + return true; +} + +void ImGui_ImplDX10_Shutdown() +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplDX10_ShutdownPlatformInterface(); + ImGui_ImplDX10_InvalidateDeviceObjects(); + if (bd->pFactory) { bd->pFactory->Release(); } + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplDX10_NewFrame() +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX10_Init()?"); + + if (!bd->pFontSampler) + ImGui_ImplDX10_CreateDeviceObjects(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplDX10_ViewportData +{ + IDXGISwapChain* SwapChain; + ID3D10RenderTargetView* RTView; + + ImGui_ImplDX10_ViewportData() { SwapChain = NULL; RTView = NULL; } + ~ImGui_ImplDX10_ViewportData() { IM_ASSERT(SwapChain == NULL && RTView == NULL); } +}; + +static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)(); + viewport->RendererUserData = vd; + + // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). + // Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. + HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; + IM_ASSERT(hwnd != 0); + + // Create swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferDesc.Width = (UINT)viewport->Size.x; + sd.BufferDesc.Height = (UINT)viewport->Size.y; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.BufferCount = 1; + sd.OutputWindow = hwnd; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + sd.Flags = 0; + + IM_ASSERT(vd->SwapChain == NULL && vd->RTView == NULL); + bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain); + + // Create the render target + if (vd->SwapChain) + { + ID3D10Texture2D* pBackBuffer; + vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView); + pBackBuffer->Release(); + } +} + +static void ImGui_ImplDX10_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL here since we didn't create the data for it. + if (ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData) + { + if (vd->SwapChain) + vd->SwapChain->Release(); + vd->SwapChain = NULL; + if (vd->RTView) + vd->RTView->Release(); + vd->RTView = NULL; + IM_DELETE(vd); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplDX10_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData; + if (vd->RTView) + { + vd->RTView->Release(); + vd->RTView = NULL; + } + if (vd->SwapChain) + { + ID3D10Texture2D* pBackBuffer = NULL; + vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0); + vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX10_SetWindowSize() failed creating buffers.\n"); return; } + bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView); + pBackBuffer->Release(); + } +} + +static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); + ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData; + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + bd->pd3dDevice->OMSetRenderTargets(1, &vd->RTView, NULL); + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + bd->pd3dDevice->ClearRenderTargetView(vd->RTView, (float*)&clear_color); + ImGui_ImplDX10_RenderDrawData(viewport->DrawData); +} + +static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData; + vd->SwapChain->Present(0, 0); // Present without vsync +} + +void ImGui_ImplDX10_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplDX10_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplDX10_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderViewport; + platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers; +} + +void ImGui_ImplDX10_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.h new file mode 100644 index 000000000..84ec353ff --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx10.h @@ -0,0 +1,26 @@ +// dear imgui: Renderer Backend for DirectX10 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct ID3D10Device; + +IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device); +IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects(); +IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.cpp new file mode 100644 index 000000000..0e5d9c9e3 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.cpp @@ -0,0 +1,728 @@ +// dear imgui: Renderer Backend for DirectX11 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. +// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). +// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. +// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. +// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions. +// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example. +// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2016-05-07: DirectX11: Disabling depth-write. + +#include "../imgui.h" +#include "imgui_impl_dx11.h" + +// DirectX +#include +#include +#include +#ifdef _MSC_VER +#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. +#endif + +// DirectX11 data +struct ImGui_ImplDX11_Data +{ + ID3D11Device* pd3dDevice; + ID3D11DeviceContext* pd3dDeviceContext; + IDXGIFactory* pFactory; + ID3D11Buffer* pVB; + ID3D11Buffer* pIB; + ID3D11VertexShader* pVertexShader; + ID3D11InputLayout* pInputLayout; + ID3D11Buffer* pVertexConstantBuffer; + ID3D11PixelShader* pPixelShader; + ID3D11SamplerState* pFontSampler; + ID3D11ShaderResourceView* pFontTextureView; + ID3D11RasterizerState* pRasterizerState; + ID3D11BlendState* pBlendState; + ID3D11DepthStencilState* pDepthStencilState; + int VertexBufferSize; + int IndexBufferSize; + + ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } +}; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplDX11_InitPlatformInterface(); +static void ImGui_ImplDX11_ShutdownPlatformInterface(); + +// Functions +static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + + // Setup viewport + D3D11_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D11_VIEWPORT)); + vp.Width = draw_data->DisplaySize.x; + vp.Height = draw_data->DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0; + ctx->RSSetViewports(1, &vp); + + // Setup shader and vertex buffers + unsigned int stride = sizeof(ImDrawVert); + unsigned int offset = 0; + ctx->IASetInputLayout(bd->pInputLayout); + ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset); + ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->VSSetShader(bd->pVertexShader, NULL, 0); + ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer); + ctx->PSSetShader(bd->pPixelShader, NULL, 0); + ctx->PSSetSamplers(0, 1, &bd->pFontSampler); + ctx->GSSetShader(NULL, NULL, 0); + ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. + ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. + ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. + + // Setup blend state + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff); + ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0); + ctx->RSSetState(bd->pRasterizerState); +} + +// Render function +void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + ID3D11DeviceContext* ctx = bd->pd3dDeviceContext; + + // Create and grow vertex/index buffers if needed + if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) + { + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert); + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0) + return; + } + if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) + { + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx); + desc.BindFlags = D3D11_BIND_INDEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0) + return; + } + + // Upload vertex/index data into a single contiguous GPU buffer + D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; + if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) + return; + if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) + return; + ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; + ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + ctx->Unmap(bd->pVB, 0); + ctx->Unmap(bd->pIB, 0); + + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + { + D3D11_MAPPED_SUBRESOURCE mapped_resource; + if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) + return; + VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); + ctx->Unmap(bd->pVertexConstantBuffer, 0); + } + + // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) + struct BACKUP_DX11_STATE + { + UINT ScissorRectsCount, ViewportsCount; + D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D11RasterizerState* RS; + ID3D11BlendState* BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + UINT StencilRef; + ID3D11DepthStencilState* DepthStencilState; + ID3D11ShaderResourceView* PSShaderResource; + ID3D11SamplerState* PSSampler; + ID3D11PixelShader* PS; + ID3D11VertexShader* VS; + ID3D11GeometryShader* GS; + UINT PSInstancesCount, VSInstancesCount, GSInstancesCount; + ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation + D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; + ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; + UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; + DXGI_FORMAT IndexBufferFormat; + ID3D11InputLayout* InputLayout; + }; + BACKUP_DX11_STATE old = {}; + old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); + ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); + ctx->RSGetState(&old.RS); + ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); + ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); + ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); + ctx->PSGetSamplers(0, 1, &old.PSSampler); + old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256; + ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); + ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); + ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); + ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount); + + ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); + ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); + ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); + ctx->IAGetInputLayout(&old.InputLayout); + + // Setup desired DX state + ImGui_ImplDX11_SetupRenderState(draw_data, ctx); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_idx_offset = 0; + int global_vtx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDX11_SetupRenderState(draw_data, ctx); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle + const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; + ctx->RSSetScissorRects(1, &r); + + // Bind texture, Draw + ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID(); + ctx->PSSetShaderResources(0, 1, &texture_srv); + ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } + + // Restore modified DX state + ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); + ctx->RSSetViewports(old.ViewportsCount, old.Viewports); + ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); + ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); + ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); + ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); + ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); + ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); + for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); + ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); + ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); + ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release(); + for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); + ctx->IASetPrimitiveTopology(old.PrimitiveTopology); + ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); + ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); + ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); +} + +static void ImGui_ImplDX11_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + + ID3D11Texture2D* pTexture = NULL; + D3D11_SUBRESOURCE_DATA subResource; + subResource.pSysMem = pixels; + subResource.SysMemPitch = desc.Width * 4; + subResource.SysMemSlicePitch = 0; + bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); + IM_ASSERT(pTexture != NULL); + + // Create texture view + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView); + pTexture->Release(); + } + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView); + + // Create texture sampler + { + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + desc.MipLODBias = 0.f; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0.f; + desc.MaxLOD = 0.f; + bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler); + } +} + +bool ImGui_ImplDX11_CreateDeviceObjects() +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + if (!bd->pd3dDevice) + return false; + if (bd->pFontSampler) + ImGui_ImplDX11_InvalidateDeviceObjects(); + + // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) + // If you would like to use this DX11 sample code but remove this dependency you can: + // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] + // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. + // See https://github.com/ocornut/imgui/pull/638 for sources and details. + + // Create the vertex shader + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + ID3DBlob* vertexShaderBlob; + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK) + { + vertexShaderBlob->Release(); + return false; + } + + // Create the input layout + D3D11_INPUT_ELEMENT_DESC local_layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) + { + vertexShaderBlob->Release(); + return false; + } + vertexShaderBlob->Release(); + + // Create the constant buffer + { + D3D11_BUFFER_DESC desc; + desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer); + } + } + + // Create the pixel shader + { + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + sampler sampler0;\ + Texture2D texture0;\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + ID3DBlob* pixelShaderBlob; + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK) + { + pixelShaderBlob->Release(); + return false; + } + pixelShaderBlob->Release(); + } + + // Create the blending setup + { + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.AlphaToCoverageEnable = false; + desc.RenderTarget[0].BlendEnable = true; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState); + } + + // Create the rasterizer state + { + D3D11_RASTERIZER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.FillMode = D3D11_FILL_SOLID; + desc.CullMode = D3D11_CULL_NONE; + desc.ScissorEnable = true; + desc.DepthClipEnable = true; + bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState); + } + + // Create depth-stencil State + { + D3D11_DEPTH_STENCIL_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.DepthEnable = false; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D11_COMPARISON_ALWAYS; + desc.StencilEnable = false; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.BackFace = desc.FrontFace; + bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState); + } + + ImGui_ImplDX11_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplDX11_InvalidateDeviceObjects() +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + if (!bd->pd3dDevice) + return; + + if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; } + if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well. + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; } + if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; } + if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; } + if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; } + if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; } + if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; } + if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; } +} + +bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_dx11"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + // Get factory from device + IDXGIDevice* pDXGIDevice = NULL; + IDXGIAdapter* pDXGIAdapter = NULL; + IDXGIFactory* pFactory = NULL; + + if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK) + if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK) + if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK) + { + bd->pd3dDevice = device; + bd->pd3dDeviceContext = device_context; + bd->pFactory = pFactory; + } + if (pDXGIDevice) pDXGIDevice->Release(); + if (pDXGIAdapter) pDXGIAdapter->Release(); + bd->pd3dDevice->AddRef(); + bd->pd3dDeviceContext->AddRef(); + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplDX11_InitPlatformInterface(); + + return true; +} + +void ImGui_ImplDX11_Shutdown() +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplDX11_ShutdownPlatformInterface(); + ImGui_ImplDX11_InvalidateDeviceObjects(); + if (bd->pFactory) { bd->pFactory->Release(); } + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } + if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); } + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplDX11_NewFrame() +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?"); + + if (!bd->pFontSampler) + ImGui_ImplDX11_CreateDeviceObjects(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplDX11_ViewportData +{ + IDXGISwapChain* SwapChain; + ID3D11RenderTargetView* RTView; + + ImGui_ImplDX11_ViewportData() { SwapChain = NULL; RTView = NULL; } + ~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == NULL && RTView == NULL); } +}; + +static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)(); + viewport->RendererUserData = vd; + + // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). + // Some backend will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. + HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; + IM_ASSERT(hwnd != 0); + + // Create swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferDesc.Width = (UINT)viewport->Size.x; + sd.BufferDesc.Height = (UINT)viewport->Size.y; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.BufferCount = 1; + sd.OutputWindow = hwnd; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + sd.Flags = 0; + + IM_ASSERT(vd->SwapChain == NULL && vd->RTView == NULL); + bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain); + + // Create the render target + if (vd->SwapChain) + { + ID3D11Texture2D* pBackBuffer; + vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView); + pBackBuffer->Release(); + } +} + +static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. + if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData) + { + if (vd->SwapChain) + vd->SwapChain->Release(); + vd->SwapChain = NULL; + if (vd->RTView) + vd->RTView->Release(); + vd->RTView = NULL; + IM_DELETE(vd); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData; + if (vd->RTView) + { + vd->RTView->Release(); + vd->RTView = NULL; + } + if (vd->SwapChain) + { + ID3D11Texture2D* pBackBuffer = NULL; + vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0); + vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; } + bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView); + pBackBuffer->Release(); + } +} + +static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); + ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData; + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, NULL); + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color); + ImGui_ImplDX11_RenderDrawData(viewport->DrawData); +} + +static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData; + vd->SwapChain->Present(0, 0); // Present without vsync +} + +static void ImGui_ImplDX11_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow; + platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers; +} + +static void ImGui_ImplDX11_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.h new file mode 100644 index 000000000..7471a155f --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx11.h @@ -0,0 +1,27 @@ +// dear imgui: Renderer Backend for DirectX11 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "../imgui.h" // IMGUI_IMPL_API + +struct ID3D11Device; +struct ID3D11DeviceContext; + +IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); +IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); +IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.cpp new file mode 100644 index 000000000..e0e74c88e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.cpp @@ -0,0 +1,1073 @@ +// dear imgui: Renderer Backend for DirectX12 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. +// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. +// To build this on 32-bit systems: +// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file) +// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. +// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) +// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file) + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer. +// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. +// 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning. +// 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID. +// 2019-10-18: DirectX12: *BREAKING CHANGE* Added extra ID3D12DescriptorHeap parameter to ImGui_ImplDX12_Init() function. +// 2019-05-29: DirectX12: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: DirectX12: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-03-29: Misc: Various minor tidying up. +// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). +// 2018-06-08: Misc: Extracted imgui_impl_dx12.cpp/.h away from the old combined DX12+Win32 example. +// 2018-06-08: DirectX12: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle (to ease support for future multi-viewport). +// 2018-02-22: Merged into master with all Win32 code synchronized to other examples. + +#include "imgui.h" +#include "imgui_impl_dx12.h" + +// DirectX +#include +#include +#include +#ifdef _MSC_VER +#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. +#endif + +// DirectX data +struct ImGui_ImplDX12_Data +{ + ID3D12Device* pd3dDevice; + ID3D12RootSignature* pRootSignature; + ID3D12PipelineState* pPipelineState; + DXGI_FORMAT RTVFormat; + ID3D12Resource* pFontTextureResource; + D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle; + D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle; + ID3D12DescriptorHeap* pd3dSrvDescHeap; + UINT numFramesInFlight; + + ImGui_ImplDX12_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Buffers used during the rendering of a frame +struct ImGui_ImplDX12_RenderBuffers +{ + ID3D12Resource* IndexBuffer; + ID3D12Resource* VertexBuffer; + int IndexBufferSize; + int VertexBufferSize; +}; + +// Buffers used for secondary viewports created by the multi-viewports systems +struct ImGui_ImplDX12_FrameContext +{ + ID3D12CommandAllocator* CommandAllocator; + ID3D12Resource* RenderTarget; + D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetCpuDescriptors; +}; + +// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data. +// Main viewport created by application will only use the Resources field. +// Secondary viewports created by this backend will use all the fields (including Window fields), +struct ImGui_ImplDX12_ViewportData +{ + // Window + ID3D12CommandQueue* CommandQueue; + ID3D12GraphicsCommandList* CommandList; + ID3D12DescriptorHeap* RtvDescHeap; + IDXGISwapChain3* SwapChain; + ID3D12Fence* Fence; + UINT64 FenceSignaledValue; + HANDLE FenceEvent; + UINT NumFramesInFlight; + ImGui_ImplDX12_FrameContext* FrameCtx; + + // Render buffers + UINT FrameIndex; + ImGui_ImplDX12_RenderBuffers* FrameRenderBuffers; + + ImGui_ImplDX12_ViewportData(UINT num_frames_in_flight) + { + CommandQueue = NULL; + CommandList = NULL; + RtvDescHeap = NULL; + SwapChain = NULL; + Fence = NULL; + FenceSignaledValue = 0; + FenceEvent = NULL; + NumFramesInFlight = num_frames_in_flight; + FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight]; + FrameIndex = UINT_MAX; + FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[NumFramesInFlight]; + + for (UINT i = 0; i < NumFramesInFlight; ++i) + { + FrameCtx[i].CommandAllocator = NULL; + FrameCtx[i].RenderTarget = NULL; + + // Create buffers with a default size (they will later be grown as needed) + FrameRenderBuffers[i].IndexBuffer = NULL; + FrameRenderBuffers[i].VertexBuffer = NULL; + FrameRenderBuffers[i].VertexBufferSize = 5000; + FrameRenderBuffers[i].IndexBufferSize = 10000; + } + } + ~ImGui_ImplDX12_ViewportData() + { + IM_ASSERT(CommandQueue == NULL && CommandList == NULL); + IM_ASSERT(RtvDescHeap == NULL); + IM_ASSERT(SwapChain == NULL); + IM_ASSERT(Fence == NULL); + IM_ASSERT(FenceEvent == NULL); + + for (UINT i = 0; i < NumFramesInFlight; ++i) + { + IM_ASSERT(FrameCtx[i].CommandAllocator == NULL && FrameCtx[i].RenderTarget == NULL); + IM_ASSERT(FrameRenderBuffers[i].IndexBuffer == NULL && FrameRenderBuffers[i].VertexBuffer == NULL); + } + + delete[] FrameCtx; FrameCtx = NULL; + delete[] FrameRenderBuffers; FrameRenderBuffers = NULL; + } +}; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +// Forward Declarations +static void ImGui_ImplDX12_InitPlatformInterface(); +static void ImGui_ImplDX12_ShutdownPlatformInterface(); + +// Functions +static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr) +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). + VERTEX_CONSTANT_BUFFER vertex_constant_buffer; + { + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); + } + + // Setup viewport + D3D12_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D12_VIEWPORT)); + vp.Width = draw_data->DisplaySize.x; + vp.Height = draw_data->DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0.0f; + ctx->RSSetViewports(1, &vp); + + // Bind shader and vertex buffers + unsigned int stride = sizeof(ImDrawVert); + unsigned int offset = 0; + D3D12_VERTEX_BUFFER_VIEW vbv; + memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); + vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset; + vbv.SizeInBytes = fr->VertexBufferSize * stride; + vbv.StrideInBytes = stride; + ctx->IASetVertexBuffers(0, 1, &vbv); + D3D12_INDEX_BUFFER_VIEW ibv; + memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); + ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress(); + ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx); + ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + ctx->IASetIndexBuffer(&ibv); + ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->SetPipelineState(bd->pPipelineState); + ctx->SetGraphicsRootSignature(bd->pRootSignature); + ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); + + // Setup blend factor + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendFactor(blend_factor); +} + +template +static inline void SafeRelease(T*& res) +{ + if (res) + res->Release(); + res = NULL; +} + +// Render function +void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData; + vd->FrameIndex++; + ImGui_ImplDX12_RenderBuffers* fr = &vd->FrameRenderBuffers[vd->FrameIndex % bd->numFramesInFlight]; + + // Create and grow vertex/index buffers if needed + if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) + { + SafeRelease(fr->VertexBuffer); + fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + D3D12_RESOURCE_DESC desc; + memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert); + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0) + return; + } + if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) + { + SafeRelease(fr->IndexBuffer); + fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + D3D12_RESOURCE_DESC desc; + memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx); + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + if (bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0) + return; + } + + // Upload vertex/index data into a single contiguous GPU buffer + void* vtx_resource, *idx_resource; + D3D12_RANGE range; + memset(&range, 0, sizeof(D3D12_RANGE)); + if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK) + return; + if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK) + return; + ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource; + ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + fr->VertexBuffer->Unmap(0, &range); + fr->IndexBuffer->Unmap(0, &range); + + // Setup desired DX state + ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply Scissor/clipping rectangle, Bind texture, Draw + const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; + D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {}; + texture_handle.ptr = (UINT64)pcmd->GetTexID(); + ctx->SetGraphicsRootDescriptorTable(1, texture_handle); + ctx->RSSetScissorRects(1, &r); + ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } +} + +static void ImGui_ImplDX12_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D12_HEAP_PROPERTIES props; + memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); + props.Type = D3D12_HEAP_TYPE_DEFAULT; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_RESOURCE_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Alignment = 0; + desc.Width = width; + desc.Height = height; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + ID3D12Resource* pTexture = NULL; + bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_COPY_DEST, NULL, IID_PPV_ARGS(&pTexture)); + + UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u); + UINT uploadSize = height * uploadPitch; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Alignment = 0; + desc.Width = uploadSize; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + ID3D12Resource* uploadBuffer = NULL; + HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&uploadBuffer)); + IM_ASSERT(SUCCEEDED(hr)); + + void* mapped = NULL; + D3D12_RANGE range = { 0, uploadSize }; + hr = uploadBuffer->Map(0, &range, &mapped); + IM_ASSERT(SUCCEEDED(hr)); + for (int y = 0; y < height; y++) + memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4); + uploadBuffer->Unmap(0, &range); + + D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; + srcLocation.pResource = uploadBuffer; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srcLocation.PlacedFootprint.Footprint.Width = width; + srcLocation.PlacedFootprint.Footprint.Height = height; + srcLocation.PlacedFootprint.Footprint.Depth = 1; + srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch; + + D3D12_TEXTURE_COPY_LOCATION dstLocation = {}; + dstLocation.pResource = pTexture; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = 0; + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = pTexture; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + ID3D12Fence* fence = NULL; + hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); + IM_ASSERT(SUCCEEDED(hr)); + + HANDLE event = CreateEvent(0, 0, 0, 0); + IM_ASSERT(event != NULL); + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.NodeMask = 1; + + ID3D12CommandQueue* cmdQueue = NULL; + hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue)); + IM_ASSERT(SUCCEEDED(hr)); + + ID3D12CommandAllocator* cmdAlloc = NULL; + hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc)); + IM_ASSERT(SUCCEEDED(hr)); + + ID3D12GraphicsCommandList* cmdList = NULL; + hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList)); + IM_ASSERT(SUCCEEDED(hr)); + + cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL); + cmdList->ResourceBarrier(1, &barrier); + + hr = cmdList->Close(); + IM_ASSERT(SUCCEEDED(hr)); + + cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList); + hr = cmdQueue->Signal(fence, 1); + IM_ASSERT(SUCCEEDED(hr)); + + fence->SetEventOnCompletion(1, event); + WaitForSingleObject(event, INFINITE); + + cmdList->Release(); + cmdAlloc->Release(); + cmdQueue->Release(); + CloseHandle(event); + fence->Release(); + uploadBuffer->Release(); + + // Create texture view + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle); + SafeRelease(bd->pFontTextureResource); + bd->pFontTextureResource = pTexture; + } + + // Store our identifier + // READ THIS IF THE STATIC_ASSERT() TRIGGERS: + // - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. + // - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. + // [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file) + // [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. + // [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) + // [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file) + static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet."); + io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr); +} + +bool ImGui_ImplDX12_CreateDeviceObjects() +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + if (!bd || !bd->pd3dDevice) + return false; + if (bd->pPipelineState) + ImGui_ImplDX12_InvalidateDeviceObjects(); + + // Create the root signature + { + D3D12_DESCRIPTOR_RANGE descRange = {}; + descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descRange.NumDescriptors = 1; + descRange.BaseShaderRegister = 0; + descRange.RegisterSpace = 0; + descRange.OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER param[2] = {}; + + param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + param[0].Constants.ShaderRegister = 0; + param[0].Constants.RegisterSpace = 0; + param[0].Constants.Num32BitValues = 16; + param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + + param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param[1].DescriptorTable.NumDescriptorRanges = 1; + param[1].DescriptorTable.pDescriptorRanges = &descRange; + param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_STATIC_SAMPLER_DESC staticSampler = {}; + staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.MipLODBias = 0.f; + staticSampler.MaxAnisotropy = 0; + staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; + staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; + staticSampler.MinLOD = 0.f; + staticSampler.MaxLOD = 0.f; + staticSampler.ShaderRegister = 0; + staticSampler.RegisterSpace = 0; + staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_ROOT_SIGNATURE_DESC desc = {}; + desc.NumParameters = _countof(param); + desc.pParameters = param; + desc.NumStaticSamplers = 1; + desc.pStaticSamplers = &staticSampler; + desc.Flags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; + + // Load d3d12.dll and D3D12SerializeRootSignature() function address dynamically to facilitate using with D3D12On7. + // See if any version of d3d12.dll is already loaded in the process. If so, give preference to that. + static HINSTANCE d3d12_dll = ::GetModuleHandleA("d3d12.dll"); + if (d3d12_dll == NULL) + { + // Attempt to load d3d12.dll from local directories. This will only succeed if + // (1) the current OS is Windows 7, and + // (2) there exists a version of d3d12.dll for Windows 7 (D3D12On7) in one of the following directories. + // See https://github.com/ocornut/imgui/pull/3696 for details. + const char* localD3d12Paths[] = { ".\\d3d12.dll", ".\\d3d12on7\\d3d12.dll", ".\\12on7\\d3d12.dll" }; // A. current directory, B. used by some games, C. used in Microsoft D3D12On7 sample + for (int i = 0; i < IM_ARRAYSIZE(localD3d12Paths); i++) + if ((d3d12_dll = ::LoadLibraryA(localD3d12Paths[i])) != NULL) + break; + + // If failed, we are on Windows >= 10. + if (d3d12_dll == NULL) + d3d12_dll = ::LoadLibraryA("d3d12.dll"); + + if (d3d12_dll == NULL) + return false; + } + + PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature"); + if (D3D12SerializeRootSignatureFn == NULL) + return false; + + ID3DBlob* blob = NULL; + if (D3D12SerializeRootSignatureFn(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK) + return false; + + bd->pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&bd->pRootSignature)); + blob->Release(); + } + + // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) + // If you would like to use this DX12 sample code but remove this dependency you can: + // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] + // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. + // See https://github.com/ocornut/imgui/pull/638 for sources and details. + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc; + memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC)); + psoDesc.NodeMask = 1; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + psoDesc.pRootSignature = bd->pRootSignature; + psoDesc.SampleMask = UINT_MAX; + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = bd->RTVFormat; + psoDesc.SampleDesc.Count = 1; + psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + ID3DBlob* vertexShaderBlob; + ID3DBlob* pixelShaderBlob; + + // Create the vertex shader + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() }; + + // Create the input layout + static D3D12_INPUT_ELEMENT_DESC local_layout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + psoDesc.InputLayout = { local_layout, 3 }; + } + + // Create the pixel shader + { + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + SamplerState sampler0 : register(s0);\ + Texture2D texture0 : register(t0);\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &pixelShaderBlob, NULL))) + { + vertexShaderBlob->Release(); + return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + } + psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() }; + } + + // Create the blending setup + { + D3D12_BLEND_DESC& desc = psoDesc.BlendState; + desc.AlphaToCoverageEnable = false; + desc.RenderTarget[0].BlendEnable = true; + desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; + desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + } + + // Create the rasterizer state + { + D3D12_RASTERIZER_DESC& desc = psoDesc.RasterizerState; + desc.FillMode = D3D12_FILL_MODE_SOLID; + desc.CullMode = D3D12_CULL_MODE_NONE; + desc.FrontCounterClockwise = FALSE; + desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + desc.DepthClipEnable = true; + desc.MultisampleEnable = FALSE; + desc.AntialiasedLineEnable = FALSE; + desc.ForcedSampleCount = 0; + desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + + // Create depth-stencil State + { + D3D12_DEPTH_STENCIL_DESC& desc = psoDesc.DepthStencilState; + desc.DepthEnable = false; + desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; + desc.StencilEnable = false; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + desc.BackFace = desc.FrontFace; + } + + HRESULT result_pipeline_state = bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState)); + vertexShaderBlob->Release(); + pixelShaderBlob->Release(); + if (result_pipeline_state != S_OK) + return false; + + ImGui_ImplDX12_CreateFontsTexture(); + + return true; +} + +static void ImGui_ImplDX12_DestroyRenderBuffers(ImGui_ImplDX12_RenderBuffers* render_buffers) +{ + SafeRelease(render_buffers->IndexBuffer); + SafeRelease(render_buffers->VertexBuffer); + render_buffers->IndexBufferSize = render_buffers->VertexBufferSize = 0; +} + +void ImGui_ImplDX12_InvalidateDeviceObjects() +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + if (!bd || !bd->pd3dDevice) + return; + + ImGuiIO& io = ImGui::GetIO(); + SafeRelease(bd->pRootSignature); + SafeRelease(bd->pPipelineState); + SafeRelease(bd->pFontTextureResource); + io.Fonts->SetTexID(NULL); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. +} + +bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap, + D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_dx12"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplDX12_InitPlatformInterface(); + + bd->pd3dDevice = device; + bd->RTVFormat = rtv_format; + bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; + bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; + bd->numFramesInFlight = num_frames_in_flight; + bd->pd3dSrvDescHeap = cbv_srv_heap; + + // Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport, + // Since this is created and managed by the application, we will only use the ->Resources[] fields. + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight); + + return true; +} + +void ImGui_ImplDX12_Shutdown() +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + // Manually delete main viewport render resources in-case we haven't initialized for viewports + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)main_viewport->RendererUserData) + { + // We could just call ImGui_ImplDX12_DestroyWindow(main_viewport) as a convenience but that would be misleading since we only use data->Resources[] + for (UINT i = 0; i < bd->numFramesInFlight; i++) + ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]); + IM_DELETE(vd); + main_viewport->RendererUserData = NULL; + } + + // Clean up windows and device objects + ImGui_ImplDX12_ShutdownPlatformInterface(); + ImGui_ImplDX12_InvalidateDeviceObjects(); + + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplDX12_NewFrame() +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX12_Init()?"); + + if (!bd->pPipelineState) + ImGui_ImplDX12_CreateDeviceObjects(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight); + viewport->RendererUserData = vd; + + // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). + // Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. + HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; + IM_ASSERT(hwnd != 0); + + vd->FrameIndex = UINT_MAX; + + // Create command queue. + D3D12_COMMAND_QUEUE_DESC queue_desc = {}; + queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + HRESULT res = S_OK; + res = bd->pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&vd->CommandQueue)); + IM_ASSERT(res == S_OK); + + // Create command allocator. + for (UINT i = 0; i < bd->numFramesInFlight; ++i) + { + res = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&vd->FrameCtx[i].CommandAllocator)); + IM_ASSERT(res == S_OK); + } + + // Create command list. + res = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, vd->FrameCtx[0].CommandAllocator, NULL, IID_PPV_ARGS(&vd->CommandList)); + IM_ASSERT(res == S_OK); + vd->CommandList->Close(); + + // Create fence. + res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&vd->Fence)); + IM_ASSERT(res == S_OK); + + vd->FenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + IM_ASSERT(vd->FenceEvent != NULL); + + // Create swap chain + // FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application. + DXGI_SWAP_CHAIN_DESC1 sd1; + ZeroMemory(&sd1, sizeof(sd1)); + sd1.BufferCount = bd->numFramesInFlight; + sd1.Width = (UINT)viewport->Size.x; + sd1.Height = (UINT)viewport->Size.y; + sd1.Format = bd->RTVFormat; + sd1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd1.SampleDesc.Count = 1; + sd1.SampleDesc.Quality = 0; + sd1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + sd1.Scaling = DXGI_SCALING_STRETCH; + sd1.Stereo = FALSE; + + IDXGIFactory4* dxgi_factory = NULL; + res = ::CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_factory)); + IM_ASSERT(res == S_OK); + + IDXGISwapChain1* swap_chain = NULL; + res = dxgi_factory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, NULL, NULL, &swap_chain); + IM_ASSERT(res == S_OK); + + dxgi_factory->Release(); + + // Or swapChain.As(&mSwapChain) + IM_ASSERT(vd->SwapChain == NULL); + swap_chain->QueryInterface(IID_PPV_ARGS(&vd->SwapChain)); + swap_chain->Release(); + + // Create the render targets + if (vd->SwapChain) + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + desc.NumDescriptors = bd->numFramesInFlight; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + desc.NodeMask = 1; + + HRESULT hr = bd->pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&vd->RtvDescHeap)); + IM_ASSERT(hr == S_OK); + + SIZE_T rtv_descriptor_size = bd->pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = vd->RtvDescHeap->GetCPUDescriptorHandleForHeapStart(); + for (UINT i = 0; i < bd->numFramesInFlight; i++) + { + vd->FrameCtx[i].RenderTargetCpuDescriptors = rtv_handle; + rtv_handle.ptr += rtv_descriptor_size; + } + + ID3D12Resource* back_buffer; + for (UINT i = 0; i < bd->numFramesInFlight; i++) + { + IM_ASSERT(vd->FrameCtx[i].RenderTarget == NULL); + vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer)); + bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, vd->FrameCtx[i].RenderTargetCpuDescriptors); + vd->FrameCtx[i].RenderTarget = back_buffer; + } + } + + for (UINT i = 0; i < bd->numFramesInFlight; i++) + ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]); +} + +static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd) +{ + HRESULT hr = S_FALSE; + if (vd && vd->CommandQueue && vd->Fence && vd->FenceEvent) + { + hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue); + IM_ASSERT(hr == S_OK); + ::WaitForSingleObject(vd->FenceEvent, 0); // Reset any forgotten waits + hr = vd->Fence->SetEventOnCompletion(vd->FenceSignaledValue, vd->FenceEvent); + IM_ASSERT(hr == S_OK); + ::WaitForSingleObject(vd->FenceEvent, INFINITE); + } +} + +static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData) + { + ImGui_WaitForPendingOperations(vd); + + SafeRelease(vd->CommandQueue); + SafeRelease(vd->CommandList); + SafeRelease(vd->SwapChain); + SafeRelease(vd->RtvDescHeap); + SafeRelease(vd->Fence); + ::CloseHandle(vd->FenceEvent); + vd->FenceEvent = NULL; + + for (UINT i = 0; i < bd->numFramesInFlight; i++) + { + SafeRelease(vd->FrameCtx[i].RenderTarget); + SafeRelease(vd->FrameCtx[i].CommandAllocator); + ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]); + } + IM_DELETE(vd); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData; + + ImGui_WaitForPendingOperations(vd); + + for (UINT i = 0; i < bd->numFramesInFlight; i++) + SafeRelease(vd->FrameCtx[i].RenderTarget); + + if (vd->SwapChain) + { + ID3D12Resource* back_buffer = NULL; + vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0); + for (UINT i = 0; i < bd->numFramesInFlight; i++) + { + vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer)); + bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, vd->FrameCtx[i].RenderTargetCpuDescriptors); + vd->FrameCtx[i].RenderTarget = back_buffer; + } + } +} + +static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData; + + ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % bd->numFramesInFlight]; + UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex(); + + const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = vd->FrameCtx[back_buffer_idx].RenderTarget; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + + // Draw + ID3D12GraphicsCommandList* cmd_list = vd->CommandList; + + frame_context->CommandAllocator->Reset(); + cmd_list->Reset(frame_context->CommandAllocator, NULL); + cmd_list->ResourceBarrier(1, &barrier); + cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, NULL); + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (float*)&clear_color, 0, NULL); + cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap); + + ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list); + + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + cmd_list->ResourceBarrier(1, &barrier); + cmd_list->Close(); + + vd->CommandQueue->Wait(vd->Fence, vd->FenceSignaledValue); + vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list); + vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue); +} + +static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData; + + vd->SwapChain->Present(0, 0); + while (vd->Fence->GetCompletedValue() < vd->FenceSignaledValue) + ::SwitchToThread(); +} + +void ImGui_ImplDX12_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_CreateWindow = ImGui_ImplDX12_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplDX12_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplDX12_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplDX12_RenderWindow; + platform_io.Renderer_SwapBuffers = ImGui_ImplDX12_SwapBuffers; +} + +void ImGui_ImplDX12_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.h new file mode 100644 index 000000000..e453218c2 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx12.h @@ -0,0 +1,39 @@ +// dear imgui: Renderer Backend for DirectX12 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. +// See imgui_impl_dx12.cpp file for details. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API +#include // DXGI_FORMAT + +struct ID3D12Device; +struct ID3D12DescriptorHeap; +struct ID3D12GraphicsCommandList; +struct D3D12_CPU_DESCRIPTOR_HANDLE; +struct D3D12_GPU_DESCRIPTOR_HANDLE; + +// cmd_list is the command list that the implementation will use to render imgui draw lists. +// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate +// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle. +// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture. +IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap, + D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle); +IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects(); +IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.cpp new file mode 100644 index 000000000..45be26a54 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.cpp @@ -0,0 +1,540 @@ +// dear imgui: Renderer Backend for DirectX9 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1. +// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states. +// 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857). +// 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file. +// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. +// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). +// 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288. +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. +// 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. + +#include "imgui.h" +#include "imgui_impl_dx9.h" + +// DirectX +#include + +// DirectX data +struct ImGui_ImplDX9_Data +{ + LPDIRECT3DDEVICE9 pd3dDevice; + LPDIRECT3DVERTEXBUFFER9 pVB; + LPDIRECT3DINDEXBUFFER9 pIB; + LPDIRECT3DTEXTURE9 FontTexture; + int VertexBufferSize; + int IndexBufferSize; + + ImGui_ImplDX9_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } +}; + +struct CUSTOMVERTEX +{ + float pos[3]; + D3DCOLOR col; + float uv[2]; +}; +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) + +#ifdef IMGUI_USE_BGRA_PACKED_COLOR +#define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL) +#else +#define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16)) +#endif + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplDX9_InitPlatformInterface(); +static void ImGui_ImplDX9_ShutdownPlatformInterface(); +static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows(); +static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); + +// Functions +static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + + // Setup viewport + D3DVIEWPORT9 vp; + vp.X = vp.Y = 0; + vp.Width = (DWORD)draw_data->DisplaySize.x; + vp.Height = (DWORD)draw_data->DisplaySize.y; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + bd->pd3dDevice->SetViewport(&vp); + + // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient) + bd->pd3dDevice->SetPixelShader(NULL); + bd->pd3dDevice->SetVertexShader(NULL); + bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); + bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); + bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE); + bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + // Setup orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() + { + float L = draw_data->DisplayPos.x + 0.5f; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; + float T = draw_data->DisplayPos.y + 0.5f; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; + D3DMATRIX mat_identity = { { { 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 } } }; + D3DMATRIX mat_projection = + { { { + 2.0f/(R-L), 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f/(T-B), 0.0f, 0.0f, + 0.0f, 0.0f, 0.5f, 0.0f, + (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f + } } }; + bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); + bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); + bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); + } +} + +// Render function. +void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + // Create and grow buffers if needed + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) + { + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; + if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, NULL) < 0) + return; + } + if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) + { + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; + if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, NULL) < 0) + return; + } + + // Backup the DX9 state + IDirect3DStateBlock9* d3d9_state_block = NULL; + if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) + return; + if (d3d9_state_block->Capture() < 0) + { + d3d9_state_block->Release(); + return; + } + + // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) + D3DMATRIX last_world, last_view, last_projection; + bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); + bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); + bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); + + // Allocate buffers + CUSTOMVERTEX* vtx_dst; + ImDrawIdx* idx_dst; + if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) + { + d3d9_state_block->Release(); + return; + } + if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) + { + bd->pVB->Unlock(); + d3d9_state_block->Release(); + return; + } + + // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. + // FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and + // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR + // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; + for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) + { + vtx_dst->pos[0] = vtx_src->pos.x; + vtx_dst->pos[1] = vtx_src->pos.y; + vtx_dst->pos[2] = 0.0f; + vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col); + vtx_dst->uv[0] = vtx_src->uv.x; + vtx_dst->uv[1] = vtx_src->uv.y; + vtx_dst++; + vtx_src++; + } + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + idx_dst += cmd_list->IdxBuffer.Size; + } + bd->pVB->Unlock(); + bd->pIB->Unlock(); + bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX)); + bd->pd3dDevice->SetIndices(bd->pIB); + bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); + + // Setup desired DX state + ImGui_ImplDX9_SetupRenderState(draw_data); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplDX9_SetupRenderState(draw_data); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply Scissor/clipping rectangle, Bind texture, Draw + const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; + const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); + bd->pd3dDevice->SetTexture(0, texture); + bd->pd3dDevice->SetScissorRect(&r); + bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } + + // When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows + // from rendering until the first window submits at least one draw call, even once. That's our workaround. (see #2560) + if (global_vtx_offset == 0) + bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0); + + // Restore the DX9 transform + bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); + bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); + bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); + + // Restore the DX9 state + d3d9_state_block->Apply(); + d3d9_state_block->Release(); +} + +bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_dx9"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + bd->pd3dDevice = device; + bd->pd3dDevice->AddRef(); + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplDX9_InitPlatformInterface(); + + return true; +} + +void ImGui_ImplDX9_Shutdown() +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplDX9_ShutdownPlatformInterface(); + ImGui_ImplDX9_InvalidateDeviceObjects(); + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +static bool ImGui_ImplDX9_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + unsigned char* pixels; + int width, height, bytes_per_pixel; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel); + + // Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices) +#ifndef IMGUI_USE_BGRA_PACKED_COLOR + if (io.Fonts->TexPixelsUseColors) + { + ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel); + for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++) + *dst = IMGUI_COL_TO_DX9_ARGB(*src); + pixels = (unsigned char*)dst_start; + } +#endif + + // Upload texture to graphics system + bd->FontTexture = NULL; + if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, NULL) < 0) + return false; + D3DLOCKED_RECT tex_locked_rect; + if (bd->FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) + return false; + for (int y = 0; y < height; y++) + memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel); + bd->FontTexture->UnlockRect(0); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)bd->FontTexture); + +#ifndef IMGUI_USE_BGRA_PACKED_COLOR + if (io.Fonts->TexPixelsUseColors) + ImGui::MemFree(pixels); +#endif + + return true; +} + +bool ImGui_ImplDX9_CreateDeviceObjects() +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + if (!bd || !bd->pd3dDevice) + return false; + if (!ImGui_ImplDX9_CreateFontsTexture()) + return false; + ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows(); + return true; +} + +void ImGui_ImplDX9_InvalidateDeviceObjects() +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + if (!bd || !bd->pd3dDevice) + return; + if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; } + if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; } + if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well. + ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); +} + +void ImGui_ImplDX9_NewFrame() +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX9_Init()?"); + + if (!bd->FontTexture) + ImGui_ImplDX9_CreateDeviceObjects(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplDX9_ViewportData +{ + IDirect3DSwapChain9* SwapChain; + D3DPRESENT_PARAMETERS d3dpp; + + ImGui_ImplDX9_ViewportData() { SwapChain = NULL; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); } + ~ImGui_ImplDX9_ViewportData() { IM_ASSERT(SwapChain == NULL); } +}; + +static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)(); + viewport->RendererUserData = vd; + + // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). + // Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. + HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; + IM_ASSERT(hwnd != 0); + + ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS)); + vd->d3dpp.Windowed = TRUE; + vd->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + vd->d3dpp.BackBufferWidth = (UINT)viewport->Size.x; + vd->d3dpp.BackBufferHeight = (UINT)viewport->Size.y; + vd->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + vd->d3dpp.hDeviceWindow = hwnd; + vd->d3dpp.EnableAutoDepthStencil = FALSE; + vd->d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + vd->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync + + HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr); + IM_ASSERT(hr == D3D_OK); + IM_ASSERT(vd->SwapChain != NULL); +} + +static void ImGui_ImplDX9_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. + if (ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData) + { + if (vd->SwapChain) + vd->SwapChain->Release(); + vd->SwapChain = NULL; + ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS)); + IM_DELETE(vd); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplDX9_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; + if (vd->SwapChain) + { + vd->SwapChain->Release(); + vd->SwapChain = NULL; + vd->d3dpp.BackBufferWidth = (UINT)size.x; + vd->d3dpp.BackBufferHeight = (UINT)size.y; + HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr); + IM_ASSERT(hr == D3D_OK); + } +} + +static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); + ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + + LPDIRECT3DSURFACE9 render_target = NULL; + LPDIRECT3DSURFACE9 last_render_target = NULL; + LPDIRECT3DSURFACE9 last_depth_stencil = NULL; + vd->SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target); + bd->pd3dDevice->GetRenderTarget(0, &last_render_target); + bd->pd3dDevice->GetDepthStencilSurface(&last_depth_stencil); + bd->pd3dDevice->SetRenderTarget(0, render_target); + bd->pd3dDevice->SetDepthStencilSurface(NULL); + + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + { + D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f)); + bd->pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, clear_col_dx, 1.0f, 0); + } + + ImGui_ImplDX9_RenderDrawData(viewport->DrawData); + + // Restore render target + bd->pd3dDevice->SetRenderTarget(0, last_render_target); + bd->pd3dDevice->SetDepthStencilSurface(last_depth_stencil); + render_target->Release(); + last_render_target->Release(); + if (last_depth_stencil) last_depth_stencil->Release(); +} + +static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; + HRESULT hr = vd->SwapChain->Present(NULL, NULL, vd->d3dpp.hDeviceWindow, NULL, 0); + // Let main application handle D3DERR_DEVICELOST by resetting the device. + IM_ASSERT(hr == D3D_OK || hr == D3DERR_DEVICELOST); +} + +static void ImGui_ImplDX9_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplDX9_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplDX9_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplDX9_RenderWindow; + platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers; +} + +static void ImGui_ImplDX9_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + +static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int i = 1; i < platform_io.Viewports.Size; i++) + if (!platform_io.Viewports[i]->RendererUserData) + ImGui_ImplDX9_CreateWindow(platform_io.Viewports[i]); +} + +static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int i = 1; i < platform_io.Viewports.Size; i++) + if (platform_io.Viewports[i]->RendererUserData) + ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.h new file mode 100644 index 000000000..773acda7e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_dx9.h @@ -0,0 +1,26 @@ +// dear imgui: Renderer Backend for DirectX9 +// This needs to be used along with a Platform Backend (e.g. Win32) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct IDirect3DDevice9; + +IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); +IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.cpp new file mode 100644 index 000000000..4a5a9855d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.cpp @@ -0,0 +1,1135 @@ +// dear imgui: Platform Backend for GLFW +// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..) +// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+). +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// Issues: +// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor). + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after iniitializing backend. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback(). +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API. +// 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback(). +// 2021-07-29: *BREAKING CHANGE*: Now using glfwSetCursorEnterCallback(). MousePos is correctly reported when the host platform window is hovered but not focused. If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() callback and forward it to the backend via ImGui_ImplGlfw_CursorEnterCallback(). +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors. +// 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor). +// 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown. +// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. +// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter(). +// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them. +// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. +// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. +// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples. +// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value, passed to glfwSetCursor()). +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set. +// 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. + +#include "imgui.h" +#include "imgui_impl_glfw.h" + +// Clang warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +#endif + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#include // for glfwGetWin32Window +#endif +#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING +#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED +#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity +#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale +#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface +#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwFocusWindow +#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW +#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorWorkarea +#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION * 10 >= 3310) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553 +#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released? +#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR +#else +#define GLFW_HAS_NEW_CURSORS (0) +#endif +#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough) +#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH +#else +#define GLFW_HAS_MOUSE_PASSTHROUGH (0) +#endif +#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetGamepadState() new api +#define GLFW_HAS_GET_KEY_NAME (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwGetKeyName() + +// GLFW data +enum GlfwClientApi +{ + GlfwClientApi_Unknown, + GlfwClientApi_OpenGL, + GlfwClientApi_Vulkan +}; + +struct ImGui_ImplGlfw_Data +{ + GLFWwindow* Window; + GlfwClientApi ClientApi; + double Time; + GLFWwindow* MouseWindow; + GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; + ImVec2 LastValidMousePos; + GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; + bool InstalledCallbacks; + bool WantUpdateMonitors; + + // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. + GLFWwindowfocusfun PrevUserCallbackWindowFocus; + GLFWcursorposfun PrevUserCallbackCursorPos; + GLFWcursorenterfun PrevUserCallbackCursorEnter; + GLFWmousebuttonfun PrevUserCallbackMousebutton; + GLFWscrollfun PrevUserCallbackScroll; + GLFWkeyfun PrevUserCallbackKey; + GLFWcharfun PrevUserCallbackChar; + GLFWmonitorfun PrevUserCallbackMonitor; + + ImGui_ImplGlfw_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +// - Because glfwPollEvents() process all windows and some events may be called outside of it, you will need to register your own callbacks +// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks. +// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it. +// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. +static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplGlfw_UpdateMonitors(); +static void ImGui_ImplGlfw_InitPlatformInterface(); +static void ImGui_ImplGlfw_ShutdownPlatformInterface(); + +// Functions +static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) +{ + return glfwGetClipboardString((GLFWwindow*)user_data); +} + +static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) +{ + glfwSetClipboardString((GLFWwindow*)user_data, text); +} + +static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key) +{ + switch (key) + { + case GLFW_KEY_TAB: return ImGuiKey_Tab; + case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow; + case GLFW_KEY_RIGHT: return ImGuiKey_RightArrow; + case GLFW_KEY_UP: return ImGuiKey_UpArrow; + case GLFW_KEY_DOWN: return ImGuiKey_DownArrow; + case GLFW_KEY_PAGE_UP: return ImGuiKey_PageUp; + case GLFW_KEY_PAGE_DOWN: return ImGuiKey_PageDown; + case GLFW_KEY_HOME: return ImGuiKey_Home; + case GLFW_KEY_END: return ImGuiKey_End; + case GLFW_KEY_INSERT: return ImGuiKey_Insert; + case GLFW_KEY_DELETE: return ImGuiKey_Delete; + case GLFW_KEY_BACKSPACE: return ImGuiKey_Backspace; + case GLFW_KEY_SPACE: return ImGuiKey_Space; + case GLFW_KEY_ENTER: return ImGuiKey_Enter; + case GLFW_KEY_ESCAPE: return ImGuiKey_Escape; + case GLFW_KEY_APOSTROPHE: return ImGuiKey_Apostrophe; + case GLFW_KEY_COMMA: return ImGuiKey_Comma; + case GLFW_KEY_MINUS: return ImGuiKey_Minus; + case GLFW_KEY_PERIOD: return ImGuiKey_Period; + case GLFW_KEY_SLASH: return ImGuiKey_Slash; + case GLFW_KEY_SEMICOLON: return ImGuiKey_Semicolon; + case GLFW_KEY_EQUAL: return ImGuiKey_Equal; + case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket; + case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash; + case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket; + case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent; + case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock; + case GLFW_KEY_SCROLL_LOCK: return ImGuiKey_ScrollLock; + case GLFW_KEY_NUM_LOCK: return ImGuiKey_NumLock; + case GLFW_KEY_PRINT_SCREEN: return ImGuiKey_PrintScreen; + case GLFW_KEY_PAUSE: return ImGuiKey_Pause; + case GLFW_KEY_KP_0: return ImGuiKey_Keypad0; + case GLFW_KEY_KP_1: return ImGuiKey_Keypad1; + case GLFW_KEY_KP_2: return ImGuiKey_Keypad2; + case GLFW_KEY_KP_3: return ImGuiKey_Keypad3; + case GLFW_KEY_KP_4: return ImGuiKey_Keypad4; + case GLFW_KEY_KP_5: return ImGuiKey_Keypad5; + case GLFW_KEY_KP_6: return ImGuiKey_Keypad6; + case GLFW_KEY_KP_7: return ImGuiKey_Keypad7; + case GLFW_KEY_KP_8: return ImGuiKey_Keypad8; + case GLFW_KEY_KP_9: return ImGuiKey_Keypad9; + case GLFW_KEY_KP_DECIMAL: return ImGuiKey_KeypadDecimal; + case GLFW_KEY_KP_DIVIDE: return ImGuiKey_KeypadDivide; + case GLFW_KEY_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; + case GLFW_KEY_KP_SUBTRACT: return ImGuiKey_KeypadSubtract; + case GLFW_KEY_KP_ADD: return ImGuiKey_KeypadAdd; + case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter; + case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual; + case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift; + case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl; + case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt; + case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper; + case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift; + case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightCtrl; + case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt; + case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper; + case GLFW_KEY_MENU: return ImGuiKey_Menu; + case GLFW_KEY_0: return ImGuiKey_0; + case GLFW_KEY_1: return ImGuiKey_1; + case GLFW_KEY_2: return ImGuiKey_2; + case GLFW_KEY_3: return ImGuiKey_3; + case GLFW_KEY_4: return ImGuiKey_4; + case GLFW_KEY_5: return ImGuiKey_5; + case GLFW_KEY_6: return ImGuiKey_6; + case GLFW_KEY_7: return ImGuiKey_7; + case GLFW_KEY_8: return ImGuiKey_8; + case GLFW_KEY_9: return ImGuiKey_9; + case GLFW_KEY_A: return ImGuiKey_A; + case GLFW_KEY_B: return ImGuiKey_B; + case GLFW_KEY_C: return ImGuiKey_C; + case GLFW_KEY_D: return ImGuiKey_D; + case GLFW_KEY_E: return ImGuiKey_E; + case GLFW_KEY_F: return ImGuiKey_F; + case GLFW_KEY_G: return ImGuiKey_G; + case GLFW_KEY_H: return ImGuiKey_H; + case GLFW_KEY_I: return ImGuiKey_I; + case GLFW_KEY_J: return ImGuiKey_J; + case GLFW_KEY_K: return ImGuiKey_K; + case GLFW_KEY_L: return ImGuiKey_L; + case GLFW_KEY_M: return ImGuiKey_M; + case GLFW_KEY_N: return ImGuiKey_N; + case GLFW_KEY_O: return ImGuiKey_O; + case GLFW_KEY_P: return ImGuiKey_P; + case GLFW_KEY_Q: return ImGuiKey_Q; + case GLFW_KEY_R: return ImGuiKey_R; + case GLFW_KEY_S: return ImGuiKey_S; + case GLFW_KEY_T: return ImGuiKey_T; + case GLFW_KEY_U: return ImGuiKey_U; + case GLFW_KEY_V: return ImGuiKey_V; + case GLFW_KEY_W: return ImGuiKey_W; + case GLFW_KEY_X: return ImGuiKey_X; + case GLFW_KEY_Y: return ImGuiKey_Y; + case GLFW_KEY_Z: return ImGuiKey_Z; + case GLFW_KEY_F1: return ImGuiKey_F1; + case GLFW_KEY_F2: return ImGuiKey_F2; + case GLFW_KEY_F3: return ImGuiKey_F3; + case GLFW_KEY_F4: return ImGuiKey_F4; + case GLFW_KEY_F5: return ImGuiKey_F5; + case GLFW_KEY_F6: return ImGuiKey_F6; + case GLFW_KEY_F7: return ImGuiKey_F7; + case GLFW_KEY_F8: return ImGuiKey_F8; + case GLFW_KEY_F9: return ImGuiKey_F9; + case GLFW_KEY_F10: return ImGuiKey_F10; + case GLFW_KEY_F11: return ImGuiKey_F11; + case GLFW_KEY_F12: return ImGuiKey_F12; + default: return ImGuiKey_None; + } +} + +static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(ImGuiKey_ModCtrl, (mods & GLFW_MOD_CONTROL) != 0); + io.AddKeyEvent(ImGuiKey_ModShift, (mods & GLFW_MOD_SHIFT) != 0); + io.AddKeyEvent(ImGuiKey_ModAlt, (mods & GLFW_MOD_ALT) != 0); + io.AddKeyEvent(ImGuiKey_ModSuper, (mods & GLFW_MOD_SUPER) != 0); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackMousebutton != NULL && window == bd->Window) + bd->PrevUserCallbackMousebutton(window, button, action, mods); + + ImGui_ImplGlfw_UpdateKeyModifiers(mods); + + ImGuiIO& io = ImGui::GetIO(); + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, action == GLFW_PRESS); +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackScroll != NULL && window == bd->Window) + bd->PrevUserCallbackScroll(window, xoffset, yoffset); + + ImGuiIO& io = ImGui::GetIO(); + io.AddMouseWheelEvent((float)xoffset, (float)yoffset); +} + +static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode) +{ +#if GLFW_HAS_GET_KEY_NAME && !defined(__EMSCRIPTEN__) + // GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult. + // (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently) + // See https://github.com/glfw/glfw/issues/1502 for details. + // Adding a workaround to undo this (so our keys are translated->untranslated->translated, likely a lossy process). + // This won't cover edge cases but this is at least going to cover common cases. + if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL) + return key; + const char* key_name = glfwGetKeyName(key, scancode); + if (key_name && key_name[0] != 0 && key_name[1] == 0) + { + const char char_names[] = "`-=[]\\,;\'./"; + const int char_keys[] = { GLFW_KEY_GRAVE_ACCENT, GLFW_KEY_MINUS, GLFW_KEY_EQUAL, GLFW_KEY_LEFT_BRACKET, GLFW_KEY_RIGHT_BRACKET, GLFW_KEY_BACKSLASH, GLFW_KEY_COMMA, GLFW_KEY_SEMICOLON, GLFW_KEY_APOSTROPHE, GLFW_KEY_PERIOD, GLFW_KEY_SLASH, 0 }; + IM_ASSERT(IM_ARRAYSIZE(char_names) == IM_ARRAYSIZE(char_keys)); + if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); } + else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); } + else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; } + } + // if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name); +#else + IM_UNUSED(scancode); +#endif + return key; +} + +void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackKey != NULL && window == bd->Window) + bd->PrevUserCallbackKey(window, keycode, scancode, action, mods); + + if (action != GLFW_PRESS && action != GLFW_RELEASE) + return; + + ImGui_ImplGlfw_UpdateKeyModifiers(mods); + + if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows)) + bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : NULL; + + keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode); + + ImGuiIO& io = ImGui::GetIO(); + ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode); + io.AddKeyEvent(imgui_key, (action == GLFW_PRESS)); + io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code) +} + +void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackWindowFocus != NULL && window == bd->Window) + bd->PrevUserCallbackWindowFocus(window, focused); + + ImGuiIO& io = ImGui::GetIO(); + io.AddFocusEvent(focused != 0); +} + +void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackCursorPos != NULL && window == bd->Window) + bd->PrevUserCallbackCursorPos(window, x, y); + + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + int window_x, window_y; + glfwGetWindowPos(window, &window_x, &window_y); + x += window_x; + y += window_y; + } + io.AddMousePosEvent((float)x, (float)y); + bd->LastValidMousePos = ImVec2((float)x, (float)y); +} + +// Workaround: X11 seems to send spurious Leave/Enter events which would make us lose our position, +// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984) +void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackCursorEnter != NULL && window == bd->Window) + bd->PrevUserCallbackCursorEnter(window, entered); + + ImGuiIO& io = ImGui::GetIO(); + if (entered) + { + bd->MouseWindow = window; + io.AddMousePosEvent(bd->LastValidMousePos.x, bd->LastValidMousePos.y); + } + else if (!entered && bd->MouseWindow == window) + { + bd->LastValidMousePos = io.MousePos; + bd->MouseWindow = NULL; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + } +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (bd->PrevUserCallbackChar != NULL && window == bd->Window) + bd->PrevUserCallbackChar(window, c); + + ImGuiIO& io = ImGui::GetIO(); + io.AddInputCharacter(c); +} + +void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + bd->WantUpdateMonitors = true; +} + +void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!"); + IM_ASSERT(bd->Window == window); + + bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback); + bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback); + bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback); + bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + bd->PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + bd->PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); + bd->InstalledCallbacks = true; +} + +void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!"); + IM_ASSERT(bd->Window == window); + + glfwSetWindowFocusCallback(window, bd->PrevUserCallbackWindowFocus); + glfwSetCursorEnterCallback(window, bd->PrevUserCallbackCursorEnter); + glfwSetCursorPosCallback(window, bd->PrevUserCallbackCursorPos); + glfwSetMouseButtonCallback(window, bd->PrevUserCallbackMousebutton); + glfwSetScrollCallback(window, bd->PrevUserCallbackScroll); + glfwSetKeyCallback(window, bd->PrevUserCallbackKey); + glfwSetCharCallback(window, bd->PrevUserCallbackChar); + glfwSetMonitorCallback(bd->PrevUserCallbackMonitor); + bd->InstalledCallbacks = false; + bd->PrevUserCallbackWindowFocus = NULL; + bd->PrevUserCallbackCursorEnter = NULL; + bd->PrevUserCallbackCursorPos = NULL; + bd->PrevUserCallbackMousebutton = NULL; + bd->PrevUserCallbackScroll = NULL; + bd->PrevUserCallbackKey = NULL; + bd->PrevUserCallbackChar = NULL; + bd->PrevUserCallbackMonitor = NULL; +} + +static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); + + // Setup backend capabilities flags + ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_glfw"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) +#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)) + io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) +#endif + + bd->Window = window; + bd->Time = 0.0; + bd->WantUpdateMonitors = true; + + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; + io.ClipboardUserData = bd->Window; + + // Create mouse cursors + // (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist, + // GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting. + // Missing cursors will return NULL and our _UpdateMouseCursor() function will use the Arrow cursor instead.) + GLFWerrorfun prev_error_callback = glfwSetErrorCallback(NULL); + bd->MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR); +#if GLFW_HAS_NEW_CURSORS + bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_RESIZE_ALL_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_RESIZE_NESW_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR); +#else + bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); +#endif + glfwSetErrorCallback(prev_error_callback); + + // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. + if (install_callbacks) + ImGui_ImplGlfw_InstallCallbacks(window); + + // Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784) + ImGui_ImplGlfw_UpdateMonitors(); + glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); + + // Our mouse update function expect PlatformHandle to be filled for the main viewport + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)bd->Window; +#ifdef _WIN32 + main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window); +#endif + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplGlfw_InitPlatformInterface(); + + bd->ClientApi = client_api; + return true; +} + +bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks) +{ + return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL); +} + +bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks) +{ + return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan); +} + +bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks) +{ + return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Unknown); +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplGlfw_ShutdownPlatformInterface(); + + if (bd->InstalledCallbacks) + ImGui_ImplGlfw_RestoreCallbacks(bd->Window); + + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) + glfwDestroyCursor(bd->MouseCursors[cursor_n]); + + io.BackendPlatformName = NULL; + io.BackendPlatformUserData = NULL; + IM_DELETE(bd); +} + +static void ImGui_ImplGlfw_UpdateMouseData() +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + + ImGuiID mouse_viewport_id = 0; + const ImVec2 mouse_pos_prev = io.MousePos; + for (int n = 0; n < platform_io.Viewports.Size; n++) + { + ImGuiViewport* viewport = platform_io.Viewports[n]; + GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle; + +#ifdef __EMSCRIPTEN__ + const bool is_window_focused = true; +#else + const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0; +#endif + if (is_window_focused) + { + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions. + if (io.WantSetMousePos) + glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y)); + + // (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured) + if (bd->MouseWindow == NULL) + { + double mouse_x, mouse_y; + glfwGetCursorPos(window, &mouse_x, &mouse_y); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) + // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) + int window_x, window_y; + glfwGetWindowPos(window, &window_x, &window_y); + mouse_x += window_x; + mouse_y += window_y; + } + bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y); + io.AddMousePosEvent((float)mouse_x, (float)mouse_y); + } + } + + // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering. + // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic. + // - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag. + // - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture. + // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window + // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported + // by the backend, and use its flawed heuristic to guess the viewport behind. + // - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target). + // FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems. + // See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature. +#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)) + const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0; +#if GLFW_HAS_MOUSE_PASSTHROUGH + glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input); +#endif + if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input) + mouse_viewport_id = viewport->ID; +#else + // We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse. +#endif + } + + if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) + io.AddMouseViewportEvent(mouse_viewport_id); +} + +static void ImGui_ImplGlfw_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) + return; + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int n = 0; n < platform_io.Viewports.Size; n++) + { + GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle; + if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + } + else + { + // Show OS mouse cursor + // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here. + glfwSetCursor(window, bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + } +} + +// Update gamepad inputs +static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; } +static void ImGui_ImplGlfw_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; +#if GLFW_HAS_GAMEPAD_API + GLFWgamepadstate gamepad; + if (!glfwGetGamepadState(GLFW_JOYSTICK_1, &gamepad)) + return; + #define MAP_BUTTON(KEY_NO, BUTTON_NO, _UNUSED) do { io.AddKeyEvent(KEY_NO, gamepad.buttons[BUTTON_NO] != 0); } while (0) + #define MAP_ANALOG(KEY_NO, AXIS_NO, _UNUSED, V0, V1) do { float v = gamepad.axes[AXIS_NO]; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0) +#else + int axes_count = 0, buttons_count = 0; + const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axes_count); + const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &buttons_count); + if (axes_count == 0 || buttons_count == 0) + return; + #define MAP_BUTTON(KEY_NO, _UNUSED, BUTTON_NO) do { io.AddKeyEvent(KEY_NO, (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS)); } while (0) + #define MAP_ANALOG(KEY_NO, _UNUSED, AXIS_NO, V0, V1) do { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0) +#endif + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + MAP_BUTTON(ImGuiKey_GamepadStart, GLFW_GAMEPAD_BUTTON_START, 7); + MAP_BUTTON(ImGuiKey_GamepadBack, GLFW_GAMEPAD_BUTTON_BACK, 6); + MAP_BUTTON(ImGuiKey_GamepadFaceDown, GLFW_GAMEPAD_BUTTON_A, 0); // Xbox A, PS Cross + MAP_BUTTON(ImGuiKey_GamepadFaceRight, GLFW_GAMEPAD_BUTTON_B, 1); // Xbox B, PS Circle + MAP_BUTTON(ImGuiKey_GamepadFaceLeft, GLFW_GAMEPAD_BUTTON_X, 2); // Xbox X, PS Square + MAP_BUTTON(ImGuiKey_GamepadFaceUp, GLFW_GAMEPAD_BUTTON_Y, 3); // Xbox Y, PS Triangle + MAP_BUTTON(ImGuiKey_GamepadDpadLeft, GLFW_GAMEPAD_BUTTON_DPAD_LEFT, 13); + MAP_BUTTON(ImGuiKey_GamepadDpadRight, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, 11); + MAP_BUTTON(ImGuiKey_GamepadDpadUp, GLFW_GAMEPAD_BUTTON_DPAD_UP, 10); + MAP_BUTTON(ImGuiKey_GamepadDpadDown, GLFW_GAMEPAD_BUTTON_DPAD_DOWN, 12); + MAP_BUTTON(ImGuiKey_GamepadL1, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, 4); + MAP_BUTTON(ImGuiKey_GamepadR1, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, 5); + MAP_ANALOG(ImGuiKey_GamepadL2, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, 4, -0.75f, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadR2, GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, 5, -0.75f, +1.0f); + MAP_BUTTON(ImGuiKey_GamepadL3, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, 8); + MAP_BUTTON(ImGuiKey_GamepadR3, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, 9); + MAP_ANALOG(ImGuiKey_GamepadLStickLeft, GLFW_GAMEPAD_AXIS_LEFT_X, 0, -0.25f, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickRight, GLFW_GAMEPAD_AXIS_LEFT_X, 0, +0.25f, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickUp, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, -0.25f, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickDown, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, +0.25f, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickLeft, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, -0.25f, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickRight, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, +0.25f, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickUp, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, -0.25f, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickDown, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, +0.25f, +1.0f); + #undef MAP_BUTTON + #undef MAP_ANALOG +} + +static void ImGui_ImplGlfw_UpdateMonitors() +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + int monitors_count = 0; + GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count); + platform_io.Monitors.resize(0); + for (int n = 0; n < monitors_count; n++) + { + ImGuiPlatformMonitor monitor; + int x, y; + glfwGetMonitorPos(glfw_monitors[n], &x, &y); + const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]); + monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height); +#if GLFW_HAS_MONITOR_WORK_AREA + int w, h; + glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h); + if (w > 0 && h > 0) // Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761 + { + monitor.WorkPos = ImVec2((float)x, (float)y); + monitor.WorkSize = ImVec2((float)w, (float)h); + } +#endif +#if GLFW_HAS_PER_MONITOR_DPI + // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. + float x_scale, y_scale; + glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale); + monitor.DpiScale = x_scale; +#endif + platform_io.Monitors.push_back(monitor); + } + bd->WantUpdateMonitors = false; +} + +void ImGui_ImplGlfw_NewFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplGlfw_InitForXXX()?"); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(bd->Window, &w, &h); + glfwGetFramebufferSize(bd->Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + if (w > 0 && h > 0) + io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h); + if (bd->WantUpdateMonitors) + ImGui_ImplGlfw_UpdateMonitors(); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); + bd->Time = current_time; + + ImGui_ImplGlfw_UpdateMouseData(); + ImGui_ImplGlfw_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplGlfw_UpdateGamepads(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplGlfw_ViewportData +{ + GLFWwindow* Window; + bool WindowOwned; + int IgnoreWindowPosEventFrame; + int IgnoreWindowSizeEventFrame; + + ImGui_ImplGlfw_ViewportData() { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; } + ~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == NULL); } +}; + +static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window) +{ + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) + viewport->PlatformRequestClose = true; +} + +// GLFW may dispatch window pos/size events after calling glfwSetWindowPos()/glfwSetWindowSize(). +// However: depending on the platform the callback may be invoked at different time: +// - on Windows it appears to be called within the glfwSetWindowPos()/glfwSetWindowSize() call +// - on Linux it is queued and invoked during glfwPollEvents() +// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only +// ignore recent glfwSetWindowXXX() calls. +static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int) +{ + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) + { + if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) + { + bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1); + //data->IgnoreWindowPosEventFrame = -1; + if (ignore_event) + return; + } + viewport->PlatformRequestMove = true; + } +} + +static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int) +{ + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) + { + if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) + { + bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1); + //data->IgnoreWindowSizeEventFrame = -1; + if (ignore_event) + return; + } + viewport->PlatformRequestResize = true; + } +} + +static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); + viewport->PlatformUserData = vd; + + // GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED + // With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem + glfwWindowHint(GLFW_VISIBLE, false); + glfwWindowHint(GLFW_FOCUSED, false); +#if GLFW_HAS_FOCUS_ON_SHOW + glfwWindowHint(GLFW_FOCUS_ON_SHOW, false); + #endif + glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true); +#if GLFW_HAS_WINDOW_TOPMOST + glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false); +#endif + GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : NULL; + vd->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window); + vd->WindowOwned = true; + viewport->PlatformHandle = (void*)vd->Window; +#ifdef _WIN32 + viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window); +#endif + glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y); + + // Install GLFW callbacks for secondary viewports + glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback); + glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback); + glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback); + glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback); + glfwSetCharCallback(vd->Window, ImGui_ImplGlfw_CharCallback); + glfwSetWindowCloseCallback(vd->Window, ImGui_ImplGlfw_WindowCloseCallback); + glfwSetWindowPosCallback(vd->Window, ImGui_ImplGlfw_WindowPosCallback); + glfwSetWindowSizeCallback(vd->Window, ImGui_ImplGlfw_WindowSizeCallback); + if (bd->ClientApi == GlfwClientApi_OpenGL) + { + glfwMakeContextCurrent(vd->Window); + glfwSwapInterval(0); + } +} + +static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) + { + if (vd->WindowOwned) + { +#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32) + HWND hwnd = (HWND)viewport->PlatformHandleRaw; + ::RemovePropA(hwnd, "IMGUI_VIEWPORT"); +#endif + + // Release any keys that were pressed in the window being destroyed and are still held down, + // because we will not receive any release events after window is destroyed. + for (int i = 0; i < IM_ARRAYSIZE(bd->KeyOwnerWindows); i++) + if (bd->KeyOwnerWindows[i] == vd->Window) + ImGui_ImplGlfw_KeyCallback(vd->Window, i, 0, GLFW_RELEASE, 0); // Later params are only used for main viewport, on which this function is never called. + + glfwDestroyWindow(vd->Window); + } + vd->Window = NULL; + IM_DELETE(vd); + } + viewport->PlatformUserData = viewport->PlatformHandle = NULL; +} + +// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs". +// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!) +#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32) +static WNDPROC g_GlfwWndProc = NULL; +static LRESULT CALLBACK WndProcNoInputs(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_NCHITTEST) + { + // Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL). + // The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging. + // If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in + // your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system. + ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT"); + if (viewport->Flags & ImGuiViewportFlags_NoInputs) + return HTTRANSPARENT; + } + return ::CallWindowProc(g_GlfwWndProc, hWnd, msg, wParam, lParam); +} +#endif + +static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + +#if defined(_WIN32) + // GLFW hack: Hide icon from task bar + HWND hwnd = (HWND)viewport->PlatformHandleRaw; + if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) + { + LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + ex_style &= ~WS_EX_APPWINDOW; + ex_style |= WS_EX_TOOLWINDOW; + ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); + } + + // GLFW hack: install hook for WM_NCHITTEST message handler +#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32) + ::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport); + if (g_GlfwWndProc == NULL) + g_GlfwWndProc = (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC); + ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WndProcNoInputs); +#endif + +#if !GLFW_HAS_FOCUS_ON_SHOW + // GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window. + // The fix was pushed to GLFW repository on 2018/01/09 and should be included in GLFW 3.3 via a GLFW_FOCUS_ON_SHOW window attribute. + // See https://github.com/glfw/glfw/issues/1189 + // FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile. + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) + { + ::ShowWindow(hwnd, SW_SHOWNA); + return; + } +#endif +#endif + + glfwShowWindow(vd->Window); +} + +static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + int x = 0, y = 0; + glfwGetWindowPos(vd->Window, &x, &y); + return ImVec2((float)x, (float)y); +} + +static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount(); + glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y); +} + +static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + int w = 0, h = 0; + glfwGetWindowSize(vd->Window, &w, &h); + return ImVec2((float)w, (float)h); +} + +static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; +#if __APPLE__ && !GLFW_HAS_OSX_WINDOW_POS_FIX + // Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are + // positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it + // doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based + // on the upper-left corner. + int x, y, width, height; + glfwGetWindowPos(vd->Window, &x, &y); + glfwGetWindowSize(vd->Window, &width, &height); + glfwSetWindowPos(vd->Window, x, y - height + size.y); +#endif + vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount(); + glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y); +} + +static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + glfwSetWindowTitle(vd->Window, title); +} + +static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport) +{ +#if GLFW_HAS_FOCUS_WINDOW + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + glfwFocusWindow(vd->Window); +#else + // FIXME: What are the effect of not having this function? At the moment imgui doesn't actually call SetWindowFocus - we set that up ahead, will answer that question later. + (void)viewport; +#endif +} + +static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + return glfwGetWindowAttrib(vd->Window, GLFW_FOCUSED) != 0; +} + +static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + return glfwGetWindowAttrib(vd->Window, GLFW_ICONIFIED) != 0; +} + +#if GLFW_HAS_WINDOW_ALPHA +static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + glfwSetWindowOpacity(vd->Window, alpha); +} +#endif + +static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + if (bd->ClientApi == GlfwClientApi_OpenGL) + glfwMakeContextCurrent(vd->Window); +} + +static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + if (bd->ClientApi == GlfwClientApi_OpenGL) + { + glfwMakeContextCurrent(vd->Window); + glfwSwapBuffers(vd->Window); + } +} + +//-------------------------------------------------------------------------------------------------------- +// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface) +//-------------------------------------------------------------------------------------------------------- + +// Avoid including so we can build without it +#if GLFW_HAS_VULKAN +#ifndef VULKAN_H_ +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +struct VkAllocationCallbacks; +enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF }; +#endif // VULKAN_H_ +extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); } +static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) +{ + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; + IM_UNUSED(bd); + IM_ASSERT(bd->ClientApi == GlfwClientApi_Vulkan); + VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, vd->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface); + return (int)err; +} +#endif // GLFW_HAS_VULKAN + +static void ImGui_ImplGlfw_InitPlatformInterface() +{ + // Register platform interface (will be coupled with a renderer interface) + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow; + platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow; + platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow; + platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos; + platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos; + platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize; + platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize; + platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus; + platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized; + platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle; + platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow; + platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers; +#if GLFW_HAS_WINDOW_ALPHA + platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha; +#endif +#if GLFW_HAS_VULKAN + platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface; +#endif + + // Register main window handle (which is owned by the main application, not by us) + // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports. + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); + vd->Window = bd->Window; + vd->WindowOwned = false; + main_viewport->PlatformUserData = vd; + main_viewport->PlatformHandle = (void*)bd->Window; +} + +static void ImGui_ImplGlfw_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.h new file mode 100644 index 000000000..b96f3ee2c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glfw.h @@ -0,0 +1,51 @@ +// dear imgui: Platform Backend for GLFW +// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..) +// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+). +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// Issues: +// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor). + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// About GLSL version: +// The 'glsl_version' initialization parameter defaults to "#version 150" if NULL. +// Only override if your GL version doesn't handle this GLSL version. Keep NULL if unsure! + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct GLFWwindow; +struct GLFWmonitor; + +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); + +// GLFW callbacks (installer) +// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any. +// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks. +IMGUI_IMPL_API void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window); +IMGUI_IMPL_API void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window); + +// GLFW callbacks (individual callbacks to call if you didn't install callbacks) +IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84 +IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84 +IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87 +IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); +IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.cpp new file mode 100644 index 000000000..d3e638b52 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.cpp @@ -0,0 +1,297 @@ +// dear imgui: Platform Backend for GLUT/FreeGLUT +// This needs to be used along with a Renderer (e.g. OpenGL2) + +// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!! +// !!! Nowadays, prefer using GLFW or SDL instead! + +// Implemented features: +// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// Issues: +// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I +// [ ] Platform: Missing mouse cursor shape/visibility support. +// [ ] Platform: Missing clipboard support (not supported by Glut). +// [ ] Platform: Missing gamepad support. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. +// 2019-03-25: Misc: Made io.DeltaTime always above zero. +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-03-22: Added GLUT Platform binding. + +#include "imgui.h" +#include "imgui_impl_glut.h" +#ifdef __APPLE__ +#include +#else +#include +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) +#endif + +static int g_Time = 0; // Current time, in milliseconds + +// Glut has 1 function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above. +static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key) +{ + switch (key) + { + case '\t': return ImGuiKey_Tab; + case 256 + GLUT_KEY_LEFT: return ImGuiKey_LeftArrow; + case 256 + GLUT_KEY_RIGHT: return ImGuiKey_RightArrow; + case 256 + GLUT_KEY_UP: return ImGuiKey_UpArrow; + case 256 + GLUT_KEY_DOWN: return ImGuiKey_DownArrow; + case 256 + GLUT_KEY_PAGE_UP: return ImGuiKey_PageUp; + case 256 + GLUT_KEY_PAGE_DOWN: return ImGuiKey_PageDown; + case 256 + GLUT_KEY_HOME: return ImGuiKey_Home; + case 256 + GLUT_KEY_END: return ImGuiKey_End; + case 256 + GLUT_KEY_INSERT: return ImGuiKey_Insert; + case 127: return ImGuiKey_Delete; + case 8: return ImGuiKey_Backspace; + case ' ': return ImGuiKey_Space; + case 13: return ImGuiKey_Enter; + case 27: return ImGuiKey_Escape; + case 39: return ImGuiKey_Apostrophe; + case 44: return ImGuiKey_Comma; + case 45: return ImGuiKey_Minus; + case 46: return ImGuiKey_Period; + case 47: return ImGuiKey_Slash; + case 59: return ImGuiKey_Semicolon; + case 61: return ImGuiKey_Equal; + case 91: return ImGuiKey_LeftBracket; + case 92: return ImGuiKey_Backslash; + case 93: return ImGuiKey_RightBracket; + case 96: return ImGuiKey_GraveAccent; + //case 0: return ImGuiKey_CapsLock; + //case 0: return ImGuiKey_ScrollLock; + case 256 + 0x006D: return ImGuiKey_NumLock; + //case 0: return ImGuiKey_PrintScreen; + //case 0: return ImGuiKey_Pause; + //case '0': return ImGuiKey_Keypad0; + //case '1': return ImGuiKey_Keypad1; + //case '2': return ImGuiKey_Keypad2; + //case '3': return ImGuiKey_Keypad3; + //case '4': return ImGuiKey_Keypad4; + //case '5': return ImGuiKey_Keypad5; + //case '6': return ImGuiKey_Keypad6; + //case '7': return ImGuiKey_Keypad7; + //case '8': return ImGuiKey_Keypad8; + //case '9': return ImGuiKey_Keypad9; + //case 46: return ImGuiKey_KeypadDecimal; + //case 47: return ImGuiKey_KeypadDivide; + case 42: return ImGuiKey_KeypadMultiply; + //case 45: return ImGuiKey_KeypadSubtract; + case 43: return ImGuiKey_KeypadAdd; + //case 13: return ImGuiKey_KeypadEnter; + //case 0: return ImGuiKey_KeypadEqual; + case 256 + 0x0072: return ImGuiKey_LeftCtrl; + case 256 + 0x0070: return ImGuiKey_LeftShift; + case 256 + 0x0074: return ImGuiKey_LeftAlt; + //case 0: return ImGuiKey_LeftSuper; + case 256 + 0x0073: return ImGuiKey_RightCtrl; + case 256 + 0x0071: return ImGuiKey_RightShift; + case 256 + 0x0075: return ImGuiKey_RightAlt; + //case 0: return ImGuiKey_RightSuper; + //case 0: return ImGuiKey_Menu; + case '0': return ImGuiKey_0; + case '1': return ImGuiKey_1; + case '2': return ImGuiKey_2; + case '3': return ImGuiKey_3; + case '4': return ImGuiKey_4; + case '5': return ImGuiKey_5; + case '6': return ImGuiKey_6; + case '7': return ImGuiKey_7; + case '8': return ImGuiKey_8; + case '9': return ImGuiKey_9; + case 'A': case 'a': return ImGuiKey_A; + case 'B': case 'b': return ImGuiKey_B; + case 'C': case 'c': return ImGuiKey_C; + case 'D': case 'd': return ImGuiKey_D; + case 'E': case 'e': return ImGuiKey_E; + case 'F': case 'f': return ImGuiKey_F; + case 'G': case 'g': return ImGuiKey_G; + case 'H': case 'h': return ImGuiKey_H; + case 'I': case 'i': return ImGuiKey_I; + case 'J': case 'j': return ImGuiKey_J; + case 'K': case 'k': return ImGuiKey_K; + case 'L': case 'l': return ImGuiKey_L; + case 'M': case 'm': return ImGuiKey_M; + case 'N': case 'n': return ImGuiKey_N; + case 'O': case 'o': return ImGuiKey_O; + case 'P': case 'p': return ImGuiKey_P; + case 'Q': case 'q': return ImGuiKey_Q; + case 'R': case 'r': return ImGuiKey_R; + case 'S': case 's': return ImGuiKey_S; + case 'T': case 't': return ImGuiKey_T; + case 'U': case 'u': return ImGuiKey_U; + case 'V': case 'v': return ImGuiKey_V; + case 'W': case 'w': return ImGuiKey_W; + case 'X': case 'x': return ImGuiKey_X; + case 'Y': case 'y': return ImGuiKey_Y; + case 'Z': case 'z': return ImGuiKey_Z; + case 256 + GLUT_KEY_F1: return ImGuiKey_F1; + case 256 + GLUT_KEY_F2: return ImGuiKey_F2; + case 256 + GLUT_KEY_F3: return ImGuiKey_F3; + case 256 + GLUT_KEY_F4: return ImGuiKey_F4; + case 256 + GLUT_KEY_F5: return ImGuiKey_F5; + case 256 + GLUT_KEY_F6: return ImGuiKey_F6; + case 256 + GLUT_KEY_F7: return ImGuiKey_F7; + case 256 + GLUT_KEY_F8: return ImGuiKey_F8; + case 256 + GLUT_KEY_F9: return ImGuiKey_F9; + case 256 + GLUT_KEY_F10: return ImGuiKey_F10; + case 256 + GLUT_KEY_F11: return ImGuiKey_F11; + case 256 + GLUT_KEY_F12: return ImGuiKey_F12; + default: return ImGuiKey_None; + } +} + +bool ImGui_ImplGLUT_Init() +{ + ImGuiIO& io = ImGui::GetIO(); + +#ifdef FREEGLUT + io.BackendPlatformName = "imgui_impl_glut (freeglut)"; +#else + io.BackendPlatformName = "imgui_impl_glut"; +#endif + g_Time = 0; + + return true; +} + +void ImGui_ImplGLUT_InstallFuncs() +{ + glutReshapeFunc(ImGui_ImplGLUT_ReshapeFunc); + glutMotionFunc(ImGui_ImplGLUT_MotionFunc); + glutPassiveMotionFunc(ImGui_ImplGLUT_MotionFunc); + glutMouseFunc(ImGui_ImplGLUT_MouseFunc); +#ifdef __FREEGLUT_EXT_H__ + glutMouseWheelFunc(ImGui_ImplGLUT_MouseWheelFunc); +#endif + glutKeyboardFunc(ImGui_ImplGLUT_KeyboardFunc); + glutKeyboardUpFunc(ImGui_ImplGLUT_KeyboardUpFunc); + glutSpecialFunc(ImGui_ImplGLUT_SpecialFunc); + glutSpecialUpFunc(ImGui_ImplGLUT_SpecialUpFunc); +} + +void ImGui_ImplGLUT_Shutdown() +{ +} + +void ImGui_ImplGLUT_NewFrame() +{ + // Setup time step + ImGuiIO& io = ImGui::GetIO(); + int current_time = glutGet(GLUT_ELAPSED_TIME); + int delta_time_ms = (current_time - g_Time); + if (delta_time_ms <= 0) + delta_time_ms = 1; + io.DeltaTime = delta_time_ms / 1000.0f; + g_Time = current_time; + + // Start the frame + ImGui::NewFrame(); +} + +static void ImGui_ImplGLUT_UpdateKeyModifiers() +{ + ImGuiIO& io = ImGui::GetIO(); + int glut_key_mods = glutGetModifiers(); + io.AddKeyEvent(ImGuiKey_ModCtrl, (glut_key_mods & GLUT_ACTIVE_CTRL) != 0); + io.AddKeyEvent(ImGuiKey_ModShift, (glut_key_mods & GLUT_ACTIVE_SHIFT) != 0); + io.AddKeyEvent(ImGuiKey_ModAlt, (glut_key_mods & GLUT_ACTIVE_ALT) != 0); +} + +static void ImGui_ImplGLUT_AddKeyEvent(ImGuiKey key, bool down, int native_keycode) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(key, down); + io.SetKeyEventNativeData(key, native_keycode, -1); // To support legacy indexing (<1.87 user code) +} + +void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y) +{ + // Send character to imgui + //printf("char_down_func %d '%c'\n", c, c); + ImGuiIO& io = ImGui::GetIO(); + if (c >= 32) + io.AddInputCharacter((unsigned int)c); + + ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); + ImGui_ImplGLUT_AddKeyEvent(key, true, c); + ImGui_ImplGLUT_UpdateKeyModifiers(); + (void)x; (void)y; // Unused +} + +void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y) +{ + //printf("char_up_func %d '%c'\n", c, c); + ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c); + ImGui_ImplGLUT_AddKeyEvent(key, false, c); + ImGui_ImplGLUT_UpdateKeyModifiers(); + (void)x; (void)y; // Unused +} + +void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y) +{ + //printf("key_down_func %d\n", key); + ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); + ImGui_ImplGLUT_AddKeyEvent(imgui_key, true, key + 256); + ImGui_ImplGLUT_UpdateKeyModifiers(); + (void)x; (void)y; // Unused +} + +void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y) +{ + //printf("key_up_func %d\n", key); + ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256); + ImGui_ImplGLUT_AddKeyEvent(imgui_key, false, key + 256); + ImGui_ImplGLUT_UpdateKeyModifiers(); + (void)x; (void)y; // Unused +} + +void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddMousePosEvent((float)x, (float)y); + int button = -1; + if (glut_button == GLUT_LEFT_BUTTON) button = 0; + if (glut_button == GLUT_RIGHT_BUTTON) button = 1; + if (glut_button == GLUT_MIDDLE_BUTTON) button = 2; + if (button != -1 && state == GLUT_DOWN || state == GLUT_UP) + io.AddMouseButtonEvent(button, state == GLUT_DOWN); +} + +#ifdef __FREEGLUT_EXT_H__ +void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddMousePosEvent((float)x, (float)y); + if (dir != 0) + io.AddMouseWheelEvent(0.0f, dir > 0 ? 1.0f : -1.0f); + (void)button; // Unused +} +#endif + +void ImGui_ImplGLUT_ReshapeFunc(int w, int h) +{ + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize = ImVec2((float)w, (float)h); +} + +void ImGui_ImplGLUT_MotionFunc(int x, int y) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddMousePosEvent((float)x, (float)y); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.h new file mode 100644 index 000000000..98d4e5989 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_glut.h @@ -0,0 +1,39 @@ +// dear imgui: Platform Backend for GLUT/FreeGLUT +// This needs to be used along with a Renderer (e.g. OpenGL2) + +// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!! +// !!! Nowadays, prefer using GLFW or SDL instead! + +// Implemented features: +// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// Issues: +// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I +// [ ] Platform: Missing mouse cursor shape/visibility support. +// [ ] Platform: Missing clipboard support (not supported by Glut). +// [ ] Platform: Missing gamepad support. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +IMGUI_IMPL_API bool ImGui_ImplGLUT_Init(); +IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs(); +IMGUI_IMPL_API void ImGui_ImplGLUT_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame(); + +// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically, +// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency.. +//---------------------------------------- GLUT name --------------------------------------------- Decent Name --------- +IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y); // ~ MouseWheelFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y); // ~ CharPressedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.h new file mode 100644 index 000000000..180fd777e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.h @@ -0,0 +1,69 @@ +// dear imgui: Renderer Backend for Metal +// This needs to be used along with a Platform Backend (e.g. OSX) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport / platform windows. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" // IMGUI_IMPL_API + +//----------------------------------------------------------------------------- +// ObjC API +//----------------------------------------------------------------------------- + +#ifdef __OBJC__ + +@class MTLRenderPassDescriptor; +@protocol MTLDevice, MTLCommandBuffer, MTLRenderCommandEncoder; + +IMGUI_IMPL_API bool ImGui_ImplMetal_Init(id device); +IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor); +IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, + id commandBuffer, + id commandEncoder); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplMetal_CreateFontsTexture(id device); +IMGUI_IMPL_API void ImGui_ImplMetal_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(id device); +IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects(); + +#endif + +//----------------------------------------------------------------------------- +// C++ API +//----------------------------------------------------------------------------- + +// Enable Metal C++ binding support with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file +// More info about using Metal from C++: https://developer.apple.com/metal/cpp/ + +#ifdef IMGUI_IMPL_METAL_CPP + +#include + +#ifndef __OBJC__ + +IMGUI_IMPL_API bool ImGui_ImplMetal_Init(MTL::Device* device); +IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor); +IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, + MTL::CommandBuffer* commandBuffer, + MTL::RenderCommandEncoder* commandEncoder); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplMetal_CreateFontsTexture(MTL::Device* device); +IMGUI_IMPL_API void ImGui_ImplMetal_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device); +IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects(); + +#endif + +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.mm b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.mm new file mode 100644 index 000000000..c6288e34e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_metal.mm @@ -0,0 +1,598 @@ +// dear imgui: Renderer Backend for Metal +// This needs to be used along with a Platform Backend (e.g. OSX) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport / platform windows. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code). +// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file. +// 2021-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464) +// 2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. +// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. +// 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-02-11: Metal: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-07-05: Metal: Added new Metal backend implementation. + +#include "imgui.h" +#include "imgui_impl_metal.h" + +#import +// #import // Not supported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...) +#import + +#pragma mark - Support classes + +// A wrapper around a MTLBuffer object that knows the last time it was reused +@interface MetalBuffer : NSObject +@property (nonatomic, strong) id buffer; +@property (nonatomic, assign) NSTimeInterval lastReuseTime; +- (instancetype)initWithBuffer:(id)buffer; +@end + +// An object that encapsulates the data necessary to uniquely identify a +// render pipeline state. These are used as cache keys. +@interface FramebufferDescriptor : NSObject +@property (nonatomic, assign) unsigned long sampleCount; +@property (nonatomic, assign) MTLPixelFormat colorPixelFormat; +@property (nonatomic, assign) MTLPixelFormat depthPixelFormat; +@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat; +- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPassDescriptor; +@end + +// A singleton that stores long-lived objects that are needed by the Metal +// renderer backend. Stores the render pipeline state cache and the default +// font texture, and manages the reusable buffer cache. +@interface MetalContext : NSObject +@property (nonatomic, strong) id depthStencilState; +@property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient +@property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors +@property (nonatomic, strong, nullable) id fontTexture; +@property (nonatomic, strong) NSMutableArray *bufferCache; +@property (nonatomic, assign) NSTimeInterval lastBufferCachePurge; +- (void)makeDeviceObjectsWithDevice:(id)device; +- (void)makeFontTextureWithDevice:(id)device; +- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id)device; +- (void)enqueueReusableBuffer:(MetalBuffer *)buffer; +- (id)renderPipelineStateForFrameAndDevice:(id)device; +- (void)emptyRenderPipelineStateCache; +- (void)setupRenderState:(ImDrawData *)drawData + commandBuffer:(id)commandBuffer + commandEncoder:(id)commandEncoder + renderPipelineState:(id)renderPipelineState + vertexBuffer:(MetalBuffer *)vertexBuffer + vertexBufferOffset:(size_t)vertexBufferOffset; +- (void)renderDrawData:(ImDrawData *)drawData + commandBuffer:(id)commandBuffer + commandEncoder:(id)commandEncoder; +@end + +static MetalContext *g_sharedMetalContext = nil; + +#ifdef IMGUI_IMPL_METAL_CPP + +#pragma mark - Dear ImGui Metal C++ Backend API + +bool ImGui_ImplMetal_Init(MTL::Device* device) +{ + return ImGui_ImplMetal_Init((id)(device)); +} + +void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor) +{ + ImGui_ImplMetal_NewFrame((MTLRenderPassDescriptor*)(renderPassDescriptor)); +} + +void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, + MTL::CommandBuffer* commandBuffer, + MTL::RenderCommandEncoder* commandEncoder) +{ + ImGui_ImplMetal_RenderDrawData(draw_data, + (id)(commandBuffer), + (id)(commandEncoder)); + +} + +bool ImGui_ImplMetal_CreateFontsTexture(MTL::Device* device) +{ + return ImGui_ImplMetal_CreateFontsTexture((id)(device)); +} + +bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device) +{ + return ImGui_ImplMetal_CreateDeviceObjects((id)(device)); +} + +#endif // #ifdef IMGUI_IMPL_METAL_CPP + +#pragma mark - Dear ImGui Metal Backend API + +bool ImGui_ImplMetal_Init(id device) +{ + ImGuiIO& io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_metal"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + g_sharedMetalContext = [[MetalContext alloc] init]; + }); + + ImGui_ImplMetal_CreateDeviceObjects(device); + + return true; +} + +void ImGui_ImplMetal_Shutdown() +{ + ImGui_ImplMetal_DestroyDeviceObjects(); +} + +void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor) +{ + IM_ASSERT(g_sharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?"); + + g_sharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]; +} + +// Metal Render function. +void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id commandBuffer, id commandEncoder) +{ + [g_sharedMetalContext renderDrawData:draw_data commandBuffer:commandBuffer commandEncoder:commandEncoder]; +} + +bool ImGui_ImplMetal_CreateFontsTexture(id device) +{ + [g_sharedMetalContext makeFontTextureWithDevice:device]; + + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->SetTexID((__bridge void *)g_sharedMetalContext.fontTexture); // ImTextureID == void* + + return (g_sharedMetalContext.fontTexture != nil); +} + +void ImGui_ImplMetal_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + g_sharedMetalContext.fontTexture = nil; + io.Fonts->SetTexID(nullptr); +} + +bool ImGui_ImplMetal_CreateDeviceObjects(id device) +{ + [g_sharedMetalContext makeDeviceObjectsWithDevice:device]; + + ImGui_ImplMetal_CreateFontsTexture(device); + + return true; +} + +void ImGui_ImplMetal_DestroyDeviceObjects() +{ + ImGui_ImplMetal_DestroyFontsTexture(); + [g_sharedMetalContext emptyRenderPipelineStateCache]; +} + +#pragma mark - MetalBuffer implementation + +@implementation MetalBuffer +- (instancetype)initWithBuffer:(id)buffer +{ + if ((self = [super init])) + { + _buffer = buffer; + _lastReuseTime = [NSDate date].timeIntervalSince1970; + } + return self; +} +@end + +#pragma mark - FramebufferDescriptor implementation + +@implementation FramebufferDescriptor +- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPassDescriptor +{ + if ((self = [super init])) + { + _sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount; + _colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat; + _depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat; + _stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat; + } + return self; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone +{ + FramebufferDescriptor *copy = [[FramebufferDescriptor allocWithZone:zone] init]; + copy.sampleCount = self.sampleCount; + copy.colorPixelFormat = self.colorPixelFormat; + copy.depthPixelFormat = self.depthPixelFormat; + copy.stencilPixelFormat = self.stencilPixelFormat; + return copy; +} + +- (NSUInteger)hash +{ + NSUInteger sc = _sampleCount & 0x3; + NSUInteger cf = _colorPixelFormat & 0x3FF; + NSUInteger df = _depthPixelFormat & 0x3FF; + NSUInteger sf = _stencilPixelFormat & 0x3FF; + NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc; + return hash; +} + +- (BOOL)isEqual:(id)object +{ + FramebufferDescriptor *other = object; + if (![other isKindOfClass:[FramebufferDescriptor class]]) + return NO; + return other.sampleCount == self.sampleCount && + other.colorPixelFormat == self.colorPixelFormat && + other.depthPixelFormat == self.depthPixelFormat && + other.stencilPixelFormat == self.stencilPixelFormat; +} + +@end + +#pragma mark - MetalContext implementation + +@implementation MetalContext +- (instancetype)init { + if ((self = [super init])) + { + _renderPipelineStateCache = [NSMutableDictionary dictionary]; + _bufferCache = [NSMutableArray array]; + _lastBufferCachePurge = [NSDate date].timeIntervalSince1970; + } + return self; +} + +- (void)makeDeviceObjectsWithDevice:(id)device +{ + MTLDepthStencilDescriptor *depthStencilDescriptor = [[MTLDepthStencilDescriptor alloc] init]; + depthStencilDescriptor.depthWriteEnabled = NO; + depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways; + self.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor]; +} + +// We are retrieving and uploading the font atlas as a 4-channels RGBA texture here. +// In theory we could call GetTexDataAsAlpha8() and upload a 1-channel texture to save on memory access bandwidth. +// However, using a shader designed for 1-channel texture would make it less obvious to use the ImTextureID facility to render users own textures. +// You can make that change in your implementation. +- (void)makeFontTextureWithDevice:(id)device +{ + ImGuiIO &io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm + width:(NSUInteger)width + height:(NSUInteger)height + mipmapped:NO]; + textureDescriptor.usage = MTLTextureUsageShaderRead; +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + textureDescriptor.storageMode = MTLStorageModeManaged; +#else + textureDescriptor.storageMode = MTLStorageModeShared; +#endif + id texture = [device newTextureWithDescriptor:textureDescriptor]; + [texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4]; + self.fontTexture = texture; +} + +- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id)device +{ + NSTimeInterval now = [NSDate date].timeIntervalSince1970; + + // Purge old buffers that haven't been useful for a while + if (now - self.lastBufferCachePurge > 1.0) + { + NSMutableArray *survivors = [NSMutableArray array]; + for (MetalBuffer *candidate in self.bufferCache) + { + if (candidate.lastReuseTime > self.lastBufferCachePurge) + { + [survivors addObject:candidate]; + } + } + self.bufferCache = [survivors mutableCopy]; + self.lastBufferCachePurge = now; + } + + // See if we have a buffer we can reuse + MetalBuffer *bestCandidate = nil; + for (MetalBuffer *candidate in self.bufferCache) + if (candidate.buffer.length >= length && (bestCandidate == nil || bestCandidate.lastReuseTime > candidate.lastReuseTime)) + bestCandidate = candidate; + + if (bestCandidate != nil) + { + [self.bufferCache removeObject:bestCandidate]; + bestCandidate.lastReuseTime = now; + return bestCandidate; + } + + // No luck; make a new buffer + id backing = [device newBufferWithLength:length options:MTLResourceStorageModeShared]; + return [[MetalBuffer alloc] initWithBuffer:backing]; +} + +- (void)enqueueReusableBuffer:(MetalBuffer *)buffer +{ + [self.bufferCache addObject:buffer]; +} + +- (_Nullable id)renderPipelineStateForFrameAndDevice:(id)device +{ + // Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame + // The hit rate for this cache should be very near 100%. + id renderPipelineState = self.renderPipelineStateCache[self.framebufferDescriptor]; + + if (renderPipelineState == nil) + { + // No luck; make a new render pipeline state + renderPipelineState = [self _renderPipelineStateForFramebufferDescriptor:self.framebufferDescriptor device:device]; + // Cache render pipeline state for later reuse + self.renderPipelineStateCache[self.framebufferDescriptor] = renderPipelineState; + } + + return renderPipelineState; +} + +- (id)_renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor *)descriptor device:(id)device +{ + NSError *error = nil; + + NSString *shaderSource = @"" + "#include \n" + "using namespace metal;\n" + "\n" + "struct Uniforms {\n" + " float4x4 projectionMatrix;\n" + "};\n" + "\n" + "struct VertexIn {\n" + " float2 position [[attribute(0)]];\n" + " float2 texCoords [[attribute(1)]];\n" + " uchar4 color [[attribute(2)]];\n" + "};\n" + "\n" + "struct VertexOut {\n" + " float4 position [[position]];\n" + " float2 texCoords;\n" + " float4 color;\n" + "};\n" + "\n" + "vertex VertexOut vertex_main(VertexIn in [[stage_in]],\n" + " constant Uniforms &uniforms [[buffer(1)]]) {\n" + " VertexOut out;\n" + " out.position = uniforms.projectionMatrix * float4(in.position, 0, 1);\n" + " out.texCoords = in.texCoords;\n" + " out.color = float4(in.color) / float4(255.0);\n" + " return out;\n" + "}\n" + "\n" + "fragment half4 fragment_main(VertexOut in [[stage_in]],\n" + " texture2d texture [[texture(0)]]) {\n" + " constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n" + " half4 texColor = texture.sample(linearSampler, in.texCoords);\n" + " return half4(in.color) * texColor;\n" + "}\n"; + + id library = [device newLibraryWithSource:shaderSource options:nil error:&error]; + if (library == nil) + { + NSLog(@"Error: failed to create Metal library: %@", error); + return nil; + } + + id vertexFunction = [library newFunctionWithName:@"vertex_main"]; + id fragmentFunction = [library newFunctionWithName:@"fragment_main"]; + + if (vertexFunction == nil || fragmentFunction == nil) + { + NSLog(@"Error: failed to find Metal shader functions in library: %@", error); + return nil; + } + + MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; + vertexDescriptor.attributes[0].offset = IM_OFFSETOF(ImDrawVert, pos); + vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position + vertexDescriptor.attributes[0].bufferIndex = 0; + vertexDescriptor.attributes[1].offset = IM_OFFSETOF(ImDrawVert, uv); + vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords + vertexDescriptor.attributes[1].bufferIndex = 0; + vertexDescriptor.attributes[2].offset = IM_OFFSETOF(ImDrawVert, col); + vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color + vertexDescriptor.attributes[2].bufferIndex = 0; + vertexDescriptor.layouts[0].stepRate = 1; + vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; + vertexDescriptor.layouts[0].stride = sizeof(ImDrawVert); + + MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineDescriptor.vertexFunction = vertexFunction; + pipelineDescriptor.fragmentFunction = fragmentFunction; + pipelineDescriptor.vertexDescriptor = vertexDescriptor; + pipelineDescriptor.sampleCount = self.framebufferDescriptor.sampleCount; + pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat; + pipelineDescriptor.colorAttachments[0].blendingEnabled = YES; + pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat; + pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat; + + id renderPipelineState = [device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error]; + if (error != nil) + { + NSLog(@"Error: failed to create Metal pipeline state: %@", error); + } + + return renderPipelineState; +} + +- (void)emptyRenderPipelineStateCache +{ + [self.renderPipelineStateCache removeAllObjects]; +} + +- (void)setupRenderState:(ImDrawData *)drawData + commandBuffer:(id)commandBuffer + commandEncoder:(id)commandEncoder + renderPipelineState:(id)renderPipelineState + vertexBuffer:(MetalBuffer *)vertexBuffer + vertexBufferOffset:(size_t)vertexBufferOffset +{ + [commandEncoder setCullMode:MTLCullModeNone]; + [commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState]; + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to + // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. + MTLViewport viewport = + { + .originX = 0.0, + .originY = 0.0, + .width = (double)(drawData->DisplaySize.x * drawData->FramebufferScale.x), + .height = (double)(drawData->DisplaySize.y * drawData->FramebufferScale.y), + .znear = 0.0, + .zfar = 1.0 + }; + [commandEncoder setViewport:viewport]; + + float L = drawData->DisplayPos.x; + float R = drawData->DisplayPos.x + drawData->DisplaySize.x; + float T = drawData->DisplayPos.y; + float B = drawData->DisplayPos.y + drawData->DisplaySize.y; + float N = (float)viewport.znear; + float F = (float)viewport.zfar; + const float ortho_projection[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 1/(F-N), 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f }, + }; + [commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1]; + + [commandEncoder setRenderPipelineState:renderPipelineState]; + + [commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0]; + [commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0]; +} + +- (void)renderDrawData:(ImDrawData *)drawData + commandBuffer:(id)commandBuffer + commandEncoder:(id)commandEncoder +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x); + int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0) + return; + + id renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device]; + + size_t vertexBufferLength = (size_t)drawData->TotalVtxCount * sizeof(ImDrawVert); + size_t indexBufferLength = (size_t)drawData->TotalIdxCount * sizeof(ImDrawIdx); + MetalBuffer* vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device]; + MetalBuffer* indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device]; + + [self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:0]; + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = drawData->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = drawData->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + size_t vertexBufferOffset = 0; + size_t indexBufferOffset = 0; + for (int n = 0; n < drawData->CmdListsCount; n++) + { + const ImDrawList* cmd_list = drawData->CmdLists[n]; + + memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + [self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:vertexBufferOffset]; + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + + // Clamp to viewport as setScissorRect() won't accept values that are off bounds + if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } + if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } + if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } + if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + if (pcmd->ElemCount == 0) // drawIndexedPrimitives() validation doesn't accept this + continue; + + // Apply scissor/clipping rectangle + MTLScissorRect scissorRect = + { + .x = NSUInteger(clip_min.x), + .y = NSUInteger(clip_min.y), + .width = NSUInteger(clip_max.x - clip_min.x), + .height = NSUInteger(clip_max.y - clip_min.y) + }; + [commandEncoder setScissorRect:scissorRect]; + + // Bind texture, Draw + if (ImTextureID tex_id = pcmd->GetTexID()) + [commandEncoder setFragmentTexture:(__bridge id)(tex_id) atIndex:0]; + + [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; + [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle + indexCount:pcmd->ElemCount + indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32 + indexBuffer:indexBuffer.buffer + indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)]; + } + } + + vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); + } + + __weak id weakSelf = self; + [commandBuffer addCompletedHandler:^(id) + { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf enqueueReusableBuffer:vertexBuffer]; + [weakSelf enqueueReusableBuffer:indexBuffer]; + }); + }]; +} + +@end diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.cpp new file mode 100644 index 000000000..2b6d10ca8 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.cpp @@ -0,0 +1,324 @@ +// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline) +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in imgui_impl_opengl3.cpp** +// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more +// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might +// confuse your GPU driver. +// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications. +// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications. +// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications. +// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples. +// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself. +// 2017-09-01: OpenGL: Save and restore current polygon mode. +// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal). +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. + +#include "imgui.h" +#include "imgui_impl_opengl2.h" +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Include OpenGL header (without an OpenGL loader) requires a bit of fiddling +#if defined(_WIN32) && !defined(APIENTRY) +#define APIENTRY __stdcall // It is customary to use APIENTRY for OpenGL function pointer declarations on all platforms. Additionally, the Windows OpenGL header needs APIENTRY. +#endif +#if defined(_WIN32) && !defined(WINGDIAPI) +#define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this +#endif +#if defined(__APPLE__) +#define GL_SILENCE_DEPRECATION +#include +#else +#include +#endif + +struct ImGui_ImplOpenGL2_Data +{ + GLuint FontTexture; + + ImGui_ImplOpenGL2_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplOpenGL2_InitPlatformInterface(); +static void ImGui_ImplOpenGL2_ShutdownPlatformInterface(); + +// Functions +bool ImGui_ImplOpenGL2_Init() +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_opengl2"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplOpenGL2_InitPlatformInterface(); + + return true; +} + +void ImGui_ImplOpenGL2_Shutdown() +{ + ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplOpenGL2_ShutdownPlatformInterface(); + ImGui_ImplOpenGL2_DestroyDeviceObjects(); + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplOpenGL2_NewFrame() +{ + ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplOpenGL2_Init()?"); + + if (!bd->FontTexture) + ImGui_ImplOpenGL2_CreateDeviceObjects(); +} + +static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glShadeModel(GL_SMOOTH); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), + // you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below. + // (DO NOT MODIFY THIS FILE! Add the code in your calling function) + // GLint last_program; + // glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + // glUseProgram(0); + // ImGui_ImplOpenGL2_RenderDrawData(...); + // glUseProgram(last_program) + // There are potentially many more states you could need to clear/setup that we can't access from default headers. + // e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP). + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +} + +// OpenGL2 Render function. +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly. +// This is in order to be able to run within an OpenGL engine that doesn't do so. +void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + + // Backup GL state + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model); + GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + + // Setup desired GL state + ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle (Y is inverted in OpenGL) + glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset); + } + } + } + + // Restore modified GL state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); + glShadeModel(last_shade_model); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode); +} + +bool ImGui_ImplOpenGL2_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &bd->FontTexture); + glBindTexture(GL_TEXTURE_2D, bd->FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL2_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); + if (bd->FontTexture) + { + glDeleteTextures(1, &bd->FontTexture); + io.Fonts->SetTexID(0); + bd->FontTexture = 0; + } +} + +bool ImGui_ImplOpenGL2_CreateDeviceObjects() +{ + return ImGui_ImplOpenGL2_CreateFontsTexture(); +} + +void ImGui_ImplOpenGL2_DestroyDeviceObjects() +{ + ImGui_ImplOpenGL2_DestroyFontsTexture(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*) +{ + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + { + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + } + ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData); +} + +static void ImGui_ImplOpenGL2_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow; +} + +static void ImGui_ImplOpenGL2_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.h new file mode 100644 index 000000000..780204a22 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl2.h @@ -0,0 +1,33 @@ +// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline) +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in imgui_impl_opengl3.cpp** +// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more +// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might +// confuse your GPU driver. +// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init(); +IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp new file mode 100644 index 000000000..499798bb0 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp @@ -0,0 +1,838 @@ +// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 2.x 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers. +// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions. +// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-06-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state. +// 2021-06-21: OpenGL: Destroy individual vertex/fragment shader objects right after they are linked into the main shader. +// 2021-05-24: OpenGL: Access GL_CLIP_ORIGIN when "GL_ARB_clip_control" extension is detected, inside of just OpenGL 4.5 version. +// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater. +// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer. +// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state. +// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. +// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x) +// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader. +// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader. +// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX. +// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix. +// 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset. +// 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader. +// 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader. +// 2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders. +// 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility. +// 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call. +// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop. +// 2019-03-15: OpenGL: Added a GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. +// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0). +// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader. +// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. +// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450). +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN. +// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used. +// 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES". +// 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. +// 2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link. +// 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples. +// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state. +// 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a NULL pointer. +// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150". +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. +// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. +// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode. +// 2017-05-01: OpenGL: Fixed save and restore of current blend func state. +// 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. +// 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) + +//---------------------------------------- +// OpenGL GLSL GLSL +// version version string +//---------------------------------------- +// 2.0 110 "#version 110" +// 2.1 120 "#version 120" +// 3.0 130 "#version 130" +// 3.1 140 "#version 140" +// 3.2 150 "#version 150" +// 3.3 330 "#version 330 core" +// 4.0 400 "#version 400 core" +// 4.1 410 "#version 410 core" +// 4.2 420 "#version 410 core" +// 4.3 430 "#version 430 core" +// ES 2.0 100 "#version 100" = WebGL 1.0 +// ES 3.0 300 "#version 300 es" = WebGL 2.0 +//---------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "../imgui.h" +#include "imgui_impl_opengl3.h" +#include +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Clang warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +#endif + +// GL includes +#if defined(IMGUI_IMPL_OPENGL_ES2) +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) +#include // Use GL ES 2 +#else +#include // Use GL ES 2 +#endif +#if defined(__EMSCRIPTEN__) +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif +#include +#endif +#elif defined(IMGUI_IMPL_OPENGL_ES3) +#if defined(__APPLE__) +#include +#endif +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) +#include // Use GL ES 3 +#else +#include // Use GL ES 3 +#endif +#elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) +// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. +// Helper libraries are often used for this purpose! Here we are using our own minimal custom loader based on gl3w. +// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.). +// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp): +// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped +// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases +// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version. +#define IMGL3W_IMPL +#include "imgui_impl_opengl3_loader.h" +#endif + +// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension +#ifndef IMGUI_IMPL_OPENGL_ES2 +#define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY +#elif defined(__EMSCRIPTEN__) +#define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY +#define glBindVertexArray glBindVertexArrayOES +#define glGenVertexArrays glGenVertexArraysOES +#define glDeleteVertexArrays glDeleteVertexArraysOES +#define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES +#endif + +// Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have. +#ifdef GL_POLYGON_MODE +#define IMGUI_IMPL_HAS_POLYGON_MODE +#endif + +// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have. +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2) +#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET +#endif + +// Desktop GL 3.3+ has glBindSampler() +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_3) +#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER +#endif + +// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1) +#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART +#endif + +// Desktop GL use extension detection +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) +#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS +#endif + +// OpenGL Data +struct ImGui_ImplOpenGL3_Data +{ + GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) + char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings. + GLuint FontTexture; + GLuint ShaderHandle; + GLint AttribLocationTex; // Uniforms location + GLint AttribLocationProjMtx; + GLuint AttribLocationVtxPos; // Vertex attributes location + GLuint AttribLocationVtxUV; + GLuint AttribLocationVtxColor; + unsigned int VboHandle, ElementsHandle; + GLsizeiptr VertexBufferSize; + GLsizeiptr IndexBufferSize; + bool HasClipOrigin; + + ImGui_ImplOpenGL3_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplOpenGL3_InitPlatformInterface(); +static void ImGui_ImplOpenGL3_ShutdownPlatformInterface(); + +// Functions +bool ImGui_ImplOpenGL3_Init(const char* glsl_version) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Initialize our loader +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + if (imgl3wInit() != 0) + { + fprintf(stderr, "Failed to initialize OpenGL loader!\n"); + return false; + } +#endif + + // Setup backend capabilities flags + ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_opengl3"; + + // Query for GL version (e.g. 320 for GL 3.2) +#if !defined(IMGUI_IMPL_OPENGL_ES2) + GLint major = 0; + GLint minor = 0; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + if (major == 0 && minor == 0) + { + // Query GL_VERSION in desktop GL 2.x, the string will start with "." + const char* gl_version = (const char*)glGetString(GL_VERSION); + sscanf(gl_version, "%d.%d", &major, &minor); + } + bd->GlVersion = (GLuint)(major * 100 + minor * 10); +#else + bd->GlVersion = 200; // GLES 2 +#endif + +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET + if (bd->GlVersion >= 320) + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. +#endif + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + // Store GLSL version string so we can refer to it later in case we recreate shaders. + // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. + if (glsl_version == NULL) + { +#if defined(IMGUI_IMPL_OPENGL_ES2) + glsl_version = "#version 100"; +#elif defined(IMGUI_IMPL_OPENGL_ES3) + glsl_version = "#version 300 es"; +#elif defined(__APPLE__) + glsl_version = "#version 150"; +#else + glsl_version = "#version 130"; +#endif + } + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(bd->GlslVersionString)); + strcpy(bd->GlslVersionString, glsl_version); + strcat(bd->GlslVersionString, "\n"); + + // Make an arbitrary GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means the OpenGL function loader didn't do its job. Let us know! + GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + + // Detect extensions we support + bd->HasClipOrigin = (bd->GlVersion >= 450); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS + GLint num_extensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); + for (GLint i = 0; i < num_extensions; i++) + { + const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i); + if (extension != NULL && strcmp(extension, "GL_ARB_clip_control") == 0) + bd->HasClipOrigin = true; + } +#endif + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplOpenGL3_InitPlatformInterface(); + + return true; +} + +void ImGui_ImplOpenGL3_Shutdown() +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplOpenGL3_ShutdownPlatformInterface(); + ImGui_ImplOpenGL3_DestroyDeviceObjects(); + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplOpenGL3_NewFrame() +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplOpenGL3_Init()?"); + + if (!bd->ShaderHandle) + ImGui_ImplOpenGL3_CreateDeviceObjects(); +} + +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glEnable(GL_SCISSOR_TEST); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART + if (bd->GlVersion >= 310) + glDisable(GL_PRIMITIVE_RESTART); +#endif +#ifdef IMGUI_IMPL_HAS_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif + + // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) +#if defined(GL_CLIP_ORIGIN) + bool clip_origin_lower_left = true; + if (bd->HasClipOrigin) + { + GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); + if (current_clip_origin == GL_UPPER_LEFT) + clip_origin_lower_left = false; + } +#endif + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; +#if defined(GL_CLIP_ORIGIN) + if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left +#endif + const float ortho_projection[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f }, + }; + glUseProgram(bd->ShaderHandle); + glUniform1i(bd->AttribLocationTex, 0); + glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER + if (bd->GlVersion >= 330) + glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. +#endif + + (void)vertex_array_object; +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + glBindVertexArray(vertex_array_object); +#endif + + // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindBuffer(GL_ARRAY_BUFFER, bd->VboHandle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle); + glEnableVertexAttribArray(bd->AttribLocationVtxPos); + glEnableVertexAttribArray(bd->AttribLocationVtxUV); + glEnableVertexAttribArray(bd->AttribLocationVtxColor); + glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); +} + +// OpenGL3 Render function. +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly. +// This is in order to be able to run within an OpenGL engine that doesn't do so. +void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + + // Backup GL state + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); + glActiveTexture(GL_TEXTURE0); + GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program); + GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER + GLuint last_sampler; if (bd->GlVersion >= 330) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; } +#endif + GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object); +#endif +#ifdef IMGUI_IMPL_HAS_POLYGON_MODE + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +#endif + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART + GLboolean last_enable_primitive_restart = (bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE; +#endif + + // Setup desired GL state + // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) + // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound. + GLuint vertex_array_object = 0; +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + glGenVertexArrays(1, &vertex_array_object); +#endif + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + + // Upload vertex/index buffers + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), static_cast(cmd_list->VtxBuffer.Data), GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx), static_cast(cmd_list->IdxBuffer.Data), GL_STREAM_DRAW); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle (Y is inverted in OpenGL) + glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET + if (bd->GlVersion >= 320) + glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); + else +#endif + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); + } + } + } + + // Destroy the temporary VAO +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + glDeleteVertexArrays(1, &vertex_array_object); +#endif + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER + if (bd->GlVersion >= 330) + glBindSampler(0, last_sampler); +#endif + glActiveTexture(last_active_texture); +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + glBindVertexArray(last_vertex_array_object); +#endif + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART + if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); } +#endif + +#ifdef IMGUI_IMPL_HAS_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +#endif + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); + (void)bd; // Not all compilation paths use this +} + +bool ImGui_ImplOpenGL3_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + + // Build texture atlas + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &bd->FontTexture); + glBindTexture(GL_TEXTURE_2D, bd->FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL3_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + if (bd->FontTexture) + { + glDeleteTextures(1, &bd->FontTexture); + io.Fonts->SetTexID(0); + bd->FontTexture = 0; + } +} + +// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file. +static bool CheckShader(GLuint handle, const char* desc) +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + GLint status = 0, log_length = 0; + glGetShaderiv(handle, GL_COMPILE_STATUS, &status); + glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s! With GLSL: %s\n", desc, bd->GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +// If you get an error please report on GitHub. You may try different GL context version or GLSL version. +static bool CheckProgram(GLuint handle, const char* desc) +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + GLint status = 0, log_length = 0; + glGetProgramiv(handle, GL_LINK_STATUS, &status); + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! With GLSL %s\n", desc, bd->GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +bool ImGui_ImplOpenGL3_CreateDeviceObjects() +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + + // Backup GL state + GLint last_texture, last_array_buffer; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + GLint last_vertex_array; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +#endif + + // Parse GLSL version string + int glsl_version = 130; + sscanf(bd->GlslVersionString, "#version %d", &glsl_version); + + const GLchar* vertex_shader_glsl_120 = + "uniform mat4 ProjMtx;\n" + "attribute vec2 Position;\n" + "attribute vec2 UV;\n" + "attribute vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying 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* vertex_shader_glsl_130 = + "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* vertex_shader_glsl_300_es = + "precision highp float;\n" + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\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* vertex_shader_glsl_410_core = + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\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_glsl_120 = + "#ifdef GL_ES\n" + " precision mediump float;\n" + "#endif\n" + "uniform sampler2D Texture;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_130 = + "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"; + + const GLchar* fragment_shader_glsl_300_es = + "precision mediump float;\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_410_core = + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "uniform sampler2D Texture;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + // Select shaders matching our GLSL versions + const GLchar* vertex_shader = NULL; + const GLchar* fragment_shader = NULL; + if (glsl_version < 130) + { + vertex_shader = vertex_shader_glsl_120; + fragment_shader = fragment_shader_glsl_120; + } + else if (glsl_version >= 410) + { + vertex_shader = vertex_shader_glsl_410_core; + fragment_shader = fragment_shader_glsl_410_core; + } + else if (glsl_version == 300) + { + vertex_shader = vertex_shader_glsl_300_es; + fragment_shader = fragment_shader_glsl_300_es; + } + else + { + vertex_shader = vertex_shader_glsl_130; + fragment_shader = fragment_shader_glsl_130; + } + + // Create shaders + const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader }; + GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vert_handle, 2, vertex_shader_with_version, NULL); + glCompileShader(vert_handle); + CheckShader(vert_handle, "vertex shader"); + + const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader }; + GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(frag_handle, 2, fragment_shader_with_version, NULL); + glCompileShader(frag_handle); + CheckShader(frag_handle, "fragment shader"); + + // Link + bd->ShaderHandle = glCreateProgram(); + glAttachShader(bd->ShaderHandle, vert_handle); + glAttachShader(bd->ShaderHandle, frag_handle); + glLinkProgram(bd->ShaderHandle); + CheckProgram(bd->ShaderHandle, "shader program"); + + glDetachShader(bd->ShaderHandle, vert_handle); + glDetachShader(bd->ShaderHandle, frag_handle); + glDeleteShader(vert_handle); + glDeleteShader(frag_handle); + + bd->AttribLocationTex = glGetUniformLocation(bd->ShaderHandle, "Texture"); + bd->AttribLocationProjMtx = glGetUniformLocation(bd->ShaderHandle, "ProjMtx"); + bd->AttribLocationVtxPos = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Position"); + bd->AttribLocationVtxUV = (GLuint)glGetAttribLocation(bd->ShaderHandle, "UV"); + bd->AttribLocationVtxColor = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Color"); + + // Create buffers + glGenBuffers(1, &bd->VboHandle); + glGenBuffers(1, &bd->ElementsHandle); + + ImGui_ImplOpenGL3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY + glBindVertexArray(last_vertex_array); +#endif + + return true; +} + +void ImGui_ImplOpenGL3_DestroyDeviceObjects() +{ + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; } + if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; } + if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; } + ImGui_ImplOpenGL3_DestroyFontsTexture(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*) +{ + if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) + { + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + } + ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData); +} + +static void ImGui_ImplOpenGL3_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow; +} + +static void ImGui_ImplOpenGL3_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.h new file mode 100644 index 000000000..ce00e48f1 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.h @@ -0,0 +1,56 @@ +// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 2.x 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// About GLSL version: +// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. +// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es" +// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp. + +#pragma once +#include "../imgui.h" // IMGUI_IMPL_API + +// Backend API +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); + +// (Optional) Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); + +// Specific OpenGL ES versions +//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten +//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android + +// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. +#if !defined(IMGUI_IMPL_OPENGL_ES2) \ + && !defined(IMGUI_IMPL_OPENGL_ES3) + +// Try to detect GLES on matching platforms +#if defined(__APPLE__) +#include +#endif +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) +#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" +#elif defined(__EMSCRIPTEN__) +#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" +#else +// Otherwise imgui_impl_opengl3_loader.h will be used. +#endif + +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3_loader.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3_loader.h new file mode 100644 index 000000000..e24760df7 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3_loader.h @@ -0,0 +1,757 @@ +//----------------------------------------------------------------------------- +// About imgui_impl_opengl3_loader.h: +// +// We embed our own OpenGL loader to not require user to provide their own or to have to use ours, +// which proved to be endless problems for users. +// Our loader is custom-generated, based on gl3w but automatically filtered to only include +// enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small. +// +// YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY. +// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE. +// +// Regenerate with: +// python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt +// +// More info: +// https://github.com/dearimgui/gl3w_stripped +// https://github.com/ocornut/imgui/issues/4445 +//----------------------------------------------------------------------------- + +/* + * This file was generated with gl3w_gen.py, part of imgl3w + * (hosted at https://github.com/dearimgui/gl3w_stripped) + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * 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 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. + */ + +#ifndef __gl3w_h_ +#define __gl3w_h_ + +// Adapted from KHR/khrplatform.h to avoid including entire file. +#ifndef __khrplatform_h_ +typedef float khronos_float_t; +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; +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef signed long long int khronos_ssize_t; +#else +typedef signed long int khronos_intptr_t; +typedef signed long int khronos_ssize_t; +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +typedef signed __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100) +#include +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#else +typedef signed long long khronos_int64_t; +typedef unsigned long long khronos_uint64_t; +#endif +#endif // __khrplatform_h_ + +#ifndef __gl_glcorearb_h_ +#define __gl_glcorearb_h_ 1 +#ifdef __cplusplus +extern "C" { +#endif +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT +** +** 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 +** https://github.com/KhronosGroup/OpenGL-Registry +*/ +#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 +/* glcorearb.h is for use with OpenGL core profile implementations. +** It should should be placed in the same directory as gl.h and +** included as . +** +** glcorearb.h includes only APIs in the latest OpenGL core profile +** implementation together with APIs in newer ARB extensions which +** can be supported by the core profile. It does not, and never will +** include functionality removed from the core profile, such as +** fixed-function vertex and fragment processing. +** +** Do not #include both and either of or +** in the same source file. +*/ +/* Generated C header for: + * API: gl + * Profile: core + * Versions considered: .* + * Versions emitted: .* + * Default extensions included: glcore + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ +#ifndef GL_VERSION_1_0 +typedef void GLvoid; +typedef unsigned int GLenum; + +typedef khronos_float_t GLfloat; +typedef int GLint; +typedef int GLsizei; +typedef unsigned int GLbitfield; +typedef double GLdouble; +typedef unsigned int GLuint; +typedef unsigned char GLboolean; +typedef khronos_uint8_t GLubyte; +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_TRIANGLES 0x0004 +#define GL_ONE 1 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_POLYGON_MODE 0x0B40 +#define GL_CULL_FACE 0x0B44 +#define GL_DEPTH_TEST 0x0B71 +#define GL_STENCIL_TEST 0x0B90 +#define GL_VIEWPORT 0x0BA2 +#define GL_BLEND 0x0BE2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_RGBA 0x1908 +#define GL_FILL 0x1B02 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_LINEAR 0x2601 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glClear (GLbitfield mask); +GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glDisable (GLenum cap); +GLAPI void APIENTRY glEnable (GLenum cap); +GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GLAPI GLenum APIENTRY glGetError (void); +GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GLAPI const GLubyte *APIENTRY glGetString (GLenum name); +GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap); +GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_VERSION_1_0 */ +#ifndef GL_VERSION_1_1 +typedef khronos_float_t GLclampf; +typedef double GLclampd; +#define GL_TEXTURE_BINDING_2D 0x8069 +typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures); +#endif +#endif /* GL_VERSION_1_1 */ +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_ACTIVE_TEXTURE 0x84E0 +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum texture); +#endif +#endif /* GL_VERSION_1_3 */ +#ifndef GL_VERSION_1_4 +#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_FUNC_ADD 0x8006 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +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 glBlendEquation (GLenum mode); +#endif +#endif /* GL_VERSION_1_4 */ +#ifndef GL_VERSION_1_5 +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_STREAM_DRAW 0x88E0 +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 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); +#ifdef GL_GLEXT_PROTOTYPES +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 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); +#endif +#endif /* GL_VERSION_1_5 */ +#ifndef GL_VERSION_2_0 +typedef char GLchar; +typedef khronos_int16_t GLshort; +typedef khronos_int8_t GLbyte; +typedef khronos_uint16_t GLushort; +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_UPPER_LEFT 0x8CA2 +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +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 PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +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 GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +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 PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +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 glAttachShader (GLuint program, GLuint shader); +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 glEnableVertexAttribArray (GLuint index); +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 GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +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 glUniform1i (GLint location, GLint v0); +GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +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_3_0 +typedef khronos_uint16_t GLhalf; +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); +GLAPI void APIENTRY glBindVertexArray (GLuint array); +GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +#endif +#endif /* GL_VERSION_3_0 */ +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +#define GL_PRIMITIVE_RESTART 0x8F9D +#endif /* GL_VERSION_3_1 */ +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +typedef struct __GLsync *GLsync; +typedef khronos_uint64_t GLuint64; +typedef khronos_int64_t GLint64; +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +#endif +#endif /* GL_VERSION_3_2 */ +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +#define GL_SAMPLER_BINDING 0x8919 +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); +#endif +#endif /* GL_VERSION_3_3 */ +#ifndef GL_VERSION_4_1 +typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); +#endif /* GL_VERSION_4_1 */ +#ifndef GL_VERSION_4_3 +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#endif /* GL_VERSION_4_3 */ +#ifndef GL_VERSION_4_5 +#define GL_CLIP_ORIGIN 0x935C +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); +#endif /* GL_VERSION_4_5 */ +#ifndef GL_ARB_bindless_texture +typedef khronos_uint64_t GLuint64EXT; +#endif /* GL_ARB_bindless_texture */ +#ifndef GL_ARB_cl_event +struct _cl_context; +struct _cl_event; +#endif /* GL_ARB_cl_event */ +#ifndef GL_ARB_clip_control +#define GL_ARB_clip_control 1 +#endif /* GL_ARB_clip_control */ +#ifndef GL_ARB_debug_output +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#endif /* GL_ARB_debug_output */ +#ifndef GL_EXT_EGL_image_storage +typedef void *GLeglImageOES; +#endif /* GL_EXT_EGL_image_storage */ +#ifndef GL_EXT_direct_state_access +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 PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); +#endif /* GL_EXT_direct_state_access */ +#ifndef GL_NV_draw_vulkan_image +typedef void (APIENTRY *GLVULKANPROCNV)(void); +#endif /* GL_NV_draw_vulkan_image */ +#ifndef GL_NV_gpu_shader5 +typedef khronos_int64_t GLint64EXT; +#endif /* GL_NV_gpu_shader5 */ +#ifndef GL_NV_vertex_buffer_unified_memory +typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); +#endif /* GL_NV_vertex_buffer_unified_memory */ +#ifdef __cplusplus +} +#endif +#endif + +#ifndef GL3W_API +#define GL3W_API +#endif + +#ifndef __gl_h_ +#define __gl_h_ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define GL3W_OK 0 +#define GL3W_ERROR_INIT -1 +#define GL3W_ERROR_LIBRARY_OPEN -2 +#define GL3W_ERROR_OPENGL_VERSION -3 + +typedef void (*GL3WglProc)(void); +typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc); + +/* gl3w api */ +GL3W_API int imgl3wInit(void); +GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc); +GL3W_API int imgl3wIsSupported(int major, int minor); +GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc); + +/* gl3w internal state */ +union GL3WProcs { + GL3WglProc ptr[54]; + struct { + PFNGLACTIVETEXTUREPROC ActiveTexture; + PFNGLATTACHSHADERPROC AttachShader; + PFNGLBINDBUFFERPROC BindBuffer; + PFNGLBINDSAMPLERPROC BindSampler; + PFNGLBINDTEXTUREPROC BindTexture; + PFNGLBINDVERTEXARRAYPROC BindVertexArray; + PFNGLBLENDEQUATIONPROC BlendEquation; + PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; + PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; + PFNGLBUFFERDATAPROC BufferData; + PFNGLBUFFERSUBDATAPROC BufferSubData; + PFNGLCLEARPROC Clear; + PFNGLCLEARCOLORPROC ClearColor; + PFNGLCOMPILESHADERPROC CompileShader; + PFNGLCREATEPROGRAMPROC CreateProgram; + PFNGLCREATESHADERPROC CreateShader; + PFNGLDELETEBUFFERSPROC DeleteBuffers; + PFNGLDELETEPROGRAMPROC DeleteProgram; + PFNGLDELETESHADERPROC DeleteShader; + PFNGLDELETETEXTURESPROC DeleteTextures; + PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; + PFNGLDETACHSHADERPROC DetachShader; + PFNGLDISABLEPROC Disable; + PFNGLDRAWELEMENTSPROC DrawElements; + PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; + PFNGLENABLEPROC Enable; + PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; + PFNGLGENBUFFERSPROC GenBuffers; + PFNGLGENTEXTURESPROC GenTextures; + PFNGLGENVERTEXARRAYSPROC GenVertexArrays; + PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; + PFNGLGETERRORPROC GetError; + PFNGLGETINTEGERVPROC GetIntegerv; + PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; + PFNGLGETPROGRAMIVPROC GetProgramiv; + PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; + PFNGLGETSHADERIVPROC GetShaderiv; + PFNGLGETSTRINGPROC GetString; + PFNGLGETSTRINGIPROC GetStringi; + PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; + PFNGLISENABLEDPROC IsEnabled; + PFNGLLINKPROGRAMPROC LinkProgram; + PFNGLPIXELSTOREIPROC PixelStorei; + PFNGLPOLYGONMODEPROC PolygonMode; + PFNGLREADPIXELSPROC ReadPixels; + PFNGLSCISSORPROC Scissor; + PFNGLSHADERSOURCEPROC ShaderSource; + PFNGLTEXIMAGE2DPROC TexImage2D; + PFNGLTEXPARAMETERIPROC TexParameteri; + PFNGLUNIFORM1IPROC Uniform1i; + PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; + PFNGLUSEPROGRAMPROC UseProgram; + PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; + PFNGLVIEWPORTPROC Viewport; + } gl; +}; + +GL3W_API extern union GL3WProcs imgl3wProcs; + +/* OpenGL functions */ +#define glActiveTexture imgl3wProcs.gl.ActiveTexture +#define glAttachShader imgl3wProcs.gl.AttachShader +#define glBindBuffer imgl3wProcs.gl.BindBuffer +#define glBindSampler imgl3wProcs.gl.BindSampler +#define glBindTexture imgl3wProcs.gl.BindTexture +#define glBindVertexArray imgl3wProcs.gl.BindVertexArray +#define glBlendEquation imgl3wProcs.gl.BlendEquation +#define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate +#define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate +#define glBufferData imgl3wProcs.gl.BufferData +#define glBufferSubData imgl3wProcs.gl.BufferSubData +#define glClear imgl3wProcs.gl.Clear +#define glClearColor imgl3wProcs.gl.ClearColor +#define glCompileShader imgl3wProcs.gl.CompileShader +#define glCreateProgram imgl3wProcs.gl.CreateProgram +#define glCreateShader imgl3wProcs.gl.CreateShader +#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers +#define glDeleteProgram imgl3wProcs.gl.DeleteProgram +#define glDeleteShader imgl3wProcs.gl.DeleteShader +#define glDeleteTextures imgl3wProcs.gl.DeleteTextures +#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays +#define glDetachShader imgl3wProcs.gl.DetachShader +#define glDisable imgl3wProcs.gl.Disable +#define glDrawElements imgl3wProcs.gl.DrawElements +#define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex +#define glEnable imgl3wProcs.gl.Enable +#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray +#define glGenBuffers imgl3wProcs.gl.GenBuffers +#define glGenTextures imgl3wProcs.gl.GenTextures +#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays +#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation +#define glGetError imgl3wProcs.gl.GetError +#define glGetIntegerv imgl3wProcs.gl.GetIntegerv +#define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog +#define glGetProgramiv imgl3wProcs.gl.GetProgramiv +#define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog +#define glGetShaderiv imgl3wProcs.gl.GetShaderiv +#define glGetString imgl3wProcs.gl.GetString +#define glGetStringi imgl3wProcs.gl.GetStringi +#define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation +#define glIsEnabled imgl3wProcs.gl.IsEnabled +#define glLinkProgram imgl3wProcs.gl.LinkProgram +#define glPixelStorei imgl3wProcs.gl.PixelStorei +#define glPolygonMode imgl3wProcs.gl.PolygonMode +#define glReadPixels imgl3wProcs.gl.ReadPixels +#define glScissor imgl3wProcs.gl.Scissor +#define glShaderSource imgl3wProcs.gl.ShaderSource +#define glTexImage2D imgl3wProcs.gl.TexImage2D +#define glTexParameteri imgl3wProcs.gl.TexParameteri +#define glUniform1i imgl3wProcs.gl.Uniform1i +#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv +#define glUseProgram imgl3wProcs.gl.UseProgram +#define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer +#define glViewport imgl3wProcs.gl.Viewport + +#ifdef __cplusplus +} +#endif + +#endif + +#ifdef IMGL3W_IMPL +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include + +static HMODULE libgl; +typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR); +static GL3WglGetProcAddr wgl_get_proc_address; + +static int open_libgl(void) +{ + libgl = LoadLibraryA("opengl32.dll"); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + wgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, "wglGetProcAddress"); + return GL3W_OK; +} + +static void close_libgl(void) { FreeLibrary(libgl); } +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + res = (GL3WglProc)wgl_get_proc_address(proc); + if (!res) + res = (GL3WglProc)GetProcAddress(libgl, proc); + return res; +} +#elif defined(__APPLE__) +#include + +static void *libgl; +static int open_libgl(void) +{ + libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + return GL3W_OK; +} + +static void close_libgl(void) { dlclose(libgl); } + +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + *(void **)(&res) = dlsym(libgl, proc); + return res; +} +#else +#include + +static void *libgl; +static GL3WglProc (*glx_get_proc_address)(const GLubyte *); + +static int open_libgl(void) +{ + libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB"); + return GL3W_OK; +} + +static void close_libgl(void) { dlclose(libgl); } + +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + res = glx_get_proc_address((const GLubyte *)proc); + if (!res) + *(void **)(&res) = dlsym(libgl, proc); + return res; +} +#endif + +static struct { int major, minor; } version; + +static int parse_version(void) +{ + if (!glGetIntegerv) + return GL3W_ERROR_INIT; + glGetIntegerv(GL_MAJOR_VERSION, &version.major); + glGetIntegerv(GL_MINOR_VERSION, &version.minor); + if (version.major < 3) + return GL3W_ERROR_OPENGL_VERSION; + return GL3W_OK; +} + +static void load_procs(GL3WGetProcAddressProc proc); + +int imgl3wInit(void) +{ + int res = open_libgl(); + if (res) + return res; + atexit(close_libgl); + return imgl3wInit2(get_proc); +} + +int imgl3wInit2(GL3WGetProcAddressProc proc) +{ + load_procs(proc); + return parse_version(); +} + +int imgl3wIsSupported(int major, int minor) +{ + if (major < 3) + return 0; + if (version.major == major) + return version.minor >= minor; + return version.major >= major; +} + +GL3WglProc imgl3wGetProcAddress(const char *proc) { return get_proc(proc); } + +static const char *proc_names[] = { + "glActiveTexture", + "glAttachShader", + "glBindBuffer", + "glBindSampler", + "glBindTexture", + "glBindVertexArray", + "glBlendEquation", + "glBlendEquationSeparate", + "glBlendFuncSeparate", + "glBufferData", + "glBufferSubData", + "glClear", + "glClearColor", + "glCompileShader", + "glCreateProgram", + "glCreateShader", + "glDeleteBuffers", + "glDeleteProgram", + "glDeleteShader", + "glDeleteTextures", + "glDeleteVertexArrays", + "glDetachShader", + "glDisable", + "glDrawElements", + "glDrawElementsBaseVertex", + "glEnable", + "glEnableVertexAttribArray", + "glGenBuffers", + "glGenTextures", + "glGenVertexArrays", + "glGetAttribLocation", + "glGetError", + "glGetIntegerv", + "glGetProgramInfoLog", + "glGetProgramiv", + "glGetShaderInfoLog", + "glGetShaderiv", + "glGetString", + "glGetStringi", + "glGetUniformLocation", + "glIsEnabled", + "glLinkProgram", + "glPixelStorei", + "glPolygonMode", + "glReadPixels", + "glScissor", + "glShaderSource", + "glTexImage2D", + "glTexParameteri", + "glUniform1i", + "glUniformMatrix4fv", + "glUseProgram", + "glVertexAttribPointer", + "glViewport", +}; + +GL3W_API union GL3WProcs imgl3wProcs; + +static void load_procs(GL3WGetProcAddressProc proc) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE(proc_names); i++) + imgl3wProcs.ptr[i] = proc(proc_names[i]); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.h new file mode 100644 index 000000000..33485c734 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.h @@ -0,0 +1,27 @@ +// dear imgui: Platform Backend for OSX / Cocoa +// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..) +// [ALPHA] Early backend, not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac. + +// Implemented features: +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: IME support. +// Issues: +// [ ] Platform: Multi-viewport / platform windows. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" // IMGUI_IMPL_API + +@class NSEvent; +@class NSView; + +IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view); +IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view); +IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.mm b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.mm new file mode 100644 index 000000000..521f2ffe7 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_osx.mm @@ -0,0 +1,712 @@ +// dear imgui: Platform Backend for OSX / Cocoa +// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..) +// [ALPHA] Early backend, not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac. + +// Implemented features: +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: IME support. +// Issues: +// [ ] Platform: Multi-viewport / platform windows. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#import "imgui.h" +#import "imgui_impl_osx.h" +#import +#import +#import +#import + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-02-07: Inputs: Forward keyDown/keyUp events to OS when unused by dear imgui. +// 2022-01-31: Fix building with old Xcode versions that are missing gamepad features. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function. +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys. +// 2021-12-13: Add game controller support. +// 2021-09-21: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards. +// 2021-08-17: Calling io.AddFocusEvent() on NSApplicationDidBecomeActiveNotification/NSApplicationDidResignActiveNotification events. +// 2021-06-23: Inputs: Added a fix for shortcuts using CTRL key instead of CMD key. +// 2021-04-19: Inputs: Added a fix for keys remaining stuck in pressed state when CMD-tabbing into different application. +// 2021-01-27: Inputs: Added a fix for mouse position not being reported when mouse buttons other than left one are down. +// 2020-10-28: Inputs: Added a fix for handling keypad-enter key. +// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap". +// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. +// 2019-10-11: Inputs: Fix using Backspace key. +// 2019-07-21: Re-added clipboard handlers as they are not enabled by default in core imgui.cpp (reverted 2019-05-18 change). +// 2019-05-28: Inputs: Added mouse cursor shape and visibility support. +// 2019-05-18: Misc: Removed clipboard handlers as they are now supported by core imgui.cpp. +// 2019-05-11: Inputs: Don't filter character values before calling AddInputCharacter() apart from 0xF700..0xFFFF range. +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-07-07: Initial version. + +#define APPLE_HAS_BUTTON_OPTIONS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 || __TV_OS_VERSION_MIN_REQUIRED >= 130000) +#define APPLE_HAS_CONTROLLER (__IPHONE_OS_VERSION_MIN_REQUIRED >= 140000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000 || __TV_OS_VERSION_MIN_REQUIRED >= 140000) +#define APPLE_HAS_THUMBSTICKS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 120100 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101401 || __TV_OS_VERSION_MIN_REQUIRED >= 120100) + +@class ImFocusObserver; +@class KeyEventResponder; + +// Data +static double g_HostClockPeriod = 0.0; +static double g_Time = 0.0; +static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; +static bool g_MouseCursorHidden = false; +static ImFocusObserver* g_FocusObserver = nil; +static KeyEventResponder* g_KeyEventResponder = nil; +static NSTextInputContext* g_InputContext = nil; + +// Undocumented methods for creating cursors. +@interface NSCursor() ++ (id)_windowResizeNorthWestSouthEastCursor; ++ (id)_windowResizeNorthEastSouthWestCursor; ++ (id)_windowResizeNorthSouthCursor; ++ (id)_windowResizeEastWestCursor; +@end + +static void InitHostClockPeriod() +{ + struct mach_timebase_info info; + mach_timebase_info(&info); + g_HostClockPeriod = 1e-9 * ((double)info.denom / (double)info.numer); // Period is the reciprocal of frequency. +} + +static double GetMachAbsoluteTimeInSeconds() +{ + return (double)mach_absolute_time() * g_HostClockPeriod; +} + +/** + KeyEventResponder implements the NSTextInputClient protocol as is required by the macOS text input manager. + + The macOS text input manager is invoked by calling the interpretKeyEvents method from the keyDown method. + Keyboard events are then evaluated by the macOS input manager and valid text input is passed back via the + insertText:replacementRange method. + + This is the same approach employed by other cross-platform libraries such as SDL2: + https://github.com/spurious/SDL-mirror/blob/e17aacbd09e65a4fd1e166621e011e581fb017a8/src/video/cocoa/SDL_cocoakeyboard.m#L53 + and GLFW: + https://github.com/glfw/glfw/blob/b55a517ae0c7b5127dffa79a64f5406021bf9076/src/cocoa_window.m#L722-L723 + */ +@interface KeyEventResponder: NSView +@end + +@implementation KeyEventResponder +{ + float _posX; + float _posY; + NSRect _imeRect; +} + +#pragma mark - Public + +- (void)setImePosX:(float)posX imePosY:(float)posY +{ + _posX = posX; + _posY = posY; +} + +- (void)updateImePosWithView:(NSView *)view +{ + NSWindow *window = view.window; + if (!window) + return; + NSRect contentRect = [window contentRectForFrameRect:window.frame]; + NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0); + _imeRect = [window convertRectToScreen:rect]; +} + +- (void)viewDidMoveToWindow +{ + // Ensure self is a first responder to receive the input events. + [self.window makeFirstResponder:self]; +} + +- (void)keyDown:(NSEvent*)event +{ + if (!ImGui_ImplOSX_HandleEvent(event, self)) + [super keyDown:event]; + + // Call to the macOS input manager system. + [self interpretKeyEvents:@[event]]; +} + +- (void)keyUp:(NSEvent*)event +{ + if (!ImGui_ImplOSX_HandleEvent(event, self)) + [super keyUp:event]; +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange +{ + ImGuiIO& io = ImGui::GetIO(); + + NSString* characters; + if ([aString isKindOfClass:[NSAttributedString class]]) + characters = [aString string]; + else + characters = (NSString*)aString; + + io.AddInputCharactersUTF8(characters.UTF8String); +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (void)doCommandBySelector:(SEL)myselector +{ +} + +- (nullable NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange +{ + return nil; +} + +- (NSUInteger)characterIndexForPoint:(NSPoint)point +{ + return 0; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange +{ + return _imeRect; +} + +- (BOOL)hasMarkedText +{ + return NO; +} + +- (NSRange)markedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (NSRange)selectedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (void)setMarkedText:(nonnull id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange +{ +} + +- (void)unmarkText +{ +} + +- (nonnull NSArray*)validAttributesForMarkedText +{ + return @[]; +} + +@end + +@interface ImFocusObserver : NSObject + +- (void)onApplicationBecomeActive:(NSNotification*)aNotification; +- (void)onApplicationBecomeInactive:(NSNotification*)aNotification; + +@end + +@implementation ImFocusObserver + +- (void)onApplicationBecomeActive:(NSNotification*)aNotification +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddFocusEvent(true); +} + +- (void)onApplicationBecomeInactive:(NSNotification*)aNotification +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddFocusEvent(false); +} + +@end + +// Functions +static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code) +{ + switch (key_code) + { + case kVK_ANSI_A: return ImGuiKey_A; + case kVK_ANSI_S: return ImGuiKey_S; + case kVK_ANSI_D: return ImGuiKey_D; + case kVK_ANSI_F: return ImGuiKey_F; + case kVK_ANSI_H: return ImGuiKey_H; + case kVK_ANSI_G: return ImGuiKey_G; + case kVK_ANSI_Z: return ImGuiKey_Z; + case kVK_ANSI_X: return ImGuiKey_X; + case kVK_ANSI_C: return ImGuiKey_C; + case kVK_ANSI_V: return ImGuiKey_V; + case kVK_ANSI_B: return ImGuiKey_B; + case kVK_ANSI_Q: return ImGuiKey_Q; + case kVK_ANSI_W: return ImGuiKey_W; + case kVK_ANSI_E: return ImGuiKey_E; + case kVK_ANSI_R: return ImGuiKey_R; + case kVK_ANSI_Y: return ImGuiKey_Y; + case kVK_ANSI_T: return ImGuiKey_T; + case kVK_ANSI_1: return ImGuiKey_1; + case kVK_ANSI_2: return ImGuiKey_2; + case kVK_ANSI_3: return ImGuiKey_3; + case kVK_ANSI_4: return ImGuiKey_4; + case kVK_ANSI_6: return ImGuiKey_6; + case kVK_ANSI_5: return ImGuiKey_5; + case kVK_ANSI_Equal: return ImGuiKey_Equal; + case kVK_ANSI_9: return ImGuiKey_9; + case kVK_ANSI_7: return ImGuiKey_7; + case kVK_ANSI_Minus: return ImGuiKey_Minus; + case kVK_ANSI_8: return ImGuiKey_8; + case kVK_ANSI_0: return ImGuiKey_0; + case kVK_ANSI_RightBracket: return ImGuiKey_RightBracket; + case kVK_ANSI_O: return ImGuiKey_O; + case kVK_ANSI_U: return ImGuiKey_U; + case kVK_ANSI_LeftBracket: return ImGuiKey_LeftBracket; + case kVK_ANSI_I: return ImGuiKey_I; + case kVK_ANSI_P: return ImGuiKey_P; + case kVK_ANSI_L: return ImGuiKey_L; + case kVK_ANSI_J: return ImGuiKey_J; + case kVK_ANSI_Quote: return ImGuiKey_Apostrophe; + case kVK_ANSI_K: return ImGuiKey_K; + case kVK_ANSI_Semicolon: return ImGuiKey_Semicolon; + case kVK_ANSI_Backslash: return ImGuiKey_Backslash; + case kVK_ANSI_Comma: return ImGuiKey_Comma; + case kVK_ANSI_Slash: return ImGuiKey_Slash; + case kVK_ANSI_N: return ImGuiKey_N; + case kVK_ANSI_M: return ImGuiKey_M; + case kVK_ANSI_Period: return ImGuiKey_Period; + case kVK_ANSI_Grave: return ImGuiKey_GraveAccent; + case kVK_ANSI_KeypadDecimal: return ImGuiKey_KeypadDecimal; + case kVK_ANSI_KeypadMultiply: return ImGuiKey_KeypadMultiply; + case kVK_ANSI_KeypadPlus: return ImGuiKey_KeypadAdd; + case kVK_ANSI_KeypadClear: return ImGuiKey_NumLock; + case kVK_ANSI_KeypadDivide: return ImGuiKey_KeypadDivide; + case kVK_ANSI_KeypadEnter: return ImGuiKey_KeypadEnter; + case kVK_ANSI_KeypadMinus: return ImGuiKey_KeypadSubtract; + case kVK_ANSI_KeypadEquals: return ImGuiKey_KeypadEqual; + case kVK_ANSI_Keypad0: return ImGuiKey_Keypad0; + case kVK_ANSI_Keypad1: return ImGuiKey_Keypad1; + case kVK_ANSI_Keypad2: return ImGuiKey_Keypad2; + case kVK_ANSI_Keypad3: return ImGuiKey_Keypad3; + case kVK_ANSI_Keypad4: return ImGuiKey_Keypad4; + case kVK_ANSI_Keypad5: return ImGuiKey_Keypad5; + case kVK_ANSI_Keypad6: return ImGuiKey_Keypad6; + case kVK_ANSI_Keypad7: return ImGuiKey_Keypad7; + case kVK_ANSI_Keypad8: return ImGuiKey_Keypad8; + case kVK_ANSI_Keypad9: return ImGuiKey_Keypad9; + case kVK_Return: return ImGuiKey_Enter; + case kVK_Tab: return ImGuiKey_Tab; + case kVK_Space: return ImGuiKey_Space; + case kVK_Delete: return ImGuiKey_Backspace; + case kVK_Escape: return ImGuiKey_Escape; + case kVK_CapsLock: return ImGuiKey_CapsLock; + case kVK_Control: return ImGuiKey_LeftCtrl; + case kVK_Shift: return ImGuiKey_LeftShift; + case kVK_Option: return ImGuiKey_LeftAlt; + case kVK_Command: return ImGuiKey_LeftSuper; + case kVK_RightControl: return ImGuiKey_RightCtrl; + case kVK_RightShift: return ImGuiKey_RightShift; + case kVK_RightOption: return ImGuiKey_RightAlt; + case kVK_RightCommand: return ImGuiKey_RightSuper; +// case kVK_Function: return ImGuiKey_; +// case kVK_F17: return ImGuiKey_; +// case kVK_VolumeUp: return ImGuiKey_; +// case kVK_VolumeDown: return ImGuiKey_; +// case kVK_Mute: return ImGuiKey_; +// case kVK_F18: return ImGuiKey_; +// case kVK_F19: return ImGuiKey_; +// case kVK_F20: return ImGuiKey_; + case kVK_F5: return ImGuiKey_F5; + case kVK_F6: return ImGuiKey_F6; + case kVK_F7: return ImGuiKey_F7; + case kVK_F3: return ImGuiKey_F3; + case kVK_F8: return ImGuiKey_F8; + case kVK_F9: return ImGuiKey_F9; + case kVK_F11: return ImGuiKey_F11; + case kVK_F13: return ImGuiKey_PrintScreen; +// case kVK_F16: return ImGuiKey_; +// case kVK_F14: return ImGuiKey_; + case kVK_F10: return ImGuiKey_F10; + case 0x6E: return ImGuiKey_Menu; + case kVK_F12: return ImGuiKey_F12; +// case kVK_F15: return ImGuiKey_; + case kVK_Help: return ImGuiKey_Insert; + case kVK_Home: return ImGuiKey_Home; + case kVK_PageUp: return ImGuiKey_PageUp; + case kVK_ForwardDelete: return ImGuiKey_Delete; + case kVK_F4: return ImGuiKey_F4; + case kVK_End: return ImGuiKey_End; + case kVK_F2: return ImGuiKey_F2; + case kVK_PageDown: return ImGuiKey_PageDown; + case kVK_F1: return ImGuiKey_F1; + case kVK_LeftArrow: return ImGuiKey_LeftArrow; + case kVK_RightArrow: return ImGuiKey_RightArrow; + case kVK_DownArrow: return ImGuiKey_DownArrow; + case kVK_UpArrow: return ImGuiKey_UpArrow; + default: return ImGuiKey_None; + } +} + + +bool ImGui_ImplOSX_Init(NSView* view) +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup backend capabilities flags + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + //io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + //io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) + io.BackendPlatformName = "imgui_impl_osx"; + + // Load cursors. Some of them are undocumented. + g_MouseCursorHidden = false; + g_MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor]; + g_MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor]; + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor]; + g_MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor]; + g_MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor]; + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor]; + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor]; + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor]; + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor]; + + // Note that imgui.cpp also include default OSX clipboard handlers which can be enabled + // by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line. + // Since we are already in ObjC land here, it is easy for us to add a clipboard handler using the NSPasteboard api. + io.SetClipboardTextFn = [](void*, const char* str) -> void + { + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + [pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil]; + [pasteboard setString:[NSString stringWithUTF8String:str] forType:NSPasteboardTypeString]; + }; + + io.GetClipboardTextFn = [](void*) -> const char* + { + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + NSString* available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:NSPasteboardTypeString]]; + if (![available isEqualToString:NSPasteboardTypeString]) + return NULL; + + NSString* string = [pasteboard stringForType:NSPasteboardTypeString]; + if (string == nil) + return NULL; + + const char* string_c = (const char*)[string UTF8String]; + size_t string_len = strlen(string_c); + static ImVector s_clipboard; + s_clipboard.resize((int)string_len + 1); + strcpy(s_clipboard.Data, string_c); + return s_clipboard.Data; + }; + + g_FocusObserver = [[ImFocusObserver alloc] init]; + [[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver + selector:@selector(onApplicationBecomeActive:) + name:NSApplicationDidBecomeActiveNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver + selector:@selector(onApplicationBecomeInactive:) + name:NSApplicationDidResignActiveNotification + object:nil]; + + // Add the NSTextInputClient to the view hierarchy, + // to receive keyboard events and translate them to input text. + g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect]; + g_InputContext = [[NSTextInputContext alloc] initWithClient:g_KeyEventResponder]; + [view addSubview:g_KeyEventResponder]; + + // Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down). + // This monitor taps into global event stream and captures these events. + NSEventMask eventMask = NSEventMaskFlagsChanged; + [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) + { + ImGui_ImplOSX_HandleEvent(event, g_KeyEventResponder); + return event; + }]; + + io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void + { + if (data->WantVisible) + { + [g_InputContext activate]; + } + else + { + [g_InputContext discardMarkedText]; + [g_InputContext invalidateCharacterCoordinates]; + [g_InputContext deactivate]; + } + [g_KeyEventResponder setImePosX:data->InputPos.x imePosY:data->InputPos.y + data->InputLineHeight]; + }; + + return true; +} + +void ImGui_ImplOSX_Shutdown() +{ + g_FocusObserver = NULL; +} + +static void ImGui_ImplOSX_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + if (!g_MouseCursorHidden) + { + g_MouseCursorHidden = true; + [NSCursor hide]; + } + } + else + { + NSCursor* desired = g_MouseCursors[imgui_cursor] ?: g_MouseCursors[ImGuiMouseCursor_Arrow]; + // -[NSCursor set] generates measureable overhead if called unconditionally. + if (desired != NSCursor.currentCursor) + { + [desired set]; + } + if (g_MouseCursorHidden) + { + g_MouseCursorHidden = false; + [NSCursor unhide]; + } + } +} + +static void ImGui_ImplOSX_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + memset(io.NavInputs, 0, sizeof(io.NavInputs)); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + +#if APPLE_HAS_CONTROLLER + GCController* controller = GCController.current; +#else + GCController* controller = GCController.controllers.firstObject; +#endif + if (controller == nil || controller.extendedGamepad == nil) + { + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + return; + } + + GCExtendedGamepad* gp = controller.extendedGamepad; + + // Update gamepad inputs + #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V) + #define MAP_BUTTON(KEY_NO, BUTTON_NAME) { io.AddKeyEvent(KEY_NO, gp.BUTTON_NAME.isPressed); } + #define MAP_ANALOG(KEY_NO, AXIS_NAME, V0, V1) { float vn = (float)(gp.AXIS_NAME.value - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); } + const float thumb_dead_zone = 0.0f; + +#if APPLE_HAS_BUTTON_OPTIONS + MAP_BUTTON(ImGuiKey_GamepadBack, buttonOptions); +#endif + MAP_BUTTON(ImGuiKey_GamepadFaceDown, buttonA); // Xbox A, PS Cross + MAP_BUTTON(ImGuiKey_GamepadFaceRight, buttonB); // Xbox B, PS Circle + MAP_BUTTON(ImGuiKey_GamepadFaceLeft, buttonX); // Xbox X, PS Square + MAP_BUTTON(ImGuiKey_GamepadFaceUp, buttonY); // Xbox Y, PS Triangle + MAP_BUTTON(ImGuiKey_GamepadDpadLeft, dpad.left); + MAP_BUTTON(ImGuiKey_GamepadDpadRight, dpad.right); + MAP_BUTTON(ImGuiKey_GamepadDpadUp, dpad.up); + MAP_BUTTON(ImGuiKey_GamepadDpadDown, dpad.down); + MAP_ANALOG(ImGuiKey_GamepadL1, leftShoulder, 0.0f, 1.0f); + MAP_ANALOG(ImGuiKey_GamepadR1, rightShoulder, 0.0f, 1.0f); + MAP_ANALOG(ImGuiKey_GamepadL2, leftTrigger, 0.0f, 1.0f); + MAP_ANALOG(ImGuiKey_GamepadR2, rightTrigger, 0.0f, 1.0f); +#if APPLE_HAS_THUMBSTICKS + MAP_BUTTON(ImGuiKey_GamepadL3, leftThumbstickButton); + MAP_BUTTON(ImGuiKey_GamepadR3, rightThumbstickButton); +#endif + MAP_ANALOG(ImGuiKey_GamepadLStickLeft, leftThumbstick.xAxis, -thumb_dead_zone, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickRight, leftThumbstick.xAxis, +thumb_dead_zone, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickUp, leftThumbstick.yAxis, +thumb_dead_zone, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadLStickDown, leftThumbstick.yAxis, -thumb_dead_zone, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickLeft, rightThumbstick.xAxis, -thumb_dead_zone, -1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickRight, rightThumbstick.xAxis, +thumb_dead_zone, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickUp, rightThumbstick.yAxis, +thumb_dead_zone, +1.0f); + MAP_ANALOG(ImGuiKey_GamepadRStickDown, rightThumbstick.yAxis, -thumb_dead_zone, -1.0f); + #undef MAP_BUTTON + #undef MAP_ANALOG + + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; +} + +static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view) +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.WantTextInput) + [g_KeyEventResponder updateImePosWithView:view]; +} + +void ImGui_ImplOSX_NewFrame(NSView* view) +{ + // Setup display size + ImGuiIO& io = ImGui::GetIO(); + if (view) + { + const float dpi = (float)[view.window backingScaleFactor]; + io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height); + io.DisplayFramebufferScale = ImVec2(dpi, dpi); + } + + // Setup time step + if (g_Time == 0.0) + { + InitHostClockPeriod(); + g_Time = GetMachAbsoluteTimeInSeconds(); + } + double current_time = GetMachAbsoluteTimeInSeconds(); + io.DeltaTime = (float)(current_time - g_Time); + g_Time = current_time; + + ImGui_ImplOSX_UpdateMouseCursor(); + ImGui_ImplOSX_UpdateGamepads(); + ImGui_ImplOSX_UpdateImePosWithView(view); +} + +bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) +{ + ImGuiIO& io = ImGui::GetIO(); + + if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) + { + int button = (int)[event buttonNumber]; + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, true); + return io.WantCaptureMouse; + } + + if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp) + { + int button = (int)[event buttonNumber]; + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, false); + return io.WantCaptureMouse; + } + + if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged || event.type == NSEventTypeRightMouseDragged || event.type == NSEventTypeOtherMouseDragged) + { + NSPoint mousePoint = event.locationInWindow; + mousePoint = [view convertPoint:mousePoint fromView:nil]; + mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y); + io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y); + } + + if (event.type == NSEventTypeScrollWheel) + { + // Ignore canceled events. + // + // From macOS 12.1, scrolling with two fingers and then decelerating + // by tapping two fingers results in two events appearing: + // + // 1. A scroll wheel NSEvent, with a phase == NSEventPhaseMayBegin, when the user taps + // two fingers to decelerate or stop the scroll events. + // + // 2. A scroll wheel NSEvent, with a phase == NSEventPhaseCancelled, when the user releases the + // two-finger tap. It is this event that sometimes contains large values for scrollingDeltaX and + // scrollingDeltaY. When these are added to the current x and y positions of the scrolling view, + // it appears to jump up or down. It can be observed in Preview, various JetBrains IDEs and here. + if (event.phase == NSEventPhaseCancelled) + return false; + + double wheel_dx = 0.0; + double wheel_dy = 0.0; + + #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + wheel_dx = [event scrollingDeltaX]; + wheel_dy = [event scrollingDeltaY]; + if ([event hasPreciseScrollingDeltas]) + { + wheel_dx *= 0.1; + wheel_dy *= 0.1; + } + } + else + #endif // MAC_OS_X_VERSION_MAX_ALLOWED + { + wheel_dx = [event deltaX]; + wheel_dy = [event deltaY]; + } + if (wheel_dx != 0.0 || wheel_dx != 0.0) + io.AddMouseWheelEvent((float)wheel_dx * 0.1f, (float)wheel_dy * 0.1f); + + return io.WantCaptureMouse; + } + + if (event.type == NSEventTypeKeyDown || event.type == NSEventTypeKeyUp) + { + if ([event isARepeat]) + return io.WantCaptureKeyboard; + + int key_code = (int)[event keyCode]; + ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code); + io.AddKeyEvent(key, event.type == NSEventTypeKeyDown); + io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code) + + return io.WantCaptureKeyboard; + } + + if (event.type == NSEventTypeFlagsChanged) + { + unsigned short key_code = [event keyCode]; + NSEventModifierFlags modifier_flags = [event modifierFlags]; + + io.AddKeyEvent(ImGuiKey_ModShift, (modifier_flags & NSEventModifierFlagShift) != 0); + io.AddKeyEvent(ImGuiKey_ModCtrl, (modifier_flags & NSEventModifierFlagControl) != 0); + io.AddKeyEvent(ImGuiKey_ModAlt, (modifier_flags & NSEventModifierFlagOption) != 0); + io.AddKeyEvent(ImGuiKey_ModSuper, (modifier_flags & NSEventModifierFlagCommand) != 0); + + ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code); + if (key != ImGuiKey_None) + { + // macOS does not generate down/up event for modifiers. We're trying + // to use hardware dependent masks to extract that information. + // 'imgui_mask' is left as a fallback. + NSEventModifierFlags mask = 0; + switch (key) + { + case ImGuiKey_LeftCtrl: mask = 0x0001; break; + case ImGuiKey_RightCtrl: mask = 0x2000; break; + case ImGuiKey_LeftShift: mask = 0x0002; break; + case ImGuiKey_RightShift: mask = 0x0004; break; + case ImGuiKey_LeftSuper: mask = 0x0008; break; + case ImGuiKey_RightSuper: mask = 0x0010; break; + case ImGuiKey_LeftAlt: mask = 0x0020; break; + case ImGuiKey_RightAlt: mask = 0x0040; break; + default: + return io.WantCaptureKeyboard; + } + + NSEventModifierFlags modifier_flags = [event modifierFlags]; + io.AddKeyEvent(key, (modifier_flags & mask) != 0); + io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code) + } + + return io.WantCaptureKeyboard; + } + + return false; +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp new file mode 100644 index 000000000..61e6d99ac --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp @@ -0,0 +1,917 @@ +// dear imgui: Platform Backend for SDL2 +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) +// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) +// (Prefer SDL 2.0.5+ for full feature support.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// Missing features: +// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. +// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. +// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST. +// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+) +// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950) +// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. +// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). +// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). +// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. +// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. +// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). +// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. +// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. +// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. +// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. +// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. +// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. +// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText). +// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. +// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. + +#include "../imgui.h" +#include "imgui_impl_sdl.h" + +// SDL +// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) +#include +#include +#include +#if defined(__APPLE__) +#include +#endif + +#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) +#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 +#else +#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 +#endif +#define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4) +#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6) +#if !SDL_HAS_VULKAN +static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; +#endif + +// SDL Data +struct ImGui_ImplSDL2_Data +{ + SDL_Window* Window; + SDL_Renderer* Renderer; + Uint64 Time; + Uint32 MouseWindowID; + int MouseButtonsDown; + SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; + char* ClipboardTextData; + bool MouseCanUseGlobalState; + bool UseVulkan; + + ImGui_ImplSDL2_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. +static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} + +// Forward Declarations +static void ImGui_ImplSDL2_UpdateMonitors(); +static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context); +static void ImGui_ImplSDL2_ShutdownPlatformInterface(); + +// Functions +static const char* ImGui_ImplSDL2_GetClipboardText(void*) +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + if (bd->ClipboardTextData) + SDL_free(bd->ClipboardTextData); + bd->ClipboardTextData = SDL_GetClipboardText(); + return bd->ClipboardTextData; +} + +static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) +{ + SDL_SetClipboardText(text); +} + +static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) +{ + switch (keycode) + { + case SDLK_TAB: return ImGuiKey_Tab; + case SDLK_LEFT: return ImGuiKey_LeftArrow; + case SDLK_RIGHT: return ImGuiKey_RightArrow; + case SDLK_UP: return ImGuiKey_UpArrow; + case SDLK_DOWN: return ImGuiKey_DownArrow; + case SDLK_PAGEUP: return ImGuiKey_PageUp; + case SDLK_PAGEDOWN: return ImGuiKey_PageDown; + case SDLK_HOME: return ImGuiKey_Home; + case SDLK_END: return ImGuiKey_End; + case SDLK_INSERT: return ImGuiKey_Insert; + case SDLK_DELETE: return ImGuiKey_Delete; + case SDLK_BACKSPACE: return ImGuiKey_Backspace; + case SDLK_SPACE: return ImGuiKey_Space; + case SDLK_RETURN: return ImGuiKey_Enter; + case SDLK_ESCAPE: return ImGuiKey_Escape; + case SDLK_QUOTE: return ImGuiKey_Apostrophe; + case SDLK_COMMA: return ImGuiKey_Comma; + case SDLK_MINUS: return ImGuiKey_Minus; + case SDLK_PERIOD: return ImGuiKey_Period; + case SDLK_SLASH: return ImGuiKey_Slash; + case SDLK_SEMICOLON: return ImGuiKey_Semicolon; + case SDLK_EQUALS: return ImGuiKey_Equal; + case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket; + case SDLK_BACKSLASH: return ImGuiKey_Backslash; + case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket; + case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent; + case SDLK_CAPSLOCK: return ImGuiKey_CapsLock; + case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock; + case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock; + case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen; + case SDLK_PAUSE: return ImGuiKey_Pause; + case SDLK_KP_0: return ImGuiKey_Keypad0; + case SDLK_KP_1: return ImGuiKey_Keypad1; + case SDLK_KP_2: return ImGuiKey_Keypad2; + case SDLK_KP_3: return ImGuiKey_Keypad3; + case SDLK_KP_4: return ImGuiKey_Keypad4; + case SDLK_KP_5: return ImGuiKey_Keypad5; + case SDLK_KP_6: return ImGuiKey_Keypad6; + case SDLK_KP_7: return ImGuiKey_Keypad7; + case SDLK_KP_8: return ImGuiKey_Keypad8; + case SDLK_KP_9: return ImGuiKey_Keypad9; + case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal; + case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide; + case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; + case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract; + case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd; + case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter; + case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual; + case SDLK_LCTRL: return ImGuiKey_LeftCtrl; + case SDLK_LSHIFT: return ImGuiKey_LeftShift; + case SDLK_LALT: return ImGuiKey_LeftAlt; + case SDLK_LGUI: return ImGuiKey_LeftSuper; + case SDLK_RCTRL: return ImGuiKey_RightCtrl; + case SDLK_RSHIFT: return ImGuiKey_RightShift; + case SDLK_RALT: return ImGuiKey_RightAlt; + case SDLK_RGUI: return ImGuiKey_RightSuper; + case SDLK_APPLICATION: return ImGuiKey_Menu; + case SDLK_0: return ImGuiKey_0; + case SDLK_1: return ImGuiKey_1; + case SDLK_2: return ImGuiKey_2; + case SDLK_3: return ImGuiKey_3; + case SDLK_4: return ImGuiKey_4; + case SDLK_5: return ImGuiKey_5; + case SDLK_6: return ImGuiKey_6; + case SDLK_7: return ImGuiKey_7; + case SDLK_8: return ImGuiKey_8; + case SDLK_9: return ImGuiKey_9; + case SDLK_a: return ImGuiKey_A; + case SDLK_b: return ImGuiKey_B; + case SDLK_c: return ImGuiKey_C; + case SDLK_d: return ImGuiKey_D; + case SDLK_e: return ImGuiKey_E; + case SDLK_f: return ImGuiKey_F; + case SDLK_g: return ImGuiKey_G; + case SDLK_h: return ImGuiKey_H; + case SDLK_i: return ImGuiKey_I; + case SDLK_j: return ImGuiKey_J; + case SDLK_k: return ImGuiKey_K; + case SDLK_l: return ImGuiKey_L; + case SDLK_m: return ImGuiKey_M; + case SDLK_n: return ImGuiKey_N; + case SDLK_o: return ImGuiKey_O; + case SDLK_p: return ImGuiKey_P; + case SDLK_q: return ImGuiKey_Q; + case SDLK_r: return ImGuiKey_R; + case SDLK_s: return ImGuiKey_S; + case SDLK_t: return ImGuiKey_T; + case SDLK_u: return ImGuiKey_U; + case SDLK_v: return ImGuiKey_V; + case SDLK_w: return ImGuiKey_W; + case SDLK_x: return ImGuiKey_X; + case SDLK_y: return ImGuiKey_Y; + case SDLK_z: return ImGuiKey_Z; + case SDLK_F1: return ImGuiKey_F1; + case SDLK_F2: return ImGuiKey_F2; + case SDLK_F3: return ImGuiKey_F3; + case SDLK_F4: return ImGuiKey_F4; + case SDLK_F5: return ImGuiKey_F5; + case SDLK_F6: return ImGuiKey_F6; + case SDLK_F7: return ImGuiKey_F7; + case SDLK_F8: return ImGuiKey_F8; + case SDLK_F9: return ImGuiKey_F9; + case SDLK_F10: return ImGuiKey_F10; + case SDLK_F11: return ImGuiKey_F11; + case SDLK_F12: return ImGuiKey_F12; + } + return ImGuiKey_None; +} + +static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(ImGuiKey_ModCtrl, (sdl_key_mods & KMOD_CTRL) != 0); + io.AddKeyEvent(ImGuiKey_ModShift, (sdl_key_mods & KMOD_SHIFT) != 0); + io.AddKeyEvent(ImGuiKey_ModAlt, (sdl_key_mods & KMOD_ALT) != 0); + io.AddKeyEvent(ImGuiKey_ModSuper, (sdl_key_mods & KMOD_GUI) != 0); +} + +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. +bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + + switch (event->type) + { + case SDL_MOUSEMOTION: + { + ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + int window_x, window_y; + SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y); + mouse_pos.x += window_x; + mouse_pos.y += window_y; + } + io.AddMousePosEvent(mouse_pos.x, mouse_pos.y); + return true; + } + case SDL_MOUSEWHEEL: + { + float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f; + float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f; + io.AddMouseWheelEvent(wheel_x, wheel_y); + return true; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + int mouse_button = -1; + if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; } + if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; } + if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; } + if (mouse_button == -1) + break; + io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN)); + bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button)); + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); + ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); + io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); + io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. + return true; + } + case SDL_WINDOWEVENT: + { + // When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right. + // However we won't get a correct LEAVE event for a captured window. + Uint8 window_event = event->window.event; + if (window_event == SDL_WINDOWEVENT_ENTER) + bd->MouseWindowID = event->window.windowID; + if (window_event == SDL_WINDOWEVENT_LEAVE) + { + bd->MouseWindowID = 0; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + } + if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) + io.AddFocusEvent(true); + else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) + io.AddFocusEvent(false); + if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED) + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID))) + { + if (window_event == SDL_WINDOWEVENT_CLOSE) + viewport->PlatformRequestClose = true; + if (window_event == SDL_WINDOWEVENT_MOVED) + viewport->PlatformRequestMove = true; + if (window_event == SDL_WINDOWEVENT_RESIZED) + viewport->PlatformRequestResize = true; + return true; + } + return true; + } + } + return false; +} + +static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); + + // Check and store if we are on a SDL backend that supports global mouse position + // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) + bool mouse_can_use_global_state = false; +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + const char* sdl_backend = SDL_GetCurrentVideoDriver(); + const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; + for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) + if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) + mouse_can_use_global_state = true; +#endif + + // Setup backend capabilities flags + ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_sdl"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + if (mouse_can_use_global_state) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + + // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960) +#ifndef __APPLE__ + if (mouse_can_use_global_state) + io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;// We can call io.AddMouseViewportEvent() with correct data (optional) +#endif + + bd->Window = window; + bd->Renderer = renderer; + bd->MouseCanUseGlobalState = mouse_can_use_global_state; + + io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; + io.ClipboardUserData = NULL; + + // Load mouse cursors + bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + + // Set platform dependent data in viewport + // Our mouse update function expect PlatformHandle to be filled for the main viewport + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)window; +#ifdef _WIN32 + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(window, &info)) + main_viewport->PlatformHandleRaw = (void*)info.info.win.window; +#endif + + // Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event. + // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered. + // (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application. + // It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: + // you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED) +#if SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); +#endif + + // Update monitors + ImGui_ImplSDL2_UpdateMonitors(); + + // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. + // We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings. + if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) + ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); + + return true; +} + +bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) +{ + return ImGui_ImplSDL2_Init(window, NULL, sdl_gl_context); +} + +bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) +{ +#if !SDL_HAS_VULKAN + IM_ASSERT(0 && "Unsupported"); +#endif + if (!ImGui_ImplSDL2_Init(window, NULL, NULL)) + return false; + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + bd->UseVulkan = true; + return true; +} + +bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) +{ +#if !defined(_WIN32) + IM_ASSERT(0 && "Unsupported"); +#endif + return ImGui_ImplSDL2_Init(window, NULL, NULL); +} + +bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) +{ + return ImGui_ImplSDL2_Init(window, NULL, NULL); +} + +bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer) +{ + return ImGui_ImplSDL2_Init(window, renderer, NULL); +} + +void ImGui_ImplSDL2_Shutdown() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplSDL2_ShutdownPlatformInterface(); + + if (bd->ClipboardTextData) + SDL_free(bd->ClipboardTextData); + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) + SDL_FreeCursor(bd->MouseCursors[cursor_n]); + + io.BackendPlatformName = NULL; + io.BackendPlatformUserData = NULL; + IM_DELETE(bd); +} + +// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4. +static void ImGui_ImplSDL2_UpdateMouseData() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + + // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below) +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside + SDL_CaptureMouse(bd->MouseButtonsDown != 0 ? SDL_TRUE : SDL_FALSE); + SDL_Window* focused_window = SDL_GetKeyboardFocus(); + const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window))); +#else + SDL_Window* focused_window = bd->Window; + const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only +#endif + + if (is_app_focused) + { + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + if (io.WantSetMousePos) + { +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y); + else +#endif + SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y); + } + + // (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured) + if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0) + { + // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) + // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) + int mouse_x, mouse_y, window_x, window_y; + SDL_GetGlobalMouseState(&mouse_x, &mouse_y); + if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + { + SDL_GetWindowPosition(focused_window, &window_x, &window_y); + mouse_x -= window_x; + mouse_y -= window_y; + } + io.AddMousePosEvent((float)mouse_x, (float)mouse_y); + } + } + + // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering. + // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic. + // - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag. + // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window + // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported + // by the backend, and use its flawed heuristic to guess the viewport behind. + // - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target). + if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) + { + ImGuiID mouse_viewport_id = 0; + if (SDL_Window* sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID)) + if (ImGuiViewport* mouse_viewport = ImGui::FindViewportByPlatformHandle((void*)sdl_mouse_window)) + mouse_viewport_id = mouse_viewport->ID; + io.AddMouseViewportEvent(mouse_viewport_id); + } +} + +static void ImGui_ImplSDL2_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + // Commenting these out allows custom hiding of the cursor when hovering over imGUI elements. + //SDL_ShowCursor(SDL_FALSE); + } + else + { + // Show OS mouse cursor + //SDL_SetCursor(bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]); + //SDL_ShowCursor(SDL_TRUE); + } +} + +static void ImGui_ImplSDL2_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + // Get gamepad + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + SDL_GameController* game_controller = SDL_GameControllerOpen(0); + if (!game_controller) + return; + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + + // Update gamepad inputs + #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V) + #define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); } + #define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); } + const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value. + MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START); + MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK); + MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross + MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle + MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square + MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle + MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); + MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); + MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); + MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); + MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767); + MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767); + MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK); + MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK); + MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767); + #undef MAP_BUTTON + #undef MAP_ANALOG +} + +// FIXME-PLATFORM: SDL doesn't have an event to notify the application of display/monitor changes +static void ImGui_ImplSDL2_UpdateMonitors() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Monitors.resize(0); + int display_count = SDL_GetNumVideoDisplays(); + for (int n = 0; n < display_count; n++) + { + // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. + ImGuiPlatformMonitor monitor; + SDL_Rect r; + SDL_GetDisplayBounds(n, &r); + monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); +#if SDL_HAS_USABLE_DISPLAY_BOUNDS + SDL_GetDisplayUsableBounds(n, &r); + monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.WorkSize = ImVec2((float)r.w, (float)r.h); +#endif +#if SDL_HAS_PER_MONITOR_DPI + float dpi = 0.0f; + if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL)) + monitor.DpiScale = dpi / 96.0f; +#endif + platform_io.Monitors.push_back(monitor); + } +} + +void ImGui_ImplSDL2_NewFrame() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplSDL2_Init()?"); + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(bd->Window, &w, &h); + if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED) + w = h = 0; + if (bd->Renderer != NULL) + SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h); + else + SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + if (w > 0 && h > 0) + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) + static Uint64 frequency = SDL_GetPerformanceFrequency(); + Uint64 current_time = SDL_GetPerformanceCounter(); + io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); + bd->Time = current_time; + + ImGui_ImplSDL2_UpdateMouseData(); + ImGui_ImplSDL2_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplSDL2_UpdateGamepads(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplSDL2_ViewportData +{ + SDL_Window* Window; + Uint32 WindowID; + bool WindowOwned; + SDL_GLContext GLContext; + + ImGui_ImplSDL2_ViewportData() { Window = NULL; WindowID = 0; WindowOwned = false; GLContext = NULL; } + ~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == NULL && GLContext == NULL); } +}; + +static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); + viewport->PlatformUserData = vd; + + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData; + + // Share GL resources with main context + bool use_opengl = (main_viewport_data->GLContext != NULL); + SDL_GLContext backup_context = NULL; + if (use_opengl) + { + backup_context = SDL_GL_GetCurrentContext(); + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext); + } + + Uint32 sdl_flags = 0; + sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0); + sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI; + sdl_flags |= SDL_WINDOW_HIDDEN; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; +#if !defined(_WIN32) + // See SDL hack in ImGui_ImplSDL2_ShowWindow(). + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; +#endif +#if SDL_HAS_ALWAYS_ON_TOP + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; +#endif + vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags); + vd->WindowOwned = true; + if (use_opengl) + { + vd->GLContext = SDL_GL_CreateContext(vd->Window); + SDL_GL_SetSwapInterval(0); + } + if (use_opengl && backup_context) + SDL_GL_MakeCurrent(vd->Window, backup_context); + + viewport->PlatformHandle = (void*)vd->Window; +#if defined(_WIN32) + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(vd->Window, &info)) + viewport->PlatformHandleRaw = info.info.win.window; +#endif +} + +static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport) +{ + if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData) + { + if (vd->GLContext && vd->WindowOwned) + SDL_GL_DeleteContext(vd->GLContext); + if (vd->Window && vd->WindowOwned) + SDL_DestroyWindow(vd->Window); + vd->GLContext = NULL; + vd->Window = NULL; + IM_DELETE(vd); + } + viewport->PlatformUserData = viewport->PlatformHandle = NULL; +} + +static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; +#if defined(_WIN32) + HWND hwnd = (HWND)viewport->PlatformHandleRaw; + + // SDL hack: Hide icon from task bar + // Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition. + if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) + { + LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + ex_style &= ~WS_EX_APPWINDOW; + ex_style |= WS_EX_TOOLWINDOW; + ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); + } + + // SDL hack: SDL always activate/focus windows :/ + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) + { + ::ShowWindow(hwnd, SW_SHOWNA); + return; + } +#endif + + SDL_ShowWindow(vd->Window); +} + +static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + int x = 0, y = 0; + SDL_GetWindowPosition(vd->Window, &x, &y); + return ImVec2((float)x, (float)y); +} + +static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y); +} + +static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + int w = 0, h = 0; + SDL_GetWindowSize(vd->Window, &w, &h); + return ImVec2((float)w, (float)h); +} + +static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y); +} + +static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowTitle(vd->Window, title); +} + +#if SDL_HAS_WINDOW_ALPHA +static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowOpacity(vd->Window, alpha); +} +#endif + +static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_RaiseWindow(vd->Window); +} + +static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; +} + +static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0; +} + +static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + if (vd->GLContext) + SDL_GL_MakeCurrent(vd->Window, vd->GLContext); +} + +static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + if (vd->GLContext) + { + SDL_GL_MakeCurrent(vd->Window, vd->GLContext); + SDL_GL_SwapWindow(vd->Window); + } +} + +// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface) +// SDL is graceful enough to _not_ need so we can safely include this. +#if SDL_HAS_VULKAN +#include +static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + (void)vk_allocator; + SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface); + return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY +} +#endif // SDL_HAS_VULKAN + +static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context) +{ + // Register platform interface (will be coupled with a renderer interface) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow; + platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow; + platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow; + platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos; + platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos; + platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize; + platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize; + platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus; + platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized; + platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle; + platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow; + platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers; +#if SDL_HAS_WINDOW_ALPHA + platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha; +#endif +#if SDL_HAS_VULKAN + platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface; +#endif + + // Register main window handle (which is owned by the main application, not by us) + // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports. + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); + vd->Window = window; + vd->WindowID = SDL_GetWindowID(window); + vd->WindowOwned = false; + vd->GLContext = sdl_gl_context; + main_viewport->PlatformUserData = vd; + main_viewport->PlatformHandle = vd->Window; +} + +static void ImGui_ImplSDL2_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.h new file mode 100644 index 000000000..7642644a1 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.h @@ -0,0 +1,38 @@ +// dear imgui: Platform Backend for SDL2 +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) +// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// Missing features: +// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. +// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "../imgui.h" // IMGUI_IMPL_API + +struct SDL_Window; +struct SDL_Renderer; +typedef union SDL_Event SDL_Event; + +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer); +IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +static inline void ImGui_ImplSDL2_NewFrame(SDL_Window*) { ImGui_ImplSDL2_NewFrame(); } // 1.84: removed unnecessary parameter +#endif diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.cpp new file mode 100644 index 000000000..ae034179c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.cpp @@ -0,0 +1,249 @@ +// dear imgui: Renderer Backend for SDL_Renderer +// (Requires: SDL 2.0.17+) + +// Important to understand: SDL_Renderer is an _optional_ component of SDL. +// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. +// If your application will want to render any non trivial amount of graphics other than UI, +// please be aware that SDL_Renderer offers a limited graphic API to the end-user and it might +// be difficult to step out of those boundaries. +// However, we understand it is a convenient choice to get an app started easily. + +// Implemented features: +// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19. +// 2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2021-10-06: Backup and restore modified ClipRect/Viewport. +// 2021-09-21: Initial version. + +#include "imgui.h" +#include "imgui_impl_sdlrenderer.h" +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// SDL +#include +#if !SDL_VERSION_ATLEAST(2,0,17) +#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function +#endif + +// SDL_Renderer data +struct ImGui_ImplSDLRenderer_Data +{ + SDL_Renderer* SDLRenderer; + SDL_Texture* FontTexture; + ImGui_ImplSDLRenderer_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplSDLRenderer_Data* ImGui_ImplSDLRenderer_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Functions +bool ImGui_ImplSDLRenderer_Init(SDL_Renderer* renderer) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + IM_ASSERT(renderer != NULL && "SDL_Renderer not initialized!"); + + // Setup backend capabilities flags + ImGui_ImplSDLRenderer_Data* bd = IM_NEW(ImGui_ImplSDLRenderer_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_sdlrenderer"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + bd->SDLRenderer = renderer; + + return true; +} + +void ImGui_ImplSDLRenderer_Shutdown() +{ + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplSDLRenderer_DestroyDeviceObjects(); + + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +static void ImGui_ImplSDLRenderer_SetupRenderState() +{ + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + + // Clear out any viewports and cliprect set by the user + // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process. + SDL_RenderSetViewport(bd->SDLRenderer, NULL); + SDL_RenderSetClipRect(bd->SDLRenderer, NULL); +} + +void ImGui_ImplSDLRenderer_NewFrame() +{ + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplSDLRenderer_Init()?"); + + if (!bd->FontTexture) + ImGui_ImplSDLRenderer_CreateDeviceObjects(); +} + +void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data) +{ + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + + // If there's a scale factor set by the user, use that instead + // If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass + // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here. + float rsx = 1.0f; + float rsy = 1.0f; + SDL_RenderGetScale(bd->SDLRenderer, &rsx, &rsy); + ImVec2 render_scale; + render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f; + render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f; + + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x); + int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y); + if (fb_width == 0 || fb_height == 0) + return; + + // Backup SDL_Renderer state that will be modified to restore it afterwards + struct BackupSDLRendererState + { + SDL_Rect Viewport; + bool ClipEnabled; + SDL_Rect ClipRect; + }; + BackupSDLRendererState old = {}; + old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer) == SDL_TRUE; + SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport); + SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = render_scale; + + // Render command lists + ImGui_ImplSDLRenderer_SetupRenderState(); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplSDLRenderer_SetupRenderState(); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } + if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } + if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } + if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; + SDL_RenderSetClipRect(bd->SDLRenderer, &r); + + const float* xy = (const float*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos)); + const float* uv = (const float*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv)); +#if SDL_VERSION_ATLEAST(2,0,19) + const SDL_Color* color = (const SDL_Color*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+ +#else + const int* color = (const int*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 +#endif + + // Bind texture, Draw + SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); + SDL_RenderGeometryRaw(bd->SDLRenderer, tex, + xy, (int)sizeof(ImDrawVert), + color, (int)sizeof(ImDrawVert), + uv, (int)sizeof(ImDrawVert), + cmd_list->VtxBuffer.Size - pcmd->VtxOffset, + idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx)); + } + } + } + + // Restore modified SDL_Renderer state + SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport); + SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : NULL); +} + +// Called by Init/NewFrame/Shutdown +bool ImGui_ImplSDLRenderer_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + + // Build texture atlas + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height); + if (bd->FontTexture == NULL) + { + SDL_Log("error creating texture"); + return false; + } + SDL_UpdateTexture(bd->FontTexture, NULL, pixels, 4 * width); + SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); + + return true; +} + +void ImGui_ImplSDLRenderer_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData(); + if (bd->FontTexture) + { + io.Fonts->SetTexID(0); + SDL_DestroyTexture(bd->FontTexture); + bd->FontTexture = NULL; + } +} + +bool ImGui_ImplSDLRenderer_CreateDeviceObjects() +{ + return ImGui_ImplSDLRenderer_CreateFontsTexture(); +} + +void ImGui_ImplSDLRenderer_DestroyDeviceObjects() +{ + ImGui_ImplSDLRenderer_DestroyFontsTexture(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.h new file mode 100644 index 000000000..37adce66a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdlrenderer.h @@ -0,0 +1,31 @@ +// dear imgui: Renderer Backend for SDL_Renderer +// (Requires: SDL 2.0.17+) + +// Important to understand: SDL_Renderer is an _optional_ component of SDL. +// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. +// If your application will want to render any non trivial amount of graphics other than UI, +// please be aware that SDL_Renderer offers a limited graphic API to the end-user and it might +// be difficult to step out of those boundaries. +// However, we understand it is a convenient choice to get an app started easily. + +// Implemented features: +// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct SDL_Renderer; + +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_Init(SDL_Renderer* renderer); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer_DestroyDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.cpp new file mode 100644 index 000000000..c262096b5 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.cpp @@ -0,0 +1,1758 @@ +// dear imgui: Renderer Backend for Vulkan +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// [x] Platform: Multi-viewport / platform windows. With issues (flickering when creating a new viewport). +// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. + +// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. +// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. +// To build this on 32-bit systems and support texture changes: +// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in our .vcxproj files) +// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. +// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) +// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in our batch files) + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. +// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ + +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. +// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// You will use those if you want to use this rendering backend in your engine/app. +// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by +// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. +// Read comments in imgui_impl_vulkan.h. + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize. +// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer. +// 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions(). +// 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. +// 2020-09-07: Vulkan: Added VkPipeline parameter to ImGui_ImplVulkan_RenderDrawData (default to one passed to ImGui_ImplVulkan_Init). +// 2020-05-04: Vulkan: Fixed crash if initial frame has no vertices. +// 2020-04-26: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData didn't have vertices. +// 2019-08-01: Vulkan: Added support for specifying multisample count. Set ImGui_ImplVulkan_InitInfo::MSAASamples to one of the VkSampleCountFlagBits values to use, default is non-multisampled as before. +// 2019-05-29: Vulkan: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2019-04-30: Vulkan: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. +// 2019-04-04: *BREAKING CHANGE*: Vulkan: Added ImageCount/MinImageCount fields in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetMinImageCount(). +// 2019-04-04: Vulkan: Added VkInstance argument to ImGui_ImplVulkanH_CreateWindow() optional helper. +// 2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. +// 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int). +// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display. +// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. +// 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case. +// 2018-06-22: Inverted the parameters to ImGui_ImplVulkan_RenderDrawData() to be consistent with other backends. +// 2018-06-08: Misc: Extracted imgui_impl_vulkan.cpp/.h away from the old combined GLFW+Vulkan example. +// 2018-06-08: Vulkan: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. +// 2018-03-03: Vulkan: Various refactor, created a couple of ImGui_ImplVulkanH_XXX helper that the example can use and that viewport support will use. +// 2018-03-01: Vulkan: Renamed ImGui_ImplVulkan_Init_Info to ImGui_ImplVulkan_InitInfo and fields to match more closely Vulkan terminology. +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplVulkan_Render() calls ImGui_ImplVulkan_RenderDrawData() itself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2017-05-15: Vulkan: Fix scissor offset being negative. Fix new Vulkan validation warnings. Set required depth member for buffer image copy. +// 2016-11-13: Vulkan: Fix validation layer warnings and errors and redeclare gl_PerVertex. +// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources. +// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active. + +#include "imgui_impl_vulkan.h" +#include + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#endif + +// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData() +// [Please zero-clear before use!] +struct ImGui_ImplVulkanH_FrameRenderBuffers +{ + VkDeviceMemory VertexBufferMemory; + VkDeviceMemory IndexBufferMemory; + VkDeviceSize VertexBufferSize; + VkDeviceSize IndexBufferSize; + VkBuffer VertexBuffer; + VkBuffer IndexBuffer; +}; + +// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers +// [Please zero-clear before use!] +struct ImGui_ImplVulkanH_WindowRenderBuffers +{ + uint32_t Index; + uint32_t Count; + ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers; +}; + +// For multi-viewport support: +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplVulkan_ViewportData +{ + bool WindowOwned; + ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only + ImGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports + + ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); } + ~ImGui_ImplVulkan_ViewportData() { } +}; + +// Vulkan data +struct ImGui_ImplVulkan_Data +{ + ImGui_ImplVulkan_InitInfo VulkanInitInfo; + VkRenderPass RenderPass; + VkDeviceSize BufferMemoryAlignment; + VkPipelineCreateFlags PipelineCreateFlags; + VkDescriptorSetLayout DescriptorSetLayout; + VkPipelineLayout PipelineLayout; + VkPipeline Pipeline; + uint32_t Subpass; + VkShaderModule ShaderModuleVert; + VkShaderModule ShaderModuleFrag; + + // Font data + VkSampler FontSampler; + VkDeviceMemory FontMemory; + VkImage FontImage; + VkImageView FontView; + VkDescriptorSet FontDescriptorSet; + VkDeviceMemory UploadBufferMemory; + VkBuffer UploadBuffer; + + // Render buffers for main window + ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers; + + ImGui_ImplVulkan_Data() + { + memset(this, 0, sizeof(*this)); + BufferMemoryAlignment = 256; + } +}; + +// Forward Declarations +bool ImGui_ImplVulkan_CreateDeviceObjects(); +void ImGui_ImplVulkan_DestroyDeviceObjects(); +void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); +void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); + +// Vulkan prototypes for use with custom loaders +// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h +#ifdef VK_NO_PROTOTYPES +static bool g_FunctionsLoaded = false; +#else +static bool g_FunctionsLoaded = true; +#endif +#ifdef VK_NO_PROTOTYPES +#define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindIndexBuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindPipeline) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindVertexBuffers) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdCopyBufferToImage) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdDrawIndexed) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPipelineBarrier) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPushConstants) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetScissor) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetViewport) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateBuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateCommandPool) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateDescriptorSetLayout) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFence) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateFramebuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateGraphicsPipelines) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateImage) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateImageView) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreatePipelineLayout) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateRenderPass) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSampler) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSemaphore) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateShaderModule) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCreateSwapchainKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyBuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyCommandPool) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyDescriptorSetLayout) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFence) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyFramebuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyImage) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyImageView) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyPipeline) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyPipelineLayout) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyRenderPass) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySampler) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySemaphore) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroyShaderModule) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySurfaceKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDestroySwapchainKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkDeviceWaitIdle) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkFlushMappedMemoryRanges) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeCommandBuffers) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkFreeMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetBufferMemoryRequirements) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetImageMemoryRequirements) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceMemoryProperties) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceSupportKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBeginRenderPass) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdEndRenderPass) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueuePresentKHR) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkEndCommandBuffer) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetFences) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \ + IMGUI_VULKAN_FUNC_MAP_MACRO(vkAcquireNextImageKHR) + +// Define function pointers +#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func; +IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF) +#undef IMGUI_VULKAN_FUNC_DEF +#endif // VK_NO_PROTOTYPES + +//----------------------------------------------------------------------------- +// SHADERS +//----------------------------------------------------------------------------- + +// Forward Declarations +static void ImGui_ImplVulkan_InitPlatformInterface(); +static void ImGui_ImplVulkan_ShutdownPlatformInterface(); + +// glsl_shader.vert, compiled with: +// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert +/* +#version 450 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; +layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc; + +out gl_PerVertex { vec4 gl_Position; }; +layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; + +void main() +{ + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); +} +*/ +static uint32_t __glsl_shader_vert_spv[] = +{ + 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015, + 0x0000001b,0x0000001c,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43, + 0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f, + 0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005, + 0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00040005,0x0000001c, + 0x736f5061,0x00000000,0x00060005,0x0000001e,0x73755075,0x6e6f4368,0x6e617473,0x00000074, + 0x00050006,0x0000001e,0x00000000,0x61635375,0x0000656c,0x00060006,0x0000001e,0x00000001, + 0x61725475,0x616c736e,0x00006574,0x00030005,0x00000020,0x00006370,0x00040047,0x0000000b, + 0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015, + 0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047, + 0x00000019,0x00000002,0x00040047,0x0000001c,0x0000001e,0x00000000,0x00050048,0x0000001e, + 0x00000000,0x00000023,0x00000000,0x00050048,0x0000001e,0x00000001,0x00000023,0x00000008, + 0x00030047,0x0000001e,0x00000002,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017, + 0x00000008,0x00000006,0x00000002,0x0004001e,0x00000009,0x00000007,0x00000008,0x00040020, + 0x0000000a,0x00000003,0x00000009,0x0004003b,0x0000000a,0x0000000b,0x00000003,0x00040015, + 0x0000000c,0x00000020,0x00000001,0x0004002b,0x0000000c,0x0000000d,0x00000000,0x00040020, + 0x0000000e,0x00000001,0x00000007,0x0004003b,0x0000000e,0x0000000f,0x00000001,0x00040020, + 0x00000011,0x00000003,0x00000007,0x0004002b,0x0000000c,0x00000013,0x00000001,0x00040020, + 0x00000014,0x00000001,0x00000008,0x0004003b,0x00000014,0x00000015,0x00000001,0x00040020, + 0x00000017,0x00000003,0x00000008,0x0003001e,0x00000019,0x00000007,0x00040020,0x0000001a, + 0x00000003,0x00000019,0x0004003b,0x0000001a,0x0000001b,0x00000003,0x0004003b,0x00000014, + 0x0000001c,0x00000001,0x0004001e,0x0000001e,0x00000008,0x00000008,0x00040020,0x0000001f, + 0x00000009,0x0000001e,0x0004003b,0x0000001f,0x00000020,0x00000009,0x00040020,0x00000021, + 0x00000009,0x00000008,0x0004002b,0x00000006,0x00000028,0x00000000,0x0004002b,0x00000006, + 0x00000029,0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012, + 0x0000000b,0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016, + 0x00000015,0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018, + 0x00000016,0x0004003d,0x00000008,0x0000001d,0x0000001c,0x00050041,0x00000021,0x00000022, + 0x00000020,0x0000000d,0x0004003d,0x00000008,0x00000023,0x00000022,0x00050085,0x00000008, + 0x00000024,0x0000001d,0x00000023,0x00050041,0x00000021,0x00000025,0x00000020,0x00000013, + 0x0004003d,0x00000008,0x00000026,0x00000025,0x00050081,0x00000008,0x00000027,0x00000024, + 0x00000026,0x00050051,0x00000006,0x0000002a,0x00000027,0x00000000,0x00050051,0x00000006, + 0x0000002b,0x00000027,0x00000001,0x00070050,0x00000007,0x0000002c,0x0000002a,0x0000002b, + 0x00000028,0x00000029,0x00050041,0x00000011,0x0000002d,0x0000001b,0x0000000d,0x0003003e, + 0x0000002d,0x0000002c,0x000100fd,0x00010038 +}; + +// glsl_shader.frag, compiled with: +// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +/* +#version 450 core +layout(location = 0) out vec4 fColor; +layout(set=0, binding=0) uniform sampler2D sTexture; +layout(location = 0) in struct { vec4 Color; vec2 UV; } In; +void main() +{ + fColor = In.Color * texture(sTexture, In.UV.st); +} +*/ +static uint32_t __glsl_shader_frag_spv[] = +{ + 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000, + 0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001, + 0x00005655,0x00030005,0x0000000d,0x00006e49,0x00050005,0x00000016,0x78655473,0x65727574, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,0x0000001e, + 0x00000000,0x00040047,0x00000016,0x00000022,0x00000000,0x00040047,0x00000016,0x00000021, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003, + 0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006, + 0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,0x00000001, + 0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,0x00000020, + 0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,0x00000001, + 0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x0003001b,0x00000014,0x00000013,0x00040020,0x00000015,0x00000000, + 0x00000014,0x0004003b,0x00000015,0x00000016,0x00000000,0x0004002b,0x0000000e,0x00000018, + 0x00000001,0x00040020,0x00000019,0x00000001,0x0000000a,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,0x00000010,0x00000011,0x0000000d, + 0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,0x0004003d,0x00000014,0x00000017, + 0x00000016,0x00050041,0x00000019,0x0000001a,0x0000000d,0x00000018,0x0004003d,0x0000000a, + 0x0000001b,0x0000001a,0x00050057,0x00000007,0x0000001c,0x00000017,0x0000001b,0x00050085, + 0x00000007,0x0000001d,0x00000012,0x0000001c,0x0003003e,0x00000009,0x0000001d,0x000100fd, + 0x00010038 +}; + +//----------------------------------------------------------------------------- +// FUNCTIONS +//----------------------------------------------------------------------------- + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not tested and probably dysfunctional in this backend. +static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkPhysicalDeviceMemoryProperties prop; + vkGetPhysicalDeviceMemoryProperties(v->PhysicalDevice, &prop); + for (uint32_t i = 0; i < prop.memoryTypeCount; i++) + if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1 << i)) + return i; + return 0xFFFFFFFF; // Unable to find memoryType +} + +static void check_vk_result(VkResult err) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (!bd) + return; + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + if (v->CheckVkResultFn) + v->CheckVkResultFn(err); +} + +static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkResult err; + if (buffer != VK_NULL_HANDLE) + vkDestroyBuffer(v->Device, buffer, v->Allocator); + if (buffer_memory != VK_NULL_HANDLE) + vkFreeMemory(v->Device, buffer_memory, v->Allocator); + + VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / bd->BufferMemoryAlignment + 1) * bd->BufferMemoryAlignment; + VkBufferCreateInfo buffer_info = {}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = vertex_buffer_size_aligned; + buffer_info.usage = usage; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer); + check_vk_result(err); + + VkMemoryRequirements req; + vkGetBufferMemoryRequirements(v->Device, buffer, &req); + bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment; + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); + err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &buffer_memory); + check_vk_result(err); + + err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0); + check_vk_result(err); + p_buffer_size = req.size; +} + +static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + + // Bind pipeline: + { + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + } + + // Bind Vertex And Index Buffer: + if (draw_data->TotalVtxCount > 0) + { + VkBuffer vertex_buffers[1] = { rb->VertexBuffer }; + VkDeviceSize vertex_offset[1] = { 0 }; + vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset); + vkCmdBindIndexBuffer(command_buffer, rb->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); + } + + // Setup viewport: + { + VkViewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = (float)fb_width; + viewport.height = (float)fb_height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); + } + + // Setup scale and translation: + // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + { + float scale[2]; + scale[0] = 2.0f / draw_data->DisplaySize.x; + scale[1] = 2.0f / draw_data->DisplaySize.y; + float translate[2]; + translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0]; + translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1]; + vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); + vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); + } +} + +// Render function +void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + if (pipeline == VK_NULL_HANDLE) + pipeline = bd->Pipeline; + + // Allocate array to store enough vertex/index buffers. Each unique viewport gets its own storage. + ImGui_ImplVulkan_ViewportData* viewport_renderer_data = (ImGui_ImplVulkan_ViewportData*)draw_data->OwnerViewport->RendererUserData; + IM_ASSERT(viewport_renderer_data != NULL); + ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers; + if (wrb->FrameRenderBuffers == NULL) + { + wrb->Index = 0; + wrb->Count = v->ImageCount; + wrb->FrameRenderBuffers = (ImGui_ImplVulkanH_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count); + memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count); + } + IM_ASSERT(wrb->Count == v->ImageCount); + wrb->Index = (wrb->Index + 1) % wrb->Count; + ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index]; + + if (draw_data->TotalVtxCount > 0) + { + // Create or resize the vertex/index buffers + size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); + size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); + if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) + CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size) + CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + + // Upload vertex/index data into a single contiguous GPU buffer + ImDrawVert* vtx_dst = NULL; + ImDrawIdx* idx_dst = NULL; + VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst)); + check_vk_result(err); + err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst)); + check_vk_result(err); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + VkMappedMemoryRange range[2] = {}; + range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[0].memory = rb->VertexBufferMemory; + range[0].size = VK_WHOLE_SIZE; + range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[1].memory = rb->IndexBufferMemory; + range[1].size = VK_WHOLE_SIZE; + err = vkFlushMappedMemoryRanges(v->Device, 2, range); + check_vk_result(err); + vkUnmapMemory(v->Device, rb->VertexBufferMemory); + vkUnmapMemory(v->Device, rb->IndexBufferMemory); + } + + // Setup desired Vulkan state + ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + + // Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds + if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } + if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } + if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } + if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle + VkRect2D scissor; + scissor.offset.x = (int32_t)(clip_min.x); + scissor.offset.y = (int32_t)(clip_min.y); + scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x); + scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y); + vkCmdSetScissor(command_buffer, 0, 1, &scissor); + + // Bind DescriptorSet with font or user texture + VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId }; + if (sizeof(ImTextureID) < sizeof(ImU64)) + { + // We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used. + IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet); + desc_set[0] = bd->FontDescriptorSet; + } + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, NULL); + + // Draw + vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } + + // Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called. + // Our last values will leak into user/application rendering IF: + // - Your app uses a pipeline with VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR dynamic state + // - And you forgot to call vkCmdSetViewport() and vkCmdSetScissor() yourself to explicitely set that state. + // If you use VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR you are responsible for setting the values before rendering. + // In theory we should aim to backup/restore those values but I am not sure this is possible. + // We perform a call to vkCmdSetScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644) + VkRect2D scissor = { { 0, 0 }, { (uint32_t)fb_width, (uint32_t)fb_height } }; + vkCmdSetScissor(command_buffer, 0, 1, &scissor); +} + +bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + size_t upload_size = width * height * 4 * sizeof(char); + + VkResult err; + + // Create the Image: + { + VkImageCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + info.imageType = VK_IMAGE_TYPE_2D; + info.format = VK_FORMAT_R8G8B8A8_UNORM; + info.extent.width = width; + info.extent.height = height; + info.extent.depth = 1; + info.mipLevels = 1; + info.arrayLayers = 1; + info.samples = VK_SAMPLE_COUNT_1_BIT; + info.tiling = VK_IMAGE_TILING_OPTIMAL; + info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + err = vkCreateImage(v->Device, &info, v->Allocator, &bd->FontImage); + check_vk_result(err); + VkMemoryRequirements req; + vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req); + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits); + err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->FontMemory); + check_vk_result(err); + err = vkBindImageMemory(v->Device, bd->FontImage, bd->FontMemory, 0); + check_vk_result(err); + } + + // Create the Image View: + { + VkImageViewCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + info.image = bd->FontImage; + info.viewType = VK_IMAGE_VIEW_TYPE_2D; + info.format = VK_FORMAT_R8G8B8A8_UNORM; + info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + info.subresourceRange.levelCount = 1; + info.subresourceRange.layerCount = 1; + err = vkCreateImageView(v->Device, &info, v->Allocator, &bd->FontView); + check_vk_result(err); + } + + // Create the Descriptor Set: + bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // Create the Upload Buffer: + { + VkBufferCreateInfo buffer_info = {}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = upload_size; + buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &bd->UploadBuffer); + check_vk_result(err); + VkMemoryRequirements req; + vkGetBufferMemoryRequirements(v->Device, bd->UploadBuffer, &req); + bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment; + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); + err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->UploadBufferMemory); + check_vk_result(err); + err = vkBindBufferMemory(v->Device, bd->UploadBuffer, bd->UploadBufferMemory, 0); + check_vk_result(err); + } + + // Upload to Buffer: + { + char* map = NULL; + err = vkMapMemory(v->Device, bd->UploadBufferMemory, 0, upload_size, 0, (void**)(&map)); + check_vk_result(err); + memcpy(map, pixels, upload_size); + VkMappedMemoryRange range[1] = {}; + range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[0].memory = bd->UploadBufferMemory; + range[0].size = upload_size; + err = vkFlushMappedMemoryRanges(v->Device, 1, range); + check_vk_result(err); + vkUnmapMemory(v->Device, bd->UploadBufferMemory); + } + + // Copy to Image: + { + VkImageMemoryBarrier copy_barrier[1] = {}; + copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + copy_barrier[0].image = bd->FontImage; + copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_barrier[0].subresourceRange.levelCount = 1; + copy_barrier[0].subresourceRange.layerCount = 1; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier); + + VkBufferImageCopy region = {}; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.width = width; + region.imageExtent.height = height; + region.imageExtent.depth = 1; + vkCmdCopyBufferToImage(command_buffer, bd->UploadBuffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + VkImageMemoryBarrier use_barrier[1] = {}; + use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + use_barrier[0].image = bd->FontImage; + use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + use_barrier[0].subresourceRange.levelCount = 1; + use_barrier[0].subresourceRange.layerCount = 1; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier); + } + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet); + + return true; +} + +static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator) +{ + // Create the shader modules + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (bd->ShaderModuleVert == VK_NULL_HANDLE) + { + VkShaderModuleCreateInfo vert_info = {}; + vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + vert_info.codeSize = sizeof(__glsl_shader_vert_spv); + vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv; + VkResult err = vkCreateShaderModule(device, &vert_info, allocator, &bd->ShaderModuleVert); + check_vk_result(err); + } + if (bd->ShaderModuleFrag == VK_NULL_HANDLE) + { + VkShaderModuleCreateInfo frag_info = {}; + frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + frag_info.codeSize = sizeof(__glsl_shader_frag_spv); + frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv; + VkResult err = vkCreateShaderModule(device, &frag_info, allocator, &bd->ShaderModuleFrag); + check_vk_result(err); + } +} + +static void ImGui_ImplVulkan_CreateFontSampler(VkDevice device, const VkAllocationCallbacks* allocator) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (bd->FontSampler) + return; + + VkSamplerCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + info.magFilter = VK_FILTER_LINEAR; + info.minFilter = VK_FILTER_LINEAR; + info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.minLod = -1000; + info.maxLod = 1000; + info.maxAnisotropy = 1.0f; + VkResult err = vkCreateSampler(device, &info, allocator, &bd->FontSampler); + check_vk_result(err); +} + +static void ImGui_ImplVulkan_CreateDescriptorSetLayout(VkDevice device, const VkAllocationCallbacks* allocator) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (bd->DescriptorSetLayout) + return; + + ImGui_ImplVulkan_CreateFontSampler(device, allocator); + VkSampler sampler[1] = { bd->FontSampler }; + VkDescriptorSetLayoutBinding binding[1] = {}; + binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + binding[0].descriptorCount = 1; + binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + binding[0].pImmutableSamplers = sampler; + VkDescriptorSetLayoutCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + info.bindingCount = 1; + info.pBindings = binding; + VkResult err = vkCreateDescriptorSetLayout(device, &info, allocator, &bd->DescriptorSetLayout); + check_vk_result(err); +} + +static void ImGui_ImplVulkan_CreatePipelineLayout(VkDevice device, const VkAllocationCallbacks* allocator) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (bd->PipelineLayout) + return; + + // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix + ImGui_ImplVulkan_CreateDescriptorSetLayout(device, allocator); + VkPushConstantRange push_constants[1] = {}; + push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constants[0].offset = sizeof(float) * 0; + push_constants[0].size = sizeof(float) * 4; + VkDescriptorSetLayout set_layout[1] = { bd->DescriptorSetLayout }; + VkPipelineLayoutCreateInfo layout_info = {}; + layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_info.setLayoutCount = 1; + layout_info.pSetLayouts = set_layout; + layout_info.pushConstantRangeCount = 1; + layout_info.pPushConstantRanges = push_constants; + VkResult err = vkCreatePipelineLayout(device, &layout_info, allocator, &bd->PipelineLayout); + check_vk_result(err); +} + +static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_CreateShaderModules(device, allocator); + + VkPipelineShaderStageCreateInfo stage[2] = {}; + stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stage[0].module = bd->ShaderModuleVert; + stage[0].pName = "main"; + stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stage[1].module = bd->ShaderModuleFrag; + stage[1].pName = "main"; + + VkVertexInputBindingDescription binding_desc[1] = {}; + binding_desc[0].stride = sizeof(ImDrawVert); + binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + VkVertexInputAttributeDescription attribute_desc[3] = {}; + attribute_desc[0].location = 0; + attribute_desc[0].binding = binding_desc[0].binding; + attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[0].offset = IM_OFFSETOF(ImDrawVert, pos); + attribute_desc[1].location = 1; + attribute_desc[1].binding = binding_desc[0].binding; + attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[1].offset = IM_OFFSETOF(ImDrawVert, uv); + attribute_desc[2].location = 2; + attribute_desc[2].binding = binding_desc[0].binding; + attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; + attribute_desc[2].offset = IM_OFFSETOF(ImDrawVert, col); + + VkPipelineVertexInputStateCreateInfo vertex_info = {}; + vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_info.vertexBindingDescriptionCount = 1; + vertex_info.pVertexBindingDescriptions = binding_desc; + vertex_info.vertexAttributeDescriptionCount = 3; + vertex_info.pVertexAttributeDescriptions = attribute_desc; + + VkPipelineInputAssemblyStateCreateInfo ia_info = {}; + ia_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + VkPipelineViewportStateCreateInfo viewport_info = {}; + viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_info.viewportCount = 1; + viewport_info.scissorCount = 1; + + VkPipelineRasterizationStateCreateInfo raster_info = {}; + raster_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + raster_info.polygonMode = VK_POLYGON_MODE_FILL; + raster_info.cullMode = VK_CULL_MODE_NONE; + raster_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + raster_info.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo ms_info = {}; + ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_attachment[1] = {}; + color_attachment[0].blendEnable = VK_TRUE; + color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineDepthStencilStateCreateInfo depth_info = {}; + depth_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + + VkPipelineColorBlendStateCreateInfo blend_info = {}; + blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + blend_info.attachmentCount = 1; + blend_info.pAttachments = color_attachment; + + VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamic_state = {}; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states); + dynamic_state.pDynamicStates = dynamic_states; + + ImGui_ImplVulkan_CreatePipelineLayout(device, allocator); + + VkGraphicsPipelineCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + info.flags = bd->PipelineCreateFlags; + info.stageCount = 2; + info.pStages = stage; + info.pVertexInputState = &vertex_info; + info.pInputAssemblyState = &ia_info; + info.pViewportState = &viewport_info; + info.pRasterizationState = &raster_info; + info.pMultisampleState = &ms_info; + info.pDepthStencilState = &depth_info; + info.pColorBlendState = &blend_info; + info.pDynamicState = &dynamic_state; + info.layout = bd->PipelineLayout; + info.renderPass = renderPass; + info.subpass = subpass; + VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline); + check_vk_result(err); +} + +bool ImGui_ImplVulkan_CreateDeviceObjects() +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkResult err; + + if (!bd->FontSampler) + { + VkSamplerCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + info.magFilter = VK_FILTER_LINEAR; + info.minFilter = VK_FILTER_LINEAR; + info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.minLod = -1000; + info.maxLod = 1000; + info.maxAnisotropy = 1.0f; + err = vkCreateSampler(v->Device, &info, v->Allocator, &bd->FontSampler); + check_vk_result(err); + } + + if (!bd->DescriptorSetLayout) + { + VkSampler sampler[1] = {bd->FontSampler}; + VkDescriptorSetLayoutBinding binding[1] = {}; + binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + binding[0].descriptorCount = 1; + binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + binding[0].pImmutableSamplers = sampler; + VkDescriptorSetLayoutCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + info.bindingCount = 1; + info.pBindings = binding; + err = vkCreateDescriptorSetLayout(v->Device, &info, v->Allocator, &bd->DescriptorSetLayout); + check_vk_result(err); + } + + if (!bd->PipelineLayout) + { + // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix + VkPushConstantRange push_constants[1] = {}; + push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constants[0].offset = sizeof(float) * 0; + push_constants[0].size = sizeof(float) * 4; + VkDescriptorSetLayout set_layout[1] = { bd->DescriptorSetLayout }; + VkPipelineLayoutCreateInfo layout_info = {}; + layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_info.setLayoutCount = 1; + layout_info.pSetLayouts = set_layout; + layout_info.pushConstantRangeCount = 1; + layout_info.pPushConstantRanges = push_constants; + err = vkCreatePipelineLayout(v->Device, &layout_info, v->Allocator, &bd->PipelineLayout); + check_vk_result(err); + } + + ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, bd->RenderPass, v->MSAASamples, &bd->Pipeline, bd->Subpass); + + return true; +} + +void ImGui_ImplVulkan_DestroyFontUploadObjects() +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + if (bd->UploadBuffer) + { + vkDestroyBuffer(v->Device, bd->UploadBuffer, v->Allocator); + bd->UploadBuffer = VK_NULL_HANDLE; + } + if (bd->UploadBufferMemory) + { + vkFreeMemory(v->Device, bd->UploadBufferMemory, v->Allocator); + bd->UploadBufferMemory = VK_NULL_HANDLE; + } +} + +void ImGui_ImplVulkan_DestroyDeviceObjects() +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator); + ImGui_ImplVulkan_DestroyFontUploadObjects(); + + if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; } + if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; } + if (bd->FontView) { vkDestroyImageView(v->Device, bd->FontView, v->Allocator); bd->FontView = VK_NULL_HANDLE; } + if (bd->FontImage) { vkDestroyImage(v->Device, bd->FontImage, v->Allocator); bd->FontImage = VK_NULL_HANDLE; } + if (bd->FontMemory) { vkFreeMemory(v->Device, bd->FontMemory, v->Allocator); bd->FontMemory = VK_NULL_HANDLE; } + if (bd->FontSampler) { vkDestroySampler(v->Device, bd->FontSampler, v->Allocator); bd->FontSampler = VK_NULL_HANDLE; } + if (bd->DescriptorSetLayout) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayout, v->Allocator); bd->DescriptorSetLayout = VK_NULL_HANDLE; } + if (bd->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; } + if (bd->Pipeline) { vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator); bd->Pipeline = VK_NULL_HANDLE; } +} + +bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data) +{ + // Load function pointers + // You can use the default Vulkan loader using: + // ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); }); + // But this would be equivalent to not setting VK_NO_PROTOTYPES. +#ifdef VK_NO_PROTOTYPES +#define IMGUI_VULKAN_FUNC_LOAD(func) \ + func = reinterpret_cast(loader_func(#func, user_data)); \ + if (func == NULL) \ + return false; + IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD) +#undef IMGUI_VULKAN_FUNC_LOAD +#else + IM_UNUSED(loader_func); + IM_UNUSED(user_data); +#endif + g_FunctionsLoaded = true; + return true; +} + +bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass) +{ + IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); + + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplVulkan_Data* bd = IM_NEW(ImGui_ImplVulkan_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_vulkan"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + + IM_ASSERT(info->Instance != VK_NULL_HANDLE); + IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE); + IM_ASSERT(info->Device != VK_NULL_HANDLE); + IM_ASSERT(info->Queue != VK_NULL_HANDLE); + IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); + IM_ASSERT(info->MinImageCount >= 2); + IM_ASSERT(info->ImageCount >= info->MinImageCount); + IM_ASSERT(render_pass != VK_NULL_HANDLE); + + bd->VulkanInitInfo = *info; + bd->RenderPass = render_pass; + bd->Subpass = info->Subpass; + + ImGui_ImplVulkan_CreateDeviceObjects(); + + // Our render function expect RendererUserData to be storing the window render buffer we need (for the main viewport we won't use ->Window) + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)(); + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplVulkan_InitPlatformInterface(); + + return true; +} + +void ImGui_ImplVulkan_Shutdown() +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + // First destroy objects in all viewports + ImGui_ImplVulkan_DestroyDeviceObjects(); + + // Manually delete main viewport render data in-case we haven't initialized for viewports + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)main_viewport->RendererUserData) + IM_DELETE(vd); + main_viewport->RendererUserData = NULL; + + // Clean up windows + ImGui_ImplVulkan_ShutdownPlatformInterface(); + + io.BackendRendererName = NULL; + io.BackendRendererUserData = NULL; + IM_DELETE(bd); +} + +void ImGui_ImplVulkan_NewFrame() +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplVulkan_Init()?"); + IM_UNUSED(bd); +} + +void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + IM_ASSERT(min_image_count >= 2); + if (bd->VulkanInitInfo.MinImageCount == min_image_count) + return; + + IM_ASSERT(0); // FIXME-VIEWPORT: Unsupported. Need to recreate all swap chains! + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkResult err = vkDeviceWaitIdle(v->Device); + check_vk_result(err); + ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator); + + bd->VulkanInitInfo.MinImageCount = min_image_count; +} + +// Register a texture +// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions. +VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + + // Create Descriptor Set: + VkDescriptorSet descriptor_set; + { + VkDescriptorSetAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = v->DescriptorPool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = &bd->DescriptorSetLayout; + VkResult err = vkAllocateDescriptorSets(v->Device, &alloc_info, &descriptor_set); + check_vk_result(err); + } + + // Update the Descriptor Set: + { + VkDescriptorImageInfo desc_image[1] = {}; + desc_image[0].sampler = sampler; + desc_image[0].imageView = image_view; + desc_image[0].imageLayout = image_layout; + VkWriteDescriptorSet write_desc[1] = {}; + write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_desc[0].dstSet = descriptor_set; + write_desc[0].descriptorCount = 1; + write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_desc[0].pImageInfo = desc_image; + vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL); + } + return descriptor_set; +} + +//------------------------------------------------------------------------- +// Internal / Miscellaneous Vulkan Helpers +// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.) +//------------------------------------------------------------------------- +// You probably do NOT need to use or care about those functions. +// Those functions only exist because: +// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files. +// 2) the upcoming multi-viewport feature will need them internally. +// Generally we avoid exposing any kind of superfluous high-level helpers in the backends, +// but it is too much code to duplicate everywhere so we exceptionally expose them. +// +// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). +// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. +// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) +//------------------------------------------------------------------------- + +VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space) +{ + IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); + IM_ASSERT(request_formats != NULL); + IM_ASSERT(request_formats_count > 0); + + // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation + // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format + // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, + // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. + uint32_t avail_count; + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, NULL); + ImVector avail_format; + avail_format.resize((int)avail_count); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, avail_format.Data); + + // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available + if (avail_count == 1) + { + if (avail_format[0].format == VK_FORMAT_UNDEFINED) + { + VkSurfaceFormatKHR ret; + ret.format = request_formats[0]; + ret.colorSpace = request_color_space; + return ret; + } + else + { + // No point in searching another format + return avail_format[0]; + } + } + else + { + // Request several formats, the first found will be used + for (int request_i = 0; request_i < request_formats_count; request_i++) + for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++) + if (avail_format[avail_i].format == request_formats[request_i] && avail_format[avail_i].colorSpace == request_color_space) + return avail_format[avail_i]; + + // If none of the requested image formats could be found, use the first available + return avail_format[0]; + } +} + +VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count) +{ + IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); + IM_ASSERT(request_modes != NULL); + IM_ASSERT(request_modes_count > 0); + + // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory + uint32_t avail_count = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, NULL); + ImVector avail_modes; + avail_modes.resize((int)avail_count); + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, avail_modes.Data); + //for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++) + // printf("[vulkan] avail_modes[%d] = %d\n", avail_i, avail_modes[avail_i]); + + for (int request_i = 0; request_i < request_modes_count; request_i++) + for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++) + if (request_modes[request_i] == avail_modes[avail_i]) + return request_modes[request_i]; + + return VK_PRESENT_MODE_FIFO_KHR; // Always available +} + +void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator) +{ + IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE); + (void)physical_device; + (void)allocator; + + // Create Command Buffers + VkResult err; + for (uint32_t i = 0; i < wd->ImageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; + ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i]; + { + VkCommandPoolCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + info.queueFamilyIndex = queue_family; + err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool); + check_vk_result(err); + } + { + VkCommandBufferAllocateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + info.commandPool = fd->CommandPool; + info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + info.commandBufferCount = 1; + err = vkAllocateCommandBuffers(device, &info, &fd->CommandBuffer); + check_vk_result(err); + } + { + VkFenceCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + info.flags = VK_FENCE_CREATE_SIGNALED_BIT; + err = vkCreateFence(device, &info, allocator, &fd->Fence); + check_vk_result(err); + } + { + VkSemaphoreCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + err = vkCreateSemaphore(device, &info, allocator, &fsd->ImageAcquiredSemaphore); + check_vk_result(err); + err = vkCreateSemaphore(device, &info, allocator, &fsd->RenderCompleteSemaphore); + check_vk_result(err); + } + } +} + +int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode) +{ + if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) + return 3; + if (present_mode == VK_PRESENT_MODE_FIFO_KHR || present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR) + return 2; + if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) + return 1; + IM_ASSERT(0); + return 1; +} + +// Also destroy old swap chain and in-flight frames data, if any. +void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count) +{ + VkResult err; + VkSwapchainKHR old_swapchain = wd->Swapchain; + wd->Swapchain = VK_NULL_HANDLE; + err = vkDeviceWaitIdle(device); + check_vk_result(err); + + // We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one. + // Destroy old Framebuffer + for (uint32_t i = 0; i < wd->ImageCount; i++) + { + ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); + } + IM_FREE(wd->Frames); + IM_FREE(wd->FrameSemaphores); + wd->Frames = NULL; + wd->FrameSemaphores = NULL; + wd->ImageCount = 0; + if (wd->RenderPass) + vkDestroyRenderPass(device, wd->RenderPass, allocator); + if (wd->Pipeline) + vkDestroyPipeline(device, wd->Pipeline, allocator); + + // If min image count was not specified, request different count of images dependent on selected present mode + if (min_image_count == 0) + min_image_count = ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(wd->PresentMode); + + // Create Swapchain + { + VkSwapchainCreateInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + info.surface = wd->Surface; + info.minImageCount = min_image_count; + info.imageFormat = wd->SurfaceFormat.format; + info.imageColorSpace = wd->SurfaceFormat.colorSpace; + info.imageArrayLayers = 1; + info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family + info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + info.presentMode = wd->PresentMode; + info.clipped = VK_TRUE; + info.oldSwapchain = old_swapchain; + VkSurfaceCapabilitiesKHR cap; + err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, wd->Surface, &cap); + check_vk_result(err); + if (info.minImageCount < cap.minImageCount) + info.minImageCount = cap.minImageCount; + else if (cap.maxImageCount != 0 && info.minImageCount > cap.maxImageCount) + info.minImageCount = cap.maxImageCount; + + if (cap.currentExtent.width == 0xffffffff) + { + info.imageExtent.width = wd->Width = w; + info.imageExtent.height = wd->Height = h; + } + else + { + info.imageExtent.width = wd->Width = cap.currentExtent.width; + info.imageExtent.height = wd->Height = cap.currentExtent.height; + } + err = vkCreateSwapchainKHR(device, &info, allocator, &wd->Swapchain); + check_vk_result(err); + err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, NULL); + check_vk_result(err); + VkImage backbuffers[16] = {}; + IM_ASSERT(wd->ImageCount >= min_image_count); + IM_ASSERT(wd->ImageCount < IM_ARRAYSIZE(backbuffers)); + err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers); + check_vk_result(err); + + IM_ASSERT(wd->Frames == NULL); + wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount); + wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->ImageCount); + memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount); + memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->ImageCount); + for (uint32_t i = 0; i < wd->ImageCount; i++) + wd->Frames[i].Backbuffer = backbuffers[i]; + } + if (old_swapchain) + vkDestroySwapchainKHR(device, old_swapchain, allocator); + + // Create the Render Pass + { + VkAttachmentDescription attachment = {}; + attachment.format = wd->SurfaceFormat.format; + attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.loadOp = wd->ClearEnable ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + VkAttachmentReference color_attachment = {}; + color_attachment.attachment = 0; + color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkSubpassDescription subpass = {}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &color_attachment; + VkSubpassDependency dependency = {}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + VkRenderPassCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + info.attachmentCount = 1; + info.pAttachments = &attachment; + info.subpassCount = 1; + info.pSubpasses = &subpass; + info.dependencyCount = 1; + info.pDependencies = &dependency; + err = vkCreateRenderPass(device, &info, allocator, &wd->RenderPass); + check_vk_result(err); + + // We do not create a pipeline by default as this is also used by examples' main.cpp, + // but secondary viewport in multi-viewport mode may want to create one with: + //ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, bd->Subpass); + } + + // Create The Image Views + { + VkImageViewCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + info.viewType = VK_IMAGE_VIEW_TYPE_2D; + info.format = wd->SurfaceFormat.format; + info.components.r = VK_COMPONENT_SWIZZLE_R; + info.components.g = VK_COMPONENT_SWIZZLE_G; + info.components.b = VK_COMPONENT_SWIZZLE_B; + info.components.a = VK_COMPONENT_SWIZZLE_A; + VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + info.subresourceRange = image_range; + for (uint32_t i = 0; i < wd->ImageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; + info.image = fd->Backbuffer; + err = vkCreateImageView(device, &info, allocator, &fd->BackbufferView); + check_vk_result(err); + } + } + + // Create Framebuffer + { + VkImageView attachment[1]; + VkFramebufferCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + info.renderPass = wd->RenderPass; + info.attachmentCount = 1; + info.pAttachments = attachment; + info.width = wd->Width; + info.height = wd->Height; + info.layers = 1; + for (uint32_t i = 0; i < wd->ImageCount; i++) + { + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; + attachment[0] = fd->BackbufferView; + err = vkCreateFramebuffer(device, &info, allocator, &fd->Framebuffer); + check_vk_result(err); + } + } +} + +// Create or resize window +void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) +{ + IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!"); + (void)instance; + ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count); + //ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, g_VulkanInitInfo.Subpass); + ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator); +} + +void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator) +{ + vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) + //vkQueueWaitIdle(bd->Queue); + + for (uint32_t i = 0; i < wd->ImageCount; i++) + { + ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); + } + IM_FREE(wd->Frames); + IM_FREE(wd->FrameSemaphores); + wd->Frames = NULL; + wd->FrameSemaphores = NULL; + vkDestroyPipeline(device, wd->Pipeline, allocator); + vkDestroyRenderPass(device, wd->RenderPass, allocator); + vkDestroySwapchainKHR(device, wd->Swapchain, allocator); + vkDestroySurfaceKHR(instance, wd->Surface, allocator); + + *wd = ImGui_ImplVulkanH_Window(); +} + +void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator) +{ + vkDestroyFence(device, fd->Fence, allocator); + vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer); + vkDestroyCommandPool(device, fd->CommandPool, allocator); + fd->Fence = VK_NULL_HANDLE; + fd->CommandBuffer = VK_NULL_HANDLE; + fd->CommandPool = VK_NULL_HANDLE; + + vkDestroyImageView(device, fd->BackbufferView, allocator); + vkDestroyFramebuffer(device, fd->Framebuffer, allocator); +} + +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) +{ + vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator); + vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator); + fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; +} + +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator) +{ + if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; } + if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; } + if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; } + if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; } + buffers->VertexBufferSize = 0; + buffers->IndexBufferSize = 0; +} + +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator) +{ + for (uint32_t n = 0; n < buffers->Count; n++) + ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator); + IM_FREE(buffers->FrameRenderBuffers); + buffers->FrameRenderBuffers = NULL; + buffers->Index = 0; + buffers->Count = 0; +} + +void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator) +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int n = 0; n < platform_io.Viewports.Size; n++) + if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)platform_io.Viewports[n]->RendererUserData) + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_ViewportData* vd = IM_NEW(ImGui_ImplVulkan_ViewportData)(); + viewport->RendererUserData = vd; + ImGui_ImplVulkanH_Window* wd = &vd->Window; + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + + // Create surface + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + VkResult err = (VkResult)platform_io.Platform_CreateVkSurface(viewport, (ImU64)v->Instance, (const void*)v->Allocator, (ImU64*)&wd->Surface); + check_vk_result(err); + + // Check for WSI support + VkBool32 res; + vkGetPhysicalDeviceSurfaceSupportKHR(v->PhysicalDevice, v->QueueFamily, wd->Surface, &res); + if (res != VK_TRUE) + { + IM_ASSERT(0); // Error: no WSI support on physical device + return; + } + + // Select Surface Format + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); + + // Select Present Mode + // FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1) + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; + wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(v->PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); + //printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode); + + // Create SwapChain, RenderPass, Framebuffer, etc. + wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true; + ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount); + vd->WindowOwned = true; +} + +static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport) +{ + // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData) + { + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + if (vd->WindowOwned) + ImGui_ImplVulkanH_DestroyWindow(v->Instance, v->Device, &vd->Window, v->Allocator); + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator); + IM_DELETE(vd); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData; + if (vd == NULL) // This is NULL for the main viewport (which is left to the user/app to handle) + return; + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true; + ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount); +} + +static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData; + ImGui_ImplVulkanH_Window* wd = &vd->Window; + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkResult err; + + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex]; + { + { + err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex); + check_vk_result(err); + fd = &wd->Frames[wd->FrameIndex]; + } + for (;;) + { + err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100); + if (err == VK_SUCCESS) break; + if (err == VK_TIMEOUT) continue; + check_vk_result(err); + } + { + err = vkResetCommandPool(v->Device, fd->CommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(fd->CommandBuffer, &info); + check_vk_result(err); + } + { + ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); + + VkRenderPassBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = wd->RenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = wd->Width; + info.renderArea.extent.height = wd->Height; + info.clearValueCount = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? 0 : 1; + info.pClearValues = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? NULL : &wd->ClearValue; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } + } + + ImGui_ImplVulkan_RenderDrawData(viewport->DrawData, fd->CommandBuffer, wd->Pipeline); + + { + vkCmdEndRenderPass(fd->CommandBuffer); + { + VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &fsd->ImageAcquiredSemaphore; + info.pWaitDstStageMask = &wait_stage; + info.commandBufferCount = 1; + info.pCommandBuffers = &fd->CommandBuffer; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &fsd->RenderCompleteSemaphore; + + err = vkEndCommandBuffer(fd->CommandBuffer); + check_vk_result(err); + err = vkResetFences(v->Device, 1, &fd->Fence); + check_vk_result(err); + err = vkQueueSubmit(v->Queue, 1, &info, fd->Fence); + check_vk_result(err); + } + } +} + +static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData; + ImGui_ImplVulkanH_Window* wd = &vd->Window; + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + + VkResult err; + uint32_t present_index = wd->FrameIndex; + + ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex]; + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &fsd->RenderCompleteSemaphore; + info.swapchainCount = 1; + info.pSwapchains = &wd->Swapchain; + info.pImageIndices = &present_index; + err = vkQueuePresentKHR(v->Queue, &info); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount); + else + check_vk_result(err); + + wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // This is for the next vkWaitForFences() + wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores +} + +void ImGui_ImplVulkan_InitPlatformInterface() +{ + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + IM_ASSERT(platform_io.Platform_CreateVkSurface != NULL && "Platform needs to setup the CreateVkSurface handler."); + platform_io.Renderer_CreateWindow = ImGui_ImplVulkan_CreateWindow; + platform_io.Renderer_DestroyWindow = ImGui_ImplVulkan_DestroyWindow; + platform_io.Renderer_SetWindowSize = ImGui_ImplVulkan_SetWindowSize; + platform_io.Renderer_RenderWindow = ImGui_ImplVulkan_RenderWindow; + platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers; +} + +void ImGui_ImplVulkan_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.h new file mode 100644 index 000000000..06dd495a5 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_vulkan.h @@ -0,0 +1,156 @@ +// dear imgui: Renderer Backend for Vulkan +// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. +// [x] Platform: Multi-viewport / platform windows. With issues (flickering when creating a new viewport). +// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. + +// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. +// See imgui_impl_vulkan.cpp file for details. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. +// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ + +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. +// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// You will use those if you want to use this rendering backend in your engine/app. +// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by +// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. +// Read comments in imgui_impl_vulkan.h. + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +// [Configuration] in order to use a custom Vulkan function loader: +// (1) You'll need to disable default Vulkan function prototypes. +// We provide a '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' convenience configuration flag. +// In order to make sure this is visible from the imgui_impl_vulkan.cpp compilation unit: +// - Add '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' in your imconfig.h file +// - Or as a compilation flag in your build system +// - Or uncomment here (not recommended because you'd be modifying imgui sources!) +// - Do not simply add it in a .cpp file! +// (2) Call ImGui_ImplVulkan_LoadFunctions() before ImGui_ImplVulkan_Init() with your custom function. +// If you have no idea what this is, leave it alone! +//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES + +// Vulkan includes +#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES) +#define VK_NO_PROTOTYPES +#endif +#include + +// Initialization data, for ImGui_ImplVulkan_Init() +// [Please zero-clear before use!] +struct ImGui_ImplVulkan_InitInfo +{ + VkInstance Instance; + VkPhysicalDevice PhysicalDevice; + VkDevice Device; + uint32_t QueueFamily; + VkQueue Queue; + VkPipelineCache PipelineCache; + VkDescriptorPool DescriptorPool; + uint32_t Subpass; + uint32_t MinImageCount; // >= 2 + uint32_t ImageCount; // >= MinImageCount + VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT) + const VkAllocationCallbacks* Allocator; + void (*CheckVkResultFn)(VkResult err); +}; + +// Called by user code +IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass); +IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE); +IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); +IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects(); +IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) + +// Register a texture (VkDescriptorSet == ImTextureID) +// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions. +IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout); + +// Optional: load Vulkan functions with a custom function loader +// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES +IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = NULL); + +//------------------------------------------------------------------------- +// Internal / Miscellaneous Vulkan Helpers +// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.) +//------------------------------------------------------------------------- +// You probably do NOT need to use or care about those functions. +// Those functions only exist because: +// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files. +// 2) the multi-viewport / platform window implementation needs them internally. +// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings, +// but it is too much code to duplicate everywhere so we exceptionally expose them. +// +// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). +// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. +// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) +//------------------------------------------------------------------------- + +struct ImGui_ImplVulkanH_Frame; +struct ImGui_ImplVulkanH_Window; + +// Helpers +IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); +IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator); +IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); +IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); +IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode); + +// Helper structure to hold the data needed by one rendering frame +// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.) +// [Please zero-clear before use!] +struct ImGui_ImplVulkanH_Frame +{ + VkCommandPool CommandPool; + VkCommandBuffer CommandBuffer; + VkFence Fence; + VkImage Backbuffer; + VkImageView BackbufferView; + VkFramebuffer Framebuffer; +}; + +struct ImGui_ImplVulkanH_FrameSemaphores +{ + VkSemaphore ImageAcquiredSemaphore; + VkSemaphore RenderCompleteSemaphore; +}; + +// Helper structure to hold the data needed by one rendering context into one OS window +// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.) +struct ImGui_ImplVulkanH_Window +{ + int Width; + int Height; + VkSwapchainKHR Swapchain; + VkSurfaceKHR Surface; + VkSurfaceFormatKHR SurfaceFormat; + VkPresentModeKHR PresentMode; + VkRenderPass RenderPass; + VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo + bool ClearEnable; + VkClearValue ClearValue; + uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) + uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) + uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data) + ImGui_ImplVulkanH_Frame* Frames; + ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; + + ImGui_ImplVulkanH_Window() + { + memset(this, 0, sizeof(*this)); + PresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; + ClearEnable = true; + } +}; + diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.cpp new file mode 100644 index 000000000..6e12c6f43 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.cpp @@ -0,0 +1,718 @@ +// dear imgui: Renderer for WebGPU +// This needs to be used along with a Platform Binding (e.g. GLFW) +// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2021-11-29: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer()/wgpuRenderPassEncoderSetIndexBuffer(). +// 2021-08-24: Fix for latest specs. +// 2021-05-24: Add support for draw_data->FramebufferScale. +// 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) +// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92). +// 2021-02-18: Change blending equation to preserve alpha in output buffer. +// 2021-01-28: Initial version. + +#include "imgui.h" +#include "imgui_impl_wgpu.h" +#include +#include + +#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny))) + +#if defined(__EMSCRIPTEN__) && !HAS_EMSCRIPTEN_VERSION(2, 0, 20) +#error "Requires at least emscripten 2.0.20" +#endif + +// Dear ImGui prototypes from imgui_internal.h +extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0); + +// WebGPU data +static WGPUDevice g_wgpuDevice = NULL; +static WGPUQueue g_defaultQueue = NULL; +static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined; +static WGPURenderPipeline g_pipelineState = NULL; + +struct RenderResources +{ + WGPUTexture FontTexture; // Font texture + WGPUTextureView FontTextureView; // Texture view for font texture + WGPUSampler Sampler; // Sampler for the font texture + WGPUBuffer Uniforms; // Shader uniforms + WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline + ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map) + WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui + WGPUBindGroupLayout ImageBindGroupLayout; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM +}; +static RenderResources g_resources; + +struct FrameResources +{ + WGPUBuffer IndexBuffer; + WGPUBuffer VertexBuffer; + ImDrawIdx* IndexBufferHost; + ImDrawVert* VertexBufferHost; + int IndexBufferSize; + int VertexBufferSize; +}; +static FrameResources* g_pFrameResources = NULL; +static unsigned int g_numFramesInFlight = 0; +static unsigned int g_frameIndex = UINT_MAX; + +struct Uniforms +{ + float MVP[4][4]; +}; + +//----------------------------------------------------------------------------- +// SHADERS +//----------------------------------------------------------------------------- + +// glsl_shader.vert, compiled with: +// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert +/* +#version 450 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; +layout(set=0, binding = 0) uniform transform { mat4 mvp; }; + +out gl_PerVertex { vec4 gl_Position; }; +layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; + +void main() +{ + Out.Color = aColor; + Out.UV = aUV; + gl_Position = mvp * vec4(aPos, 0, 1); +} +*/ +static uint32_t __glsl_shader_vert_spv[] = +{ + 0x07230203,0x00010000,0x00080007,0x0000002c,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015, + 0x0000001b,0x00000023,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43, + 0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f, + 0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005, + 0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00050005,0x0000001d, + 0x6e617274,0x726f6673,0x0000006d,0x00040006,0x0000001d,0x00000000,0x0070766d,0x00030005, + 0x0000001f,0x00000000,0x00040005,0x00000023,0x736f5061,0x00000000,0x00040047,0x0000000b, + 0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015, + 0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047, + 0x00000019,0x00000002,0x00040048,0x0000001d,0x00000000,0x00000005,0x00050048,0x0000001d, + 0x00000000,0x00000023,0x00000000,0x00050048,0x0000001d,0x00000000,0x00000007,0x00000010, + 0x00030047,0x0000001d,0x00000002,0x00040047,0x0000001f,0x00000022,0x00000000,0x00040047, + 0x0000001f,0x00000021,0x00000000,0x00040047,0x00000023,0x0000001e,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000004,0x00040017,0x00000008,0x00000006,0x00000002,0x0004001e, + 0x00000009,0x00000007,0x00000008,0x00040020,0x0000000a,0x00000003,0x00000009,0x0004003b, + 0x0000000a,0x0000000b,0x00000003,0x00040015,0x0000000c,0x00000020,0x00000001,0x0004002b, + 0x0000000c,0x0000000d,0x00000000,0x00040020,0x0000000e,0x00000001,0x00000007,0x0004003b, + 0x0000000e,0x0000000f,0x00000001,0x00040020,0x00000011,0x00000003,0x00000007,0x0004002b, + 0x0000000c,0x00000013,0x00000001,0x00040020,0x00000014,0x00000001,0x00000008,0x0004003b, + 0x00000014,0x00000015,0x00000001,0x00040020,0x00000017,0x00000003,0x00000008,0x0003001e, + 0x00000019,0x00000007,0x00040020,0x0000001a,0x00000003,0x00000019,0x0004003b,0x0000001a, + 0x0000001b,0x00000003,0x00040018,0x0000001c,0x00000007,0x00000004,0x0003001e,0x0000001d, + 0x0000001c,0x00040020,0x0000001e,0x00000002,0x0000001d,0x0004003b,0x0000001e,0x0000001f, + 0x00000002,0x00040020,0x00000020,0x00000002,0x0000001c,0x0004003b,0x00000014,0x00000023, + 0x00000001,0x0004002b,0x00000006,0x00000025,0x00000000,0x0004002b,0x00000006,0x00000026, + 0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012,0x0000000b, + 0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016,0x00000015, + 0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018,0x00000016, + 0x00050041,0x00000020,0x00000021,0x0000001f,0x0000000d,0x0004003d,0x0000001c,0x00000022, + 0x00000021,0x0004003d,0x00000008,0x00000024,0x00000023,0x00050051,0x00000006,0x00000027, + 0x00000024,0x00000000,0x00050051,0x00000006,0x00000028,0x00000024,0x00000001,0x00070050, + 0x00000007,0x00000029,0x00000027,0x00000028,0x00000025,0x00000026,0x00050091,0x00000007, + 0x0000002a,0x00000022,0x00000029,0x00050041,0x00000011,0x0000002b,0x0000001b,0x0000000d, + 0x0003003e,0x0000002b,0x0000002a,0x000100fd,0x00010038 +}; + +// glsl_shader.frag, compiled with: +// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +/* +#version 450 core +layout(location = 0) out vec4 fColor; +layout(set=0, binding=1) uniform sampler s; +layout(set=1, binding=0) uniform texture2D t; +layout(location = 0) in struct { vec4 Color; vec2 UV; } In; +void main() +{ + fColor = In.Color * texture(sampler2D(t, s), In.UV.st); +} +*/ +static uint32_t __glsl_shader_frag_spv[] = +{ + 0x07230203,0x00010000,0x00080007,0x00000023,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000, + 0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001, + 0x00005655,0x00030005,0x0000000d,0x00006e49,0x00030005,0x00000015,0x00000074,0x00030005, + 0x00000019,0x00000073,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d, + 0x0000001e,0x00000000,0x00040047,0x00000015,0x00000022,0x00000001,0x00040047,0x00000015, + 0x00000021,0x00000000,0x00040047,0x00000019,0x00000022,0x00000000,0x00040047,0x00000019, + 0x00000021,0x00000001,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008, + 0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a, + 0x00000006,0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c, + 0x00000001,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e, + 0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010, + 0x00000001,0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x00000014,0x00000000,0x00000013,0x0004003b, + 0x00000014,0x00000015,0x00000000,0x0002001a,0x00000017,0x00040020,0x00000018,0x00000000, + 0x00000017,0x0004003b,0x00000018,0x00000019,0x00000000,0x0003001b,0x0000001b,0x00000013, + 0x0004002b,0x0000000e,0x0000001d,0x00000001,0x00040020,0x0000001e,0x00000001,0x0000000a, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041, + 0x00000010,0x00000011,0x0000000d,0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011, + 0x0004003d,0x00000013,0x00000016,0x00000015,0x0004003d,0x00000017,0x0000001a,0x00000019, + 0x00050056,0x0000001b,0x0000001c,0x00000016,0x0000001a,0x00050041,0x0000001e,0x0000001f, + 0x0000000d,0x0000001d,0x0004003d,0x0000000a,0x00000020,0x0000001f,0x00050057,0x00000007, + 0x00000021,0x0000001c,0x00000020,0x00050085,0x00000007,0x00000022,0x00000012,0x00000021, + 0x0003003e,0x00000009,0x00000022,0x000100fd,0x00010038 +}; + +static void SafeRelease(ImDrawIdx*& res) +{ + if (res) + delete[] res; + res = NULL; +} +static void SafeRelease(ImDrawVert*& res) +{ + if (res) + delete[] res; + res = NULL; +} +static void SafeRelease(WGPUBindGroupLayout& res) +{ + if (res) + wgpuBindGroupLayoutRelease(res); + res = NULL; +} +static void SafeRelease(WGPUBindGroup& res) +{ + if (res) + wgpuBindGroupRelease(res); + res = NULL; +} +static void SafeRelease(WGPUBuffer& res) +{ + if (res) + wgpuBufferRelease(res); + res = NULL; +} +static void SafeRelease(WGPURenderPipeline& res) +{ + if (res) + wgpuRenderPipelineRelease(res); + res = NULL; +} +static void SafeRelease(WGPUSampler& res) +{ + if (res) + wgpuSamplerRelease(res); + res = NULL; +} +static void SafeRelease(WGPUShaderModule& res) +{ + if (res) + wgpuShaderModuleRelease(res); + res = NULL; +} +static void SafeRelease(WGPUTextureView& res) +{ + if (res) + wgpuTextureViewRelease(res); + res = NULL; +} +static void SafeRelease(WGPUTexture& res) +{ + if (res) + wgpuTextureRelease(res); + res = NULL; +} + +static void SafeRelease(RenderResources& res) +{ + SafeRelease(res.FontTexture); + SafeRelease(res.FontTextureView); + SafeRelease(res.Sampler); + SafeRelease(res.Uniforms); + SafeRelease(res.CommonBindGroup); + SafeRelease(res.ImageBindGroup); + SafeRelease(res.ImageBindGroupLayout); +}; + +static void SafeRelease(FrameResources& res) +{ + SafeRelease(res.IndexBuffer); + SafeRelease(res.VertexBuffer); + SafeRelease(res.IndexBufferHost); + SafeRelease(res.VertexBufferHost); +} + +static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_t* binary_data, uint32_t binary_data_size) +{ + WGPUShaderModuleSPIRVDescriptor spirv_desc = {}; + spirv_desc.chain.sType = WGPUSType_ShaderModuleSPIRVDescriptor; + spirv_desc.codeSize = binary_data_size; + spirv_desc.code = binary_data; + + WGPUShaderModuleDescriptor desc = {}; + desc.nextInChain = reinterpret_cast(&spirv_desc); + + WGPUProgrammableStageDescriptor stage_desc = {}; + stage_desc.module = wgpuDeviceCreateShaderModule(g_wgpuDevice, &desc); + stage_desc.entryPoint = "main"; + return stage_desc; +} + +static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture) +{ + WGPUBindGroupEntry image_bg_entries[] = { { nullptr, 0, 0, 0, 0, 0, texture } }; + + WGPUBindGroupDescriptor image_bg_descriptor = {}; + image_bg_descriptor.layout = layout; + image_bg_descriptor.entryCount = sizeof(image_bg_entries) / sizeof(WGPUBindGroupEntry); + image_bg_descriptor.entries = image_bg_entries; + return wgpuDeviceCreateBindGroup(g_wgpuDevice, &image_bg_descriptor); +} + +static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPassEncoder ctx, FrameResources* fr) +{ + // Setup orthographic projection matrix into our constant buffer + // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). + { + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + wgpuQueueWriteBuffer(g_defaultQueue, g_resources.Uniforms, 0, mvp, sizeof(mvp)); + } + + // Setup viewport + wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1); + + // Bind shader and vertex buffers + wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert)); + wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx)); + wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState); + wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL); + + // Setup blend factor + WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f }; + wgpuRenderPassEncoderSetBlendConstant(ctx, &blend_color); +} + +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder) +{ + // Avoid rendering when minimized + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) + return; + + // FIXME: Assuming that this only gets called once per frame! + // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. + g_frameIndex = g_frameIndex + 1; + FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; + + // Create and grow vertex/index buffers if needed + if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) + { + if (fr->VertexBuffer) + { + wgpuBufferDestroy(fr->VertexBuffer); + wgpuBufferRelease(fr->VertexBuffer); + } + SafeRelease(fr->VertexBufferHost); + fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; + + WGPUBufferDescriptor vb_desc = + { + NULL, + "Dear ImGui Vertex buffer", + WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, + fr->VertexBufferSize * sizeof(ImDrawVert), + false + }; + fr->VertexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &vb_desc); + if (!fr->VertexBuffer) + return; + + fr->VertexBufferHost = new ImDrawVert[fr->VertexBufferSize]; + } + if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) + { + if (fr->IndexBuffer) + { + wgpuBufferDestroy(fr->IndexBuffer); + wgpuBufferRelease(fr->IndexBuffer); + } + SafeRelease(fr->IndexBufferHost); + fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; + + WGPUBufferDescriptor ib_desc = + { + NULL, + "Dear ImGui Index buffer", + WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index, + fr->IndexBufferSize * sizeof(ImDrawIdx), + false + }; + fr->IndexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &ib_desc); + if (!fr->IndexBuffer) + return; + + fr->IndexBufferHost = new ImDrawIdx[fr->IndexBufferSize]; + } + + // Upload vertex/index data into a single contiguous GPU buffer + ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost; + ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.Size; + idx_dst += cmd_list->IdxBuffer.Size; + } + int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3; + int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3; + wgpuQueueWriteBuffer(g_defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size); + wgpuQueueWriteBuffer(g_defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size); + + // Setup desired render state + ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + ImVec2 clip_scale = draw_data->FramebufferScale; + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Bind custom texture + ImTextureID tex_id = pcmd->GetTexID(); + ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id)); + auto bind_group = g_resources.ImageBindGroups.GetVoidPtr(tex_id_hash); + if (bind_group) + { + wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, NULL); + } + else + { + WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)tex_id); + g_resources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group); + wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL); + } + + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle, Draw + wgpuRenderPassEncoderSetScissorRect(pass_encoder, (uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y)); + wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += cmd_list->IdxBuffer.Size; + global_vtx_offset += cmd_list->VtxBuffer.Size; + } +} + +static void ImGui_ImplWGPU_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height, size_pp; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &size_pp); + + // Upload texture to graphics system + { + WGPUTextureDescriptor tex_desc = {}; + tex_desc.label = "Dear ImGui Font Texture"; + tex_desc.dimension = WGPUTextureDimension_2D; + tex_desc.size.width = width; + tex_desc.size.height = height; + tex_desc.size.depthOrArrayLayers = 1; + tex_desc.sampleCount = 1; + tex_desc.format = WGPUTextureFormat_RGBA8Unorm; + tex_desc.mipLevelCount = 1; + tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding; + g_resources.FontTexture = wgpuDeviceCreateTexture(g_wgpuDevice, &tex_desc); + + WGPUTextureViewDescriptor tex_view_desc = {}; + tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm; + tex_view_desc.dimension = WGPUTextureViewDimension_2D; + tex_view_desc.baseMipLevel = 0; + tex_view_desc.mipLevelCount = 1; + tex_view_desc.baseArrayLayer = 0; + tex_view_desc.arrayLayerCount = 1; + tex_view_desc.aspect = WGPUTextureAspect_All; + g_resources.FontTextureView = wgpuTextureCreateView(g_resources.FontTexture, &tex_view_desc); + } + + // Upload texture data + { + WGPUImageCopyTexture dst_view = {}; + dst_view.texture = g_resources.FontTexture; + dst_view.mipLevel = 0; + dst_view.origin = { 0, 0, 0 }; + dst_view.aspect = WGPUTextureAspect_All; + WGPUTextureDataLayout layout = {}; + layout.offset = 0; + layout.bytesPerRow = width * size_pp; + layout.rowsPerImage = height; + WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 }; + wgpuQueueWriteTexture(g_defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size); + } + + // Create the associated sampler + { + WGPUSamplerDescriptor sampler_desc = {}; + sampler_desc.minFilter = WGPUFilterMode_Linear; + sampler_desc.magFilter = WGPUFilterMode_Linear; + sampler_desc.mipmapFilter = WGPUFilterMode_Linear; + sampler_desc.addressModeU = WGPUAddressMode_Repeat; + sampler_desc.addressModeV = WGPUAddressMode_Repeat; + sampler_desc.addressModeW = WGPUAddressMode_Repeat; + sampler_desc.maxAnisotropy = 1; + g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc); + } + + // Store our identifier + static_assert(sizeof(ImTextureID) >= sizeof(g_resources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet."); + io.Fonts->SetTexID((ImTextureID)g_resources.FontTextureView); +} + +static void ImGui_ImplWGPU_CreateUniformBuffer() +{ + WGPUBufferDescriptor ub_desc = + { + NULL, + "Dear ImGui Uniform buffer", + WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform, + sizeof(Uniforms), + false + }; + g_resources.Uniforms = wgpuDeviceCreateBuffer(g_wgpuDevice, &ub_desc); +} + +bool ImGui_ImplWGPU_CreateDeviceObjects() +{ + if (!g_wgpuDevice) + return false; + if (g_pipelineState) + ImGui_ImplWGPU_InvalidateDeviceObjects(); + + // Create render pipeline + WGPURenderPipelineDescriptor graphics_pipeline_desc = {}; + graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; + graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; + graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None; + graphics_pipeline_desc.multisample.count = 1; + graphics_pipeline_desc.multisample.mask = UINT_MAX; + graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false; + graphics_pipeline_desc.layout = nullptr; // Use automatic layout generation + + // Create the vertex shader + WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t)); + graphics_pipeline_desc.vertex.module = vertex_shader_desc.module; + graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint; + + // Vertex input configuration + WGPUVertexAttribute attribute_desc[] = + { + { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 }, + { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 }, + { WGPUVertexFormat_Unorm8x4, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 }, + }; + + WGPUVertexBufferLayout buffer_layouts[1]; + buffer_layouts[0].arrayStride = sizeof(ImDrawVert); + buffer_layouts[0].stepMode = WGPUVertexStepMode_Vertex; + buffer_layouts[0].attributeCount = 3; + buffer_layouts[0].attributes = attribute_desc; + + graphics_pipeline_desc.vertex.bufferCount = 1; + graphics_pipeline_desc.vertex.buffers = buffer_layouts; + + // Create the pixel shader + WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t)); + + // Create the blending setup + WGPUBlendState blend_state = {}; + blend_state.alpha.operation = WGPUBlendOperation_Add; + blend_state.alpha.srcFactor = WGPUBlendFactor_One; + blend_state.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; + blend_state.color.operation = WGPUBlendOperation_Add; + blend_state.color.srcFactor = WGPUBlendFactor_SrcAlpha; + blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; + + WGPUColorTargetState color_state = {}; + color_state.format = g_renderTargetFormat; + color_state.blend = &blend_state; + color_state.writeMask = WGPUColorWriteMask_All; + + WGPUFragmentState fragment_state = {}; + fragment_state.module = pixel_shader_desc.module; + fragment_state.entryPoint = pixel_shader_desc.entryPoint; + fragment_state.targetCount = 1; + fragment_state.targets = &color_state; + + graphics_pipeline_desc.fragment = &fragment_state; + + // Create depth-stencil State + WGPUDepthStencilState depth_stencil_state = {}; + depth_stencil_state.depthBias = 0; + depth_stencil_state.depthBiasClamp = 0; + depth_stencil_state.depthBiasSlopeScale = 0; + + // Configure disabled depth-stencil state + graphics_pipeline_desc.depthStencil = nullptr; + + g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc); + + ImGui_ImplWGPU_CreateFontsTexture(); + ImGui_ImplWGPU_CreateUniformBuffer(); + + // Create resource bind group + WGPUBindGroupLayout bg_layouts[2]; + bg_layouts[0] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 0); + bg_layouts[1] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1); + + WGPUBindGroupEntry common_bg_entries[] = + { + { nullptr, 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 }, + { nullptr, 1, 0, 0, 0, g_resources.Sampler, 0 }, + }; + + WGPUBindGroupDescriptor common_bg_descriptor = {}; + common_bg_descriptor.layout = bg_layouts[0]; + common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry); + common_bg_descriptor.entries = common_bg_entries; + g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor); + + WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView); + g_resources.ImageBindGroup = image_bind_group; + g_resources.ImageBindGroupLayout = bg_layouts[1]; + g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group); + + SafeRelease(vertex_shader_desc.module); + SafeRelease(pixel_shader_desc.module); + SafeRelease(bg_layouts[0]); + + return true; +} + +void ImGui_ImplWGPU_InvalidateDeviceObjects() +{ + if (!g_wgpuDevice) + return; + + SafeRelease(g_pipelineState); + SafeRelease(g_resources); + + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->SetTexID(NULL); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. + + for (unsigned int i = 0; i < g_numFramesInFlight; i++) + SafeRelease(g_pFrameResources[i]); +} + +bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format) +{ + // Setup backend capabilities flags + ImGuiIO& io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_webgpu"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + g_wgpuDevice = device; + g_defaultQueue = wgpuDeviceGetQueue(g_wgpuDevice); + g_renderTargetFormat = rt_format; + g_pFrameResources = new FrameResources[num_frames_in_flight]; + g_numFramesInFlight = num_frames_in_flight; + g_frameIndex = UINT_MAX; + + g_resources.FontTexture = NULL; + g_resources.FontTextureView = NULL; + g_resources.Sampler = NULL; + g_resources.Uniforms = NULL; + g_resources.CommonBindGroup = NULL; + g_resources.ImageBindGroups.Data.reserve(100); + g_resources.ImageBindGroup = NULL; + g_resources.ImageBindGroupLayout = NULL; + + // Create buffers with a default size (they will later be grown as needed) + for (int i = 0; i < num_frames_in_flight; i++) + { + FrameResources* fr = &g_pFrameResources[i]; + fr->IndexBuffer = NULL; + fr->VertexBuffer = NULL; + fr->IndexBufferHost = NULL; + fr->VertexBufferHost = NULL; + fr->IndexBufferSize = 10000; + fr->VertexBufferSize = 5000; + } + + return true; +} + +void ImGui_ImplWGPU_Shutdown() +{ + ImGui_ImplWGPU_InvalidateDeviceObjects(); + delete[] g_pFrameResources; + g_pFrameResources = NULL; + wgpuQueueRelease(g_defaultQueue); + g_wgpuDevice = NULL; + g_numFramesInFlight = 0; + g_frameIndex = UINT_MAX; +} + +void ImGui_ImplWGPU_NewFrame() +{ + if (!g_pipelineState) + ImGui_ImplWGPU_CreateDeviceObjects(); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.h new file mode 100644 index 000000000..ec10768e9 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_wgpu.h @@ -0,0 +1,25 @@ +// dear imgui: Renderer for WebGPU +// This needs to be used along with a Platform Binding (e.g. GLFW) +// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API +#include + +IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format); +IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder); + +// Use if you want to reset your rendering device without losing Dear ImGui state. +IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(); +IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.cpp new file mode 100644 index 000000000..ed6fe94c8 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.cpp @@ -0,0 +1,1195 @@ +// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications) +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) + +// Implemented features: +// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "../imgui.h" +#include "imgui_impl_win32.h" +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include // GET_X_LPARAM(), GET_Y_LPARAM() +#include +#include + +// Configuration flags to add in your imconfig.h file: +//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant. + +// Using XInput for gamepad (will load DLL dynamically) +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD +#include +typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*); +typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); +#endif + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-17: Inputs: always update key mods next and before a key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. +// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness. +// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages. +// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus. +// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events). +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1). +// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS). +// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi). +// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1. +// 2021-01-25: Inputs: Dynamically loading XInput DLL. +// 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed. +// 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs) +// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions. +// 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT. +// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. +// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). +// 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. +// 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. +// 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. +// 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). +// 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. +// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. +// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. +// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. +// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. +// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. + +// Forward Declarations +static void ImGui_ImplWin32_InitPlatformInterface(); +static void ImGui_ImplWin32_ShutdownPlatformInterface(); +static void ImGui_ImplWin32_UpdateMonitors(); + +struct ImGui_ImplWin32_Data +{ + HWND hWnd; + HWND MouseHwnd; + bool MouseTracked; + int MouseButtonsDown; + INT64 Time; + INT64 TicksPerSecond; + ImGuiMouseCursor LastMouseCursor; + bool HasGamepad; + bool WantUpdateHasGamepad; + bool WantUpdateMonitors; + +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + HMODULE XInputDLL; + PFN_XInputGetCapabilities XInputGetCapabilities; + PFN_XInputGetState XInputGetState; +#endif + + ImGui_ImplWin32_Data() { memset(this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. +static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} + +// Functions +bool ImGui_ImplWin32_Init(void* hwnd) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); + + INT64 perf_frequency, perf_counter; + if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency)) + return false; + if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter)) + return false; + + // Setup backend capabilities flags + ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_win32"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) + + bd->hWnd = (HWND)hwnd; + bd->WantUpdateHasGamepad = true; + bd->WantUpdateMonitors = true; + bd->TicksPerSecond = perf_frequency; + bd->Time = perf_counter; + bd->LastMouseCursor = ImGuiMouseCursor_COUNT; + + // Our mouse update function expect PlatformHandle to be filled for the main viewport + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd; + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ImGui_ImplWin32_InitPlatformInterface(); + + // Dynamically load XInput library +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + const char* xinput_dll_names[] = + { + "xinput1_4.dll", // Windows 8+ + "xinput1_3.dll", // DirectX SDK + "xinput9_1_0.dll", // Windows Vista, Windows 7 + "xinput1_2.dll", // DirectX SDK + "xinput1_1.dll" // DirectX SDK + }; + for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++) + if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n])) + { + bd->XInputDLL = dll; + bd->XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities"); + bd->XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState"); + break; + } +#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + + return true; +} + +void ImGui_ImplWin32_Shutdown() +{ + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplWin32_ShutdownPlatformInterface(); + + // Unload XInput library +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + if (bd->XInputDLL) + ::FreeLibrary(bd->XInputDLL); +#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + + io.BackendPlatformName = NULL; + io.BackendPlatformUserData = NULL; + IM_DELETE(bd); +} + +static bool ImGui_ImplWin32_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return false; + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + ::SetCursor(NULL); + } + else + { + // Show OS mouse cursor + LPTSTR win32_cursor = IDC_ARROW; + switch (imgui_cursor) + { + case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; + case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; + case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; + } + ::SetCursor(::LoadCursor(NULL, win32_cursor)); + } + return true; +} + +static bool IsVkDown(int vk) +{ + return (::GetKeyState(vk) & 0x8000) != 0; +} + +static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(key, down); + io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code) + IM_UNUSED(native_scancode); +} + +static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds() +{ + // Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one. + if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT)) + ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT); + if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT)) + ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT); + + // Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW). + if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN)) + ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN); + if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN)) + ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN); +} + +static void ImGui_ImplWin32_UpdateKeyModifiers() +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(ImGuiKey_ModCtrl, IsVkDown(VK_CONTROL)); + io.AddKeyEvent(ImGuiKey_ModShift, IsVkDown(VK_SHIFT)); + io.AddKeyEvent(ImGuiKey_ModAlt, IsVkDown(VK_MENU)); + io.AddKeyEvent(ImGuiKey_ModSuper, IsVkDown(VK_APPS)); +} + +// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports) +// Because of that, it is a little more complicated than your typical single-viewport binding code! +static void ImGui_ImplWin32_UpdateMouseData() +{ + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(bd->hWnd != 0); + + POINT mouse_screen_pos; + bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0; + + HWND focused_window = ::GetForegroundWindow(); + const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window))); + if (is_app_focused) + { + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions. + if (io.WantSetMousePos) + { + POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; + if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0) + ::ClientToScreen(focused_window, &pos); + ::SetCursorPos(pos.x, pos.y); + } + + // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured) + if (!io.WantSetMousePos && !bd->MouseTracked && has_mouse_screen_pos) + { + // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) + // (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.) + // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) + // (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.) + POINT mouse_pos = mouse_screen_pos; + if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + ::ScreenToClient(bd->hWnd, &mouse_pos); + io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); + } + } + + // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering. + // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic. + // - [X] Win32 backend correctly ignore viewports with the _NoInputs flag (here using ::WindowFromPoint with WM_NCHITTEST + HTTRANSPARENT in WndProc does that) + // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window + // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported + // by the backend, and use its flawed heuristic to guess the viewport behind. + // - [X] Win32 backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target). + ImGuiID mouse_viewport_id = 0; + if (has_mouse_screen_pos) + if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos)) + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd)) + mouse_viewport_id = viewport->ID; + io.AddMouseViewportEvent(mouse_viewport_id); +} + +// Gamepad navigation mapping +static void ImGui_ImplWin32_UpdateGamepads() +{ +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. + // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. + if (bd->WantUpdateHasGamepad) + { + XINPUT_CAPABILITIES caps = {}; + bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false; + bd->WantUpdateHasGamepad = false; + } + + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + XINPUT_STATE xinput_state; + XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; + if (!bd->HasGamepad || bd->XInputGetState == NULL || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS) + return; + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + + #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V) + #define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); } + #define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn)); } + MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START); + MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK); + MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A); + MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B); + MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X); + MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y); + MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); + MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); + MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP); + MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN); + MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER); + MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER); + MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255); + MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255); + MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB); + MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB); + MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); + MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); + MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); + MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); + #undef MAP_BUTTON + #undef MAP_ANALOG +#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD +} + +static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM) +{ + MONITORINFO info = {}; + info.cbSize = sizeof(MONITORINFO); + if (!::GetMonitorInfo(monitor, &info)) + return TRUE; + ImGuiPlatformMonitor imgui_monitor; + imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top); + imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top)); + imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top); + imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top)); + imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); + ImGuiPlatformIO& io = ImGui::GetPlatformIO(); + if (info.dwFlags & MONITORINFOF_PRIMARY) + io.Monitors.push_front(imgui_monitor); + else + io.Monitors.push_back(imgui_monitor); + return TRUE; +} + +static void ImGui_ImplWin32_UpdateMonitors() +{ + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + ImGui::GetPlatformIO().Monitors.resize(0); + ::EnumDisplayMonitors(NULL, NULL, ImGui_ImplWin32_UpdateMonitors_EnumFunc, 0); + bd->WantUpdateMonitors = false; +} + +void ImGui_ImplWin32_NewFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?"); + + // Setup display size (every frame to accommodate for window resizing) + RECT rect = { 0, 0, 0, 0 }; + ::GetClientRect(bd->hWnd, &rect); + io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); + if (bd->WantUpdateMonitors) + ImGui_ImplWin32_UpdateMonitors(); + + // Setup time step + INT64 current_time = 0; + ::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time); + io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond; + bd->Time = current_time; + + // Update OS mouse position + ImGui_ImplWin32_UpdateMouseData(); + + // Process workarounds for known Windows key handling issues + ImGui_ImplWin32_ProcessKeyEventsWorkarounds(); + + // Update OS mouse cursor with the cursor requested by imgui + ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (bd->LastMouseCursor != mouse_cursor) + { + bd->LastMouseCursor = mouse_cursor; + ImGui_ImplWin32_UpdateMouseCursor(); + } + + // Update game controllers (if enabled and available) + ImGui_ImplWin32_UpdateGamepads(); +} + +// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255) +#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256) + +// Map VK_xxx to ImGuiKey_xxx. +static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam) +{ + switch (wParam) + { + case VK_TAB: return ImGuiKey_Tab; + case VK_LEFT: return ImGuiKey_LeftArrow; + case VK_RIGHT: return ImGuiKey_RightArrow; + case VK_UP: return ImGuiKey_UpArrow; + case VK_DOWN: return ImGuiKey_DownArrow; + case VK_PRIOR: return ImGuiKey_PageUp; + case VK_NEXT: return ImGuiKey_PageDown; + case VK_HOME: return ImGuiKey_Home; + case VK_END: return ImGuiKey_End; + case VK_INSERT: return ImGuiKey_Insert; + case VK_DELETE: return ImGuiKey_Delete; + case VK_BACK: return ImGuiKey_Backspace; + case VK_SPACE: return ImGuiKey_Space; + case VK_RETURN: return ImGuiKey_Enter; + case VK_ESCAPE: return ImGuiKey_Escape; + case VK_OEM_7: return ImGuiKey_Apostrophe; + case VK_OEM_COMMA: return ImGuiKey_Comma; + case VK_OEM_MINUS: return ImGuiKey_Minus; + case VK_OEM_PERIOD: return ImGuiKey_Period; + case VK_OEM_2: return ImGuiKey_Slash; + case VK_OEM_1: return ImGuiKey_Semicolon; + case VK_OEM_PLUS: return ImGuiKey_Equal; + case VK_OEM_4: return ImGuiKey_LeftBracket; + case VK_OEM_5: return ImGuiKey_Backslash; + case VK_OEM_6: return ImGuiKey_RightBracket; + case VK_OEM_3: return ImGuiKey_GraveAccent; + case VK_CAPITAL: return ImGuiKey_CapsLock; + case VK_SCROLL: return ImGuiKey_ScrollLock; + case VK_NUMLOCK: return ImGuiKey_NumLock; + case VK_SNAPSHOT: return ImGuiKey_PrintScreen; + case VK_PAUSE: return ImGuiKey_Pause; + case VK_NUMPAD0: return ImGuiKey_Keypad0; + case VK_NUMPAD1: return ImGuiKey_Keypad1; + case VK_NUMPAD2: return ImGuiKey_Keypad2; + case VK_NUMPAD3: return ImGuiKey_Keypad3; + case VK_NUMPAD4: return ImGuiKey_Keypad4; + case VK_NUMPAD5: return ImGuiKey_Keypad5; + case VK_NUMPAD6: return ImGuiKey_Keypad6; + case VK_NUMPAD7: return ImGuiKey_Keypad7; + case VK_NUMPAD8: return ImGuiKey_Keypad8; + case VK_NUMPAD9: return ImGuiKey_Keypad9; + case VK_DECIMAL: return ImGuiKey_KeypadDecimal; + case VK_DIVIDE: return ImGuiKey_KeypadDivide; + case VK_MULTIPLY: return ImGuiKey_KeypadMultiply; + case VK_SUBTRACT: return ImGuiKey_KeypadSubtract; + case VK_ADD: return ImGuiKey_KeypadAdd; + case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter; + case VK_LSHIFT: return ImGuiKey_LeftShift; + case VK_LCONTROL: return ImGuiKey_LeftCtrl; + case VK_LMENU: return ImGuiKey_LeftAlt; + case VK_LWIN: return ImGuiKey_LeftSuper; + case VK_RSHIFT: return ImGuiKey_RightShift; + case VK_RCONTROL: return ImGuiKey_RightCtrl; + case VK_RMENU: return ImGuiKey_RightAlt; + case VK_RWIN: return ImGuiKey_RightSuper; + case VK_APPS: return ImGuiKey_Menu; + case '0': return ImGuiKey_0; + case '1': return ImGuiKey_1; + case '2': return ImGuiKey_2; + case '3': return ImGuiKey_3; + case '4': return ImGuiKey_4; + case '5': return ImGuiKey_5; + case '6': return ImGuiKey_6; + case '7': return ImGuiKey_7; + case '8': return ImGuiKey_8; + case '9': return ImGuiKey_9; + case 'A': return ImGuiKey_A; + case 'B': return ImGuiKey_B; + case 'C': return ImGuiKey_C; + case 'D': return ImGuiKey_D; + case 'E': return ImGuiKey_E; + case 'F': return ImGuiKey_F; + case 'G': return ImGuiKey_G; + case 'H': return ImGuiKey_H; + case 'I': return ImGuiKey_I; + case 'J': return ImGuiKey_J; + case 'K': return ImGuiKey_K; + case 'L': return ImGuiKey_L; + case 'M': return ImGuiKey_M; + case 'N': return ImGuiKey_N; + case 'O': return ImGuiKey_O; + case 'P': return ImGuiKey_P; + case 'Q': return ImGuiKey_Q; + case 'R': return ImGuiKey_R; + case 'S': return ImGuiKey_S; + case 'T': return ImGuiKey_T; + case 'U': return ImGuiKey_U; + case 'V': return ImGuiKey_V; + case 'W': return ImGuiKey_W; + case 'X': return ImGuiKey_X; + case 'Y': return ImGuiKey_Y; + case 'Z': return ImGuiKey_Z; + case VK_F1: return ImGuiKey_F1; + case VK_F2: return ImGuiKey_F2; + case VK_F3: return ImGuiKey_F3; + case VK_F4: return ImGuiKey_F4; + case VK_F5: return ImGuiKey_F5; + case VK_F6: return ImGuiKey_F6; + case VK_F7: return ImGuiKey_F7; + case VK_F8: return ImGuiKey_F8; + case VK_F9: return ImGuiKey_F9; + case VK_F10: return ImGuiKey_F10; + case VK_F11: return ImGuiKey_F11; + case VK_F12: return ImGuiKey_F12; + default: return ImGuiKey_None; + } +} + +// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif +#ifndef DBT_DEVNODES_CHANGED +#define DBT_DEVNODES_CHANGED 0x0007 +#endif + +// Win32 message handler (process Win32 mouse/keyboard inputs, etc.) +// Call from your application's message handler. +// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags. +// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. +// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. +#if 0 +// Copy this line into your .cpp file to forward declare the function. +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +#endif +IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui::GetCurrentContext() == NULL) + return 0; + + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + + switch (msg) + { + case WM_MOUSEMOVE: + { + // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events + bd->MouseHwnd = hwnd; + if (!bd->MouseTracked) + { + TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 }; + ::TrackMouseEvent(&tme); + bd->MouseTracked = true; + } + POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) }; + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + ::ClientToScreen(hwnd, &mouse_pos); + io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); + break; + } + case WM_MOUSELEAVE: + if (bd->MouseHwnd == hwnd) + bd->MouseHwnd = NULL; + bd->MouseTracked = false; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + break; + case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: + case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: + { + int button = 0; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } + if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } + if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } + if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } + if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL) + ::SetCapture(hwnd); + bd->MouseButtonsDown |= 1 << button; + io.AddMouseButtonEvent(button, true); + return 0; + } + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_XBUTTONUP: + { + int button = 0; + if (msg == WM_LBUTTONUP) { button = 0; } + if (msg == WM_RBUTTONUP) { button = 1; } + if (msg == WM_MBUTTONUP) { button = 2; } + if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } + bd->MouseButtonsDown &= ~(1 << button); + if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd) + ::ReleaseCapture(); + io.AddMouseButtonEvent(button, false); + return 0; + } + case WM_MOUSEWHEEL: + io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA); + return 0; + case WM_MOUSEHWHEEL: + io.AddMouseWheelEvent((float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f); + return 0; + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + { + const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN); + if (wParam < 256) + { + // Submit modifiers + ImGui_ImplWin32_UpdateKeyModifiers(); + + // Obtain virtual key code + // (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.) + int vk = (int)wParam; + if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED)) + vk = IM_VK_KEYPAD_ENTER; + + // Submit key event + const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk); + const int scancode = (int)LOBYTE(HIWORD(lParam)); + if (key != ImGuiKey_None) + ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode); + + // Submit individual left/right modifier events + if (vk == VK_SHIFT) + { + // Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds() + if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); } + if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); } + } + else if (vk == VK_CONTROL) + { + if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); } + if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); } + } + else if (vk == VK_MENU) + { + if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); } + if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); } + } + } + return 0; + } + case WM_SETFOCUS: + case WM_KILLFOCUS: + io.AddFocusEvent(msg == WM_SETFOCUS); + return 0; + case WM_CHAR: + // You can also use ToAscii()+GetKeyboardState() to retrieve characters. + if (wParam > 0 && wParam < 0x10000) + io.AddInputCharacterUTF16((unsigned short)wParam); + return 0; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) + return 1; + return 0; + case WM_DEVICECHANGE: + if ((UINT)wParam == DBT_DEVNODES_CHANGED) + bd->WantUpdateHasGamepad = true; + return 0; + case WM_DISPLAYCHANGE: + bd->WantUpdateMonitors = true; + return 0; + } + return 0; +} + + +//-------------------------------------------------------------------------------------------------------- +// DPI-related helpers (optional) +//-------------------------------------------------------------------------------------------------------- +// - Use to enable DPI awareness without having to create an application manifest. +// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. +// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. +// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, +// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. +//--------------------------------------------------------------------------------------------------------- +// This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable. +// ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically. +// If you are trying to implement your own backend for your own engine, you may ignore that noise. +//--------------------------------------------------------------------------------------------------------- + +// Perform our own check with RtlVerifyVersionInfo() instead of using functions from as they +// require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200 +static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD) +{ + typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG); + static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = NULL; + if (RtlVerifyVersionInfoFn == NULL) + if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll")) + RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo"); + if (RtlVerifyVersionInfoFn == NULL) + return FALSE; + + RTL_OSVERSIONINFOEXW versionInfo = { }; + ULONGLONG conditionMask = 0; + versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); + versionInfo.dwMajorVersion = major; + versionInfo.dwMinorVersion = minor; + VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE; +} + +#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA +#define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8 +#define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE +#define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10 + +#ifndef DPI_ENUMS_DECLARED +typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; +typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; +#endif +#ifndef _DPI_AWARENESS_CONTEXTS_ +DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 +#endif +#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 +#endif +typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+ +typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+ +typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) + +// Helper function to enable DPI awareness without setting up a manifest +void ImGui_ImplWin32_EnableDpiAwareness() +{ + // Make sure monitors will be updated with latest correct scaling + if (ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData()) + bd->WantUpdateMonitors = true; + + if (_IsWindows10OrGreater()) + { + static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process + if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) + { + SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + return; + } + } + if (_IsWindows8Point1OrGreater()) + { + static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process + if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) + { + SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); + return; + } + } +#if _WIN32_WINNT >= 0x0600 + ::SetProcessDPIAware(); +#endif +} + +#if defined(_MSC_VER) && !defined(NOGDI) +#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32' +#endif + +float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) +{ + UINT xdpi = 96, ydpi = 96; + if (_IsWindows8Point1OrGreater()) + { + static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process + static PFN_GetDpiForMonitor GetDpiForMonitorFn = NULL; + if (GetDpiForMonitorFn == NULL && shcore_dll != NULL) + GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor"); + if (GetDpiForMonitorFn != NULL) + { + GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); + IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! + return xdpi / 96.0f; + } + } +#ifndef NOGDI + const HDC dc = ::GetDC(NULL); + xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); + ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); + IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! + ::ReleaseDC(NULL, dc); +#endif + return xdpi / 96.0f; +} + +float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) +{ + HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); + return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplWin32_ViewportData +{ + HWND Hwnd; + bool HwndOwned; + DWORD DwStyle; + DWORD DwExStyle; + + ImGui_ImplWin32_ViewportData() { Hwnd = NULL; HwndOwned = false; DwStyle = DwExStyle = 0; } + ~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == NULL); } +}; + +static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags flags, DWORD* out_style, DWORD* out_ex_style) +{ + if (flags & ImGuiViewportFlags_NoDecoration) + *out_style = WS_POPUP; + else + *out_style = WS_OVERLAPPEDWINDOW; + + if (flags & ImGuiViewportFlags_NoTaskBarIcon) + *out_ex_style = WS_EX_TOOLWINDOW; + else + *out_ex_style = WS_EX_APPWINDOW; + + if (flags & ImGuiViewportFlags_TopMost) + *out_ex_style |= WS_EX_TOPMOST; +} + +static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)(); + viewport->PlatformUserData = vd; + + // Select style and parent window + ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle); + HWND parent_window = NULL; + if (viewport->ParentViewportId != 0) + if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId)) + parent_window = (HWND)parent_viewport->PlatformHandle; + + // Create window + RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) }; + ::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); + vd->Hwnd = ::CreateWindowEx( + vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area + parent_window, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param + vd->HwndOwned = true; + viewport->PlatformRequestResize = false; + viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd; +} + +static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + if (ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData) + { + if (::GetCapture() == vd->Hwnd) + { + // Transfer capture so if we started dragging from a window that later disappears, we'll still receive the MOUSEUP event. + ::ReleaseCapture(); + ::SetCapture(bd->hWnd); + } + if (vd->Hwnd && vd->HwndOwned) + ::DestroyWindow(vd->Hwnd); + vd->Hwnd = NULL; + IM_DELETE(vd); + } + viewport->PlatformUserData = viewport->PlatformHandle = NULL; +} + +static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) + ::ShowWindow(vd->Hwnd, SW_SHOWNA); + else + ::ShowWindow(vd->Hwnd, SW_SHOW); +} + +static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport) +{ + // (Optional) Update Win32 style if it changed _after_ creation. + // Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful. + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + DWORD new_style; + DWORD new_ex_style; + ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style); + + // Only reapply the flags that have been changed from our point of view (as other flags are being modified by Windows) + if (vd->DwStyle != new_style || vd->DwExStyle != new_ex_style) + { + // (Optional) Update TopMost state if it changed _after_ creation + bool top_most_changed = (vd->DwExStyle & WS_EX_TOPMOST) != (new_ex_style & WS_EX_TOPMOST); + HWND insert_after = top_most_changed ? ((viewport->Flags & ImGuiViewportFlags_TopMost) ? HWND_TOPMOST : HWND_NOTOPMOST) : 0; + UINT swp_flag = top_most_changed ? 0 : SWP_NOZORDER; + + // Apply flags and position (since it is affected by flags) + vd->DwStyle = new_style; + vd->DwExStyle = new_ex_style; + ::SetWindowLong(vd->Hwnd, GWL_STYLE, vd->DwStyle); + ::SetWindowLong(vd->Hwnd, GWL_EXSTYLE, vd->DwExStyle); + RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) }; + ::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen + ::SetWindowPos(vd->Hwnd, insert_after, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, swp_flag | SWP_NOACTIVATE | SWP_FRAMECHANGED); + ::ShowWindow(vd->Hwnd, SW_SHOWNA); // This is necessary when we alter the style + viewport->PlatformRequestMove = viewport->PlatformRequestResize = true; + } +} + +static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + POINT pos = { 0, 0 }; + ::ClientToScreen(vd->Hwnd, &pos); + return ImVec2((float)pos.x, (float)pos.y); +} + +static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y }; + ::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); + ::SetWindowPos(vd->Hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); +} + +static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + RECT rect; + ::GetClientRect(vd->Hwnd, &rect); + return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top)); +} + +static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y }; + ::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen + ::SetWindowPos(vd->Hwnd, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); +} + +static void ImGui_ImplWin32_SetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + ::BringWindowToTop(vd->Hwnd); + ::SetForegroundWindow(vd->Hwnd); + ::SetFocus(vd->Hwnd); +} + +static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + return ::GetForegroundWindow() == vd->Hwnd; +} + +static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + return ::IsIconic(vd->Hwnd) != 0; +} + +static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title) +{ + // ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string. + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + int n = ::MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); + ImVector title_w; + title_w.resize(n); + ::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n); + ::SetWindowTextW(vd->Hwnd, title_w.Data); +} + +static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f); + if (alpha < 1.0f) + { + DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED; + ::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style); + ::SetLayeredWindowAttributes(vd->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA); + } + else + { + DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED; + ::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style); + } +} + +static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport) +{ + ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData; + IM_ASSERT(vd->Hwnd != 0); + return ImGui_ImplWin32_GetDpiScaleForHwnd(vd->Hwnd); +} + +// FIXME-DPI: Testing DPI related ideas +static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport) +{ + (void)viewport; +#if 0 + ImGuiStyle default_style; + //default_style.WindowPadding = ImVec2(0, 0); + //default_style.WindowBorderSize = 0.0f; + //default_style.ItemSpacing.y = 3.0f; + //default_style.FramePadding = ImVec2(0, 0); + default_style.ScaleAllSizes(viewport->DpiScale); + ImGuiStyle& style = ImGui::GetStyle(); + style = default_style; +#endif +} + +static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd)) + { + switch (msg) + { + case WM_CLOSE: + viewport->PlatformRequestClose = true; + return 0; + case WM_MOVE: + viewport->PlatformRequestMove = true; + break; + case WM_SIZE: + viewport->PlatformRequestResize = true; + break; + case WM_MOUSEACTIVATE: + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick) + return MA_NOACTIVATE; + break; + case WM_NCHITTEST: + // Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional). + // The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging. + // If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in + // your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system. + if (viewport->Flags & ImGuiViewportFlags_NoInputs) + return HTTRANSPARENT; + break; + } + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +static void ImGui_ImplWin32_InitPlatformInterface() +{ + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = ::GetModuleHandle(NULL); + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); + wcex.lpszMenuName = NULL; + wcex.lpszClassName = _T("ImGui Platform"); + wcex.hIconSm = NULL; + ::RegisterClassEx(&wcex); + + ImGui_ImplWin32_UpdateMonitors(); + + // Register platform interface (will be coupled with a renderer interface) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Platform_CreateWindow = ImGui_ImplWin32_CreateWindow; + platform_io.Platform_DestroyWindow = ImGui_ImplWin32_DestroyWindow; + platform_io.Platform_ShowWindow = ImGui_ImplWin32_ShowWindow; + platform_io.Platform_SetWindowPos = ImGui_ImplWin32_SetWindowPos; + platform_io.Platform_GetWindowPos = ImGui_ImplWin32_GetWindowPos; + platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize; + platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize; + platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus; + platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized; + platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle; + platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha; + platform_io.Platform_UpdateWindow = ImGui_ImplWin32_UpdateWindow; + platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI + platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI + + // Register main window handle (which is owned by the main application, not by us) + // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports. + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)(); + vd->Hwnd = bd->hWnd; + vd->HwndOwned = false; + main_viewport->PlatformUserData = vd; + main_viewport->PlatformHandle = (void*)bd->hWnd; +} + +static void ImGui_ImplWin32_ShutdownPlatformInterface() +{ + ::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(NULL)); + ImGui::DestroyPlatformWindows(); +} + +//--------------------------------------------------------------------------------------------------------- +// Transparency related helpers (optional) +//-------------------------------------------------------------------------------------------------------- + +#if defined(_MSC_VER) +#pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi' +#endif + +// [experimental] +// Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c +// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW) +void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) +{ + if (!_IsWindowsVistaOrGreater()) + return; + + BOOL composition; + if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition) + return; + + BOOL opaque; + DWORD color; + if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque)) + { + HRGN region = ::CreateRectRgn(0, 0, -1, -1); + DWM_BLURBEHIND bb = {}; + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = region; + bb.fEnable = TRUE; + ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb); + ::DeleteObject(region); + } + else + { + DWM_BLURBEHIND bb = {}; + bb.dwFlags = DWM_BB_ENABLE; + ::DwmEnableBlurBehindWindow((HWND)hwnd, &bb); + } +} + +//--------------------------------------------------------------------------------------------------------- diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.h b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.h new file mode 100644 index 000000000..d15dec575 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_win32.h @@ -0,0 +1,43 @@ +// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications) +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) + +// Implemented features: +// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once +#include "../imgui.h" // IMGUI_IMPL_API + +IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); +IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); + +// Win32 message handler your application need to call. +// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. +// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. +#if 0 +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +#endif + +// DPI-related helpers (optional) +// - Use to enable DPI awareness without having to create an application manifest. +// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. +// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. +// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, +// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. +IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor + +// Transparency related helpers (optional) [experimental] +// - Use to enable alpha compositing transparency with the desktop. +// - Use together with e.g. clearing your framebuffer with zero-alpha. +IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd diff --git a/libultraship/libultraship/Lib/ImGui/backends/vulkan/generate_spv.sh b/libultraship/libultraship/Lib/ImGui/backends/vulkan/generate_spv.sh new file mode 100644 index 000000000..948ef773d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/vulkan/generate_spv.sh @@ -0,0 +1,6 @@ +#!/bin/bash +## -V: create SPIR-V binary +## -x: save binary output as text-based 32-bit hexadecimal numbers +## -o: output file +glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert diff --git a/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.frag b/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.frag new file mode 100644 index 000000000..ce7e6f72b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.frag @@ -0,0 +1,14 @@ +#version 450 core +layout(location = 0) out vec4 fColor; + +layout(set=0, binding=0) uniform sampler2D sTexture; + +layout(location = 0) in struct { + vec4 Color; + vec2 UV; +} In; + +void main() +{ + fColor = In.Color * texture(sTexture, In.UV.st); +} diff --git a/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.vert b/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.vert new file mode 100644 index 000000000..9425365a5 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/backends/vulkan/glsl_shader.vert @@ -0,0 +1,25 @@ +#version 450 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; + +layout(push_constant) uniform uPushConstant { + vec2 uScale; + vec2 uTranslate; +} pc; + +out gl_PerVertex { + vec4 gl_Position; +}; + +layout(location = 0) out struct { + vec4 Color; + vec2 UV; +} Out; + +void main() +{ + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); +} diff --git a/libultraship/libultraship/Lib/ImGui/docs/BACKENDS.md b/libultraship/libultraship/Lib/ImGui/docs/BACKENDS.md new file mode 100644 index 000000000..cac11b6cc --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/BACKENDS.md @@ -0,0 +1,144 @@ +_(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md or view this file with any Markdown viewer)_ + +## Dear ImGui: Backends + +**The backends/ folder contains backends for popular platforms/graphics API, which you can use in +your application or engine to easily integrate Dear ImGui.** Each backend is typically self-contained in a pair of files: imgui_impl_XXXX.cpp + imgui_impl_XXXX.h. + +- The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, windowing.
      + e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc. + +- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.
      + e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc. + +- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.
      + e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same. + +An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources. +For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. + +**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.** + + +### What are backends + +Dear ImGui is highly portable and only requires a few things to run and render, typically: + + - Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure). + - Required: uploading the font atlas texture into graphics memory. + - Required: rendering indexed textured triangles with a clipping rectangle. + + Extra features are opt-in, our backends try to support as many as possible: + + - Optional: custom texture binding support. + - Optional: clipboard support. + - Optional: gamepad support. + - Optional: mouse cursor shape support. + - Optional: IME support. + - Optional: multi-viewports support. + etc. + +This is essentially what each backend is doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support). + +It is important to understand the difference between the core Dear ImGui library (files in the root folder) +and backends which we are describing here (backends/ folder). + +- Some issues may only be backend or platform specific. +- You should be able to write backends for pretty much any platform and any 3D graphics API. + e.g. you can get creative and use software rendering or render remotely on a different machine. + + +### Integrating a backend + +See "Getting Started" section of [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for more details. + + +### List of backends + +In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder: + +List of Platforms Backends: + + imgui_impl_android.cpp ; Android native app API + imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ + imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends) + imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org + imgui_impl_win32.cpp ; Win32 native API (Windows) + imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!) + +List of Renderer Backends: + + imgui_impl_dx9.cpp ; DirectX9 + imgui_impl_dx10.cpp ; DirectX10 + imgui_impl_dx11.cpp ; DirectX11 + imgui_impl_dx12.cpp ; DirectX12 + imgui_impl_metal.mm ; Metal (with ObjC) + imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context) + imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline) + imgui_impl_sdlrenderer.cpp; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+) + imgui_impl_vulkan.cpp ; Vulkan + imgui_impl_wgpu.cpp ; WebGPU + +List of high-level Frameworks Backends (combining Platform + Renderer): + + imgui_impl_allegro5.cpp + +Emscripten is also supported. +The [example_emscripten_opengl3](https://github.com/ocornut/imgui/tree/master/examples/example_emscripten_opengl3) app uses imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp, but other combos are possible. + +### Backends for third-party frameworks, graphics API or other languages + +See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others). + +### Recommended Backends + +If you are not sure which backend to use, the recommended platform/frameworks for portable applications: + +|Library |Website |Backend |Note | +|--------|--------|--------|-----| +| GLFW | https://github.com/glfw/glfw | imgui_impl_glfw.cpp | | +| SDL2 | https://www.libsdl.org | imgui_impl_sdl.cpp | | +| Sokol | https://github.com/floooh/sokol | [util/sokol_imgui.h](https://github.com/floooh/sokol/blob/master/util/sokol_imgui.h) | Lower-level than GLFW/SDL | + + +### Using a custom engine? + +You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities...
      +Think twice! + +If you are new to Dear ImGui, first try using the existing backends as-is. +You will save lots of time integrating the library. +You can LATER decide to rewrite yourself a custom backend if you really need to. +In most situations, custom backends have less features and more bugs than the standard backends we provide. +If you want portability, you can use multiple backends and choose between them either at compile time +or at runtime. + +**Example A**: your engine is built over Windows + DirectX11 but you have your own high-level rendering +system layered over DirectX11.
      +Suggestion: try using imgui_impl_win32.cpp + imgui_impl_dx11.cpp first. +Once it works, if you really need it you can replace the imgui_impl_dx11.cpp code with a +custom renderer using your own rendering functions, and keep using the standard Win32 code etc. + +**Example B**: your engine runs on Windows, Mac, Linux and uses DirectX11, Metal, Vulkan respectively.
      +Suggestion: use multiple generic backends! +Once it works, if you really need it you can replace parts of backends with your own abstractions. + +**Example C**: your engine runs on platforms we can't provide public backends for (e.g. PS4/PS5, Switch), +and you have high-level systems everywhere.
      +Suggestion: try using a non-portable backend first (e.g. win32 + underlying graphics API) to get +your desktop builds working first. This will get you running faster and get your acquainted with +how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API... + +Generally: +It is unlikely you will add value to your project by creating your own backend. + +Also: +The [multi-viewports feature](https://github.com/ocornut/imgui/issues/1542) of the 'docking' branch allows +Dear ImGui windows to be seamlessly detached from the main application window. This is achieved using an +extra layer to the Platform and Renderer backends, which allows Dear ImGui to communicate platform-specific +requests such as: "create an additional OS window", "create a render context", "get the OS position of this +window" etc. See 'ImGuiPlatformIO' for details. +Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult +than supporting single-viewport. +If you decide to use unmodified imgui_impl_XXXX.cpp files, you can automatically benefit from +improvements and fixes related to viewports and platform windows without extra work on your side. diff --git a/libultraship/libultraship/Lib/ImGui/docs/CHANGELOG.txt b/libultraship/libultraship/Lib/ImGui/docs/CHANGELOG.txt new file mode 100644 index 000000000..f15ba372e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/CHANGELOG.txt @@ -0,0 +1,3847 @@ +dear imgui +CHANGELOG + +This document holds the user-facing changelog that we also use in release notes. +We generally fold multiple commits pertaining to the same topic as a single entry. +Changes to backends are also included within the individual .cpp files of each backend. + +RELEASE NOTES: https://github.com/ocornut/imgui/releases +REPORT ISSUES: https://github.com/ocornut/imgui/issues +DISCUSS, ASK QUESTIONS: https://github.com/ocornut/imgui/discussions +FAQ https://www.dearimgui.org/faq/ +WIKI https://github.com/ocornut/imgui/wiki + +WHEN TO UPDATE? + +- Keeping your copy of Dear ImGui updated regularly is recommended. +- It is generally safe to sync to the latest commit in master or docking branches + The library is fairly stable and regressions tends to be fixed fast when reported. + +HOW TO UPDATE? + +- Overwrite every file except imconfig.h (if you have modified it). +- You may also locally branch to modify imconfig.h and merge latest into your branch. +- Read the `Breaking Changes` section (in imgui.cpp or here in the Changelog). +- If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. +- If you are dropping this repository in your codebase, please leave the demo and text files in there, they will be useful. +- You may diff your previous Changelog with the one you just copied and read that diff. +- You may enable `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in imconfig.h to forcefully disable legacy names and symbols. + Doing it every once in a while is a good way to make sure you are not using obsolete symbols. Dear ImGui is in active development, + and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. +- Please report any issue! + + +----------------------------------------------------------------------- + DOCKING+MULTI-VIEWPORT BRANCH (In Progress) +----------------------------------------------------------------------- + +DOCKING FEATURES +(see https://github.com/ocornut/imgui/wiki/Docking for quick intro) + +- Added Docking system: [BETA] (#2109, #351) + - Added ImGuiConfigFlags_DockingEnable flag to enable Docking. + Set with `io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;`. + - Added DockSpace(), DockSpaceOverViewport() API. + - Added ImGuiDockNodeFlags flags for DockSpace(). + - Added SetNextWindowDockID(), SetNextWindowClass() API. + - Added GetWindowDockID(), IsWindowDocked() API. + - Added ImGuiWindowFlags_NoDocking window flag to disable the possibility for a window to be docked. + Popup, Menu and Child windows always have the ImGuiWindowFlags_NoDocking flag set. + - Added ImGuiWindowClass to specify advanced docking/viewport related flags via SetNextWindowClass(). + - Added io.ConfigDockingNoSplit option. + - Added io.ConfigDockingWithShift option. + - Added io.ConfigDockingAlwaysTabBar option. + - Added io.ConfigDockingTransparentPayload option. + - Style: Added ImGuiCol_DockingPreview, ImGuiCol_DockingEmptyBg colors. + - Demo: Added "DockSpace" example app showcasing use of explicit dockspace nodes. + +MULTI-VIEWPORT FEATURES +(see https://github.com/ocornut/imgui/wiki/Multi-Viewports for quick intro) + +Breaking Changes: + +- IMPORTANT: When multi-viewports are enabled (with io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable), + all coordinates/positions will be in your natural OS coordinates space. It means that: + - Reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are _probably_ not what you want anymore. + Use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos). + - Likewise io.MousePos and GetMousePos() will use OS coordinates. + If you query mouse positions to interact with non-imgui coordinates you will need to offset them. + e.g. subtract GetWindowViewport()->Pos. +- IO: Removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (they were marked obsoleted, used to clip within the (0,0)..(DisplaySize) range). + +Other changes: +(FIXME: This need a fuller explanation!) + +- Added ImGuiPlatformIO structure and GetPlatformIO(). + - Similarly to ImGuiIO and GetIO(), this structure is the main point of communication for backends supporting multi-viewports. + - Backend sets functions in ImGuiPlatformIO to manipulate platform windows. + - ImGuiPlatformIO::Monitors is a list of platform monitors (input from backend) + - ImGuiPlatformIO::Viewports is a list of viewports (output from dear imgui) +- Added ImGuiPlatformMonitor to feed OS monitor information in the ImGuiPlatformIO::Monitors. +- Added GetWindowViewport(), SetNextWindowViewport(). +- Added GetWindowDpiScale(). +- Added GetOverlayDrawList(ImGuiViewport* viewport). + The no-parameter version of GetOverlayDrawList() return the overlay for the current window's viewport. +- Added UpdatePlatformWindows(), RenderPlatformWindowsDefault(), DestroyPlatformWindows() for usage in application setup. +- Added FindViewportByID(), FindViewportByPlatformHandle() for usage by backends. +- Added ImGuiConfigFlags_ViewportsEnable configuration flag and other viewport options. +- Added io.ConfigViewportsNoAutoMerge option. +- Added io.ConfigViewportsNoTaskBarIcon option. +- Added io.ConfigViewportsNoDecoration option. +- Added io.ConfigViewportsNoDefaultParent option. +- Added ImGuiBackendFlags_PlatformHasViewports, ImGuiBackendFlags_RendererHasViewports, ImGuiBackendFlags_HasMouseHoveredViewport backend flags. +- Added io.AddMouseViewportEvent() (optional _even_ for multi-viewport support, tied to ImGuiBackendFlags_HasMouseHoveredViewport flag). +- Expanded ImGuiViewport structure, ImGuiViewportFlags flags. +- Added ImGuiWindowClass and SetNextWindowClass() for passing viewport related hints to the OS/platform back-end. +- Examples: Renderer: OpenGL2, OpenGL3, DirectX9, DirectX10, DirectX11, DirectX12, Vulkan: Added support for multi-viewports. +- Examples: Platforms: Win32, GLFW, SDL2: Added support for multi-viewports. + Note that Linux/Mac still have inconsistent support for multi-viewports. If you want to help see https://github.com/ocornut/imgui/issues/2117. + + +----------------------------------------------------------------------- + VERSION 1.87 (Released 2022-02-07) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.87 + +Breaking Changes: + +- Removed support for pre-C++11 compilers. We'll stop supporting VS2010. (#4537) +- Reworked IO mouse input API: (#4921, #4858) [@thedmd, @ocornut] + - Added io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions, + obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc. + - This enable input queue trickling to support low framerates. (#2787, #1992, #3383, #2525, #1320) +- Reworked IO keyboard input API: (#4921, #2625, #3724) [@thedmd, @ocornut] + - Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays. + - For keyboard modifiers, you can call io.AddKeyEvent() with ImGuiKey_ModXXX values, + obsoleting writing directly to io.KeyCtrl, io.KeyShift etc. + - Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices. + - Added full range of key enums in ImGuiKey (e.g. ImGuiKey_F1). + - Added GetKeyName() helper function. + - Obsoleted GetKeyIndex(): it is now unnecessary and will now return the same value. + - All keyboard related functions taking 'int user_key_index' now take 'ImGuiKey key': + - IsKeyDown(), IsKeyPressed(), IsKeyReleased(), GetKeyPressedAmount(). + - Added io.ConfigInputTrickleEventQueue (defaulting to true) to disable input queue trickling. + - Backward compatibility: + - All backends updated to use new functions. + - Old backends populating those arrays should still work! + - Calling e.g. IsKeyPressed(MY_NATIVE_KEY_XXX) will still work! (for a while) + - Those legacy arrays will only be disabled if '#define IMGUI_DISABLE_OBSOLETE_KEYIO' is set in your imconfig. + In a few versions, IMGUI_DISABLE_OBSOLETE_FUNCTIONS will automatically enable IMGUI_DISABLE_OBSOLETE_KEYIO, + so this will be moved into the regular obsolescence path. + - BREAKING: If your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A") + this is a use case that will now assert and be breaking for your old backend. + - Transition guide: + - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) + - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) + - Backend writing to io.KeyMap[],KeysDown[] -> backend should call io.AddKeyEvent(), if legacy indexing is desired, call io.SetKeyEventNativeData() + - Basically the trick we took advantage of is that we previously only supported native keycode from 0 to 511, + so ImGuiKey values can still express a legacy native keycode, and new named keys are all >= 512. + - This will enable a few things in the future: + - Access to portable keys allows for backend-agnostic keyboard input code. Until now it was difficult + to share code using keyboard across project because of this gap. (#2625, #3724) + - Access to full key ranges will allow us to develop a proper keyboard shortcut system. (#456) + - io.SetKeyEventNativeData() include native keycode/scancode which may later be exposed. (#3141, #2959) +- Reworked IO nav/gamepad input API and unifying inputs sources: (#4921, #4858, #787) + - Added full range of ImGuiKey_GamepadXXXX enums (e.g. ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadR2) to use with + io.AddKeyEvent(), io.AddKeyAnalogEvent(). + - Added io.AddKeyAnalogEvent() function, obsoleting writing directly to io.NavInputs[] arrays. +- Renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. (#2625) +- Removed support for legacy arithmetic operators (+,+-,*,/) when inputing text into a slider/drag. (#4917, #3184) + This doesn't break any api/code but a feature that was accessible by end-users (which seemingly no one used). + (Instead you may implement custom expression evaluators to provide a better version of this). +- Backends: GLFW: backend now uses glfwSetCursorPosCallback(). + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: nothing to do. is already done for you. + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callback + using glfwSetCursorPosCallback() and forward it to the backend function ImGui_ImplGlfw_CursorPosCallback(). +- Backends: SDL: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so backend can call + SDL_GetRendererOutputSize() to obtain framebuffer size valid for hi-dpi. (#4927) [@Clownacy] +- Commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019) + - ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen() + - ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x + - ImGui::TreeAdvanceToLabelPos() -> use ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetTreeNodeToLabelSpacing()); + - ImFontAtlas::CustomRect -> use ImFontAtlasCustomRect + - ImGuiColorEditFlags_RGB/HSV/HEX -> use ImGuiColorEditFlags_DisplayRGB/HSV/Hex +- Removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn() for IME support. + Because this field was mostly only ever used by Dear ImGui internally, not by backends nor the vast majority + of user code, this should only affect a very small fraction for users who are already very IME-aware. +- Obsoleted 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'. + This removes an incompatibility between 'master' and 'multi-viewports' backends and toward enabling + better support for IME. Updated backends accordingly. Because the old field is set by existing backends, + we are keeping it (marked as obsolete). + +Other Changes: + +- IO: Added event based input queue API, which now trickles events to support low framerates. [@thedmd, @ocornut] + Previously the most common issue case (button presses in low framerates) was handled by backend. This is now + handled by core automatically for all kind of inputs. (#4858, #2787, #1992, #3383, #2525, #1320) + - New IO functions for keyboard/gamepad: AddKeyEvent(), AddKeyAnalogEvent(). + - New IO functions for mouse: AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent(). +- IO: Unified key enums allow using key functions on key mods and gamepad values. +- Fixed CTRL+Tab into an empty window causing artifacts on the highlight rectangle due to bad reordering on ImDrawCmd. +- Fixed a situation where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles, + which would makes the draw operation of some backends assert (e.g. Metal with debugging). (#4857) +- Popups: Fixed a regression crash when a new window is created after a modal on the same frame. (#4920) [@rokups] +- Popups: Fixed an issue when reopening a same popup multiple times would offset them by 1 pixel on the right. (#4936) +- Tables, ImDrawListSplitter: Fixed erroneously stripping trailing ImDrawList::AddCallback() when submitted in + last column or last channel and when there are no other drawing operation. (#4843, #4844) [@hoffstadt] +- Tables: Fixed positioning of Sort icon on right-most column with some settings (not resizable + no borders). (#4918). +- Nav: Fixed gamepad navigation in wrapping popups not wrapping all the way. (#4365) +- Sliders, Drags: Fixed text input of values with a leading sign, common when using a format enforcing sign. (#4917) +- Demo: draw a section of keyboard in "Inputs > Keyboard, Gamepad & Navigation state" to visualize keys. [@thedmd] +- Platform IME: changed io.ImeSetInputScreenPosFn() to io.SetPlatformImeDataFn() API, + now taking a ImGuiPlatformImeData structure which we can more easily extend in the future. +- Platform IME: moved io.ImeWindowHandle to GetMainViewport()->PlatformHandleRaw. +- Platform IME: add ImGuiPlatformImeData::WantVisible, hide IME composition window when not used. (#2589) [@actboy168] +- Platform IME: add ImGuiPlatformImeData::InputLineHeight. (#3113) [@liuliu] +- Platform IME: [windows] call ImmSetCandidateWindow() to position candidate window. +- Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. + We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of + other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625) +- Backends: GLFW: Submit keys and key mods using io.AddKeyEvent(). (#2625, #4921) +- Backends: GLFW: Submit mouse data using io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions. (#4921) +- Backends: GLFW: Retrieve mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured. +- Backends: GLFW: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921) +- Backends: GLFW: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing + callbacks after iniitializing backend. (#4981) +- Backends: Win32: Submit keys and key mods using io.AddKeyEvent(). (#2625, #4921) +- Backends: Win32: Retrieve mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured. +- Backends: Win32: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921) +- Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +- Backends: Win32: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921) +- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. (#456, #2625) +- Backends: SDL: Submit key data using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: SDL: Retrieve mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured. +- Backends: SDL: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921) +- Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +- Backends: SDL: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921) +- Backends: Allegro5: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: Allegro5: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921) +- Backends: OSX: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: OSX: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921) +- Backends: OSX: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921) +- Backends: OSX: Added basic Platform IME support. (#3108, #2598) [@liuliu] +- Backends: OSX: Fix Game Controller nav mapping to use shoulder for both focusing and tweak speed. (#4759) +- Backends: OSX: Fix building with old Xcode versions that are missing gamepad features. [@rokups] +- Backends: OSX: Forward keyDown/keyUp events to OS when unused by Dear ImGui. +- Backends: Android, GLUT: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: Android, GLUT: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) +- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk] + It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers. +- Backends: OpenGL3: Fix OpenGL ES2 includes on Apple systems. [@rokups] +- Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz] + Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file. +- Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but + can theoretically be created by user code manipulating a ImDrawList. (#4857) +- Backends: Vulkan: Added support for ImTextureID as VkDescriptorSet, add ImGui_ImplVulkan_AddTexture(). (#914) [@martty] +- Backends: SDL_Renderer: Fix texture atlas format on big-endian hardware (#4927) [@Clownacy] +- Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and + wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev] + +Docking+Viewports Branch: + +- Docking: Fixed a CTRL+TAB crash when aiming at an empty docked window. (#4792) +- Docking: Tabs use their own identifier instead of the Window identifier. + (This will invalidate some stored .ini data such as last selected tab, sorry!) +- Docking: Fixed size constraints not working on single window holding on a dock id (still doesn't work on docked windows). +- Docking: Fixed CTRL+TAB back into a docked window not selecting menu layer when no item are on main layer. +- Viewports, IO: Added io.AddMouseViewportEvent() function to queue hovered viewport change (when known by backend). +- Viewports: Relaxed specs for backend supporting ImGuiBackendFlags_HasMouseHoveredViewport: it is now _optional_ + for the backend to have to ignore viewports with the _NoInputs flag when call io.AddMouseViewportEvent(). It is + much better if they can (Win32 and GLFW 3.3+ backends can, SDL and GLFW 3.2 backends cannot, they are lacking data). + A concrete example is: when dragging a viewport for docking, the viewport is marked with _NoInputs to allow us + to pick the target viewports for docking. If the backend reports a viewport with _NoInputs when calling the + io.AddMouseViewportEvent() function, then Dear ImGui will revert to its flawed heuristic to find the viewport under. + By lowering those specs, we allow the SDL and more backend to support this, only relying on the heuristic in a few + drag and drop situations rather that relying on it everywhere. +- Viewports: Fixed a CTRL+TAB crash with viewports enabled when the window list needs to appears in + its own viewport (regression from 1.86). (#4023, #787) +- Viewports: Fixed active InputText() from preventing viewports to merge. (#4212) +- Backends: SDL: Added support for ImGuiBackendFlags_HasMouseHoveredViewport now that its specs have been lowered. +- (Breaking) Removed ImGuiPlatformIO::Platform_SetImeInputPos() in favor of newly standardized + io.SetPlatformImeDataFn() function. Should not affect more than default backends. + + +----------------------------------------------------------------------- + VERSION 1.86 (Released 2021-12-22) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.86 + +Breaking Changes: + +- Removed CalcListClipping() function. Prefer using ImGuiListClipper which can return non-contiguous ranges. + Please open an issue if you think you really need this function. (#3841) +- Backends: OSX: Added NSView* parameter to ImGui_ImplOSX_Init(). (#4759) [@stuartcarnie] +- Backends: Marmalade: Removed obsolete Marmalade backend (imgui_impl_marmalade.cpp) + example app. (#368, #375) + Find last supported version at https://github.com/ocornut/imgui/wiki/Bindings + +Other Changes: + +- Added an assertion for the common user mistake of using "" as an identifier at the root level of a window + instead of using "##something". Empty identifiers are valid and useful in a very small amount of cases, + but 99.9% of the time if you need an empty label you should use "##something". (#1414, #2562, #2807, #4008, + #4158, #4375, #4548, #4657, #4796). READ THE FAQ ABOUT HOW THE ID STACK WORKS -> https://dearimgui.org/faq +- Added GetMouseClickedCount() function, returning the number of successive clicks. (#3229) [@kudaba] + (so IsMouseDoubleClicked(ImGuiMouseButton_Left) is same as GetMouseClickedCount(ImGuiMouseButton_Left) == 2, + but it allows testing for triple clicks and more). +- Modals: fixed issue hovering popups inside a child windows inside a modal. (#4676, #4527) +- Modals, Popups, Windows: changes how appearing windows are interrupting popups and modals. (#4317) [@rokups] + - appearing windows created from within the begin stack of a popup/modal will no longer close it. + - appearing windows created not within the begin stack of a modal will no longer close the modal, + and automatically appear behind it. +- Fixed IsWindowFocused()/IsWindowHovered() issues with child windows inside popups. (#4676) +- Nav: Ctrl+tabbing to cycle through windows is now enabled regardless of using the _NavEnableKeyboard + configuration flag. This is part of an effort to generalize the use of keyboard inputs. (#4023, #787). + Note that while this is active you can also moving windows (with arrow) and resize (shift+arrows). +- Nav: tabbing now cycles through clipped items and scroll accordingly. (#4449) +- Nav: pressing PageUp/PageDown/Home/End when in Menu layer automatically moves back to Main layer. +- Nav: fixed resizing window from borders setting navigation to Menu layer. +- Nav: prevent child from clipping items when using _NavFlattened and parent has a pending request. +- Nav: pressing Esc to exit a child window reactivates the Nav highlight if it was disabled by mouse. +- Nav: with ImGuiConfigFlags_NavEnableSetMousePos enabled: Fixed absolute mouse position when using + Home/End leads to scrolling. Fixed not setting mouse position when a failed move request (e.g. when + already at edge) reactivates the navigation highlight. +- Menus: fixed closing a menu inside a popup/modal by clicking on the popup/modal. (#3496, #4797) +- Menus: fixed closing a menu by clicking on its menu-bar item when inside a popup. (#3496, #4797) [@xndcn] +- Menus: fixed menu inside a popup/modal not inhibiting hovering of items in the popup/modal. (#3496, #4797) +- Menus: fixed sub-menu items inside a popups from closing the popup. +- Menus: fixed top-level menu from not consistently using style.PopupRounding. (#4788) +- InputText, Nav: fixed repeated calls to SetKeyboardFocusHere() preventing to use InputText(). (#4682) +- Inputtext, Nav: fixed using SetKeyboardFocusHere() on InputTextMultiline(). (#4761) +- InputText: made double-click select word, triple-line select line. Word delimitation logic differs + slightly from the one used by CTRL+arrows. (#2244) +- InputText: fixed ReadOnly flag preventing callbacks from receiving the text buffer. (#4762) [@actondev] +- InputText: fixed Shift+Delete from not cutting into clipboard. (#4818, #1541) [@corporateshark] +- InputTextMultiline: fixed incorrect padding when FrameBorder > 0. (#3781, #4794) +- InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (#3781, #4794) +- Separator: fixed cover all columns while called inside a table. (#4787) +- Clipper: currently focused item is automatically included in clipper range. + Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is + still submitted. (#3841, #1725) [@GamingMinds-DanielC, @ocornut] +- Clipper: added ForceDisplayRangeByIndices() to force a given item (or several) to be stepped out + during a clipping operation. (#3841) [@@GamingMinds-DanielC] +- Clipper: rework so gamepad/keyboard navigation doesn't create spikes in number of items requested + by the clipper to display. (#3841) +- Clipper: fixed content height declaration slightly mismatching the value of when not using a clipper. + (an additional ItemSpacing.y was declared, affecting scrollbar range). +- Clipper: various and incomplete changes to tame down scrolling and precision issues on very large ranges. + Passing an explicit height to the clipper now allows larger ranges. (#3609, #3962). +- Clipper: fixed invalid state when number of frozen table row is smaller than ItemCount. +- Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceAllowNullID doesn't lose + tooltip when scrolling. (#143) +- Fonts: fixed infinite loop in ImFontGlyphRangesBuilder::AddRanges() when passing UINT16_MAX or UINT32_MAX + without the IMGUI_USE_WCHAR32 compile-time option. (#4802) [@SlavicPotato] +- Metrics: Added a node showing windows in submission order and showing the Begin() stack. +- Misc: Added missing ImGuiMouseCursor_NotAllowed cursor for software rendering (when the + io.MouseDrawCursor flag is enabled). (#4713) [@nobody-special666] +- Misc: Fixed software mouse cursor being rendered multiple times if Render() is called more than once. +- Misc: Fix MinGW DLL build issue (when IMGUI_API is defined). [@rokups] +- CI: Add MinGW DLL build to test suite. [@rokups] +- Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce + likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling + vkCmdSetScissor() explicitly every frame. (#4644) +- Backends: OpenGL3: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports + with some Intel HD drivers, and perhaps improve performances. (#4468, #4504, #2981, #3381) [@parbo] +- Backends: OpenGL2, Allegro5, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field. + This is an old bug, but due to the way we created drawlists, it never had any visible side-effect before. + The new code for handling Modal and CTRL+Tab dimming/whitening recently made the bug surface. (#4790) +- Backends: Win32: Store left/right variants of Ctrl/Shift/Alt mods in KeysDown[] array. (#2625) [@thedmd] +- Backends: DX12: Fixed DRAW_EMPTY_SCISSOR_RECTANGLE warnings. (#4775) +- Backends: SDL_Renderer: Added support for large meshes (64k+ vertices) with 16-bit indices, + enabling 'ImGuiBackendFlags_RendererHasVtxOffset' in the backend. (#3926) [@rokups] +- Backends: SDL_Renderer: Fix for SDL 2.0.19+ RenderGeometryRaw() API signature change. (#4819) [@sridenour] +- Backends: OSX: Generally fix keyboard support. Keyboard arrays indexed using kVK_* codes, e.g. + ImGui::IsKeyPressed(kVK_Space). Don't set mouse cursor shape unconditionally. Handle two fingers scroll + cancel event. (#4759, #4253, #1873) [@stuartcarnie] +- Backends: OSX: Add Game Controller support (need linking GameController framework) (#4759) [@stuartcarnie] +- Backends: WebGPU: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer() and + wgpuRenderPassEncoderSetIndexBuffer() functions as validation layers appears to not do what the + in-flux specs says. (#4766) [@meshula] + +Docking+Viewports Branch: + +- Docking: Revert removal of io.ConfigDockingWithShift config option (removed in 1.83). (#4643) +- Docking: Fixed a bug undocking windows docked into a non-visible or _KeepAliveOnly dockspace + when unrelated windows submitted before the dockspace have dynamic visibility. (#4757) +- Docking, Style: Docked windows honor ImGuiCol_WindowBg. (#2700, #2539) +- Docking, Style: Docked windows honor display their border properly. (#2522) +- Docking: Fixed incorrectly rounded tab bars for dock node that are not at the top of their dock tree. +- Docking: Fixed single-frame node pos/size inconsistencies when window stop or start being submitted. +- Docking: Prevent docking any window created above a popup/modal. (#4317) +- Viewports: Made it possible to explicitly assign ImGuiWindowClass::ParentViewportId to 0 in order + to ensure a window is not parented. Previously this would use the global default (which might be 0, + but not always as it would depend on io.ConfigViewportsNoDefaultParent). (#3152, #2871) +- Viewports: Fixed tooltip in own viewport over modal from being incorrectly dimmed. (#4729) +- Viewports: Fixed CTRL+TAB highlight outline on docked windows not always fitting in host viewport. +- Backends: Made it possible to shutdown default Platform Backends before the Renderer backends. (#4656) +- Disabled: Fixed nested BeginDisabled()/EndDisabled() bug in Docking branch due to bad merge. (#4655, #4452, #4453, #4462) + + +----------------------------------------------------------------------- + VERSION 1.85 (Released 2021-10-12) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.85 + +This is the last release officially supporting C++03 and Visual Studio 2008/2010. (#4537) +We expect that the next release will require a subset of the C++11 language (VS 2012~, GCC 4.8.1, Clang 3.3). +We may use some C++11 language features but we will not use any C++ library headers. +If you are stuck on ancient compiler you may need to stay at this version onward. + +Breaking Changes: + +- Removed GetWindowContentRegionWidth() function. keep inline redirection helper. + Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not + very useful in practice, and the only use of it in the demo was illfit. + Using 'GetContentRegionAvail().x' is generally a better choice. +- (Docking branch) IsWindowFocused() and IsWindowHovered() with only the _ChildWindows flag + and without the _RootWindow flag used to leak docking hierarchy, so a docked window would + return as the child of the window hosting the dockspace. This was inconsistent and incorrect + with other behaviors so we fixed it. Added a new _DockHierarchy flag to opt-in this behavior. + +Other Changes: + +- Debug: Stack Tool: Added "Stack Tool" available in "Demo->Tools->Stack Tool", "Metrics->Tools", + or by calling the ShowStackToolWindow() function. The tool run queries on hovered id to display + details about individual components that were hashed to create an ID. It helps understanding + the ID stack system and debugging potential ID collisions. (#4631) [@ocornut, @rokups] +- Windows: Fixed background order of overlapping childs submitted sequentially. (#4493) +- IsWindowFocused: Added ImGuiFocusedFlags_NoPopupHierarchy flag allowing to exclude child popups + from the tested windows when combined with _ChildWindows. +- IsWindowHovered: Added ImGuiHoveredFlags_NoPopupHierarchy flag allowing to exclude child popups + from the tested windows when combined with _ChildWindows. +- InputTextMultiline: Fixed label size not being included into window contents rect unless + the whole widget is clipped. +- InputText: Allow activating/cancelling/validating input with gamepad nav events. (#2321, #4552) +- InputText: Fixed selection rectangle appearing one frame late when selecting all. +- TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform + to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615) +- Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211) +- Nav: Fixed using SetKeyboardFocusHere() on non-visible/clipped items. It now works and will scroll + toward the item. When called during a frame where the parent window is appearing, scrolling will + aim to center the item in the window. When calling during a frame where the parent window is already + visible, scrolling will aim to scroll as little as possible to make the item visible. We will later + expose scroll functions and flags in public API to select those behaviors. (#343, #4079, #2352) +- Nav: Fixed using SetKeyboardFocusHere() from activating a different item on the next frame if + submitted items have changed during that frame. (#432) +- Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when + the ImGuiConfigFlags_NavEnableSetMousePos config flag is set. +- Nav: Fixed a few widgets from not setting reference keyboard/gamepad navigation ID when + activated with mouse. More specifically: BeginTabItem(), the scrolling arrows of BeginTabBar(), + the arrow section of TreeNode(), the +/- buttons of InputInt()/InputFloat(), Selectable() with + ImGuiSelectableFlags_SelectOnRelease. More generally: any direct use of ButtonBehavior() with + the PressedOnClick/PressedOnDoubleClick/PressedOnRelease button policy. +- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation + is disabled. (#4547, #4439) [@PathogenDavid] +- Nav: Fixed vertical scoring offset when wrapping on Y in a decorated window. +- Nav: Improve scrolling behavior when navigating to an item larger than view. +- TreePush(): removed unnecessary/inconsistent legacy behavior where passing a NULL value to + the TreePush(const char*) and TreePush(const void*) functions would use an hard-coded replacement. + The only situation where that change would make a meaningful difference is TreePush((const char*)NULL) + (_explicitly_ casting a null pointer to const char*), which is unlikely and will now crash. + You may replace it with anything else. +- ColorEdit4: Fixed not being able to change hue when saturation is 0. (#4014) [@rokups] +- ColorEdit4: Fixed hue resetting to 0 when it is set to 255. [@rokups] +- ColorEdit4: Fixed hue value jitter when source color is stored as RGB in 32-bit integer and perform + RGB<>HSV round trips every frames. [@rokups] +- ColorPicker4: Fixed picker being unable to select exact 1.0f color when dragging toward the edges + of the SV square (previously picked 0.999989986f). (#3517) [@rokups] +- Menus: Fixed vertical alignments of MenuItem() calls within a menu bar (broken in 1.84). (#4538) +- Menus: Improve closing logic when moving diagonally in empty between between parent and child menus to + accommodate for varying font size and dpi. +- Menus: Fixed crash when navigating left inside a child window inside a sub-menu. (#4510). +- Menus: Fixed an assertion happening in some situations when closing nested menus (broken in 1.83). (#4640) +- Drag and Drop: Fixed using BeginDragDropSource() inside a BeginChild() that returned false. (#4515) +- PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini] +- Misc: Added asserts for missing PopItemFlag() calls. +- Misc: Fixed printf-style format checks on Clang+MinGW. (#4626, #4183, #3592) [@guusw] +- IO: Added 'io.WantCaptureMouseUnlessPopupClose' alternative to `io.WantCaptureMouse'. (#4480) + This allows apps to receive the click on void when that click is used to close popup (by default, + clicking on a void when a popup is open will close the popup but not release io.WantCaptureMouse). +- Fonts: imgui_freetype: Fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL + (which apparently happens with Freetype 2.11). (#4394, #4145?). +- Fonts: Fixed ImFontAtlas::ClearInputData() marking atlas as not built. (#4455, #3487) +- Backends: Added more implicit asserts to detect invalid/redundant calls to Shutdown functions. (#4562) +- Backends: OpenGL3: Fixed our custom GL loader conflicting with user using GL3W. (#4445) [@rokups] +- Backends: WebGPU: Fixed for latest specs. (#4472, #4512) [@Kangz, @bfierz] +- Backends: SDL_Renderer: Added SDL_Renderer backend compatible with upcoming SDL 2.0.18. (#3926) [@1bsyl] +- Backends: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted via + a direct unclipped PushClipRect() call. (#4464) +- Backends: OSX: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards. (#4557, #4563) [@lfnoise] +- Backends: All renderers: Normalize clipping rect handling across backends. (#4464) +- Examples: Added SDL + SDL_Renderer example in "examples/example_sdl_sdlrenderer/" folder. (#3926) [@1bsyl] + +Docking+Viewports Branch: + +- IsWindowFocused: Fixed using ImGuiFocusedFlags_ChildWindows (without _RootWindow) from leaking the + docking hierarchy. Added ImGuiFocusedFlags_DockHierarchy flag to consider docking hierarchy in the test. +- IsWindowHovered: Fixed using ImGuiHoveredFlags_ChildWindows (without _RootWindow) from leaking the + docking hierarchy. Added ImGuiHoveredFlags_DockHierarchy flag to consider docking hierarchy in the test. +- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation + is disabled. (#4547, #4439) [@PathogenDavid] +- Docking: Fixed IsItemHovered() and functions depending on it (e.g. BeginPopupContextItem()) when + called after Begin() on a docked window (broken 2021/03/04). (#3851) +- Docking: Improved resizing system so that non-central zone are better at keeping their fixed size. + The algorithm is still not handling the allocation of size ideally for nested sibling, but it got better. +- Docking: Fixed settings load issue when mouse wheeling. (#4310) +- Docking: Fixed manually created floating node with a central node from not hiding when windows are gone. +- Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin() + that returned false because the window is docked. (#4515) +- Viewports: Fixed a crash while a window owning its viewport disappear while being dragged. + It would manifest when e.g. reconfiguring dock nodes while dragging. +- Viewports: Fixed unnecessary creation of temporary viewports when multiple docked windows + got reassigned to a new node (created mid-frame) which already has a HostWindow. +- Viewports: Fixed window with viewport ini data immediately merged into a host viewport from + leaving a temporary viewport alive for a frame (would leak into backend). + + +----------------------------------------------------------------------- + VERSION 1.84.2 (Released 2021-08-23) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.2 + +- Disabled: Fixed nested BeginDisabled()/EndDisabled() calls. (#211, #4452, #4453, #4462) [@Legulysse] +- Backends: OpenGL3: OpenGL: Fixed ES 3.0 shader ("#version 300 es") to use normal precision + floats. Avoid wobbly rendering at HD resolutions. (#4463) [@nicolasnoble] + + +----------------------------------------------------------------------- + VERSION 1.84.1 (Released 2021-08-20) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.1 + +- Disabled: Fixed BeginDisabled(false) - BeginDisabled(true) was working. (#211, #4452, #4453) + + +----------------------------------------------------------------------- + VERSION 1.84 (Released 2021-08-20) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84 + +Breaking Changes: + +- Commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): + - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() + - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder +- Backends: OpenGL3: added a third source file "imgui_impl_opengl3_loader.h". [@rokups] +- Backends: GLFW: backend now uses glfwSetCursorEnterCallback(). (#3751, #4377, #2445) +- Backends: GLFW: backend now uses glfwSetWindowFocusCallback(). (#4388) [@thedmd] + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: this is already done for you. + - If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callbacks + and forward them to the backend: + - Register glfwSetCursorEnterCallback, forward events to ImGui_ImplGlfw_CursorEnterCallback(). + - Register glfwSetWindowFocusCallback, forward events to ImGui_ImplGlfw_WindowFocusCallback(). +- Backends: SDL2: removed unnecessary SDL_Window* parameter from ImGui_ImplSDL2_NewFrame(). (#3244) [@funchal] + Kept inline redirection function (will obsolete). +- Backends: SDL2: backend needs to set 'SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1")' in order to + receive mouse clicks events on window focus, otherwise SDL doesn't emit the event. (#3751, #4377, #2445) + This is unfortunately a global SDL setting, so enabling it _might_ have a side-effect on your application. + It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: + you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED event). +- Internals: (for custom widgets): because disabled items now sets HoveredId, if you want custom widgets to + not react as hovered when disabled, in the majority of use cases it is preferable to check the "hovered" + return value of ButtonBehavior() rather than (HoveredId == id). + +Other Changes: + +- IO: Added io.AddFocusEvent() api for backend to tell when host window has gained/lost focus. (#4388) [@thedmd] + If you use a custom backend, consider adding support for this! +- Disabled: added BeginDisabled()/EndDisabled() api to create a scope where interactions are disabled. (#211) + - Added style.DisabledAlpha (default to 0.60f) and ImGuiStyleVar_DisabledAlpha. (#211) + - Unlike the internal-and-undocumented-but-somehow-known PushItemFlag(ImGuiItemFlags_Disabled), this also alters + visuals. Currently this is done by lowering alpha of all widgets. Future styling system may do that differently. + - Disabled items set HoveredId, allowing e.g. HoveredIdTimer to run. (#211, #3419) [@rokups] + - Disabled items more consistently release ActiveId if the active item got disabled. (#211) + - Nav: Fixed disabled items from being candidate for default focus. (#211, #787) + - Fixed Selectable() selection not showing when disabled. (#211) + - Fixed IsItemHovered() returning true on disabled item when navigated to. (#211) + - Fixed IsItemHovered() when popping disabled state after item, or when using Selectable_Disabled. (#211) +- Windows: ImGuiWindowFlags_UnsavedDocument/ImGuiTabItemFlags_UnsavedDocument displays a dot instead of a '*' so it + is independent from font style. When in a tab, the dot is displayed at the same position as the close button. + Added extra comments to clarify the purpose of this flag in the context of docked windows. +- Tables: Added ImGuiTableColumnFlags_Disabled acting a master disable over (hidden from user/context menu). (#3935) +- Tables: Clarified that TableSetColumnEnabled() requires the table to use the ImGuiTableFlags_Hideable flag, + because it manipulates the user-accessible show/hide state. (#3935) +- Tables: Added ImGuiTableColumnFlags_NoHeaderLabel to request TableHeadersRow() to not submit label for a column. + Convenient for some small columns. Name will still appear in context menu. (#4206). +- Tables: Fixed columns order on TableSetupScrollFreeze() if previous data got frozen columns out of their section. +- Tables: Fixed invalid data in TableGetSortSpecs() when SpecsDirty flag is unset. (#4233) +- TabBar: Fixed using more than 32 KB-worth of tab names. (#4176) +- InputInt/InputFloat: When used with Steps values and _ReadOnly flag, the step button look disabled. (#211) +- InputText: Fixed named filtering flags disabling newline or tabs in multiline inputs (#4409, #4410) [@kfsone] +- Drag and Drop: drop target highlight doesn't try to bypass host clipping rectangle. (#4281, #3272) +- Drag and Drop: Fixed using AcceptDragDropPayload() with ImGuiDragDropFlags_AcceptNoPreviewTooltip. [@JeffM2501] +- Menus: MenuItem() and BeginMenu() are not affected/overlapping when style.SelectableTextAlign is altered. +- Menus: Fixed hovering a disabled menu or menu item not closing other menus. (#211) +- Popups: Fixed BeginPopup/OpenPopup sequence failing when there are no focused windows. (#4308) [@rokups] +- Nav: Alt doesn't toggle menu layer if other modifiers are held. (#4439) +- Fixed printf-style format checks on non-MinGW flavors. (#4183, #3592) +- Fonts: Functions with a 'float size_pixels' parameter can accept zero if it is set in ImFontSize::SizePixels. +- Fonts: Prefer using U+FFFD character for fallback instead of '?', if available. (#4269) +- Fonts: Use U+FF0E dot character to construct an ellipsis if U+002E '.' is not available. (#4269) +- Fonts: Added U+FFFD ("replacement character") to default asian glyphs ranges. (#4269) +- Fonts: Fixed calling ClearTexData() (clearing CPU side font data) triggering an assert in NewFrame(). (#3487) +- DrawList: Fixed AddCircle/AddCircleFilled() with auto-tesselation not using accelerated paths for small circles. + Fixed AddCircle/AddCircleFilled() with 12 segments which had a broken edge. (#4419, #4421) [@thedmd] +- Demo: Fixed requirement in 1.83 to link with imgui_demo.cpp if IMGUI_DISABLE_METRICS_WINDOW is not set. (#4171) + Normally the right way to disable compiling the demo is to set IMGUI_DISABLE_DEMO_WINDOWS, but we want to avoid + implying that the file is required. +- Metrics: Fixed a crash when inspecting the individual draw command of a foreground drawlist. [@rokups] +- Backends: Reorganized most backends (Win32, SDL, GLFW, OpenGL2/3, DX9/10/11/12, Vulkan, Allegro) to pull their + data from a single structure stored inside the main Dear ImGui context. This facilitate/allow usage of standard + backends with multiple-contexts BUT is only partially tested and not well supported. It is generally advised to + instead use the multi-viewports feature of docking branch where a single Dear ImGui context can be used across + multiple windows. (#586, #1851, #2004, #3012, #3934, #4141) +- Backends: Win32: Rework to handle certain Windows 8.1/10 features without a manifest. (#4200, #4191) + - ImGui_ImplWin32_GetDpiScaleForMonitor() will handle per-monitor DPI on Windows 10 without a manifest. + - ImGui_ImplWin32_EnableDpiAwareness() will call SetProcessDpiAwareness() fallback on Windows 8.1 without a manifest. +- Backends: Win32: IME functions are disabled by default for non-Visual Studio compilers (MinGW etc.). Enable with + '#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS' for those compilers. Undo change from 1.82. (#2590, #738, #4185, #4301) +- Backends: Win32: Mouse position is correctly reported when the host window is hovered but not focused. (#2445, #2696, #3751, #4377) +- Backends: Win32, SDL2, GLFW, OSX, Allegro: now calling io.AddFocusEvent() on focus gain/loss. (#4388) [@thedmd] + This allow us to ignore certain inputs on focus loss (previously relied on mouse loss but backends are now + reporting mouse even when host window is unfocused, as per #2445, #2696, #3751, #4377) +- Backends: Fixed keyboard modifiers being reported when host window doesn't have focus. (#2622) +- Backends: GLFW: Mouse position is correctly reported when the host window is hovered but not focused. (#3751, #4377, #2445) + (backend now uses glfwSetCursorEnterCallback(). If you called ImGui_ImplGlfw_InitXXX with install_callbacks=false, you will + need to install this callback and forward the data to the backend via ImGui_ImplGlfw_CursorEnterCallback). +- Backends: SDL2: Mouse position is correctly reported when the host window is hovered but not focused. (#3751, #4377, #2445) + (enabled with SDL 2.0.5+ as SDL_GetMouseFocus() is only usable with SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH). +- Backends: DX9: Explicitly disable texture state stages after >= 1. (#4268) [@NZJenkins] +- Backends: DX12: Fix texture casting crash on 32-bit systems (introduced on 2021/05/19 and v1.83) + added comments + about building on 32-bit systems. (#4225) [@kingofthebongo2008] +- Backends: OpenGL3: Embed our own minimal GL headers/loader (imgui_impl_opengl3_loader.h) based on gl3w. + Reduces the frequent issues and confusion coming from having to support multiple loaders and requiring users to use and + initialize the same loader as the backend. [@rokups] + Removed support for gl3w, glew, glad, glad2, glbinding2, glbinding3 (all now unnecessary). +- Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998) +- Backends: OpenGL3: Destroy vertex/fragment shader objects right after they are linked into main shader. (#4244) [@Crowbarous] +- Backends: OpenGL3: Use OES_vertex_array extension on Emscripten + backup/restore current state. (#4266, #4267) [@harry75369] +- Backends: GLFW: Installing and exposed ImGui_ImplGlfw_MonitorCallback() for forward compatibility with docking branch. +- Backends: OSX: Added a fix for shortcuts using CTRL key instead of CMD key. (#4253) [@rokups] +- Examples: DX12: Fixed handling of Alt+Enter in example app (using swapchain's ResizeBuffers). (#4346) [@PathogenDavid] +- Examples: DX12: Removed unnecessary recreation of backend-owned device objects when window is resized. (#4347) [@PathogenDavid] +- Examples: OpenGL3+GLFW,SDL: Remove include cruft to support variety of GL loaders (no longer necessary). [@rokups] +- Examples: OSX+OpenGL2: Fix event forwarding (fix key remaining stuck when using shortcuts with Cmd/Super key). + Other OSX examples were not affected. (#4253, #1873) [@rokups] +- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg. +- Examples: SDL2: Accommodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h. + +Docking+Viewports Branch: + +- Docking: Clicking on the right-most close button of a docking node closes all windows. (#4186) +- Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061) +- Docking: Fix crash using DockBuilderRemoveNode() in some situations. (#3111, #3179, #3203, #4295) [@hsimyu] +- Docking: Fix crash when a dock node gets re-qualified as dockspace>floating>dockspace, which tends to happen + when incorrectly calling DockBuilderAddNode() without ImGuiDockNodeFlags_Dockspace and using it as a Dockspace + on the next frame after the floating window hosting the node has been automatically created. (#3203, #4295) +- Docking: Reworked node flags saving/inheritance so that flags enforced by docked windows via the + DockNodeFlagsOverrideSet mechanism are are not left in empty dockspace nodes once the windows gets undocked. + (#4292, #3834, #3633, #3521, #3492, #3335, #2999, #2648) +- Docking: (Internal/Experimental) Removed DockNodeFlagsOverrideClear flags from ImGuiWindowClass as + it is ambiguous how to apply them and we haven't got a use out of them yet. +- Viewports: Fix popup/tooltip created without a parent window from being given a ParentViewportId value + from the implicit/fallback window. (#4236, #2409) +- Backends: Vulkan: Fix the use of the incorrect fence for secondary viewports. (#4208) [@FunMiles] + + +----------------------------------------------------------------------- + VERSION 1.83 (Released 2021-05-24) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.83 + +Breaking Changes: + +- Backends: Obsoleted direct access to ImDrawCmd::TextureId in favor of calling ImDrawCmd::GetTexID(). (#3761) [@thedmd] + - If you are using official backends from the source tree: you have nothing to do. + - If you copied old backend code or using your own: change access to draw_cmd->TextureId to draw_cmd->GetTexID(). + Why are we doing this? + - This change will be required in the future when adding support for incremental texture atlas updates. + - Please note this won't break soon, but we are making the change ahead of time. + +Other Changes: + +- Scrolling: Fix scroll tracking with e.g. SetScrollHereX/Y() when WindowPadding < ItemSpacing. +- Scrolling: Fix scroll snapping on edge of scroll region when both scrollbars are enabled. +- Scrolling: Fix mouse wheel axis swap when using SHIFT on macOS (system already does it). (#4010) +- Window: Fix IsWindowAppearing() from returning true twice in most cases. (#3982, #1497, #1061) +- Nav: Fixed toggling menu layer while an InputText() is active not stealing active id. (#787) +- Nav: Fixed pressing Escape to leave menu layer while in a popup or child window. (#787) +- Nav, InputText: Fixed accidental menu toggling while typing non-ascii characters using AltGR. [@rokups] (#370) +- Nav: Fixed using SetItemDefaultFocus() on windows with _NavFlattened flag. (#787) +- Nav: Fixed Tabbing initial activation from skipping the first item if it is tabbable through. (#787) +- Nav: Fixed fast CTRL+Tab (where keys are only held for one single frame) from properly enabling the + menu layer of target window if it doesn't have other active layers. +- Tables: Expose TableSetColumnEnabled() in public api. (#3935) +- Tables: Better preserve widths when columns count changes. (#4046) +- Tables: Sharing more memory buffers between tables, reducing general memory footprints. (#3740) +- TabBar: Fixed mouse reordering with very fast movements (e.g. crossing multiple tabs in a single + frame and then immediately standing still (would only affect automation/bots). [@rokups] +- Menus: made MenuItem() in a menu bar reflect the 'selected' argument with a highlight. (#4128) [@mattelegende] +- Drags, Sliders, Inputs: Specifying a NULL format to Float functions default them to "%.3f" to be + consistent with the compile-time default. (#3922) +- DragScalar: Add default value for v_speed argument to match higher-level functions. (#3922) [@eliasdaler] +- ColorEdit4: Alpha default to 255 (instead of 0) when omitted in hex input. (#3973) [@squadack] +- InputText: Fix handling of paste failure (buffer full) which in some cases could corrupt the undo stack. (#4038) + (fix submitted to https://github.com/nothings/stb/pull/1158) [@Unit2Ed, @ocornut] +- InputText: Do not filter private unicode codepoints (e.g. icons) when pasted from clipboard. (#4005) [@dougbinks] +- InputText: Align caret/cursor to pixel coordinates. (#4080) [@elvissteinjr] +- InputText: Fixed CTRL+Arrow or OSX double-click leaking the presence of spaces when ImGuiInputTextFlags_Password + is used. (#4155, #4156) [@michael-swan] +- LabelText: Fixed clipping of multi-line value text when label is single-line. (#4004) +- LabelText: Fixed vertical alignment of single-line value text when label is multi-line. (#4004) +- Combos: Changed the combo popup to use a different id to also using a context menu with the default item id. + Fixed using BeginPopupContextItem() with no parameter after a combo. (#4167) +- Popups: Added 'OpenPopup(ImGuiID id)' overload to facilitate calling from nested stacks. (#3993, #331) [@zlash] +- Tweak computation of io.Framerate so it is less biased toward high-values in the first 120 frames. (#4138) +- Optimization: Disabling some of MSVC most aggressive Debug runtime checks for some simple/low-level functions + (e.g. ImVec2, ImVector) leading to a 10-20% increase of performances with MSVC "default" Debug settings. +- ImDrawList: Add and use SSE-enabled ImRsqrt() in place of 1.0f / ImSqrt(). (#4091) [@wolfpld] +- ImDrawList: Fixed/improved thickness of thick strokes with sharp angles. (#4053, #3366, #2964, #2868, #2518, #2183) + Effectively introduced a regression in 1.67 (Jan 2019), and a fix in 1.70 (Apr 2019) but the fix wasn't actually on + par with original version. Now incorporating the correct revert. +- ImDrawList: Fixed PathArcTo() regression from 1.82 preventing use of counter-clockwise angles. (#4030, #3491) [@thedmd] +- Demo: Improved popups demo and comments. +- Metrics: Added "Fonts" section with same information as available in "Style Editor">"Fonts". +- Backends: SDL2: Rework global mouse pos availability check listing supported platforms explicitly, + effectively fixing mouse access on Raspberry Pi. (#2837, #3950) [@lethal-guitar, @hinxx] +- Backends: Win32: Clearing keyboard down array when losing focus (WM_KILLFOCUS). (#2062, #3532, #3961) + [@1025798851] +- Backends: OSX: Fix keys remaining stuck when CMD-tabbing to a different application. (#3832) [@rokups] +- Backends: DirectX9: calling IDirect3DStateBlock9::Capture() after CreateStateBlock() which appears to + workaround/fix state restoring issues. Unknown exactly why so, bit of a cargo-cult fix. (#3857) +- Backends: DirectX9: explicitly setting up more graphics states to increase compatibility with unusual + non-default states. (#4063) +- Backends: DirectX10, DirectX11: fixed a crash when backing/restoring state if nothing is bound when + entering the rendering function. (#4045) [@Nemirtingas] +- Backends: GLFW: Adding bound check in KeyCallback because GLFW appears to send -1 on some setups. [#4124] +- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of + VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994] +- Backends: WebGPU: Update to latest specs (Chrome Canary 92 and Emscripten 2.0.20). (#4116, #3632) [@bfierz, @Kangz] +- Backends: OpenGL3: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5. (#3998, #2366, #2186) [@s7jones] +- Examples: OpenGL: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx] +- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881) +- Examples: Vulkan: Prefer using discrete GPU if there are more than one available. (#4012) [@rokups] +- Examples: SDL2: Link with shell32.lib required by SDL2main.lib since SDL 2.0.12. [#3988] +- Examples: Android: Make Android example build compatible with Gradle 7.0. (#3446) +- Docs: Improvements to description of using colored glyphs/emojis. (#4169, #3369) +- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios] + +Docking+Viewports Branch: + +- [Breaking] Removed io.ConfigDockingWithShift config option. Behavior always equivalent to having the + option set to false (dock/undock by default, hold shift to avoid docking). (#2109) +- Docking: DockSpace() returns its node ID. +- Docking: Dockspace() never draws a background. (#3924) +- Docking: Undocking nodes/windows covering most of the monitor max their size down to 90% to ease manipulations. +- Docking: Docking node tab bar honors ItemInnerSpacing.x before first tab. (#4130) +- Docking: Tweak rendering and alignment of dock node menu marker. (#4130) +- Docking: Fixed restoring of tab order within a dockspace or a split node. +- Docking: Fixed reappearing docked windows with no close button showing a tab with extraneous space for one frame. +- Docking: Fixed multiple simultaneously reappearing window from appearing undocked for one frame. +- Viewports: Hotfix for crash in monitor array access, caused by 4b9bc4902. (#3967) +- Backends, Viewports: GLFW: Add a workaround for stuck keys after closing a GLFW window (#3837). +- Backends, Viewports: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881) + + +----------------------------------------------------------------------- + VERSION 1.82 (Released 2021-02-15) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.82 + +Breaking Changes: + +- Removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018): + - ImGui::SetScrollHere() --> use ImGui::SetScrollHereY() +- ImDrawList: upgraded AddPolyline()/PathStroke()'s "bool closed" parameter to use "ImDrawFlags flags". + - bool closed = false --> use ImDrawFlags_None, or 0 + - bool closed = true --> use ImDrawFlags_Closed + The matching ImDrawFlags_Closed value is guaranteed to always stay == 1 in the future. + Difference may not be noticeable for most but zealous type-checking tools may report a need to change. +- ImDrawList: upgraded AddRect(), AddRectFilled(), PathRect() to use ImDrawFlags instead of ImDrawCornersFlags. + - ImDrawCornerFlags_TopLeft --> use ImDrawFlags_RoundCornersTopLeft + - ImDrawCornerFlags_BotRight --> use ImDrawFlags_RoundCornersBottomRight + - ImDrawCornerFlags_None --> use ImDrawFlags_RoundCornersNone etc. + Flags now sanely defaults to 0 instead of 0x0F, consistent with all other flags in the API. + IMPORTANT: The default with rounding > 0.0f is now "round all corners" vs old implicit "round no corners": + - rounding == 0.0f + flags == 0 --> meant no rounding --> unchanged (common use) + - rounding > 0.0f + flags != 0 --> meant rounding --> unchanged (common use) + - rounding == 0.0f + flags != 0 --> meant no rounding --> unchanged (unlikely use) + - rounding > 0.0f + flags == 0 --> meant no rounding --> BREAKING (unlikely use)! + - this ONLY matters for hardcoded use of 0 with rounding > 0.0f. + - fix by using named ImDrawFlags_RoundCornersNone or rounding == 0.0f! + - this is technically the only real breaking change which we can't solve automatically (it's also uncommon). + The old ImDrawCornersFlags used awkward default values of ~0 or 0xF (4 lower bits set) to signify "round all corners" + and we sometimes encouraged using them as shortcuts. As a result the legacy path still support use of hardcoded ~0 + or any value from 0x1 or 0xF. They will behave the same with legacy paths enabled (will assert otherwise). + Courtesy of legacy untangling commity: [@rokups, @ocornut, @thedmd] +- ImDrawList: clarified that PathArcTo()/PathArcToFast() won't render with radius < 0.0f. Previously it sorts + of accidentally worked but would lead to counter-clockwise paths which and have an effect on anti-aliasing. +- InputText: renamed ImGuiInputTextFlags_AlwaysInsertMode to ImGuiInputTextFlags_AlwaysOverwrite, old name was an + incorrect description of behavior. Was ostly used by memory editor. Kept inline redirection function. (#2863) +- Moved 'misc/natvis/imgui.natvis' to 'misc/debuggers/imgui.natvis' as we will provide scripts for other debuggers. +- Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) + to style.CircleTessellationMaxError (new default = 0.30f) as its meaning changed. (#3808) [@thedmd] +- Win32+MinGW: Re-enabled IME functions by default even under MinGW. In July 2016, issue #738 had me incorrectly + disable those default functions for MinGW. MinGW users should: either link with -limm32, either set their + imconfig file with '#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS'. (#2590, #738) [@actboy168] + *EDIT* Undid in 1.84. +- Backends: Win32: Pragma linking with dwmapi.lib (Vista-era, ~9 kb). MinGW users will need to link with -ldwmapi. + +Other Changes: + +- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) at the time a new window appears. (#3865) [@nem0] +- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible + area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825) +- Nav: Various fixes for losing gamepad/keyboard navigation reference point when a window reappears or + when it appears while gamepad/keyboard are not being used. (#787) +- Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.) + with ImGuiSliderFlags_AlwaysClamp + only one of either p_min or p_max set. (#3824) [@harry75369] +- Drags, Sliders: Fixed a bug where editing value would use wrong number if there were digits right after + format specifier (e.g. using "%f123" as a format string). [@rokups] +- Drags, Sliders: Fixed a bug where using custom formatting flags (',$,_) supported by stb_sprintf.h + would cause incorrect value to be displayed. (#3604) [@rokups] +- Drags, Sliders: Support ImGuiSliderFlags_Logarithmic flag with integers. Because why not? (#3786) +- Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872) +- IsItemHovered(): fixed return value false positive when used after EndChild(), EndGroup() or widgets using + either of them, when the hovered location is located within a child window, e.g. InputTextMultiline(). + This is intended to have no side effects, but brace yourself for the possible comeback.. (#3851, #1370) +- Drag and Drop: can use BeginDragDropSource() for other than the left mouse button as long as the item + has an ID (for ID-less items will add new functionalities later). (#1637, #3885) +- ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369) + This can currently only ever be set by the Freetype renderer. +- imgui_freetype: Added ImGuiFreeTypeBuilderFlags_Bitmap flag to request Freetype loading bitmap data. + This may have an effect on size and must be called with correct size values. (#3879) [@metarutaiga] +- ImDrawList: PathArcTo() now supports "int num_segments = 0" (new default) and adaptively tessellate. + The adaptive tessellation uses look up tables, tends to be faster than old PathArcTo() while maintaining + quality for large arcs (tessellation quality derived from "style.CircleTessellationMaxError") (#3491) [@thedmd] +- ImDrawList: PathArcToFast() also adaptively tessellate efficiently. This means that large rounded corners + in e.g. hi-dpi settings will generally look better. (#3491) [@thedmd] +- ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError + with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd] +- Misc: Added GetAllocatorFunctions() to facilitate sharing allocators across DLL boundaries. (#3836) +- Misc: Added 'debuggers/imgui.gdb' and 'debuggers/imgui.natstepfilter' (along with existing 'imgui.natvis') + scripts to configure popular debuggers into skipping trivial functions when using StepInto. [@rokups] +- Backends: Android: Added native Android backend. (#3446) [@duddel] +- Backends: Win32: Added ImGui_ImplWin32_EnableAlphaCompositing() to facilitate experimenting with + alpha compositing and transparent windows. (#2766, #3447 etc.). +- Backends: OpenGL, Vulkan, DX9, DX10, DX11, DX12, Metal, WebGPU, Allegro: Rework blending equation to + preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently + accross all backends), facilitating compositing of the output buffer with another buffer. + (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] +- Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha] +- Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844) +- Examples: Android: Added Android + GL ES3 example. (#3446) [@duddel] +- Examples: Reworked setup of clear color to be compatible with transparent values. +- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if + scheduled builds builds are not required. [@rokups] +- Log/Capture: Added LogTextV, a va_list variant of LogText. [@PathogenDavid] + +Docking+Viewports Branch: + +- Viewports: Fix setting of ImGuiViewportFlags_NoRendererClear. (#3213) +- Viewports: Added GetViewportPlatformMonitor() with a safety net to keep code portable. +- Viewports, Backends: SDL: Fix missing ImGuiBackendFlags_HasSetMousePos flag in docking branch. +- Viewports, Backends: GLFW: Fix application of WantSetMousePos. (#1542, #787) + + +----------------------------------------------------------------------- + VERSION 1.81 (Released 2021-02-10) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.81 + +Breaking Changes: + +- ListBox helpers: + - Renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox(). + - Renamed ListBoxFooter() to EndListBox(). + - Removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size. + In the redirection function, made vertical padding consistent regardless of (items_count <= height_in_items) or not. + - Kept inline redirection function for all threes (will obsolete). +- imgui_freetype: + - Removed ImGuiFreeType::BuildFontAtlas(). Kept inline redirection function. + Prefer using '#define IMGUI_ENABLE_FREETYPE', but there's a runtime selection path available too. + - The shared extra flags parameters (very rarely used) are now stored in ImFontAtlas::FontBuilderFlags. + - Renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags. + - Renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. + +Other Changes: + +- Viewports Added ImGui::GetMainViewport() as a way to get the bounds and work area of the host display. (#3789, #1542) + - In 'master' branch or without multi-viewports feature enabled: + - GetMainViewport()->Pos is always == (0,0) + - GetMainViewport()->Size is always == io.DisplaySize + - In 'docking' branch and with the multi-viewports feature enabled: + - GetMainViewport() will return information from your host Platform Window. + - In the future, we will support a "no main viewport" mode and this may return bounds of your main monitor. + - For forward compatibility with multi-viewports/multi-monitors: + - Code using (0,0) as a way to signify "upper-left of the host window" should use GetMainViewport()->Pos. + - Code using io.DisplaySize as a way to signify "size of the host window" should use GetMainViewport()->Size. + - We are also exposing a work area in ImGuiViewport ('WorkPos', 'WorkSize' vs 'Pos', 'Size' for full area): + - For a Platform Window, the work area is generally the full area minus space used by menu-bars. + - For a Platform Monitor, the work area is generally the full area minus space used by task-bars. + - All of this has been the case in 'docking' branch for a long time. What we've done is merely merging + a small chunk of the multi-viewport logic into 'master' to standardize some concepts ahead of time. +- Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760) +- Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no + close button in the window. (#3731) +- SliderInt: Fixed click/drag when v_min==v_max from setting the value to zero. (#3774) [@erwincoumans] + Would also repro with DragFloat() when using ImGuiSliderFlags_Logarithmic with v_min==v_max. +- Menus: Fixed an issue with child-menu auto sizing (issue introduced in 1.80 on 2021/01/25) (#3779) +- InputText: Fixed slightly off ScrollX tracking, noticeable with large values of FramePadding.x. (#3781) +- InputText: Multiline: Fixed padding/cliprect not precisely matching single-line version. (#3781) +- InputText: Multiline: Fixed FramePadding.y worth of vertical offset when aiming with mouse. +- ListBox: Tweaked default height calculation. +- Fonts: imgui_freetype: Facilitated using FreeType integration: [@Xipiryon, @ocornut] + - Use '#define IMGUI_ENABLE_FREETYPE' in imconfig.h should make it work with no other modifications + other than compiling misc/freetype/imgui_freetype.cpp and linking with FreeType. + - Use '#define IMGUI_ENABLE_STB_TRUETYPE' if you somehow need the stb_truetype rasterizer to be + compiled in along with the FreeType one, otherwise it is enabled by default. +- Fonts: imgui_freetype: Added support for colored glyphs as supported by Freetype 2.10+ (for .ttf using CPAL/COLR + tables only). Enable the ImGuiFreeTypeBuilderFlags_LoadColor on a given font. Atlas always output directly + as RGBA8 in this situation. Likely to make sense with IMGUI_USE_WCHAR32. (#3369) [@pshurgal] +- Fonts: Fixed CalcTextSize() width rounding so it behaves more like a ceil. This is in order for text wrapping + to have enough space when provided width precisely calculated with CalcTextSize().x. (#3776) + Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but + variety of code is currently on it so we are first fixing current behavior before we'll eventually change it. +- Log/Capture: Fix various new line/spacing issue when logging widgets. [@Xipiryon, @ocornut] +- Log/Capture: Improved the ASCII look of various widgets, making large dumps more easily human readable. +- ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738) + Would lead to a buffer read overflow. +- ImDrawList: Clarified PathArcTo() need for a_min <= a_max with an assert. +- ImDrawList: Fixed PathArcToFast() handling of a_min > a_max. +- Metrics: Back-ported "Viewports" debug visualizer from 'docking' branch. +- Demo: Added 'Examples->Fullscreen Window' demo using GetMainViewport() values. (#3789) +- Demo: 'Simple Overlay' demo now moves under main menu-bar (if any) using GetMainViewport()'s work area. +- Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilitate compiling with + old WindowSDK versions or running on Windows 7. (#3646, #3645, #3248, #2716) [@Demonese] +- Backends: Vulkan: Add support for custom Vulkan function loader and VK_NO_PROTOTYPES. (#3759, #3227) [@Hossein-Noroozpour] + User needs to call ImGui_ImplVulkan_LoadFunctions() with their custom loader prior to other functions. +- Backends: Metal: Fixed texture storage mode when building on Mac Catalyst. (#3748) [@Belinsky-L-V] +- Backends: OSX: Fixed mouse position not being reported when mouse buttons other than left one are down. (#3762) [@rokups] +- Backends: WebGPU: Added enderer backend for WebGPU support (imgui_impl_wgpu.cpp) (#3632) [@bfierz] + Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break. +- Examples: WebGPU: Added Emscripten+WebGPU example. (#3632) [@bfierz] +- Backends: GLFW: Added ImGui_ImplGlfw_InitForOther() initialization call to use with non OpenGL API. (#3632) + +Docking+Viewports Branch: + +- Docking: Fix losing docking information on closed windows for which the hosting node was split. (#3716) [@GamingMinds-DanielC] +- Docking: Fix gap in hit test hole when using ImGuiDockNodeFlags_PassthruCentralNode touching the edge of a viewport. (#3733) +- Viewports: (Breaking) removed ImGuiPlatformIO::MainViewport which is now pretty much unused and duplicate + (and misleading as we will evolve the concept). +- Viewports: (Breaking) turned ImGuiViewport::GetWorkPos(), ImGuiViewport::GetWorkSize() into regular fields + (WorkPos, WorkSize) before exposing in master branch. +- Viewports: Fix issue inferring viewport z-order when new popups gets created. (#3734) + Metrics updates. +- Viewports, Backends: Vulkan: handle VK_ERROR_OUT_OF_DATE_KHR when resizing secondary viewport (#3766, #3758) + + +----------------------------------------------------------------------- + VERSION 1.80 (Released 2021-01-21) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.80 + +Breaking Changes: + +- Added imgui_tables.cpp file! Manually constructed project files will need the new file added! (#3740) +- Backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/. (#3513) +- Renamed ImDrawList::AddBezierCurve() to ImDrawList::AddBezierCubic(). Kept inline redirection function (will obsolete). +- Renamed ImDrawList::PathBezierCurveTo() to ImDrawList::PathBezierCubicCurveTo(). Kept inline redirection function (will obsolete). +- Removed redirecting functions/enums names that were marked obsolete in 1.60 (April 2018): + - io.RenderDrawListsFn pointer -> use ImGui::GetDrawData() value and call the render function of your backend + - ImGui::IsAnyWindowFocused() -> use ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow) + - ImGui::IsAnyWindowHovered() -> use ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) + - ImGuiStyleVar_Count_ -> use ImGuiStyleVar_COUNT + - ImGuiMouseCursor_Count_ -> use ImGuiMouseCursor_COUNT +- Removed redirecting functions/enums names that were marked obsolete in 1.61 (May 2018): + - InputFloat (... int decimal_precision ...) -> use InputFloat (... const char* format ...) with format = "%.Xf" where X was value for decimal_precision. + - same for InputFloat2()/InputFloat3()/InputFloat4() variants taking a `int decimal_precision` parameter. +- Removed redirecting functions/enums names that were marked obsolete in 1.63 (August 2018): + - ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit(). + - ImGuiCol_ModalWindowDarkening -> use ImGuiCol_ModalWindowDimBg + - ImGuiInputTextCallback -> use ImGuiTextEditCallback + - ImGuiInputTextCallbackData -> use ImGuiTextEditCallbackData +- If you were still using the old names, while you are cleaning up, considering enabling + IMGUI_DISABLE_OBSOLETE_FUNCTIONS in imconfig.h even temporarily to have a pass at finding + and removing up old API calls, if any remaining. +- Internals: Columns: renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* to reduce + confusion with Tables API. Keep redirection enums (will obsolete). (#125, #513, #913, #1204, #1444, #2142, #2707) +- Renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature now applies + to other data structures. (#2636) + +Other Changes: + +- Tables: added new Tables Beta API as a replacement for old Columns. (#3740, #2957, #125) + Check out 'Demo->Tables' for many demos. + Read API comments in imgui.h for details. Read extra commentary in imgui_tables.cpp. + - Added 16 functions: + - BeginTable(), EndTable() + - TableNextRow(), TableNextColumn(), TableSetColumnIndex() + - TableSetupColumn(), TableSetupScrollFreeze() + - TableHeadersRow(), TableHeader() + - TableGetRowIndex(), TableGetColumnCount(), TableGetColumnIndex(), TableGetColumnName(), TableGetColumnFlags() + - TableGetSortSpecs(), TableSetBgColor() + - Added 3 flags sets: + - ImGuiTableFlags (29 flags for: features, decorations, sizing policies, padding, clipping, scrolling, sorting etc.) + - ImGuiTableColumnFlags (24 flags for: width policies, default settings, sorting options, indentation options etc.) + - ImGuiTableRowFlags (1 flag for: header row) + - Added 2 structures: ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs + - Added 2 enums: ImGuiSortDirection, ImGuiTableBgTarget + - Added 1 style variable: ImGuiStyleVar_CellPadding + - Added 5 style colors: ImGuiCol_TableHeaderBg, ImGuiCol_TableBorderStrong, ImGuiCol_TableBorderLight, ImGuiCol_TableRowBg, ImGuiCol_TableRowBgAlt. +- Tab Bar: Made it possible to append to an existing tab bar by calling BeginTabBar()/EndTabBar() again. +- Tab Bar: Fixed using more than 128 tabs in a tab bar (scrolling policy recommended). +- Tab Bar: Do not display a tooltip if the name already fits over a given tab. (#3521) +- Tab Bar: Fixed minor/unlikely bug skipping over a button when scrolling left with arrows. +- Tab Bar: Requested ideal content size (for auto-fit) doesn't affect horizontal scrolling. (#3414) +- Drag and Drop: Fix losing drop source ActiveID (and often source tooltip) when opening a TreeNode() + or CollapsingHeader() while dragging. (#1738) +- Drag and Drop: Fix drag and drop to tie same-size drop targets by chosen the later one. Fixes dragging + into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat] +- Checkbox: Added CheckboxFlags() helper with int* type (internals have a template version, not exposed). +- Clipper: Fixed incorrect end-list positioning when using ImGuiListClipper with 1 item (bug in 1.79). (#3663) [@nyorain] +- InputText: Fixed updating cursor/selection position when a callback altered the buffer in a way + where the byte count is unchanged but the decoded character count changes. (#3587) [@gqw] +- InputText: Fixed switching from single to multi-line while preserving same ID. +- Combo: Fixed using IsItemEdited() after Combo() not matching the return value from Combo(). (#2034) +- DragFloat, DragInt: very slightly increased mouse drag threshold + expressing it as a factor of default value. +- DragFloat, DragInt: added experimental io.ConfigDragClickToInputText feature to enable turning DragXXX widgets + into text input with a simple mouse click-release (without moving). (#3737) +- Nav: Fixed IsItemFocused() from returning false when Nav highlight is hidden because mouse has moved. + It's essentially been always the case but it doesn't make much sense. Instead we will aim at exposing + feedback and control of keyboard/gamepad navigation highlight and mouse hover disable flag. (#787, #2048) +- Metrics: Fixed mishandling of ImDrawCmd::VtxOffset in wireframe mesh renderer. +- Metrics: Rebranded as "Dear ImGui Metrics/Debugger" to clarify its purpose. +- ImDrawList: Added ImDrawList::AddQuadBezierCurve(), ImDrawList::PathQuadBezierCurveTo() quadratic bezier + helpers. (#3127, #3664, #3665) [@aiekick] +- Fonts: Updated GetGlyphRangesJapanese() to include a larger 2999 ideograms selection of Joyo/Jinmeiyo + kanjis, from the previous 1946 ideograms selection. This will consume a some more memory but be generally + much more fitting for Japanese display, until we switch to a more dynamic atlas. (#3627) [@vaiorabbit] +- Log/Capture: fix capture to work on clipped child windows. +- Misc: Made the ItemFlags stack shared, so effectively the ButtonRepeat/AllowKeyboardFocus states + (and others exposed in internals such as PushItemFlag) are inherited by stacked Begin/End pairs, + vs previously a non-child stacked Begin() would reset those flags back to zero for the stacked window. +- Misc: Replaced UTF-8 decoder with one based on branchless one by Christopher Wellons. [@rokups] + Super minor fix handling incomplete UTF-8 contents: if input does not contain enough bytes, decoder + returns IM_UNICODE_CODEPOINT_INVALID and consume remaining bytes (vs old decoded consumed only 1 byte). +- Misc: Fix format warnings when using gnu printf extensions in a setup that supports them (gcc/mingw). (#3592) +- Misc: Made EndFrame() assertion for key modifiers being unchanged during the frame (added in 1.76) more + lenient, allowing full mid-frame releases. This is to accommodate the use of mid-frame modal native + windows calls, which leads backends such as GLFW to send key clearing events on focus loss. (#3575) +- Style: Changed default style.WindowRounding value to 0.0f (matches default for multi-viewports). +- Style: Reduced the size of the resizing grip, made alpha less prominent. +- Style: Classic: Increase the default alpha value of WindowBg to be closer to other styles. +- Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width. +- Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...) + when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn] +- Backends: OpenGL2: Backup and restore GL_SHADE_MODEL and disable GL_NORMAL_ARRAY state to increase + compatibility with legacy code. (#3671) +- Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon] +- Backends: OpenGL2, OpenGL3: Backup and restore GL_STENCIL_TEST enable state. (#3668) +- Backends: Vulkan: Added support for specifying which sub-pass to reference during VkPipeline creation. (@3579) [@bdero] +- Backends: DX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. (#3696) [@Mattiwatti] +- Backends: Win32: Fix setting of io.DisplaySize to invalid/uninitialized data after hwnd has been closed. +- Backends: OSX: Fix keypad-enter key not working on MacOS. (#3554) [@rokups, @lfnoise] +- Examples: Apple+Metal: Consolidated/simplified to get closer to other examples. (#3543) [@warrenm] +- Examples: Apple+Metal: Forward events down so OS key combination like Cmd+Q can work. (#3554) [@rokups] +- Examples: Emscripten: Renamed example_emscripten/ to example_emscripten_opengl3/. (#3632) +- Examples: Emscripten: Added 'make serve' helper to spawn a web-server on localhost. (#3705) [@Horki] +- Examples: DirectX12: Move ImGui::Render() call above the first barrier to clarify its lack of effect on the graphics pipe. +- CI: Fix testing for Windows DLL builds. (#3603, #3601) [@iboB] +- Docs: Improved the wiki and added a https://github.com/ocornut/imgui/wiki/Useful-Widgets page. [@Xipiryon] + [2021/05/20: moved to https://github.com/ocornut/imgui/wiki/Useful-Extensions] +- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them. +- Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs. + +Docking+Viewports Branch: + +- Docking: Docked windows honor change of tab and text colors. (#2771) +- Docking: Support for appending into existing tab-bar made to work with Docking + internal helper DockNodeBeginAmendTabBar(). +- Docking: Added experimental TabItemFlagsOverrideSet to ImGuiWindowClass. +- Viewports: Fixed incorrect whitening of popups above a modal if both use their own viewport. +- Viewports: Backends: Vulkan: Fixed build, removed extraneous pipeline creation. (#3459, #3579) + + +----------------------------------------------------------------------- + VERSION 1.79 (Released 2020-10-08) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.79 + +Breaking Changes: + +- Fonts: Removed ImFont::DisplayOffset in favor of ImFontConfig::GlyphOffset. DisplayOffset was applied + after scaling and not very meaningful/useful outside of being needed by the default ProggyClean font. + It was also getting in the way of better font scaling, so let's get rid of it now! + If you used DisplayOffset it was probably in association to rasterizing a font at a specific size, + in which case the corresponding offset may be reported into GlyphOffset. (#1619) + If you scaled this value after calling AddFontDefault(), this is now done automatically. +- ImGuiListClipper: Renamed constructor parameters which created an ambiguous alternative to using + the ImGuiListClipper::Begin() function, with misleading edge cases. Always use ImGuiListClipper::Begin()! + Kept inline redirection function (will obsolete). + (note: imgui_memory_editor <0.40 from imgui_club/ used this old clipper API. Update your copy if needed). +- Style: Renamed style.TabMinWidthForUnselectedCloseButton to style.TabMinWidthForCloseButton. +- Renamed ImGuiSliderFlags_ClampOnInput to ImGuiSliderFlags_AlwaysClamp. Kept redirection enum (will obsolete). +- Renamed OpenPopupContextItem() back to OpenPopupOnItemClick(), REVERTED CHANGE FROM 1.77. + For variety of reason this is more self-explanatory and less error-prone. Kept inline redirection function. +- Removed return value from OpenPopupOnItemClick() - returned true on mouse release on an item - because it + is inconsistent with other popups API and makes others misleading. It's also and unnecessary: you can + use IsWindowAppearing() after BeginPopup() for a similar result. + +Other Changes: + +- Window: Fixed using non-zero pivot in SetNextWindowPos() when the window is collapsed. (#3433) +- Nav: Fixed navigation resuming on first visible item when using gamepad. [@rokups] +- Nav: Fixed using Alt to toggle the Menu layer when inside a Modal window. (#787) +- Scrolling: Fixed SetScrollHere(0) functions edge snapping when called during a frame where + ContentSize is changing (issue introduced in 1.78). (#3452). +- InputText: Added support for Page Up/Down in InputTextMultiline(). (#3430) [@Xipiryon] +- InputText: Added selection helpers in ImGuiInputTextCallbackData(). +- InputText: Added ImGuiInputTextFlags_CallbackEdit to modify internally owned buffer after an edit. + (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the + underlying buffer while focus is active). +- InputText: Fixed using ImGuiInputTextFlags_Password with InputTextMultiline(). (#3427, #3428) + It is a rather unusual or useless combination of features but no reason it shouldn't work! +- InputText: Fixed minor scrolling glitch when erasing trailing lines in InputTextMultiline(). +- InputText: Fixed cursor being partially covered after using Ctrl+End key. +- InputText: Fixed callback's helper DeleteChars() function when cursor is inside the deleted block. (#3454) +- InputText: Made pressing Down arrow on the last line when it doesn't have a carriage return not move to + the end of the line (so it is consistent with Up arrow, and behave same as Notepad and Visual Studio. + Note that some other text editors instead would move the cursor to the end of the line). [@Xipiryon] +- DragFloat, DragScalar: Fixed ImGuiSliderFlags_ClampOnInput not being honored in the special case + where v_min == v_max. (#3361) +- SliderInt, SliderScalar: Fixed reaching of maximum value with inverted integer min/max ranges, both + with signed and unsigned types. Added reverse Sliders to Demo. (#3432, #3449) [@rokups] +- Text: Bypass unnecessary formatting when using the TextColored()/TextWrapped()/TextDisabled() helpers + with a "%s" format string. (#3466) +- CheckboxFlags: Display mixed-value/tristate marker when passed flags that have multiple bits set and + stored value matches neither zero neither the full set. +- BeginMenuBar: Fixed minor bug where CursorPosMax gets pushed to CursorPos prior to calling BeginMenuBar(), + so e.g. calling the function at the end of a window would often add +ItemSpacing.y to scrolling range. +- TreeNode, CollapsingHeader: Made clicking on arrow toggle toggle the open state on the Mouse Down event + rather than the Mouse Down+Up sequence, even if the _OpenOnArrow flag isn't set. This is standard behavior + and amends the change done in 1.76 which only affected cases were _OpenOnArrow flag was set. + (This is also necessary to support full multi/range-select/drag and drop operations.) +- Tab Bar: Added TabItemButton() to submit tab that behave like a button. (#3291) [@Xipiryon] +- Tab Bar: Added ImGuiTabItemFlags_Leading and ImGuiTabItemFlags_Trailing flags to position tabs or button + at either end of the tab bar. Those tabs won't be part of the scrolling region, and when reordering cannot + be moving outside of their section. Most often used with TabItemButton(). (#3291) [@Xipiryon] +- Tab Bar: Added ImGuiTabItemFlags_NoReorder flag to disable reordering a given tab. +- Tab Bar: Keep tab item close button visible while dragging a tab (independent of hovering state). +- Tab Bar: Fixed a small bug where closing a tab that is not selected would leave a tab hole for a frame. +- Tab Bar: Fixed a small bug where scrolling buttons (with ImGuiTabBarFlags_FittingPolicyScroll) would + generate an unnecessary extra draw call. +- Tab Bar: Fixed a small bug where toggling a tab bar from Reorderable to not Reorderable would leave + tabs reordered in the tab list popup. [@Xipiryon] +- Columns: Fix inverted ClipRect being passed to renderer when using certain primitives inside of + a fully clipped column. (#3475) [@szreder] +- Popups, Tooltips: Fix edge cases issues with positioning popups and tooltips when they are larger than + viewport on either or both axises. [@Rokups] +- Fonts: AddFontDefault() adjust its vertical offset based on floor(size/13) instead of always +1. + Was previously done by altering DisplayOffset.y but wouldn't work for DPI scaled font. +- Metrics: Various tweaks, listing windows front-to-back, greying inactive items when possible. +- Demo: Add simple InputText() callbacks demo (aside from the more elaborate ones in 'Examples->Console'). +- Backends: OpenGL3: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 contexts which have + the defines set by a loader. (#3467, #1985) [@jjwebb] +- Backends: Vulkan: Some internal refactor aimed at allowing multi-viewport feature to create their + own render pass. (#3455, #3459) [@FunMiles] +- Backends: DX12: Clarified that imgui_impl_dx12 can be compiled on 32-bit systems by redefining + the ImTextureID to be 64-bit (e.g. '#define ImTextureID ImU64' in imconfig.h). (#301) +- Backends: DX12: Fix debug layer warning when scissor rect is zero-sized. (#3472, #3462) [@StoneWolf] +- Examples: Vulkan: Reworked buffer resize handling, fix for Linux/X11. (#3390, #2626) [@RoryO] +- Examples: Vulkan: Switch validation layer to use "VK_LAYER_KHRONOS_validation" instead of + "VK_LAYER_LUNARG_standard_validation" which is deprecated (#3459) [@FunMiles] +- Examples: DX12: Enable breaking on any warning/error when debug interface is enabled. +- Examples: DX12: Added '#define ImTextureID ImU64' in project and build files to also allow building + on 32-bit systems. Added project to default Visual Studio solution file. (#301) + +Docking+Viewports Branch: + +- Docking: DockSpace() emits ItemSize() properly (useful when not filling all space). +- Docking: Fixed docking while hovering a child window. (#3420) broken by 85a661d. Improve metrics debugging. +- Docking: Fix honoring payload filter with overlapping nodes (we incorrectly over-relied on g.HoveredDockNode + when making change for #3398). +- Docking: Fix handling of WindowMenuButtonPosition == ImGuiDir_None in Docking Nodes. (#3499) +- Viewports: Fixed a rare edge-case if the window targeted by CTRL+Tab stops being rendered. +- Viewports, Backends: DX12: Make secondary viewport format match main viewport one (#3462) {@BeastLe9enD] +- Viewports: Backends: Vulkan: Removed unused shader code. Fix leaks. Avoid unnecessary pipeline creation for main + viewport. (#3459) + Add ImGui_ImplVulkanH_CreateWindowSwapChain in ImGui_ImplVulkanH_CreateOrResizeWindow(). +- Viewports: Backends: DirectX9: Recover from D3DERR_DEVICELOST on secondary viewports. (#3424) +- Viewports, Backends: Win32: Fix toggling of ImGuiViewportFlags_TopMost (#3477) [@Kodokuna] +- Viewports: Backends: GLFW: Workaround for cases where glfwGetMonitorWorkarea fails (#3457) [@dougbinks] + + +----------------------------------------------------------------------- + VERSION 1.78 (Released 2020-08-18) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.78 + +Breaking Changes: + +- Obsoleted use of the trailing 'float power=1.0f' parameter for those functions: [@Shironekoben, @ocornut] + - DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(), DragFloatRange2(), DragScalar(), DragScalarN() + - SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(), SliderScalar(), SliderScalarN() + - VSliderFloat(), VSliderScalar() + Replaced the final 'float power=1.0f' argument with ImGuiSliderFlags defaulting to 0 (as with all our flags). + Worked out a backward-compatibility scheme so hopefully most C++ codebase should not be affected. + In short, when calling those functions: + - If you omitted the 'power' parameter (likely!), you are not affected. + - If you set the 'power' parameter to 1.0f (same as previous default value): + - Your compiler may warn on float>int conversion. + - Everything else will work (but will assert if IMGUI_DISABLE_OBSOLETE_FUNCTIONS is defined). + - You can replace the 1.0f value with 0 to fix the warning, and be technically correct. + - If you set the 'power' parameter to >1.0f (to enable non-linear editing): + - Your compiler may warn on float>int conversion. + - Code will assert at runtime for IM_ASSERT(power == 1.0f) with the following assert description: + "Call Drag function with ImGuiSliderFlags_Logarithmic instead of using the old 'float power' function!". + - In case asserts are disabled, the code will not crash and enable the _Logarithmic flag. + - You can replace the >1.0f value with ImGuiSliderFlags_Logarithmic to fix the warning/assert + and get a _similar_ effect as previous uses of power >1.0f. + See https://github.com/ocornut/imgui/issues/3361 for all details. + For shared code, you can version check at compile-time with `#if IMGUI_VERSION_NUM >= 17704`. + Kept inline redirection functions (will obsolete) apart for: DragFloatRange2(), VSliderFloat(), VSliderScalar(). + For those three the 'float power=1.0f' version was removed directly as they were most unlikely ever used. +- DragInt, DragFloat, DragScalar: Obsoleted use of v_min > v_max to lock edits (introduced in 1.73, this was not + demoed nor documented much, will be replaced a more generic ReadOnly feature). + +Other Changes: + +- Nav: Fixed clicking on void (behind any windows) from not clearing the focused window. + This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard + flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880) +- Window: Fixed clicking over an item which hovering has been disabled (e.g inhibited by a popup) + from marking the window as moved. +- Drag, Slider: Added ImGuiSliderFlags parameters. + - For float functions they replace the old trailing 'float power=1.0' parameter. + (See #3361 and the "Breaking Changes" block above for all details). + - Added ImGuiSliderFlags_Logarithmic flag to enable logarithmic editing + (generally more precision around zero), as a replacement to the old 'float power' parameter + which was obsoleted. (#1823, #1316, #642) [@Shironekoben, @AndrewBelt] + - Added ImGuiSliderFlags_ClampOnInput flag to force clamping value when using + CTRL+Click to type in a value manually. (#1829, #3209, #946, #413). + [note: RENAMED to ImGuiSliderFlags_AlwaysClamp in 1.79]. + - Added ImGuiSliderFlags_NoRoundToFormat flag to disable rounding underlying + value to match precision of the display format string. (#642) + - Added ImGuiSliderFlags_NoInput flag to disable turning widget into a text input + with CTRL+Click or Nav Enter. +- Nav, Slider: Fix using keyboard/gamepad controls with certain logarithmic sliders where + pushing a direction near zero values would be cancelled out. [@Shironekoben] +- DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both + min and max value are on the same value. (#1441) +- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more + than ~16 KB characters. (Note that current code is going to show corrupted display if after + clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText() + call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare + but it will be addressed later). (#3349) +- Selectable: Fixed highlight/hit extent when used with horizontal scrolling (in or outside columns). + Also fixed related text clipping when used in a column after the first one. (#3187, #3386) +- Scrolling: Avoid SetScroll, SetScrollFromPos functions from snapping on the edge of scroll + limits when close-enough by (WindowPadding - ItemPadding), which was a tweak with too many + side-effects. The behavior is still present in SetScrollHere functions as they are more explicitly + aiming at making widgets visible. May later be moved to a flag. +- Tab Bar: Allow calling SetTabItemClosed() after a tab has been submitted (will process next frame). +- InvisibleButton: Made public a small selection of ImGuiButtonFlags (previously in imgui_internal.h) + and allowed to pass them to InvisibleButton(): ImGuiButtonFlags_MouseButtonLeft/Right/Middle. + This is a small but rather important change because lots of multi-button behaviors could previously + only be achieved using lower-level/internal API. Now also available via high-level InvisibleButton() + with is a de-facto versatile building block to creating custom widgets with the public API. +- Fonts: Fixed ImFontConfig::GlyphExtraSpacing and ImFontConfig::PixelSnapH settings being pulled + from the merged/target font settings when merging fonts, instead of being pulled from the source + font settings. +- ImDrawList: Thick anti-aliased strokes (> 1.0f) with integer thickness now use a texture-based + path, reducing the amount of vertices/indices and CPU/GPU usage. (#3245) [@Shironekoben] + - This change will facilitate the wider use of thick borders in future style changes. + - Requires an extra bit of texture space (~64x64 by default), relies on GPU bilinear filtering. + - Set `io.AntiAliasedLinesUseTex = false` to disable rendering using this method. + - Clear `ImFontAtlasFlags_NoBakedLines` in ImFontAtlas::Flags to disable baking data in texture. +- ImDrawList: changed AddCircle(), AddCircleFilled() default num_segments from 12 to 0, effectively + enabling auto-tessellation by default. Tweak tessellation in Style Editor->Rendering section, or + by modifying the 'style.CircleSegmentMaxError' value. [@ShironekoBen] +- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate + an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen] +- Demo: Improved "Custom Rendering"->"Canvas" demo with a grid, scrolling and context menu. + Also showcase using InvisibleButton() with multiple mouse buttons flags. +- Demo: Improved "Layout & Scrolling" -> "Clipping" section. +- Demo: Improved "Layout & Scrolling" -> "Child Windows" section. +- Style Editor: Added preview of circle auto-tessellation when editing the corresponding value. +- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h] +- Backends: Allegro 5: Fixed horizontal scrolling direction with mouse wheel / touch pads (it seems + like Allegro 5 reports it differently from GLFW and SDL). (#3394, #2424, #1463) [@nobody-special666] +- Examples: Vulkan: Fixed GLFW+Vulkan and SDL+Vulkan clear color not being set. (#3390) [@RoryO] +- CI: Emscripten has stopped their support for their fastcomp backend, switching to latest sdk [@Xipiryon] + +Docking+Viewports Branch: + +- Docking: Made DockBuilderAddNode() automatically call DockBuilderRemoveNode(). (#3399, #2109) +- Docking: Storing HoveredDockNode in context which can be useful for easily detecting e.g. hovering an + empty node. (#3398) +- Docking: Fixed docking overlay bits appearing at (0,0), because of 43bd80a. Most typically noticeable + when disabling multi-viewport. +- Docking: Workaround recovery for node created without the _DockSpace flags later becoming a DockSpace. (#3340) +- Docking: Rework size allocations to recover when there's no enough room for nodes + do not hold on + _WantLockSizeOnce forever. (#3328) +- Docking: Rework size allocation to allow user code to override node sizes. Not all edge cases will be + properly handled but this is a step toward toolbar emitting size constraints. +- Docking: Added experimental flags to perform more docking filtering and disable resize per axis. + Designed for toolbar patterns. +- Viewports, Backends, GLFW: Use GLFW_MOUSE_PASSTHROUGH when available. +- Viewports, Backends: DX12: Fixed issue on shutdown when viewports are disabled. (#3347) + + +----------------------------------------------------------------------- + VERSION 1.77 (Released 2020-06-29) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.77 + +Breaking Changes: + +- Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please + note that this is a Beta api and will likely be reworked in order to support multi-DPI across + multiple monitors. +- Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete). + [NOTE: THIS WAS REVERTED IN 1.79] +- Removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor + of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems. + Kept inline redirection function (will obsolete). +- Removed obsoleted CalcItemRectClosestPoint() entry point (has been asserting since December 2017). + +Other Changes: + +- TreeNode: Fixed bug where BeginDragDropSource() failed when the _OpenOnDoubleClick flag is + enabled (bug introduced in 1.76, but pre-1.76 it would also fail unless the _OpenOnArrow + flag was also set, and _OpenOnArrow is frequently set along with _OpenOnDoubleClick). +- TreeNode: Fixed bug where dragging a payload over a TreeNode() with either _OpenOnDoubleClick + or _OpenOnArrow would open the node. (#143) +- Windows: Fix unintended feedback loops when resizing windows close to main viewport edges. [@rokups] +- Tabs: Added style.TabMinWidthForUnselectedCloseButton settings: + - Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS). + - Set to FLT_MAX to only display a close button when selected (merely hovering is not enough). + - Set to an intermediary value to toggle behavior based on width (same as Firefox). +- Tabs: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item + (vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon] +- Popups: All functions capable of opening popups (OpenPopup*, BeginPopupContext*) now take a new + ImGuiPopupFlags sets of flags instead of a mouse button index. The API is automatically backward + compatible as ImGuiPopupFlags is guaranteed to hold mouse button index in the lower bits. +- Popups: Added ImGuiPopupFlags_NoOpenOverExistingPopup for OpenPopup*/BeginPopupContext* functions + to first test for the presence of another popup at the same level. +- Popups: Added ImGuiPopupFlags_NoOpenOverItems for BeginPopupContextWindow() - similar to testing + for !IsAnyItemHovered() prior to doing an OpenPopup(). +- Popups: Added ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen(), + allowing to check if any popup is open at the current level, if a given popup is open at any popup + level, if any popup is open at all. +- Popups: Fix an edge case where programmatically closing a popup while clicking on its empty space + would attempt to focus it and close other popups. (#2880) +- Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636) +- Popups: Clarified some of the comments and function prototypes. +- Modals: BeginPopupModal() doesn't set the ImGuiWindowFlags_NoSavedSettings flag anymore, and will + not always be auto-centered. Note that modals are more similar to regular windows than they are to + popups, so api and behavior may evolve further toward embracing this. (#915, #3091) + Enforce centering using e.g. SetNextWindowPos(io.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f,0.5f)). +- Metrics: Added a "Settings" section with some details about persistent ini settings. +- Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to + BeginMenu()/EndMenu() or BeginPopup(0/EndPopup(). (#3223, #1207) [@rokups] +- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when + drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] +- Columns: Lower overhead on column switches and switching to background channel. + Benefits Columns but was primarily made with Tables in mind! +- Fonts: Fix GetGlyphRangesKorean() end-range to end at 0xD7A3 (instead of 0xD79D). (#348, #3217) [@marukrap] +- ImDrawList: Fixed an issue where draw command merging or primitive unreserve while crossing the + VtxOffset boundary would lead to draw commands with wrong VtxOffset. (#3129, #3163, #3232, #2591) + [@thedmd, @Shironekoben, @sergeyn, @ocornut] +- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where changing channels with different + TextureId, VtxOffset would incorrectly apply new settings to draw channels. (#3129, #3163) + [@ocornut, @thedmd, @Shironekoben] +- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split when current + VtxOffset was not zero would lead to draw commands with wrong VtxOffset. (#2591) +- ImDrawList, ImDrawListSplitter, Columns: Fixed an issue where starting a split right after + a callback draw command would incorrectly override the callback draw command. +- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeeds but FT_Load_Glyph() fails. +- Docs: Improved and moved font documentation to docs/FONTS.md so it can be readable on the web. + Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut] +- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, + static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). + Fixed a static constructor which led to this dependency on some compiler setups. [@rokups] +- Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) +- Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) +- Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends, + making more render/clipping code use an early out path. +- Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the + projection matrix top and bottom values. (#3143, #3146) [@u3shit] +- Backends: OpenGL: On OSX, if unspecified by app, made default GLSL version 150. (#3199) [@albertvaka] +- Backends: OpenGL: Fixed loader auto-detection to not interfere with ES2/ES3 defines. (#3246) [@funchal] +- Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) +- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData + structure didn't have any vertices. (#2697) [@kudaba] +- Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus] +- Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259) +- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm + not forwarding right and center mouse clicks. (#3260) [@nburrus] + +Docking+Viewports Branch: + +- Viewports: Don't set ImGuiViewportFlags_NoRendererClear when ImGuiWindowFlags_NoBackground is set. (#3213) +- Viewports: Report minimized viewports as zero DisplaySize to be consistent with main branch. (#1542) +- Docking, Settings: Allow reload of settings data at runtime. (#2573) +- Backends, GLFW: Fix windows resizing incorrectly on Linux due to GLFW firing window positioning + callbacks on next frame after window is resized manually. (#2117) +- Backends: DX12: Fix OBJECT_DELETED_WHILE_STILL_IN_USE on viewport resizing. (#3210) +- Backends: DX12: Fix for crash caused by early resource release. (#3121) +- Backends, Win32: Request monitor update when DPI awareness is enabled to make sure they have the correct DPI settings. + + +----------------------------------------------------------------------- + VERSION 1.76 (Released 2020-04-12) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.76 + +Other Changes: + +- Drag and Drop, Nav: Disabling navigation arrow keys when drag and drop is active. In the docking + branch pressing arrow keys while dragging a window from a tab could trigger an assert. (#3025) +- BeginMenu: Using same ID multiple times appends content to a menu. (#1207) [@rokups] +- BeginMenu: Fixed a bug where SetNextWindowXXX data before a BeginMenu() would not be cleared + when the menu is not open. (#3030) +- InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' + glyph. (#2149, #515) +- Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) +- Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. (#125) +- TreeNode: Made clicking on arrow with _OpenOnArrow toggle the open state on the Mouse Down + event rather than the Mouse Down+Up sequence (this is rather standard behavior). +- ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced + by default for standalone ColorButton. +- Nav: Fixed interactions with ImGuiListClipper, so e.g. Home/End result would not clip the + landing item on the landing frame. (#787) +- Nav: Fixed currently focused item from ever being clipped by ItemAdd(). (#787) +- Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial + cursor position. This would often get fixed after the fix item submission, but using the + ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) +- Added optional support for Unicode plane 1-16 (#2538, #2541, #2815) [@cloudwu, @samhocevar] + - Compile-time enable with '#define IMGUI_USE_WCHAR32' in imconfig.h. + - More onsistent handling of unsupported code points (0xFFFD). + - Surrogate pairs are supported when submitting UTF-16 data via io.AddInputCharacterUTF16(), + allowing for more complete CJK input. + - sizeof(ImWchar) goes from 2 to 4. IM_UNICODE_CODEPOINT_MAX goes from 0xFFFF to 0x10FFFF. + - Various structures such as ImFont, ImFontGlyphRangesBuilder will use more memory, this + is currently not particularly efficient. +- Columns: undid the change in 1.75 were Columns()/BeginColumns() were preemptively limited + to 64 columns with an assert. (#3037, #125) +- Window: Fixed a bug with child window inheriting ItemFlags from their parent when the child + window also manipulate the ItemFlags stack. (#3024) [@Stanbroek] +- Font: Fixed non-ASCII space occasionally creating unnecessary empty looking polygons. +- Misc: Added an explicit compile-time test for non-scoped IM_ASSERT() macros to redirect users + to a solution rather than encourage people to add braces in the codebase. +- Misc: Added additional checks in EndFrame() to verify that io.KeyXXX values have not been + tampered with between NewFrame() and EndFrame(). +- Misc: Made default clipboard handlers for Win32 and OSX use a buffer inside the main context + instead of a static buffer, so it can be freed properly on Shutdown. (#3110) +- Misc, Freetype: Fixed support for IMGUI_STB_RECT_PACK_FILENAME compile time directive + in imgui_freetype.cpp (matching support in the regular code path). (#3062) [@DonKult] +- Metrics: Made Tools section more prominent. Showing wire-frame mesh directly hovering the ImDrawCmd + instead of requiring to open it. Added options to disable bounding box and mesh display. + Added notes on inactive/gc-ed windows. +- Demo: Added black and white and color gradients to Demo>Examples>Custom Rendering. +- CI: Added more tests on the continuous-integration server: extra warnings for Clang/GCC, building + SDL+Metal example, building imgui_freetype.cpp, more compile-time imconfig.h settings: disabling + obsolete functions, enabling 32-bit ImDrawIdx, enabling 32-bit ImWchar, disabling demo. [@rokups] +- Backends: OpenGL3: Fixed version check mistakenly testing for GL 4.0+ instead of 3.2+ to enable + ImGuiBackendFlags_RendererHasVtxOffset, leaving 3.2 contexts without it. (#3119, #2866) [@wolfpld] +- Backends: OpenGL3: Added include support for older glbinding 2.x loader. (#3061) [@DonKult] +- Backends: Win32: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), + ImGui_ImplWin32_GetDpiScaleForMonitor() helpers functions (backported from the docking branch). + Those functions makes it easier for example apps to support hi-dpi features without setting up + a manifest. +- Backends: Win32: Calling AddInputCharacterUTF16() from WM_CHAR message handler in order to support + high-plane surrogate pairs. (#2815) [@cloudwu, @samhocevar] +- Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function + currently does nothing). +- Backends: SDL: Fixed mapping for ImGuiKey_KeyPadEnter. (#3031) [@Davido71] +- Examples: Win32+DX12: Fixed resizing main window, enabled debug layer. (#3087, #3115) [@sergeyn] +- Examples: SDL+DX11: Fixed resizing main window. (#3057) [@joeslay] +- Examples: Added SDL+Metal example application. (#3017) [@coding-jackalope] + +Docking+Viewports Branch: + +- Docking: Fixed assert preventing dockspace from being created instead a hidden tab. (#3101) +- Viewports: Fixed secondary viewports accidentally merging into a minimized host viewport. (#3118) +- Viewports, Docking: Added per-viewport work area system for e.g. menu-bars. Fixed DockspaceOverViewport() + and demo code (overlay etc) accordingly. (#3035, #2889, #2474, #1542, #2109) +- Viewports: Improve menu positioning in multi-monitor setups. [@rokups] +- Viewports: Software mouse cursor is also scaled by current DpiScale. (amend #939) +- Viewports: Avoid manually clipping resize grips and borders, which messes up with automation ability + to locate those items. Also simpler and more standard. +- Viewports: Fix for UWP in the imgui_impl_win32.cpp IME handler. (#2895, #2892). +- Viewports: Bunch of extra of comments to facilitate setting up multi-viewports. +- Viewports, GLFW: Avoid using window positioning workaround for GLFW 3.3+ versions that have it fixed. + + +----------------------------------------------------------------------- + VERSION 1.75 (Released 2020-02-10) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.75 + +Breaking Changes: + +- Removed redirecting functions/enums names that were marked obsolete in 1.53 (December 2017): + - ShowTestWindow() -> use ShowDemoWindow() + - IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow) + - IsRootWindowOrAnyChildFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) + - SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f) + - GetItemsLineHeightWithSpacing() -> use GetFrameHeightWithSpacing() + - ImGuiCol_ChildWindowBg -> use ImGuiCol_ChildBg + - ImGuiStyleVar_ChildWindowRounding -> use ImGuiStyleVar_ChildRounding + - ImGuiTreeNodeFlags_AllowOverlapMode -> use ImGuiTreeNodeFlags_AllowItemOverlap + - IMGUI_DISABLE_TEST_WINDOWS -> use IMGUI_DISABLE_DEMO_WINDOWS + If you were still using the old names, while you are cleaning up, considering enabling + IMGUI_DISABLE_OBSOLETE_FUNCTIONS in imconfig.h even temporarily to have a pass at finding + and removing up old API calls, if any remaining. +- Removed implicit default parameter to IsMouseDragging(int button = 0) to be consistent + with other mouse functions (none of the other functions have it). +- Obsoleted calling ImDrawList::PrimReserve() with a negative count (which was vaguely + documented and rarely if ever used). Instead we added an explicit PrimUnreserve() API + which can be implemented faster. Also clarified pre-existing constraints which weren't + documented (can only unreserve from the last reserve call). If you suspect you ever + used that feature before (very unlikely, but grep for call to PrimReserve in your code), + you can #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing calls. [@ShironekoBen] +- ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius. +- Limiting Columns()/BeginColumns() api to 64 columns with an assert. While the current code + technically supports it, future code may not so we're putting the restriction ahead. + [Undid that change in 1.76] +- imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead + of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by + adding points into it without explicit initialization, you may need to fix your initial value. + +Other Changes: + +- Inputs: Added ImGuiMouseButton enum for convenience (e.g. ImGuiMouseButton_Right=1). + We forever guarantee that the existing value will not changes so existing code is free to use 0/1/2. +- Nav: Fixed a bug where the initial CTRL-Tab press while in a child window sometimes selected + the current root window instead of always selecting the previous root window. (#787) +- ColorEdit: Fix label alignment when using ImGuiColorEditFlags_NoInputs. (#2955) [@rokups] +- ColorEdit: In HSV display of a RGB stored value, attempt to locally preserve Saturation + when Value==0.0 (similar to changes done in 1.73 for Hue). Removed Hue editing lock since + those improvements in 1.73 makes them unnecessary. (#2722, #2770). [@rokups] +- ColorEdit: "Copy As" context-menu tool shows hex values with a '#' prefix instead of '0x'. +- ColorEdit: "Copy As" content-menu tool shows hex values both with/without alpha when available. +- InputText: Fix corruption or crash when executing undo after clearing input with ESC, as a + byproduct we are allowing to later undo the revert with a CTRL+Z. (#3008). +- InputText: Fix using a combination of _CallbackResize (e.g. for std::string binding), along with the + _EnterReturnsTrue flag along with the rarely used property of using an InputText without persisting + user-side storage. Previously if you had e.g. a local unsaved std::string and reading result back + from the widget, the user string object wouldn't be resized when Enter key was pressed. (#3009) +- MenuBar: Fix minor clipping issue where occasionally a menu text can overlap the right-most border. +- Window: Fix SetNextWindowBgAlpha(1.0f) failing to override alpha component. (#3007) [@Albog] +- Window: When testing for the presence of the ImGuiWindowFlags_NoBringToFrontOnFocus flag we + test both the focused/clicked window (which could be a child window) and the root window. +- ImDrawList: AddCircle(), AddCircleFilled() API can now auto-tessellate when provided a segment + count of zero. Alter tessellation quality with 'style.CircleSegmentMaxError'. [@ShironekoBen] +- ImDrawList: Add AddNgon(), AddNgonFilled() API with a guarantee on the explicit segment count. + In the current branch they are essentially the same as AddCircle(), AddCircleFilled() but as + we will rework the circle rendering functions to use textures and automatic segment count + selection, those new api can fill a gap. [@ShironekoBen] +- Columns: ImDrawList::Channels* functions now work inside columns. Added extra comments to + suggest using user-owned ImDrawListSplitter instead of ImDrawList functions. [@rokups] +- Misc: Added ImGuiMouseCursor_NotAllowed enum so it can be used by more shared widgets. [@rokups] +- Misc: Added IMGUI_DISABLE compile-time definition to make all headers and sources empty. +- Misc: Disable format checks when using stb_printf, to allow using extra formats. + Made IMGUI_USE_STB_SPRINTF a properly documented imconfig.h flag. (#2954) [@loicmolinari] +- Misc: Added misc/single_file/imgui_single_file.h, We use this to validate compiling all *.cpp + files in a same compilation unit. Actual users of that technique (also called "Unity builds") + can generally provide this themselves, so we don't really recommend you use this. [@rokups] +- CI: Added PVS-Studio static analysis on the continuous-integration server. [@rokups] +- Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups] +- Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups] +- Backends: SDL: Wayland: use SDL_GetMouseState (because there is no global mouse state available + on Wayland). (#2800, #2802) [@NeroBurner] +- Backends: GLFW, SDL: report Windows key (io.KeySuper) as always released. Neither GLFW nor SDL can + correctly report the key release in every cases (e.g. when using Win+V) causing problems with some + widgets. The next release of GLFW (3.4+) will have a fix for it. However since it is both difficult + and discouraged to make use of this key for Windows application anyway, we just hide it. (#2976) +- Backends: Win32: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD to disable all + XInput using code, and IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT to disable linking with XInput, + the later may be problematic if compiling with recent Windows SDK and you want your app to run + on Windows 7. You can instead try linking with Xinput9_1_0.lib instead. (#2716) +- Backends: Glut: Improved FreeGLUT support for MinGW. (#3004) [@podsvirov] +- Backends: Emscripten: Avoid forcefully setting IMGUI_DISABLE_FILE_FUNCTIONS. (#3005) [@podsvirov] +- Examples: OpenGL: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking + settings (otherwise if another loader such as Glew is accessible, the OpenGL3 backend might + automatically use it). (#2919, #2798) +- Examples: OpenGL: Added support for glbinding OpenGL loader. (#2870) [@rokups] +- Examples: Emscripten: Demonstrating embedding fonts in Makefile and code. (#2953) [@Oipo] +- Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed + even if underlying system event loop gets paused due to app nap. (#2910, #2917) [@bear24rw] + +Docking+Viewports Branch: + +- Docking + Nav: Fixed messed up Ctrl+Tab order with docked windows. +- Docking + Nav: Fixed failing to restore NavId when refocusing a child within a docked window. +- Docking + Nav: Fixed failing to restore NavId when refocusing due to missing nav window (when + it stops being submitted). +- Docking: Fixed a bug where the tab bar of a hidden dockspace would keep requesting focus. (#2960) +- Docking: Added experimental DockNodeFlagsOverrideSet/DockNodeFlagsOverrideClear flags in ImGuiWindowClass + (currently experimenting with toolbar idioms). +- Viewports: Fix resizing viewport-owning windows when mouse pos is outside the InnerClipRect + (can happen with OS decoration enabled). +- Viewports: Preserve last known size for minimized main viewport to be consistent with secondary viewports. +- Backends: SDL: Honor NoTaskBarIcon flag under non Win32 OS. (#2117) +- Backends: GLFW, SDL: Platform monitors declared properly even if multi-viewport is not enabled. + + +----------------------------------------------------------------------- + VERSION 1.74 (Released 2019-11-25) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.74 + +Breaking Changes: + +- Removed redirecting functions/enums names that were marked obsolete in 1.52 (October 2017): + - Begin() [old 5 args version] -> use Begin() [3 args], use SetNextWindowSize() SetNextWindowBgAlpha() if needed + - IsRootWindowOrAnyChildHovered() -> use IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows) + - AlignFirstTextHeightToWidgets() -> use AlignTextToFramePadding() + - SetNextWindowPosCenter() -> use SetNextWindowPos() with a pivot of (0.5f, 0.5f) + - ImFont::Glyph -> use ImFontGlyph + If you were still using the old names, read "API Breaking Changes" section of imgui.cpp to find out + the new names or equivalent features, or see how they were implemented until 1.73. +- Inputs: Fixed a miscalculation in the keyboard/mouse "typematic" repeat delay/rate calculation, used + by keys and e.g. repeating mouse buttons as well as the GetKeyPressedAmount() function. + If you were using a non-default value for io.KeyRepeatRate (previous default was 0.250), you can + add +io.KeyRepeatDelay to it to compensate for the fix. + The function was triggering on: 0.0 and (delay+rate*N) where (N>=1). Fixed formula responds to (N>=0). + Effectively it made io.KeyRepeatRate behave like it was set to (io.KeyRepeatRate + io.KeyRepeatDelay). + Fixed the code and altered default io.KeyRepeatRate,Delay from 0.250,0.050 to 0.300,0.050 to compensate. + If you never altered io.KeyRepeatRate nor used GetKeyPressedAmount() this won't affect you. +- Misc: Renamed IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS to IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS. (#1038) +- Misc: Renamed IMGUI_DISABLE_MATH_FUNCTIONS to IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS. +- Fonts: ImFontAtlas::AddCustomRectRegular() now requires an ID larger than 0x110000 (instead of 0x10000) to + conform with supporting Unicode planes 1-16 in a future update. ID below 0x110000 will now assert. +- Backends: DX12: Added extra ID3D12DescriptorHeap parameter to ImGui_ImplDX12_Init() function. + The value is unused in master branch but will be used by the multi-viewport feature. (#2851) [@obfuscate] + +Other Changes: + +- InputText, Nav: Fixed Home/End key broken when activating Keyboard Navigation. (#787) +- InputText: Filter out ASCII 127 (DEL) emitted by low-level OSX layer, as we are using the Key value. (#2578) +- Layout: Fixed a couple of subtle bounding box vertical positioning issues relating to the handling of text + baseline alignment. The issue would generally manifest when laying out multiple items on a same line, + with varying heights and text baseline offsets. + Some specific examples, e.g. a button with regular frame padding followed by another item with a + multi-line label and no frame padding, such as: multi-line text, small button, tree node item, etc. + The second item was correctly offset to match text baseline, and would interact/display correctly, + but it wouldn't push the contents area boundary low enough. +- Scrollbar: Fixed an issue where scrollbars wouldn't display on the frame following a frame where + all child window contents would be culled. +- ColorPicker: Fixed SV triangle gradient to block (broken in 1.73). (#2864, #2711). [@lewa-j] +- TreeNode: Fixed combination of ImGuiTreeNodeFlags_SpanFullWidth and ImGuiTreeNodeFlags_OpenOnArrow + incorrectly locating the arrow hit position to the left of the frame. (#2451, #2438, #1897) +- TreeNode: The collapsing arrow accepts click even if modifier keys are being held, facilitating + interactions with custom multi-selections patterns. (#2886, #1896, #1861) +- TreeNode: Added IsItemToggledOpen() to explicitly query if item was just open/closed, facilitating + interactions with custom multi-selections patterns. (#1896, #1861) +- DragScalar, SliderScalar, InputScalar: Added p_ prefix to parameter that are pointers to the data + to clarify how they are used, and more comments redirecting to the demo code. (#2844) +- Error handling: Assert if user mistakenly calls End() instead of EndChild() on a child window. (#1651) +- Misc: Optimized storage of window settings data (reducing allocation count). +- Misc: Windows: Do not use _wfopen() if IMGUI_DISABLE_WIN32_FUNCTIONS is defined. (#2815) +- Misc: Windows: Disabled win32 function by default when building with UWP. (#2892, #2895) +- Misc: Using static_assert() when using C++11, instead of our own construct (avoid zealous Clang warnings). +- Misc: Added IMGUI_DISABLE_FILE_FUNCTIONS/IMGUI_DISABLE_DEFAULT_FILE_FUNCTION to nullify or disable + default implementation of ImFileXXX functions linking with fopen/fclose/fread/fwrite. (#2734) +- Docs: Improved and moved FAQ to docs/FAQ.md so it can be readable on the web. [@ButternCream, @ocornut] +- Docs: Moved misc/fonts/README.txt to docs/FONTS.txt. +- Docs: Added permanent redirect from https://www.dearimgui.org/faq to FAQ page. +- Demo: Added simple item reordering demo in Widgets -> Drag and Drop section. (#2823, #143) [@rokups] +- Metrics: Show wire-frame mesh and approximate surface area when hovering ImDrawCmd. [@ShironekoBen] +- Metrics: Expose basic details of each window key/value state storage. +- Examples: DX12: Using IDXGIDebug1::ReportLiveObjects() when DX12_ENABLE_DEBUG_LAYER is enabled. +- Examples: Emscripten: Removed BINARYEN_TRAP_MODE=clamp from Makefile which was removed in Emscripten 1.39.0 + but required prior to 1.39.0, making life easier for absolutely no-one. (#2877, #2878) [@podsvirov] +- Backends: OpenGL2: Explicitly backup, setup and restore GL_TEXTURE_ENV to increase compatibility with + legacy OpenGL applications. (#3000) +- Backends: OpenGL3: Fix building with pre-3.2 GL loaders which do not expose glDrawElementsBaseVertex(), + using runtime GL version to decide if we set ImGuiBackendFlags_RendererHasVtxOffset. (#2866, #2852) [@dpilawa] +- Backends: OSX: Fix using Backspace key. (#2578, #2817, #2818) [@DiligentGraphics] +- Backends: GLFW: Previously installed user callbacks are now restored on shutdown. (#2836) [@malte-v] +- CI: Set up a bunch of continuous-integration tests using GitHub Actions. We now compile many of the example + applications on Windows, Linux, MacOS, iOS, Emscripten. Removed Travis integration. (#2865) [@rokups] + +Docking+Viewports Branch: + +- Docking: Can undock from the small triangle button. (#2109,. #2645) +- Docking: Fixed node->HasCloseButton not honoring ImGuiDockNodeFlags_NoCloseButton in a floating node, + leading to empty space at the right of tab-bars with those flags. (#2109) +- Docking: Made docked windows not use style.ChildRounding. +- Multi-viewports: Added multi-viewport support in the DX12 back-end. (#2851) [@obfuscate] + + +----------------------------------------------------------------------- + VERSION 1.73 (Released 2019-09-24) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.73 + +Other Changes: + +- Nav, Scrolling: Added support for Home/End key. (#787) +- ColorEdit: Disable Hue edit when Saturation==0 instead of letting Hue values jump around. +- ColorEdit, ColorPicker: In HSV display of a RGB stored value, attempt to locally preserve Hue + when Saturation==0, which reduces accidentally lossy interactions. (#2722, #2770) [@rokups] +- ColorPicker: Made rendering aware of global style alpha of the picker can be faded out. (#2711) + Note that some elements won't accurately fade down with the same intensity, and the color wheel + when enabled will have small overlap glitches with (style.Alpha < 1.0). +- TabBar: Fixed single-tab not shrinking their width down. +- TabBar: Fixed clicking on a tab larger than tab-bar width creating a bouncing feedback loop. +- TabBar: Feed desired width (sum of unclipped tabs width) into layout system to allow for auto-resize. (#2768) + (before 1.71 tab bars fed the sum of current width which created feedback loops in certain situations). +- TabBar: Improved shrinking for large number of tabs to avoid leaving extraneous space on the right side. + Individuals tabs are given integer-rounded width and remainder is spread between tabs left-to-right. +- Columns, Separator: Fixed a bug where non-visible separators within columns would alter the next row position + differently than visible ones. +- SliderScalar: Improved assert when using U32 or U64 types with a large v_max value. (#2765) [@loicmouton] +- DragInt, DragFloat, DragScalar: Using (v_min > v_max) allows locking any edits to the value. +- DragScalar: Fixed dragging of unsigned values on ARM cpu (float to uint cast is undefined). (#2780) [@dBagrat] +- TreeNode: Added ImGuiTreeNodeFlags_SpanAvailWidth flag. (#2451, #2438, #1897) [@Melix19, @PathogenDavid] + This extends the hit-box to the right-most edge, even if the node is not framed. + (Note: this is not the default in order to allow adding other items on the same line. In the future we will + aim toward refactoring the hit-system to be front-to-back, allowing more natural overlapping of items, + and then we will be able to make this the default.) +- TreeNode: Added ImGuiTreeNodeFlags_SpanFullWidth flag. This extends the hit-box to both the left-most and + right-most edge of the working area, bypassing indentation. +- CollapsingHeader: Added support for ImGuiTreeNodeFlags_Bullet and ImGuiTreeNodeFlags_Leaf on framed nodes, + mostly for consistency. (#2159, #2160) [@goran-w] +- Selectable: Added ImGuiSelectableFlags_AllowItemOverlap flag in public api (was previously internal only). +- Style: Allow style.WindowMenuButtonPosition to be set to ImGuiDir_None to hide the collapse button. (#2634, #2639) +- Font: Better ellipsis ("...") drawing implementation. Instead of drawing three pixel-ey dots (which was glaringly + unfitting with many types of fonts) we first attempt to find a standard ellipsis glyphs within the loaded set. + Otherwise we render ellipsis using '.' from the font from where we trim excessive spacing to make it as narrow + as possible. (#2775) [@rokups] +- ImDrawList: Clarified the name of many parameters so reading the code is a little easier. (#2740) +- ImDrawListSplitter: Fixed merging channels if the last submitted draw command used a different texture. (#2506) +- Using offsetof() when available in C++11. Avoids Clang sanitizer complaining about old-style macros. (#94) +- ImVector: Added find(), find_erase(), find_erase_unsorted() helpers. +- Added a mechanism to compact/free the larger allocations of unused windows (buffers are compacted when + a window is unused for 60 seconds, as per io.ConfigWindowsMemoryCompactTimer = 60.0f). Note that memory + usage has never been reported as a problem, so this is merely a touch of overzealous luxury. (#2636) +- Documentation: Various tweaks and improvements to the README page. [@ker0chan] +- Backends: OpenGL3: Tweaked initialization code allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() + before ImGui_ImplOpenGL3_NewFrame(), which sometimes can be convenient. +- Backends: OpenGL3: Attempt to automatically detect default GL loader by using __has_include. (#2798) [@o-micron] +- Backends: DX11: Fixed GSGetShader() call not passing an initialized instance count, which would + generally make the DX11 debug layer complain (bug added in 1.72). +- Backends: Vulkan: Added support for specifying multisample count. Set 'ImGui_ImplVulkan_InitInfo::MSAASamples' to + one of the VkSampleCountFlagBits values to use, default is non-multisampled as before. (#2705, #2706) [@vilya] +- Examples: OSX: Fix example_apple_opengl2/main.mm not forwarding mouse clicks and drags correctly. (#1961, #2710) + [@intonarumori, @ElectricMagic] +- Misc: Updated stb_rect_pack.h from 0.99 to 1.00 (fixes by @rygorous: off-by-1 bug in best-fit heuristic, + fix handling of rectangles too large to fit inside texture). (#2762) [@tido64] + +Docking+Viewports Branch: + +- Docking: Fix BeginDocked() path that creates node so that SetNextWindowDockID() doesn't immediately discard the node. (#2109) +- Docking: Fix for node created at the same time as windows that are still resizing (typically with + io.ConfigDockingAlwaysTabBar) to not be zero/min sized. (#2109). The fix delays their visibility by one frame, + which is not ideal but not very problematic as the .ini data gets populated after that. +- Docking: Fix a crash that could occur with a malformed ini file (DockNode Parent value pointing to a missing node). +- Viewport: Fix modal/popup window being stuck in unowned hidden viewport associated to fallback window without stealing + it back. Fix modal reference viewport when opened outside of another window. (#1542) +- Viewport: Modals don't need to set ImGuiViewportFlags_NoFocusOnClick, this also mitigate the issue described by #2445, + which becomes particularly bad with unfocused modal. (#1542) +- Viewport: better case case where host window gets moved and resized simultaneous (toggling maximized state). + There's no perfect solution there, than using io.ConfigViewportsNoAutoMerge = false. (#1542) +- Viewport, Docking: Fixed incorrect assignment of IsFallbackWindow which would tag dock node host windows created + in NewFrame() as such, messing with popup viewport inheritance. +- Viewport: Fixed issue where resize grip would display as hovered while mouse is still off the OS bounds so a click + would miss it and focus the OS window behind expected one. (#1542) +- Viewport: Fix to allow multiple shutdown / calls to DestroyPlatformWindows(). (#2769) +- Viewport: Backends: GLFW: Fix setting window size on macOS (#2767, #2117) [@rokups] +- Viewport: Backends: GLFW+Linux: Fix window having incorrect size after uncollapse. (#2756, #2117) [@rokups] +- Viewport: Backends: DirectX9: Workaround for windows not refreshing when main viewport has no draw call. (#2560) + + +----------------------------------------------------------------------- + VERSION 1.72b (Released 2019-07-31) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.72b + +Other Changes: + +- Nav, Scrolling: Fixed programmatic scroll leading to a slightly incorrect scroll offset when + the window has decorations or a menu-bar (broken in 1.71). This was mostly noticeable when + a keyboard/gamepad movement led to scrolling the view, or using e.g. SetScrollHereY() function. +- Nav: Made hovering non-MenuItem Selectable not re-assign the source item for keyboard navigation. +- Nav: Fixed an issue with NavFlattened window flag (beta) where widgets not entirely fitting + in child window (often selectables because of their protruding sides) would be not considered + as entry points to to navigate toward the child window. (#787) + + +----------------------------------------------------------------------- + VERSION 1.72 (Released 2019-07-27) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.72 + +Breaking Changes: + +- Removed redirecting functions/enums names that were marked obsolete in 1.51 (June 2017): + - ImGuiCol_Column*, ImGuiSetCond_* enums. + - IsItemHoveredRect(), IsPosHoveringAnyWindow(), IsMouseHoveringAnyWindow(), IsMouseHoveringWindow() functions. + - IMGUI_ONCE_UPON_A_FRAME macro. + If you were still using the old names, read "API Breaking Changes" section of imgui.cpp to find out + the new names or equivalent features. +- Renamed ImFontAtlas::CustomRect to ImFontAtlasCustomRect. Kept redirection typedef (will obsolete). +- Removed TreeAdvanceToLabelPos() which is rarely used and only does SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()). + Kept redirection function (will obsolete). (#581, #324) + +Other Changes: + +- Scrolling: Made mouse-wheel scrolling lock the underlying window until the mouse is moved again or + until a short delay expires (~2 seconds). This allow uninterrupted scroll even if child windows are + passing under the mouse cursor. (#2604) +- Scrolling: Made it possible for mouse wheel and navigation-triggered scrolling to override a call to + SetScrollX()/SetScrollY(), making it possible to use a simpler stateless pattern for auto-scrolling: + // (Submit items..) + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) // If scrolling at the already at the bottom.. + ImGui::SetScrollHereY(1.0f); // ..make last item fully visible +- Scrolling: Added SetScrollHereX(), SetScrollFromPosX() for completeness. (#1580) [@kevreco] +- Scrolling: Mouse wheel scrolling while hovering a child window is automatically forwarded to parent window + if ScrollMax is zero on the scrolling axis. + Also still the case if ImGuiWindowFlags_NoScrollWithMouse is set (not new), but previously the forwarding + would be disabled if ImGuiWindowFlags_NoScrollbar was set on the child window, which is not the case + any more. Forwarding can still be disabled by setting ImGuiWindowFlags_NoInputs. (amend #1502, #1380). +- Window: Fixed InnerClipRect right-most coordinates using wrong padding setting (introduced in 1.71). +- Window: Fixed old SetWindowFontScale() api value from not being inherited by child window. Added + comments about the right way to scale your UI (load a font at the right side, rebuild atlas, scale style). +- Scrollbar: Avoid overlapping the opposite side when window (often a child window) is forcibly too small. +- Combo: Hide arrow when there's not enough space even for the square button. +- InputText: Testing for newly added ImGuiKey_KeyPadEnter key. (#2677, #2005) [@amc522] +- TabBar: Fixed unfocused tab bar separator color (was using ImGuiCol_Tab, should use ImGuiCol_TabUnfocusedActive). +- Columns: Fixed a regression from 1.71 where the right-side of the contents rectangle within each column + would wrongly use a WindowPadding.x instead of ItemSpacing.x like it always did. (#125, #2666) +- Columns: Made the right-most edge reaches up to the clipping rectangle (removing half of WindowPadding.x + worth of asymmetrical/extraneous padding, note that there's another half that conservatively has to offset + the right-most column, otherwise it's clipping width won't match the other columns). (#125, #2666) +- Columns: Improved honoring alignment with various values of ItemSpacing.x and WindowPadding.x. (#125, #2666) +- Columns: Made GetColumnOffset() and GetColumnWidth() behave when there's no column set, consistently with + other column functions. (#2683) +- InputTextMultiline: Fixed vertical scrolling tracking glitch. +- Word-wrapping: Fixed overzealous word-wrapping when glyph edge lands exactly on the limit. Because + of this, auto-fitting exactly unwrapped text would make it wrap. (fixes initial 1.15 commit, 78645a7d). +- Style: Attenuated default opacity of ImGuiCol_Separator in Classic and Light styles. +- Style: Added style.ColorButtonPosition (left/right, defaults to ImGuiDir_Right) to move the color button + of ColorEdit3/ColorEdit4 functions to either side of the inputs. +- IO: Added ImGuiKey_KeyPadEnter and support in various backends (previously backends would need to + specifically redirect key-pad keys to their regular counterpart). This is a temporary attenuating measure + until we actually refactor and add whole sets of keys into the ImGuiKey enum. (#2677, #2005) [@amc522] +- Misc: Made Button(), ColorButton() not trigger an "edited" event leading to IsItemDeactivatedAfterEdit() + returning true. This also effectively make ColorEdit4() not incorrect trigger IsItemDeactivatedAfterEdit() + when clicking the color button to open the picker popup. (#1875) +- Misc: Added IMGUI_DISABLE_METRICS_WINDOW imconfig.h setting to explicitly compile out ShowMetricsWindow(). +- Debug, Metrics: Added "Tools->Item Picker" tool which allow clicking on a widget to break in the debugger + within the item code. The tool calls IM_DEBUG_BREAK() which can be redefined in imconfig.h if needed. +- ImDrawList: Fixed CloneOutput() helper crashing. (#1860) [@gviot] +- ImDrawList::ChannelsSplit(), ImDrawListSplitter: Fixed an issue with merging draw commands between + channel 0 and 1. (#2624) +- ImDrawListSplitter: Fixed memory leak when using low-level split api (was not affecting ImDrawList api, + also this type was added in 1.71 and not advertised as a public-facing feature). +- Fonts: binary_to_compressed_c.cpp: Display an error message if failing to open/read the input font file. +- Demo: Log, Console: Using a simpler stateless pattern for auto-scrolling. +- Demo: Widgets: Showing how to use the format parameter of Slider/Drag functions to display the name + of an enum value instead of the underlying integer value. +- Demo: Renamed the "Help" menu to "Tools" (more accurate). +- Backends: DX10/DX11: Backup, clear and restore Geometry Shader is any is bound when calling renderer. +- Backends: DX11: Clear Hull Shader, Domain Shader, Compute Shader before rendering. Not backing/restoring them. +- Backends: OSX: Disabled default native Mac clipboard copy/paste implementation in core library (added in 1.71), + because it needs application to be linked with '-framework ApplicationServices'. It can be explicitly + enabled back by using '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h. Re-added + equivalent using NSPasteboard api in the imgui_impl_osx.mm experimental backend. (#2546) +- Backends: SDL2: Added ImGui_ImplSDL2_InitForD3D() function to make D3D support more visible. + (#2482, #2632) [@josiahmanson] +- Examples: Added SDL2+DirectX11 example application. (#2632, #2612, #2482) [@vincenthamm] + +Docking+Viewports Branch: + +- Docking: Making it possible to undock a node by clicking on the tab bar / title bar for the node. (#2645). +- Docking: Explicitly inhibit constraint when docked for now. Fix clipping issue related to constraints. (#2690). +- Docking: Fixed dragging/resizing from OS decoration not marking settings as dirty. +- Docking: Renamed io.ConfigDockingTabBarOnSingleWindows to io.ConfigDockingAlwaysTabBar. + Added ImGuiWindowClass::DockingAlwaysTabBar to set on individual windows. +- Docking: Perform simple check: assert if Docking or Viewport are enabled exactly on frame 1 (instead of frame 0 + or later), which is a common user error leading to loss of .ini data on load. +- Docking: Fix so that an appearing window making a dock node reappear won't have a zero-size on its first frame. +- Docking: Fixed using ImGuiDockNodeFlags_AutoHideTabBar with io.ConfigDockingTabBarOnSingleWindows. +- Docking: Added ImGuiDockNode to .natvis file. +- Docking: Fixed support for large meshes in GetBackgroundDrawList(), GetForegroundDrawList(). (#2638) +- Viewport: Fix monitor dpi info not being copied to main viewport when multi-viewports are not enabled. (#2621, #1676) +- Viewport: Refactored ImGuiWindowClass's ViewportFlagsOverrideMask + ViewportFlagsOverrideValue into + ViewportFlagsOverrideSet + ViewportFlagsOverrideClear which appears easier to grasp. (#1542) +- Viewport: Added ImGuiViewportFlags_NoAutoMerge to prevent merging into host viewport in a per-window basis + via the ImGuiWindowClass override mechanism. (#1542) + + +----------------------------------------------------------------------- + VERSION 1.71 (Released 2019-06-12) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.71 + +Breaking Changes: + +- IO: changed AddInputCharacter(unsigned short c) signature to AddInputCharacter(unsigned int c). +- Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). +- Window: rendering of child windows outer decorations (e.g. bg color, border, scrollbars) is now + performed as part of their parent window, avoiding the creation of an extraneous draw commands. + If you have overlapping child windows with decorations, and relied on their relative z-order to be + mapped to submission their order, this will affect your rendering. The optimization is disabled + if the parent window has no visual output because it appears to be the most common situation leading + to the creation of overlapping child windows. Please reach out if you are affected by this change! + +Other Changes: + +- Window: clarified behavior of SetNextWindowContentSize(). Content size is defined as the size available + after removal of WindowPadding on each sides. So SetNextWindowContentSize(ImVec2(100,100)) + auto-resize + will always allow submitting a 100x100 item without creating a scrollbar, regarding of WindowPadding. + The exact meaning of ContentSize for decorated windows was previously ill-defined. +- Window: Fixed auto-resize with AlwaysVerticalScrollbar or AlwaysHorizontalScrollbar flags. +- Window: Fixed one case where auto-resize by double-clicking the resize grip would make either scrollbar + appear for a single frame after the resize. +- Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change. It's not incorrect + but it breaks existing some layout patterns. Will return back to it when we expose Separator flags. +- Fixed InputScalar, InputScalarN, SliderScalarN, DragScalarN with non-visible label from inserting + style.ItemInnerSpacing.x worth of trailing spacing. +- Fixed InputFloatX, SliderFloatX, DragFloatX functions erroneously reporting IsItemEdited() multiple + times when the text input doesn't match the formatted output value (e.g. input "1" shows "1.000"). + It wasn't much of a problem because we typically use the return value instead of IsItemEdited() here. +- Fixed uses of IsItemDeactivated(), IsItemDeactivatedAfterEdit() on multi-components widgets and + after EndGroup(). (#2550, #1875) +- Fixed crash when appending with BeginMainMenuBar() more than once and no other window are showing. (#2567) +- ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple + options. (#2587, broken in 1.69 by #2384). +- CollapsingHeader: Better clipping when a close button is enabled and it overlaps the label. (#600) +- Scrollbar: Minor bounding box adjustment to cope with various border size. +- Scrollbar, Style: Changed default style.ScrollbarSize from 16 to 14. +- Combo: Fixed rounding not applying with the ImGuiComboFlags_NoArrowButton flag. (#2607) [@DucaRii] +- Nav: Fixed gamepad/keyboard moving of window affecting contents size incorrectly, sometimes leading + to scrollbars appearing during the movement. +- Nav: Fixed rare crash when e.g. releasing Alt-key while focusing a window with a menu at the same + frame as clearing the focus. This was in most noticeable in backends such as Glfw and SDL which + emits key release events when focusing another viewport, leading to Alt+clicking on void on another + viewport triggering the issue. (#2609) +- TreeNode, CollapsingHeader: Fixed highlight frame not covering horizontal area fully when using + horizontal scrolling. (#2211, #2579) +- TabBar: Fixed BeginTabBar() within a window with horizontal scrolling from creating a feedback + loop with the horizontal contents size. +- Columns: Fixed Columns() within a window with horizontal scrolling from not covering the full + horizontal area (previously only worked with an explicit contents size). (#125) +- Columns: Fixed Separator from creating an extraneous draw command. (#125) +- Columns: Fixed Selectable with SpanAllColumns flag from creating an extraneous draw command. (#125) +- Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the + collapsing/docking button to the other side of the title bar. +- Style: Made window close button cross slightly smaller. +- Log/Capture: Fixed BeginTabItem() label not being included in a text log/capture. +- ImDrawList: Added ImDrawCmd::VtxOffset value to support large meshes (64k+ vertices) using 16-bit indices. + The renderer backend needs to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' to enable + this, and honor the ImDrawCmd::VtxOffset field. Otherwise the value will always be zero. (#2591) + This has the advantage of preserving smaller index buffers and allowing to execute on hardware that do not + support 32-bit indices. Most examples backends have been modified to support the VtxOffset field. +- ImDrawList: Added ImDrawCmd::IdxOffset value, equivalent to summing element count for each draw command. + This is provided for convenience and consistency with VtxOffset. (#2591) +- ImDrawCallback: Allow to override the signature of ImDrawCallback by #define-ing it. This is meant to + facilitate custom rendering backends passing local render-specific data to the draw callback. +- ImFontAtlas: FreeType: Added RasterizerFlags::Monochrome flag to disable font anti-aliasing. Combine + with RasterizerFlags::MonoHinting for best results. (#2545) [@HolyBlackCat] +- ImFontGlyphRangesBuilder: Fixed unnecessarily over-sized buffer, which incidentally was also not + fully cleared. Fixed edge-case overflow when adding character 0xFFFF. (#2568). [@NIKE3500] +- Demo: Added full "Dear ImGui" prefix to the title of "Dear ImGui Demo" and "Dear ImGui Metrics" windows. +- Backends: Add native Mac clipboard copy/paste default implementation in core library to match what we are + dealing with Win32, and to facilitate integration in custom engines. (#2546) [@andrewwillmott] +- Backends: OSX: imgui_impl_osx: Added mouse cursor support. (#2585, #1873) [@actboy168] +- Examples/Backends: DirectX9/10/11/12, Metal, Vulkan, OpenGL3 (Desktop GL only): Added support for large meshes + (64k+ vertices) with 16-bit indices, enable 'ImGuiBackendFlags_RendererHasVtxOffset' in those backends. (#2591) +- Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(), + the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode + support. (#2538, #2541) + + +----------------------------------------------------------------------- + VERSION 1.70 (Released 2019-05-06) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.70 + +Breaking Changes: + +- ImDrawList: Improved algorithm for mitre joints on thick lines, preserving correct thickness + up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines, + they will appear a little thicker now. (#2518) [@rmitton] +- Obsoleted GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. + Kept inline redirection function. +- Examples: Vulkan: Added MinImageCount/ImageCount fields in ImGui_ImplVulkan_InitInfo, required + during initialization to specify the number of in-flight image requested by swap chains. + (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). (#2071, #1677) [@nathanvoglsam] +- Examples: Vulkan: Tidying up the demo/internals helpers (most engine/app should not rely + on them but it is possible you have!). + +Other Changes: + +- ImDrawList: Added ImDrawCallback_ResetRenderState, a special ImDrawList::AddCallback() value + to request the renderer backend to reset its render state. (#2037, #1639, #2452) + Examples: Added support for ImDrawCallback_ResetRenderState in all renderer backends. Each + renderer code setting up initial render state has been moved to a function so it could be + called at the start of rendering and when a ResetRenderState is requested. [@ocornut, @bear24rw] +- InputText: Fixed selection background rendering one frame after the cursor movement when + first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul] +- InputText: Work-around for buggy standard libraries where isprint('\t') returns true. (#2467, #1336) +- InputText: Fixed ImGuiInputTextFlags_AllowTabInput leading to two tabs characters being inserted + if the backend provided both Key and Character input. (#2467, #1336) +- Layout: Added SetNextItemWidth() helper to avoid using PushItemWidth/PopItemWidth() for single items. + Note that SetNextItemWidth() currently only affect the same subset of items as PushItemWidth(), + generally referred to as the large framed+labeled items. Because the new SetNextItemWidth() + function is explicit we may later extend its effect to more items. +- Layout: Fixed PushItemWidth(-width) for right-side alignment laying out some items (button, listbox, etc.) + with negative sizes if the 'width' argument was smaller than the available width at the time of item + submission. +- Window: Fixed window with the AlwaysAutoResize flag unnecessarily extending their hovering boundaries + by a few pixels (this is used to facilitate resizing from borders when available for a given window). + One of the noticeable minor side effect was that navigating menus would have had a tendency to disable + highlight from parent menu items earlier than necessary while approaching the child menu. +- Window: Close button is horizontally aligned with style.FramePadding.x. +- Window: Fixed contents region being off by WindowBorderSize amount on the right when scrollbar is active. +- Window: Fixed SetNextWindowSizeConstraints() with non-rounded positions making windows drift. (#2067, #2530) +- Popups: Closing a popup restores the focused/nav window in place at the time of the popup opening, + instead of restoring the window that was in the window stack at the time of the OpenPopup call. (#2517) + Among other things, this allows opening a popup while no window are focused, and pressing Escape to + clear the focus again. +- Popups: Fixed right-click from closing all popups instead of aiming at the hovered popup level + (regression in 1.67). +- Selectable: With ImGuiSelectableFlags_AllowDoubleClick doesn't return true on the mouse button release + following the double-click. Only first mouse release + second mouse down (double-click) returns true. + Likewise for internal ButtonBehavior() with both _PressedOnClickRelease | _PressedOnDoubleClick. (#2503) +- GetMouseDragDelta(): also returns the delta on the mouse button released frame. (#2419) +- GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero. +- Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood] +- PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485) +- Columns: Fixed boundary of clipping being off by 1 pixel within the left column. (#125) +- Separator: Declare its thickness (1.0f) to the layout, making items around separator more symmetrical. +- Combo, Slider, Scrollbar: Improve rendering in situation when there's only a few pixels available (<3 pixels). +- Nav: Fixed Drag/Slider functions going into text input mode when keyboard CTRL is held while pressing NavActivate. +- Drag and Drop: Fixed drag source with ImGuiDragDropFlags_SourceAllowNullID and null ID from receiving click + regardless of being covered by another window (it didn't honor correct hovering rules). (#2521) +- ImDrawList: Improved algorithm for mitre joints on thick lines, preserving correct thickness up to 90 degrees + angles, also faster to output. (#2518) [@rmitton] +- Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert + to using the ImGui::MemAlloc()/MemFree() calls directly. +- Misc: Made IMGUI_CHECKVERSION() macro also check for matching size of ImDrawIdx. +- Metrics: Added "Show windows rectangles" tool to visualize the different rectangles. +- Demo: Improved trees in columns demo. +- Examples: OpenGL: Added a test GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized + GL function loaders early, and help users understand what they are missing. (#2421) +- Examples: SDL: Added support for SDL_GameController gamepads (enable with ImGuiConfigFlags_NavEnableGamepad). (#2509) [@DJLink] +- Examples: Emscripten: Added Emscripten+SDL+GLES2 example. (#2494, #2492, #2351, #336) [@nicolasnoble, @redblobgames] +- Examples: Metal: Added Glfw+Metal example. (#2527) [@bear24rw] +- Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop. +- Examples: Vulkan: Fixed in-flight buffers issues when using multi-viewports. (#2461, #2348, #2378, #2097) +- Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int). +- Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. +- Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam] +- Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454) +- Examples: DirectX10/11/12, Allegro, Marmalade: Render functions early out when display size is zero (minimized). (#2496) +- Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott] +- Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott] +- Examples: GLUT: Made io.DeltaTime always > 0. (#2430) +- Examples: Visual Studio: Updated default platform toolset+sdk in vcproj files from v100+sdk7 (vs2010) + to v110+sdk8 (vs2012). This is mostly so we can remove reliance on DXSDK_DIR for the DX10/DX11 example, + which if existing and when switching to recent SDK ends up conflicting and creating warnings. + + +----------------------------------------------------------------------- + VERSION 1.69 (Released 2019-03-13) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.69 + +Breaking Changes: + +- Renamed ColorEdit/ColorPicker's ImGuiColorEditFlags_RGB/_HSV/_HEX flags to respectively + ImGuiColorEditFlags_DisplayRGB/_DisplayHSV/_DisplayHex. This is because the addition of + new flag ImGuiColorEditFlags_InputHSV makes the earlier one ambiguous. + Kept redirection enum values (will obsolete). (#2384) [@haldean] +- Renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete). (#2391) + +Other Changes: + +- Added GetBackgroundDrawList() helper to quickly get access to a ImDrawList that will be rendered + behind every other windows. (#2391, #545) +- DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types (ImGuiDataType_S8, etc.) + We are reusing function instances of larger types to reduce code size. (#643, #320, #708, #1011) +- Added InputTextWithHint() to display a description/hint in the text box when no text + has been entered. (#2400) [@Organic-Code, @ocornut] +- Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer. +- Nav: Fixed Ctrl+Tab keeping active InputText() of a previous window active after the switch. (#2380) +- Fixed IsItemDeactivated()/IsItemDeactivatedAfterEdit() from not correctly returning true + when tabbing out of a focusable widget (Input/Slider/Drag) in most situations. (#2215, #1875) +- InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when + style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are + meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367) +- InputInt, InputScalar: +/- buttons now respects the natural type limits instead of + overflowing or underflowing the value. +- InputText: Fixed an edge case crash that would happen if another widget sharing the same ID + is being swapped with an InputText that has yet to be activated. +- InputText: Fixed various display corruption related to swapping the underlying buffer while + a input widget is active (both for writable and read-only paths). Often they would manifest + when manipulating the scrollbar of a multi-line input text. +- ColorEdit, ColorPicker, ColorButton: Added ImGuiColorEditFlags_InputHSV to manipulate color + values encoded as HSV (in order to avoid HSV<>RGB round trips and associated singularities). + (#2383, #2384) [@haldean] +- ColorPicker: Fixed a bug/assertion when displaying a color picker in a collapsed window + while dragging its title bar. (#2389) +- ColorEdit: Fixed tooltip not honoring the ImGuiColorEditFlags_NoAlpha contract of never + reading the 4th float in the array (value was read and discarded). (#2384) [@haldean] +- MenuItem, Selectable: Fixed disabled widget interfering with navigation (fix c2db7f63 in 1.67). +- TabBar: Fixed a crash when using many BeginTabBar() recursively (didn't affect docking). (#2371) +- TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to + hard crashes any more, facilitating integration with scripting languages. (#1651) +- TabBar: Fixed ImGuiTabItemFlags_SetSelected being ignored if the tab is not visible (with + scrolling policy enabled) or if is currently appearing. +- TabBar: Fixed Tab tooltip code making drag and drop tooltip disappear during the frame where + the drag payload activate a tab. +- TabBar: Reworked scrolling policy (when ImGuiTabBarFlags_FittingPolicyScroll is set) to + teleport the view when aiming at a tab far away the visible section, and otherwise accelerate + the scrolling speed to cap the scrolling time to 0.3 seconds. +- Text: Fixed large Text/TextUnformatted calls not feeding their size into layout when starting + below the lower point of the current clipping rectangle. This bug has been there since v1.0! + It was hardly noticeable but would affect the scrolling range, which in turn would affect + some scrolling request functions when called during the appearing frame of a window. +- Plot: Fixed divide-by-zero in PlotLines() when passing a count of 1. (#2387) [@Lectem] +- Log/Capture: Fixed LogXXX functions emitting extraneous leading carriage return. +- Log/Capture: Fixed an issue when empty string on a new line would not emit a carriage return. +- Log/Capture: Fixed LogXXX functions 'auto_open_depth' parameter being treated as an absolute + tree depth instead of a relative one. +- Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". +- ImFont: Added GetGlyphRangesVietnamese() helper. (#2403) +- Misc: Asserting in NewFrame() if style.WindowMinSize is zero or smaller than (1.0f,1.0f). +- Demo: Using GetBackgroundDrawList() and GetForegroundDrawList() in "Custom Rendering" demo. +- Demo: InputText: Demonstrating use of ImGuiInputTextFlags_CallbackResize. (#2006, #1443, #1008). +- Examples: GLFW, SDL: Preserve DisplayFramebufferScale when main viewport is minimized. + (This is particularly useful for the viewport branch because we are not supporting per-viewport + frame-buffer scale. It fixes windows not refreshing when main viewport is minimized.) (#2416) +- Examples: OpenGL: Fix to be able to run on ES 2.0 / WebGL 1.0. [@rmitton, @gabrielcuvillier] +- Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN + even if the OpenGL headers/loader happens to define the value. (#2366, #2186) +- Examples: Allegro: Added support for touch events (emulating mouse). (#2219) [@dos1] +- Examples: DirectX9: Minor changes to match the other DirectX examples more closely. (#2394) + + +----------------------------------------------------------------------- + VERSION 1.68 (Released 2019-02-19) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.68 + +Breaking Changes: + +- Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). +- Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). + If for some reason your time step calculation gives you a zero value, replace it with a arbitrarily small value! + +Other Changes: + +- Added .editorconfig file for text editors to standardize using spaces. (#2038) [@kudaba] +- ImDrawData: Added FramebufferScale field (currently a copy of the value from io.DisplayFramebufferScale). + This is to allow render functions being written without pulling any data from ImGuiIO, allowing incoming + multi-viewport feature to behave on Retina display and with multiple displays. + If you are not using a custom backend, please update your render function code ahead of time, + and use draw_data->FramebufferScale instead of io.DisplayFramebufferScale. (#2306, #1676) +- Added IsItemActivated() as an extension to the IsItemDeactivated/IsItemDeactivatedAfterEdit functions + which are useful to implement variety of undo patterns. (#820, #956, #1875) +- InputText: Fixed a bug where ESCAPE would not restore the initial value in all situations. (#2321) [@relick] +- InputText: Fixed a bug where ESCAPE would be first captured by the Keyboard Navigation code. (#2321, #787) +- InputText: Fixed redo buffer exhaustion handling (rare) which could corrupt the undo character buffer. (#2333) + The way the redo/undo buffers work would have made it generally unnoticeable to the user. +- Fixed range-version of PushID() and GetID() not honoring the ### operator to restart from the seed value. +- Fixed CloseCurrentPopup() on a child-menu of a modal incorrectly closing the modal. (#2308) +- Tabs: Added ImGuiTabBarFlags_TabListPopupButton flag to show a popup button on manual tab bars. (#261, #351) +- Tabs: Removed ImGuiTabBarFlags_NoTabListPopupButton which was available in 1.67 but actually had zero use. +- Tabs: Fixed a minor clipping glitch when changing style's FramePadding from frame to frame. +- Tabs: Fixed border (when enabled) so it is aligned correctly mid-pixel and appears as bright as other borders. +- Style, Selectable: Added ImGuiStyle::SelectableTextAlign and ImGuiStyleVar_SelectableTextAlign. (#2347) [@haldean] +- Menus: Tweaked horizontal overlap between parent and child menu (to help convey relative depth) + from using style.ItemSpacing.x to style.ItemInnerSpacing.x, the later being expected to be smaller. (#1086) +- RadioButton: Fixed label horizontal alignment to precisely match Checkbox(). +- Window: When resizing from an edge, the border is more visible and better follow the rounded corners. +- Window: Fixed initial width of collapsed windows not taking account of contents width (broken in 1.67). (#2336, #176) +- Scrollbar: Fade out and disable interaction when too small, in order to facilitate using the resize grab on very + small window, as well as reducing visual noise/overlap. +- ListBox: Better optimized when clipped / non-visible. +- InputTextMultiline: Better optimized when clipped / non-visible. +- Font: Fixed high-level ImGui::CalcTextSize() used by most widgets from erroneously subtracting 1.0f*scale to + calculated text width. Among noticeable side-effects, it would make sequences of repeated Text/SameLine calls + not align the same as a single call, and create mismatch between high-level size calculation and those performed + with the lower-level ImDrawList api. (#792) [@SlNPacifist] +- Font: Fixed building atlas when specifying duplicate/overlapping ranges within a same font. (#2353, #2233) +- ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle" + with a small number of segments (e.g. an hexagon). (#2287) [@baktery] +- ImGuiTextBuffer: Added append() function (unformatted). +- ImFontAtlas: Added 0x2000-0x206F general punctuation range to default ChineseFull/ChineseSimplifiedCommon ranges. (#2093) +- ImFontAtlas: FreeType: Added support for imgui allocators + custom FreeType only SetAllocatorFunctions. (#2285) [@Vuhdo] +- ImFontAtlas: FreeType: Fixed using imgui_freetype.cpp in unity builds. (#2302) +- Demo: Fixed "Log" demo not initializing properly, leading to the first line not showing before a Clear. (#2318) [@bluescan] +- Demo: Added "Auto-scroll" option in Log/Console demos. (#2300) [@nicolasnoble, @ocornut] +- Examples: Metal, OpenGL2, OpenGL3, Vulkan: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0) + when the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch, + this is effectively fixing support for multi-viewport with Mac Retina Displays on those examples. (#2306) [@rasky, @ocornut] + Also using ImDrawData::FramebufferScale instead of io.DisplayFramebufferScale. +- Examples: Clarified the use the ImDrawData::DisplayPos to offset clipping rectangles. +- Examples: Win32: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created + in a different thread or parent. (#1951, #2087, #2156, #2232) [many people] +- Examples: SDL: Using the SDL_WINDOW_ALLOW_HIGHDPI flag. (#2306, #1676) [@rasky] +- Examples: Win32: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is enabled). +- Examples: Win32: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. (#2264) +- Examples: DirectX9: Explicitly disable fog (D3DRS_FOGENABLE) before drawing in case user state has it set. (#2288, #2230) +- Examples: OpenGL2: Added #define GL_SILENCE_DEPRECATION to cope with newer XCode warnings. +- Examples: OpenGL3: Using GLSL 4.10 shaders for any GLSL version over 410 (e.g. 430, 450). (#2329) [@BrutPitt] + + +----------------------------------------------------------------------- + VERSION 1.67 (Released 2019-01-14) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.67 + +Breaking Changes: + +- Made it illegal to call Begin("") with an empty string. This somehow half-worked before but had various undesirable + side-effect because the window would have ID zero. In particular it is causing problems in viewport/docking branches. +- Renamed io.ConfigResizeWindowsFromEdges to io.ConfigWindowsResizeFromEdges and removed its [Beta] mark. + The addition of new configuration options in the Docking branch is pushing for a little reorganization of those names. +- Renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete). + +Other Changes: + +- Added BETA api for Tab Bar/Tabs widgets: (#261, #351) + - Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API. + - Added ImGuiTabBarFlags flags for BeginTabBar(). + - Added ImGuiTabItemFlags flags for BeginTabItem(). + - Style: Added ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive colors. + - Demo: Added Layout->Tabs demo code. + - Demo: Added "Documents" example app showcasing possible use for tabs. + This feature was merged from the Docking branch in order to allow the use of regular tabs in your code. + (It does not provide the docking/splitting/merging of windows available in the Docking branch) +- Added ImGuiWindowFlags_UnsavedDocument window flag to append '*' to title without altering the ID, as a convenience + to avoid using the ### operator. In the Docking branch this also has an effect on tab closing behavior. +- Window, Focus, Popup: Fixed an issue where closing a popup by clicking another window with the _NoMove flag would refocus + the parent window of the popup instead of the newly clicked window. +- Window: Contents size is preserved while a window collapsed. Fix auto-resizing window losing their size for one frame when uncollapsed. +- Window: Contents size is preserved while a window contents is hidden (unless it is hidden for resizing purpose). +- Window: Resizing windows from edge is now enabled by default (io.ConfigWindowsResizeFromEdges=true). Note that + it only works _if_ the backend sets ImGuiBackendFlags_HasMouseCursors, which the standard backends do. +- Window: Added io.ConfigWindowsMoveFromTitleBarOnly option. This is ignored by window with no title bars (often popups). + This affects clamping window within the visible area: with this option enabled title bars need to be visible. (#899) +- Window: Fixed using SetNextWindowPos() on a child window (which wasn't really documented) position the cursor as expected + in the parent window, so there is no mismatch between the layout in parent and the position of the child window. +- InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257) +- DragFloat: Fixed broken mouse direction change with power!=1.0. (#2174, #2206) [@Joshhua5] +- Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary + keep the focus on the parent window, which could steal it from newly appearing windows. (#787) +- Nav: Fixed animated window titles from being updated when displayed in the CTRL+Tab list. (#787) +- Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function closer + to the user call site (instead of being reported in EndFrame). Past the assert, they don't lead to crashes any more. (#1651) + Missing calls to End(), past the assert, should not lead to crashes or to the fallback Debug window appearing on screen. + Those changes makes it easier to integrate dear imgui with a scripting language allowing, given asserts are redirected + into e.g. an error log and stopping the script execution. +- ImFontAtlas: Stb and FreeType: Atlas width is now properly based on total surface rather than glyph count (unless overridden with TexDesiredWidth). +- ImFontAtlas: Stb and FreeType: Fixed atlas builder so missing glyphs won't influence the atlas texture width. (#2233) +- ImFontAtlas: Stb and FreeType: Fixed atlas builder so duplicate glyphs (when merging fonts) won't be included in the rasterized atlas. +- ImFontAtlas: FreeType: Fixed abnormally high atlas height. +- ImFontAtlas: FreeType: Fixed support for any values of TexGlyphPadding (not just only 1). +- ImDrawList: Optimized some of the functions for performance of debug builds where non-inline function call cost are non-negligible. + (Our test UI scene on VS2015 Debug Win64 with /RTC1 went ~5.9 ms -> ~4.9 ms. In Release same scene stays at ~0.3 ms.) +- IO: Added BackendPlatformUserData, BackendRendererUserData, BackendLanguageUserData void* for storage use by backends. +- IO: Renamed InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead! +- IO: AddInputCharacter() goes into a queue which can receive as many characters as needed during the frame. This is useful + for automation to not have an upper limit on typing speed. Will later transition key/mouse to use the event queue later. +- Style: Tweaked default value of style.DisplayWindowPadding from (20,20) to (19,19) so the default style as a value + which is the same as the title bar height. +- Demo: "Simple Layout" and "Style Editor" are now using tabs. +- Demo: Added a few more things under "Child windows" (changing ImGuiCol_ChildBg, positioning child, using IsItemHovered after a child). +- Examples: DirectX10/11/12: Made imgui_impl_dx10/dx11/dx12.cpp link d3dcompiler.lib from the .cpp file to ease integration. +- Examples: Allegro 5: Properly destroy globals on shutdown to allow for restart. (#2262) [@DomRe] + + +----------------------------------------------------------------------- + VERSION 1.66b (Released 2018-12-01) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.66b + +Other Changes: + +- Fixed a text rendering/clipping bug introduced in 1.66 (on 2018-10-12, commit ede3a3b9) that affect single ImDrawList::AddText() + calls with single strings larger than 10k. Text/TextUnformatted() calls were not affected, but e.g. InputText() was. [@pdoane] +- When the focused window become inactive don't restore focus to a window with the ImGuiWindowFlags_NoInputs flag. (#2213) [@zzzyap] +- Separator: Fixed Separator() outputting an extraneous empty line when captured into clipboard/text/file. +- Demo: Added ShowAboutWindow() call, previously was only accessible from the demo window. +- Demo: ShowAboutWindow() now display various Build/Config Information (compiler, os, etc.) that can easily be copied into bug reports. +- Fixed build issue with osxcross and macOS. (#2218) [@dos1] +- Examples: Setting up 'io.BackendPlatformName'/'io.BackendRendererName' fields to the current backend can be displayed in the About window. +- Examples: SDL: changed the signature of ImGui_ImplSDL2_ProcessEvent() to use a const SDL_Event*. (#2187) + + +----------------------------------------------------------------------- + VERSION 1.66 (Released 2018-11-22) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.66 + +Breaking Changes: + +- Renamed SetScrollHere() to SetScrollHereY(). Kept redirection function (will obsolete). +- Renamed misc/stl/imgui_stl.* to misc/cpp/imgui_stdlib.* in prevision for other C++ helper files. (#2035, #2096) + +Other Changes: + +- Fixed calling SetNextWindowSize()/SetWindowSize() with non-integer values leading to + accidental alteration of window position. We now round the provided size. (#2067) +- Fixed calling DestroyContext() always saving .ini data with the current context instead + of the supplied context pointer. (#2066) +- Nav, Focus: Fixed ImGuiWindowFlags_NoBringToFrontOnFocus windows not being restoring focus + properly after the main menu bar or last focused window is deactivated. +- Nav: Fixed an assert in certain circumstance (mostly when using popups) when mouse positions stop being valid. (#2168) +- Nav: Fixed explicit directional input not re-highlighting current nav item if there is a single item in the window + and highlight has been previously disabled by the mouse. (#787) +- DragFloat: Fixed a situation where dragging with value rounding enabled or with a power curve + erroneously wrapped the value to one of the min/max edge. (#2024, #708, #320, #2075). +- DragFloat: Disabled using power curve when one edge is FLT_MAX (broken in 1.61). (#2024) +- DragFloat: Disabled setting a default drag speed when one edge is FLT_MAX. (#2024) +- SliderAngle: Added optional format argument to alter precision or localize the string. (#2150) [@podsvirov] +- Window: Resizing from edges (with io.ConfigResizeWindowsFromEdges Beta flag) extends the hit region + of root floating windows outside the window, making it easier to resize windows. Resize grips are also + extended accordingly so there are no discontinuity when hovering between borders and corners. (#1495, #822) +- Window: Added ImGuiWindowFlags_NoBackground flag to avoid rendering window background. This is mostly to allow + the creation of new flag combinations, as we could already use SetNextWindowBgAlpha(0.0f). (#1660) [@biojppm, @ocornut] +- Window: Added ImGuiWindowFlags_NoDecoration helper flag which is essentially NoTitleBar+NoResize+NoScrollbar+NoCollapse. +- Window: Added ImGuiWindowFlags_NoMouseInputs which is basically the old ImGuiWindowFlags_NoInputs (essentially + we have renamed ImGuiWindowFlags_NoInputs to ImGuiWindowFlags_NoMouseInputs). Made the new ImGuiWindowFlags_NoInputs + encompass both NoMouseInputs+NoNav, which is consistent with its description. (#1660, #787) +- Window, Inputs: Fixed resizing from edges when io.MousePos is not pixel-rounded by rounding mouse position input. (#2110) +- BeginChild(): Fixed BeginChild(const char*, ...) variation erroneously not applying the ID stack + to the provided string to uniquely identify the child window. This was undoing an intentional change + introduced in 1.50 and broken in 1.60. (#1698, #894, #713). +- TextUnformatted(): Fixed a case where large-text path would read bytes past the text_end marker depending + on the position of new lines in the buffer (it wasn't affecting the output but still not the right thing to do!) +- ListBox(): Fixed frame sizing when items_count==1 unnecessarily showing a scrollbar. (#2173) [@luk1337, @ocornut] +- ListBox(): Tweaked frame sizing so list boxes will look more consistent when FramePadding is far from ItemSpacing. +- RenderText(): Some optimization for very large text buffers, useful for non-optimized builds. +- BeginMenu(): Fixed menu popup horizontal offset being off the item in the menu bar when WindowPadding=0.0f. +- ArrowButton(): Fixed arrow shape being horizontally misaligned by (FramePadding.y-FramePadding.x) if they are different. +- Demo: Split the contents of ShowDemoWindow() into smaller functions as it appears to speed up link time with VS. (#2152) +- Drag and Drop: Added GetDragDropPayload() to peek directly into the payload (if any) from anywhere. (#143) +- ImGuiTextBuffer: Avoid heap allocation when empty. +- ImDrawList: Fixed AddConvexPolyFilled() undefined behavior when passing points_count smaller than 3, + in particular, points_count==0 could lead to a memory stomp if the draw list was previously empty. +- Examples: DirectX10, DirectX11: Removed seemingly unnecessary calls to invalidate and recreate device objects + in the WM_SIZE handler. (#2088) [@ice1000] +- Examples: GLFW: User previously installed GLFW callbacks are now saved and chain-called by the default callbacks. (#1759) +- Examples: OpenGL3: Added support for GL 4.5's glClipControl(GL_UPPER_LEFT). (#2186) +- Examples: OpenGL3+GLFW: Fixed error condition when using the GLAD loader. (#2157) [@blackball] +- Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) [@doug-moen] +- Examples: SDL2+Vulkan: Fixed application shutdown which could deadlock on Linux + Xorg. (#2181) [@eRabbit0] + + +----------------------------------------------------------------------- + VERSION 1.65 (Released 2018-09-06) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.65 + +Breaking Changes: + +- Renamed stb_truetype.h to imstb_truetype.h, stb_textedit.h to imstb_textedit.h, and + stb_rect_pack.h to imstb_rectpack.h. If you were conveniently using the imgui copy of those + STB headers in your project, you will have to update your include paths. (#1718, #2036) + The reason for this change is to avoid conflicts for projects that may also be importing + their own copy of the STB libraries. Note that imgui's copy of stb_textedit.h is modified. +- Renamed io.ConfigCursorBlink to io.ConfigInputTextCursorBlink. (#1427) + +Other Changes: + +- This is a minor release following the 1.64 refactor, with a little more shuffling of code. +- Clarified and improved the source code sectioning in all files (easier to search or browse sections). +- Nav: Removed the [Beta] tag from various descriptions of the gamepad/keyboard navigation system. + Although it is not perfect and will keep being improved, it is fairly functional and used by many. (#787) +- Fixed a build issue with non-Cygwin GCC under Windows. +- Demo: Added a "Configuration" block to make io.ConfigFlags/io.BackendFlags more prominent. +- Examples: OpenGL3+SDL2: Fixed error condition when using the GLAD loader. (#2059, #2002) [@jiri] + + +----------------------------------------------------------------------- + VERSION 1.64 (Released 2018-08-31) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.64 + +Changes: + +- Moved README, CHANGELOG and TODO files to the docs/ folder. + If you are updating dear imgui by copying files, take the chance to delete the old files. +- Added imgui_widgets.cpp file, extracted and moved widgets code out of imgui.cpp into imgui_widgets.cpp. + Re-ordered some of the code remaining in imgui.cpp. + NONE OF THE FUNCTIONS HAVE CHANGED. THE CODE IS SEMANTICALLY 100% IDENTICAL, BUT _EVERY_ FUNCTIONS HAS BEEN MOVED. + Because of this, any local modifications to imgui.cpp will likely conflict when you update. + If you have any modifications to imgui.cpp, it is suggested that you first update to 1.63, then + isolate your patches. You can peak at imgui_widgets.cpp from 1.64 to get a sense of what is included in it, + then separate your changes into several patches that can more easily be applied to 1.64 on a per-file basis. + What I found worked nicely for me, was to open the diff of the old patches in an interactive merge/diff tool, + search for the corresponding function in the new code and apply the chunks manually. +- As a reminder, if you have any change to imgui.cpp it is a good habit to discuss them on the github, + so a solution applicable on the Master branch can be found. If your company has changes that you cannot + disclose you may also contact me privately. + + +----------------------------------------------------------------------- + VERSION 1.63 (Released 2018-08-29) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.63 + +Breaking Changes: + +- Style: Renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. + Kept redirection enum (will obsolete). +- Changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecision over time. +- Removed per-window ImGuiWindowFlags_ResizeFromAnySide Beta flag in favor `io.ConfigResizeWindowsFromEdges=true` to + enable the feature globally. (#1495) + The feature is not currently enabled by default because it is not satisfying enough, but will eventually be. +- InputText: Renamed ImGuiTextEditCallback to ImGuiInputTextCallback, ImGuiTextEditCallbackData to ImGuiInputTextCallbackData + for consistency. Kept redirection types (will obsolete). +- InputText: Removed ImGuiTextEditCallbackData::ReadOnly because it is a duplication of (::Flags & ImGuiInputTextFlags_ReadOnly). +- Renamed IsItemDeactivatedAfterChange() to IsItemDeactivatedAfterEdit() for consistency with new IsItemEdited() API. + Kept redirection function (will obsolete soonish as IsItemDeactivatedAfterChange() is very recent). +- Renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to + io.ConfigMacOSXBehaviors for consistency. (#1427, #473) +- Removed obsolete redirection functions: CollapsingHeader() variation with 2 bools - marked obsolete in v1.49, May 2016. + +Other Changes: + +- ArrowButton: Fixed to honor PushButtonRepeat() setting (and internals' ImGuiItemFlags_ButtonRepeat). +- ArrowButton: Setup current line text baseline so that ArrowButton() + SameLine() + Text() are aligned properly. +- Nav: Added a CTRL+TAB window list and changed the highlight system accordingly. The change is motivated by upcoming + Docking features. (#787) +- Nav: Made CTRL+TAB skip menus + skip the current navigation window if is has the ImGuiWindow_NoNavFocus set. (#787) + While it was previously possible, you won't be able to CTRL-TAB out and immediately back in a window with the + ImGuiWindow_NoNavFocus flag. +- Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909) +- Window: Added global io.ConfigResizeWindowsFromEdges option to enable resizing windows from their edges and from + the lower-left corner. (#1495) +- Window: Collapse button shows hovering highlight + clicking and dragging on it allows to drag the window as well. +- Added IsItemEdited() to query if the last item modified its value (or was pressed). This is equivalent to the bool + returned by most widgets. + It is useful in some situation e.g. using InputText() with ImGuiInputTextFlags_EnterReturnsTrue. (#2034) +- InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008). +- InputText: Fixed not tracking the cursor horizontally when modifying the text buffer through a callback. +- InputText: Fixed minor off-by-one issue when submitting a buffer size smaller than the initial zero-terminated buffer contents. +- InputText: Fixed a few pathological crash cases on single-line InputText widget with multiple millions characters worth of contents. + Because the current text drawing function reserve for a worst-case amount of vertices and how we handle horizontal clipping, + we currently just avoid displaying those single-line widgets when they are over a threshold of 2 millions characters, + until a better solution is found. +- Drag and Drop: Fixed an incorrect assert when dropping a source that is submitted after the target (bug introduced with 1.62 changes + related to the addition of IsItemDeactivated()). (#1875, #143) +- Drag and Drop: Fixed ImGuiDragDropFlags_SourceNoDisableHover to affect hovering state prior to calling IsItemHovered() + fixed description. (#143) +- Drag and Drop: Calling BeginTooltip() between a BeginDragSource()/EndDragSource() or BeginDropTarget()/EndDropTarget() uses adjusted tooltip + settings matching the one created when calling BeginDragSource() without the ImGuiDragDropFlags_SourceNoPreviewTooltip flag. (#143) +- Drag and Drop: Payload stays available and under the mouse if the source stops being submitted, however the tooltip is replaced by "...". (#1725) +- Drag and Drop: Added ImGuiDragDropFlags_SourceAutoExpirePayload flag to force payload to expire if the source stops being submitted. (#1725, #143). +- IsItemHovered(): Added ImGuiHoveredFlags_AllowWhenDisabled flag to query hovered status on disabled items. (#1940, #211) +- Selectable: Added ImGuiSelectableFlags_Disabled flag in the public API. (#211) +- ColorEdit4: Fixed a bug when text input or drag and drop leading to unsaturated HSV values would erroneously alter the resulting color. (#2050) +- Misc: Added optional misc/stl/imgui_stl.h wrapper to use with STL types (e.g. InputText with std::string). (#2006, #1443, #1008) + [*EDIT* renamed to misc/std/imgui_stdlib.h in 1.66] +- Misc: Added IMGUI_VERSION_NUM for easy compile-time testing. (#2025) +- Misc: Added ImGuiMouseCursor_Hand cursor enum + corresponding software cursor. (#1913, 1914) [@aiekick, @ocornut] +- Misc: Tweaked software mouse cursor offset to match the offset of the corresponding Windows 10 cursors. +- Made assertion more clear when trying to call Begin() outside of the NewFrame()..EndFrame() scope. (#1987) +- Fixed assertion when transitioning from an active ID to another within a group, affecting ColorPicker (broken in 1.62). (#2023, #820, #956, #1875). +- Fixed PushID() from keeping alive the new ID Stack top value (if a previously active widget shared the ID it would be erroneously kept alive). +- Fixed horizontal mouse wheel not forwarding the request to the parent window if ImGuiWindowFlags_NoScrollWithMouse is set. (#1463, #1380, #1502) +- Fixed a include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276) +- ImDrawList: Improved handling for worst-case vertices reservation policy when large amount of text (e.g. 1+ million character strings) + are being submitted in a single call. It would typically have crashed InputTextMultiline(). (#200) +- OS/Windows: Fixed missing ImmReleaseContext() call in the default Win32 IME handler. (#1932) [@vby] +- Metrics: Changed io.MetricsActiveWindows to reflect the number of active windows (!= from visible windows), which is useful + for lazy/idle render mechanisms as new windows are typically not visible for one frame. +- Metrics: Added io.MetricsRenderWindow to reflect the number of visible windows. +- Metrics: Added io.MetricsActiveAllocations, moving away from the cross-context global counters than we previously used. (#1565, #1599, #586) +- Demo: Added basic Drag and Drop demo. (#143) +- Demo: Modified the Console example to use InsertChars() in the input text callback instead of poking directly into the buffer. + Although this won't make a difference in the example itself, using InsertChars() will honor the resizing callback properly. (#2006, #1443, #1008). +- Demo: Clarified the use of IsItemHovered()/IsItemActive() right after being in the "Active, Focused, Hovered & Focused Tests" section. +- Examples: Tweaked the main.cpp of each example. +- Examples: Metal: Added Metal rendering backend. (#1929, #1873) [@warrenm] +- Examples: OSX: Added early raw OSX platform backend. (#1873) [@pagghiu, @itamago, @ocornut] +- Examples: Added mac OSX & iOS + Metal example in example_apple_metal/. (#1929, #1873) [@warrenm] +- Examples: Added mac OSX + OpenGL2 example in example_apple_opengl2/. (#1873) +- Examples: OpenGL3: Added shaders more versions of GLSL. (#1938, #1941, #1900, #1513, #1466, etc.) +- Examples: OpenGL3: Tweaked the imgui_impl_opengl3.cpp to work as-is with Emscripten + WebGL 2.0. (#1941). [@o-micron] +- Examples: OpenGL3: Made the example app default to GL 3.0 + GLSL 130 (instead of GL 3.2 + GLSL 150) unless on Mac. +- Examples: OpenGL3: Added error output when shaders fail to compile/link. +- Examples: OpenGL3: Added support for glew and glad OpenGL loaders out of the box. (#2001, #2002) [@jdumas] +- Examples: OpenGL2: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications. (#1996) +- Examples: DirectX10, DirectX11: Fixed unreleased resources in Init and Shutdown functions. (#1944) +- Examples: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. (#1989) [@matt77hias] +- Examples: Vulkan: Fixed handling of VkSurfaceCapabilitiesKHR::maxImageCount = 0 case. Tweaked present mode selections. +- Examples: Win32, Glfw, SDL: Added support for the ImGuiMouseCursor_Hand cursor. + + +----------------------------------------------------------------------- + VERSION 1.62 (Released 2018-06-22) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.62 + +Breaking Changes: + +- TreeNodeEx(): The helper ImGuiTreeNodeFlags_CollapsingHeader flag now include ImGuiTreeNodeFlags_NoTreePushOnOpen. + The flag was already set by CollapsingHeader(). + The only difference is if you were using TreeNodeEx() manually with ImGuiTreeNodeFlags_CollapsingHeader and without + ImGuiTreeNodeFlags_NoTreePushOnOpen. In this case you can remove the ImGuiTreeNodeFlags_NoTreePushOnOpen flag from + your call (ImGuiTreeNodeFlags_CollapsingHeader & ~ImGuiTreeNodeFlags_NoTreePushOnOpen). (#1864) + This also apply if you were using internal's TreeNodeBehavior() with the ImGuiTreeNodeFlags_CollapsingHeader flag directly. +- ImFontAtlas: Renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish new smaller variants and + discourage using the full set. (#1859) + +Other Changes: + +- Examples backends have been refactored to separate the platform code (e.g. Win32, Glfw, SDL2) from the renderer code (e.g. DirectX11, OpenGL3, Vulkan). + The "Platform" backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, etc. + The "Renderer" backends are in charge of: creating the main font texture, rendering imgui draw data. + before: imgui_impl_dx11.cpp --> after: imgui_impl_win32.cpp + imgui_impl_dx11.cpp + before: imgui_impl_dx12.cpp --> after: imgui_impl_win32.cpp + imgui_impl_dx12.cpp + before: imgui_impl_glfw_gl3.cpp --> after: imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp + before: imgui_impl_glfw_vulkan.cpp --> after: imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp + before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl2.cpp + before: imgui_impl_sdl_gl3.cpp --> after: imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp etc. + - The idea is what we can now easily combine and maintain backends and reduce code redundancy. Individual files are + smaller and more reusable. Integration of imgui into a new/custom engine may also be easier as there is less overlap + between "windowing / inputs" and "rendering" code, so you may study or grab one half of the code and not the other. + - This change was motivated by the fact that adding support for the upcoming multi-viewport feature requires more work + from the Platform and Renderer backends, and the amount of redundancy across files was becoming too difficult to + maintain. If you use default backends, you'll benefit from an easy update path to support multi-viewports later + (for future ImGui 1.7x). + - This is not strictly a breaking change if you keep your old backends, but when you'll want to fully update your backends, + expect to have to reshuffle a few things. + - Each example still has its own main.cpp which you may refer you to understand how to initialize and glue everything together. + - Some frameworks (such as the Allegro, Marmalade) handle both the "platform" and "rendering" part, and your custom engine may as well. + - Read examples/README.txt for details. +- Added IsItemDeactivated() to query if the last item was active previously and isn't anymore. Useful for Undo/Redo patterns. (#820, #956, #1875) +- Added IsItemDeactivatedAfterChange() [*EDIT* renamed to IsItemDeactivatedAfterEdit() in 1.63] if the last item was active previously, + is not anymore, and during its active state modified a value. Note that you may still get false positive (e.g. drag value and while + holding return on the same value). (#820, #956, #1875) +- Nav: Added support for PageUp/PageDown (explorer-style: first aim at bottom/top most item, when scroll a page worth of contents). (#787) +- Nav: To keep the navigated item in view we also attempt to scroll the parent window as well as the current window. (#787) +- ColorEdit3, ColorEdit4, ColorButton: Added ImGuiColorEditFlags_NoDragDrop flag to disable ColorEditX as drag target and ColorButton as drag source. (#1826) +- BeginDragDropSource(): Offset tooltip position so it is off the mouse cursor, but also closer to it than regular tooltips, + and not clamped by viewport. (#1739) +- BeginDragDropTarget(): Added ImGuiDragDropFlags_AcceptNoPreviewTooltip flag to request hiding the drag source tooltip + from the target site. (#143) +- BeginCombo(), BeginMainMenuBar(), BeginChildFrame(): Temporary style modification are restored at the end of BeginXXX + instead of EndXXX, to not affect tooltips and child windows. +- Popup: Improved handling of (erroneously) repeating calls to OpenPopup() to not close the popup's child popups. (#1497, #1533, #1865). +- InputTextMultiline(): Fixed double navigation highlight when scrollbar is active. (#787) +- InputText(): Fixed Undo corruption after pasting large amount of text (Redo will still fail when undo buffers are exhausted, + but text won't be corrupted). +- SliderFloat(): When using keyboard/gamepad and a zero precision format string (e.g. "%.0f"), always step in integer units. (#1866) +- ImFontConfig: Added GlyphMinAdvanceX/GlyphMaxAdvanceX settings useful to make a font appears monospaced, particularly useful + for icon fonts. (#1869) +- ImFontAtlas: Added GetGlyphRangesChineseSimplifiedCommon() helper that returns a list of ~2500 most common Simplified Chinese + characters. (#1859) [@JX-Master, @ocornut] +- Examples: OSX: Added imgui_impl_osx.mm backend to be used along with e.g. imgui_impl_opengl2.cpp. (#281, #1870) [@pagghiu, @itamago, @ocornut] +- Examples: GLFW: Made it possible to Shutdown/Init the backend again (by resetting the time storage properly). (#1827) [@ice1000] +- Examples: Win32: Fixed handling of mouse wheel messages to support sub-unit scrolling messages (typically sent by track-pads). (#1874) [@zx64] +- Examples: SDL+Vulkan: Added SDL+Vulkan example. +- Examples: Allegro5: Added support for ImGuiConfigFlags_NoMouseCursorChange flag. Added clipboard support. +- Examples: Allegro5: Unindexing buffers ourselves as Allegro indexed drawing primitives are buggy in the DirectX9 backend + (will be fixed in Allegro 5.2.5+). +- Examples: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from ImGui_ImplDX12_NewFrame() to ImGui_ImplDX12_RenderDrawData() which makes a lots more sense. (#301) +- Examples: Vulkan: Reordered parameters ImGui_ImplVulkan_RenderDrawData() to be consistent with other backends, + a good occasion since we refactored the code. +- Examples: FreeGLUT: Added FreeGLUT backends. Added FreeGLUT+OpenGL2 example. (#801) +- Examples: The functions in imgui_impl_xxx.cpp are prefixed with IMGUI_IMPL_API (which defaults to IMGUI_API) to facilitate + some uses. (#1888) +- Examples: Fixed backends to use ImGuiMouseCursor_COUNT instead of old name ImGuiMouseCursor_Count_ so they can compile + with IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#1887) +- Misc: Updated stb_textedit from 1.09 + patches to 1.12 + minor patches. +- Internals: PushItemFlag() flags are inherited by BeginChild(). + + +----------------------------------------------------------------------- + VERSION 1.61 (Released 2018-05-14) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.61 + +Breaking Changes: + +- DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally + any more. If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format. + To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d, + giving time to users to upgrade their code. + If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your + codebase for e.g. "DragInt.*%f" to you find them. +- InputFloat(): Obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more + flexible "const char* format", consistent with other functions. Kept redirection functions (will obsolete). +- Misc: IM_DELETE() helper function added in 1.60 doesn't set the input pointer to NULL, more consistent with standard + expectation and allows passing r-values. + +Other Changes: + +- Added DragScalar, DragScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) +- Added InputScalar, InputScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) +- Added SliderScalar, SliderScalarN: supports signed/unsigned, 32/64 bits, float/double data types. (#643, #320, #708, #1011) +- Window: Fixed pop-ups/tooltips/menus not honoring style.DisplaySafeAreaPadding as well as it should have (part of menus + displayed outside the safe area, etc.). +- Window: Fixed windows using the ImGuiWindowFlags_NoSavedSettings flag from not using the same default position as other windows. (#1760) +- Window: Relaxed the internal stack size checker to allow Push/Begin/Pop/.../End patterns to be used with PushStyleColor, PushStyleVar, PushFont without causing a false positive assert. (#1767) +- Window: Fixed the default proportional item width lagging by one frame on resize. +- Columns: Fixed a bug introduced in 1.51 where columns would affect the contents size of their container, often creating + feedback loops when ImGuiWindowFlags_AlwaysAutoResize was used. (#1760) +- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741) +- Settings: Added LoadIniSettingsFromDisk(), LoadIniSettingsFromMemory(), SaveIniSettingsToDisk(), SaveIniSettingsToMemory() + to manually load/save .ini settings. (#923, #993) +- Settings: Added io.WantSaveIniSettings flag, which is set to notify the application that e.g. SaveIniSettingsToMemory() + should be called. (#923, #993) +- Scrolling: Fixed a case where using SetScrollHere(1.0f) at the bottom of a window on the same frame the window height + has been growing would have the scroll clamped using the previous height. (#1804) +- MenuBar: Made BeginMainMenuBar() honor style.DisplaySafeAreaPadding so the text can be made visible on TV settings that + don't display all pixels. (#1439) [@dougbinks] +- InputText: On Mac OS X, filter out characters when the CMD modifier is held. (#1747) [@sivu] +- InputText: On Mac OS X, support CMD+SHIFT+Z for Redo. CMD+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise] +- InputText: Fixed returning true when edition is cancelled with ESC and the current buffer matches the initial value. +- InputFloat,InputFloat2,InputFloat3,InputFloat4: Added variations taking a more flexible and consistent optional + "const char* format" parameter instead of "int decimal_precision". This allow using custom formats to display values + in scientific notation, and is generally more consistent with other API. + Obsoleted functions using the optional "int decimal_precision" parameter. (#648, #712) +- DragFloat, DragInt: Cancel mouse tweak when current value is initially past the min/max boundaries and mouse is pushing + in the same direction (keyboard/gamepad version already did this). +- DragFloat, DragInt: Honor natural type limits (e.g. INT_MAX, FLT_MAX) instead of wrapping around. (#708, #320) +- DragFloat, SliderFloat: Fixes to allow input of scientific notation numbers when using CTRL+Click to input the value. (~#648, #1011) +- DragFloat, SliderFloat: Rounding-on-write uses the provided format string instead of parsing the precision from the string, + which allows for finer uses of %e %g etc. (#648, #642) +- DragFloat: Improved computation when using the power curve. Improved lost of input precision with very small steps. + Added an assert than power-curve requires a min/max range. (~#642) +- DragFloat: The 'power' parameter is only honored if the min/max parameter are also setup. +- DragInt, SliderInt: Fixed handling of large integers (we previously passed data around internally as float, which reduced + the range of valid integers). +- ColorEdit: Fixed not being able to pass the ImGuiColorEditFlags_NoAlpha or ImGuiColorEditFlags_HDR flags to SetColorEditOptions(). +- Nav: Fixed hovering a Selectable() with the mouse so that it update the navigation cursor (as it happened in the pre-1.60 navigation branch). (#787) +- Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439) +- Fonts: When building font atlas, glyphs that are missing in the fonts are not using the glyph slot to render the default glyph. Saves space and allow merging fonts with + overlapping font ranges such as FontAwesome5 which split out the Brands separately from the Solid fonts. (#1703, #1671) +- Misc: Added IMGUI_CHECKVERSION() macro to compare version string and data structure sizes in order to catch issues with mismatching compilation unit settings. (#1695, #1769) +- Misc: Added IMGUI_DISABLE_MATH_FUNCTIONS in imconfig.h to make it easier to redefine wrappers for std/crt math functions. +- Misc: Fix to allow compiling in unity builds where stb_rectpack/stb_truetype may be already included in the same compilation unit. +- Demo: Simple Overlay: Added a context menu item to enable freely moving the window. +- Demo: Added demo for DragScalar(), InputScalar(), SliderScalar(). (#643) +- Examples: Calling IMGUI_CHECKVERSION() in the main.cpp of every example application. +- Examples: Allegro 5: Added support for 32-bit indices setup via defining ImDrawIdx, to avoid an unnecessary conversion (Allegro 5 doesn't support 16-bit indices). +- Examples: Allegro 5: Renamed backend from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp. +- Examples: DirectX 9: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud. (#1790, #1687) [@sr-tream] +- Examples: SDL: Fixed clipboard paste memory leak in the SDL backend code. (#1803) [@eliasdaler] +- Various minor fixes, tweaks, refactoring, comments. + + +----------------------------------------------------------------------- + VERSION 1.60 (Released 2018-04-07) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.60 + +The gamepad/keyboard navigation branch (which has been in the work since July 2016) has been merged. +Gamepad/keyboard navigation is still marked as Beta and has to be enabled explicitly. +Various internal refactoring have also been done, as part of the navigation work and as part of the upcoming viewport/docking work. + +Breaking Changes: + +- Obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). + e.g. with example backends, call ImDrawData* draw_data = ImGui::GetDrawData(); ImGui_ImplXXXX_RenderDrawData(draw_data). +- Reorganized context handling to be more explicit: (#1599) + - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. + - removed Shutdown() function, as DestroyContext() serve this purpose. If you are using an old backend from the examples/ folder, remove the line that calls Shutdown(). + - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance. + - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. + - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. +- Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. +- Fonts: Moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. +- Fonts: Changed ImFont::DisplayOffset.y to defaults to 0 instead of +1. Fixed vertical rounding of Ascent/Descent to match TrueType renderer. + If you were adding or subtracting (not assigning) to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. (#1619) +- BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. +- Obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). +- Obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). +- Renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, not used by core, and honored by some backend ahead of merging the Nav branch). +- Removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered style colors as the closing cross uses regular button colors now. +- Renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. +- Removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it should be easy to replicate on your side (you can find the code in 1.53). +- [EDITED] Window: BeginChild() with an explicit name doesn't include the hash within the internal window name. (#1698) + This change was erroneously introduced, undoing the change done for #894, #713, and not documented properly in the original + 1.60 release Changelog. It was fixed on 2018-09-28 (1.66) and I wrote this paragraph the same day. + +Other Changes: + +- Doc: Added a Changelog file in the repository to ease comparing versions (it goes back to dear imgui 1.48), until now it was only on GitHub. +- Navigation: merged in the gamepad/keyboard navigation (about a million changes!). (#787, #323) + The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. +- To use Gamepad Navigation: + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. + - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + fill the io.NavInputs[] fields before calling NewFrame(). Read imgui.cpp for more details. + - See https://github.com/ocornut/imgui/issues/1599 for recommended gamepad mapping or download PNG/PSD at http://goo.gl/9LgVZW + - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. Read imgui.cpp for more details. +- To use Keyboard Navigation: + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays. + - Basic controls: arrows to navigate, Alt to enter menus, Space to activate item, Enter to edit text, Escape to cancel/close, Ctrl-Tab to focus windows, etc. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. + For more advanced uses, you may want to read from io.NavActive or io.NavVisible. Read imgui.cpp for more details. +- Navigation: SetItemDefaultFocus() sets the navigation position in addition to scrolling. (#787) +- Navigation: Added IsItemFocused(), added IsAnyItemFocused(). (#787) +- Navigation: Added window flags: ImGuiWindowFlags_NoNav (== ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus). +- Navigation: Style: Added ImGuiCol_NavHighlight, ImGuiCol_NavWindowingHighlight colors. (#787) +- Navigation: TreeNode: Added ImGuiTreeNodeFlags_NavLeftJumpsBackHere flag to allow Nav Left direction to jump back to parent tree node from any of its child. (#1079) +- Navigation: IO: Added io.ConfigFlags (input), io.NavActive (output), io.NavVisible (output). (#787) +- Context: Removed the default global context and font atlas instances, which caused various problems to users of multiple contexts and DLL users. (#1565, #1599) + YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. Existing apps will assert/crash without it. +- Context: Added SetAllocatorFunctions() to rewire memory allocators (as a replacement to previous parameters to CreateContext()). Allocators are shared by all contexts and imgui helpers. (#1565, #586, #992, #1007, #1558) +- Context: You may pass a ImFontAtlas to CreateContext() to specify a font atlas to share. Shared font atlas are not owned by the context and not destroyed along with it. (#1599) +- Context: Added IMGUI_DISABLE_DEFAULT_ALLOCATORS to disable linking with malloc/free. (#1565, #586, #992, #1007, #1558) +- IO: Added io.ConfigFlags for user application to store settings for imgui and for the backend: + - ImGuiConfigFlags_NavEnableKeyboard: Enable keyboard navigation. + - ImGuiConfigFlags_NavEnableGamepad: Enable gamepad navigation (provided ImGuiBackendFlags_HasGamepad is also set by backend). + - ImGuiConfigFlags_NavEnableSetMousePos: Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. + - ImGuiConfigFlags_NoMouseCursorChange: Instruct backend to not alter mouse cursor shape and visibility (by default the example backend use mouse cursor API of the platform when available) + - ImGuiConfigFlags_NoMouse: Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information passed by the backend. + - ImGuiConfigFlags_IsSRGB, ImGuiConfigFlags_IsTouchScreen: Flags for general application use. +- IO: Added io.BackendFlags for backend to store its capabilities (currently: _HasGamepad, _HasMouseCursors, _HasSetMousePos). This will be used more in the next version. +- IO: Added ImGuiKey_Insert, ImGuiKey_Space keys. Setup in all example backends. (#1541) +- IO: Added Horizontal Mouse Wheel support for horizontal scrolling. (#1463) [@tseeker] +- IO: Added IsAnyMouseDown() helper which is helpful for backends to handle mouse capturing. +- Window: Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else when dragging afterwards. (#1381, #1337) +- Window: IsWindowHovered(): Added ImGuiHoveredFlags_AnyWindow, ImGuiFocusedFlags_AnyWindow flags (See Breaking Changes). Added to demo. (#1382) +- Window: Added SetNextWindowBgAlpha() helper. Particularly helpful since the legacy 5-parameters version of Begin() has been marked as obsolete in 1.53. (#1567) +- Window: Fixed SetNextWindowContentSize() with 0.0f on Y axis (or SetNextWindowContentWidth()) overwriting the contents size. Got broken on Dec 10 (1.53). (#1363) +- ArrowButton: Added ArrowButton() given a cardinal direction (e.g. ImGuiDir_Left). +- InputText: Added alternative clipboard shortcuts: Shift+Delete (cut), CTRL+Insert (copy), Shift+Insert (paste). (#1541) +- InputText: Fixed losing Cursor X position when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) +- InputText: Added ImGuiInputTextFlags_CharsScientific flag to also allow 'e'/'E' for input of values using scientific notation. Automatically used by InputFloat. +- Style: Default style is now StyleColorsDark(), instead of the old StyleColorsClassic(). (#707) +- Style: Enable window border by default. (#707) +- Style: Exposed ImGuiStyleVar_WindowTitleAlign, ImGuiStyleVar_ScrollbarSize, ImGuiStyleVar_ScrollbarRounding, ImGuiStyleVar_GrabRounding + added an assert to reduce accidental breakage. (#1181) +- Style: Added style.MouseCursorScale help when using the software mouse cursor facility. (#939). +- Style: Close button nows display a cross before hovering. Fixed cross positioning being a little off. Uses button colors for highlight when hovering. (#707) +- Popup: OpenPopup() Always reopen existing pop-ups. (Removed imgui_internal.h's OpenPopupEx() which was used for this.) (#1497, #1533). +- Popup: BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse press. (~#439) +- Popup: Better handling of user mistakenly calling OpenPopup() every frame (with reopen_existing option). The error will now be more visible and easier to understand. (#1497) +- Popup: BeginPopup(): Exposed extra_flags parameter that are passed through to Begin(). (#1533) +- Popup: BeginPopupModal: fixed the conditional test for SetNextWindowPos() which was polling the wrong window, which in practice made the test succeed all the time. +- Tooltip: BeginTooltip() sets ImGuiWindowFlags_NoInputs flag. +- Scrollbar: Fixed ScrollbarY enable test after ScrollbarX has been enabled being a little off (small regression from Nov 2017). (#1574) +- Scrollbar: Fixed ScrollbarX enable test subtracting WindowPadding.x (this has been there since the addition of horizontal scroll bar!). +- Columns: Clear offsets data when columns count changed. (#1525) +- Columns: Fixed a memory leak of ImGuiColumnsSet's Columns vector. (#1529) [@unprompted] +- Columns: Fixed resizing a window very small breaking some columns positioning (broken in 1.53). +- Columns: The available column extent takes consideration of the right-most clipped pixel, so the right-most column may look a little wider but will contain the same amount of visible contents. +- MenuBar: Fixed menu bar pushing a clipping rect outside of its allocated bound (usually unnoticeable). +- TreeNode: nodes with the ImGuiTreeNodeFlags_Leaf flag correctly disable highlight when DragDrop is active. (#143, #581) +- Drag and Drop: Increased payload type string to 32 characters instead of 8. (#143) +- Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143) +- DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) +- InputFloat: Allow inputing value using scientific notation e.g. "1e+10". +- InputDouble: Added InputDouble() function. We use a format string instead of a decimal_precision parameter to also for "%e" and variants. (#1011) +- Slider, Combo: Use ImGuiCol_FrameBgHovered color when hovered. (#1456) [@stfx] +- Combo: BeginCombo(): Added ImGuiComboFlags_NoArrowButton to disable the arrow button and only display the wide value preview box. +- Combo: BeginCombo(): Added ImGuiComboFlags_NoPreview to disable the preview and only display a square arrow button. +- Combo: Arrow button isn't displayed over frame background so its blended color matches other buttons. Left side of the button isn't rounded. +- PlotLines: plot a flat line if scale_min==scale_max. (#1621) +- Fonts: Changed DisplayOffset.y to defaults to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. + If you were adding or subtracting (not assigning) to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. (#1619) +- Fonts: Updated stb_truetype from 1.14 to stb_truetype 1.19. (w/ include fix from some platforms #1622) +- Fonts: Added optional FreeType rasterizer in misc/freetype. Moved from imgui_club repo. (#618) [@Vuhdo, @mikesart, @ocornut] +- Fonts: Moved extra_fonts/ to misc/fonts/. +- ImFontAtlas: Fixed cfg.MergeMode not reusing existing glyphs if available (always overwrote). +- ImFontAtlas: Handle stb_truetype stbtt_InitFont() and stbtt_PackBegin() possible failures more gracefully, GetTexDataAsRGBA32() won't crash during conversion. (#1527) +- ImFontAtlas: Moved mouse cursor data out of ImGuiContext, fix drawing them with multiple contexts. Also remove the last remaining undesirable dependency on ImGui in imgui_draw.cpp. (#939) +- ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight flag to disable padding font height to nearest power of two. (#1613) +- ImFontAtlas: Added ImFontAtlasFlags_NoMouseCursors flag to disable baking software mouse cursors, mostly to save texture memory on very low end hardware. (#1613) +- ImDrawList: Fixed AddRect() with anti-aliasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646) +- ImDrawList: Added CloneOutput() helper to facilitate the cloning of ImDrawData or ImDrawList for multi-threaded rendering. +- Misc: Functions passed to libc qsort are explicitly marked cdecl to support compiling with vectorcall as the default calling convention. (#1230, #1611) [@RandyGaul] +- Misc: ImVec2: added [] operator. This is becoming desirable for some code working of either axes independently. Better adding it sooner than later. +- Misc: NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555) +- Misc: Added IM_OFFSETOF() helper in imgui.h (previously was in imgui_internal.h) +- Misc: Added IM_NEW(), IM_DELETE() helpers in imgui.h (previously were in imgui_internal.h) +- Misc: Added obsolete redirection function GetItemsLineHeightWithSpacing() (which redirects to GetFrameHeightWithSpacing()), as intended and stated in docs of 1.53. +- Misc: Added misc/natvis/imgui.natvis for visual studio debugger users to easily visualize imgui internal types. Added to examples projects. +- Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41) +- Misc: Added IMGUI_STB_TRUETYPE_FILENAME and IMGUI_STB_RECT_PACK_FILENAME compile time directives to use another version of the stb_ files. +- Misc: Updated stb_rect_pack from 0.10 to 0.11 (minor changes). + (Those flags are not used by ImGui itself, they only exists to make it easy for the engine/backend to pass information to the application in a standard manner.) +- Metrics: Added display of Columns state. +- Demo: Improved Selectable() examples. (#1528) +- Demo: Tweaked the Child demos, added a menu bar to the second child to test some navigation functions. +- Demo: Console: Using ImGuiCol_Text to be more friendly to color changes. +- Demo: Using IM_COL32() instead of ImColor() in ImDrawList centric contexts. Trying to phase out use of the ImColor helper whenever possible. +- Examples: Files in examples/ now include their own changelog so it is easier to occasionally update your backends if needed. +- Examples: Using Dark theme by default. (#707). Tweaked demo code. +- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) [@tseeker] +- Examples: All examples now setup the io.BackendFlags to signify they can honor mouse cursors, gamepad, etc. +- Examples: DirectX10: Fixed erroneous call to io.Fonts->ClearInputData() + ClearTexData() that was left in DX10 example but removed in 1.47 (Nov 2015) in every other backends. (#1733) +- Examples: DirectX12: Added DirectX 12 example. (#301) [@jdm3] +- Examples: OpenGL3+GLFW,SDL: Changed GLSL shader version from 330 to 150. (#1466, #1504) +- Examples: OpenGL3+GLFW,SDL: Added a way to override the GLSL version string in the Init function. (#1466, #1504). +- Examples: OpenGL3+GLFW,SDL: Creating VAO in the render function so it can be more easily used by multiple shared OpenGL contexts. (#1217) +- Examples: OpenGL3+GLFW: Using 3.2 context instead of 3.3. (#1466) +- Examples: OpenGL: Setting up glPixelStorei() explicitly before uploading texture. +- Examples: OpenGL: Calls to glPolygonMode() are casting parameters as GLEnum to not fail with more strict backends. (#1628) [@ilia-glushchenko] +- Examples: Win32 (DirectX9,10,11,12): Added support for mouse cursor shapes. (#1495) +- Examples: Win32 (DirectX9,10,11,12: Support for windows using the CS_DBLCLKS class flag by handling the double-click messages (WM_LBUTTONDBLCLK etc.). (#1538, #754) [@ndandoulakis] +- Examples: Win32 (DirectX9,10,11,12): Made the Win32 proc handlers not assert if there is no active context yet, to be more flexible with creation order. (#1565) +- Examples: GLFW: Added support for mouse cursor shapes (the diagonal resize cursors are unfortunately not supported by GLFW at the moment. (#1495) +- Examples: GLFW: Don't attempt to change the mouse cursor input mode if it is set to GLFW_CURSOR_DISABLED by the application. (#1202) [@PhilCK] +- Examples: SDL: Added support for mouse cursor shapes. (#1626) [@olls] +- Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging (SDL 2.0.4+ only, otherwise using SDL_WINDOW_INPUT_FOCUS instead of previously SDL_WINDOW_MOUSE_FOCUS). (#1559) +- Examples: SDL: Enabled vsync by default so people don't come at us when the examples are running at 2000 FPS and burning a CPU core. +- Examples: SDL: Using SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency() to handle frame-rate over 1000 FPS properly. (#996) +- Examples: SDL: Using scan-code exclusively instead of a confusing mixture of scan-codes and key-codes. +- Examples: SDL: Visual Studio: Added .vcxproj file. Using %SDL2_DIR% in the default .vcxproj and build files instead of %SDL_DIR%, the earlier being more standard. +- Examples: Vulkan: Visual Studio: Added .vcxproj file. +- Examples: Apple: Fixed filenames in OSX xcode project. Various other Mac friendly fixes. [@gerryhernandez etc.] +- Examples: Visual Studio: Disabled extraneous function-level check in Release build. +- Various fixes, tweaks, internal refactoring, optimizations, comments. + + +----------------------------------------------------------------------- + VERSION 1.53 (Released 2017-12-25) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.53 + +Breaking Changes: + +- Renamed the emblematic `ShowTestWindow()` function to `ShowDemoWindow()`. Kept redirection function (will obsolete). +- Renamed `GetItemsLineHeightWithSpacing()` to `GetFrameHeightWithSpacing()` for consistency. Kept redirection function (will obsolete). +- Renamed `ImGuiTreeNodeFlags_AllowOverlapMode` flag to `ImGuiTreeNodeFlags_AllowItemOverlap`. Kept redirection enum (will obsolete). +- Obsoleted `IsRootWindowFocused()` in favor of using `IsWindowFocused(ImGuiFocusedFlags_RootWindow)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `IsRootWindowOrAnyChildFocused()` in favor of using `IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `IsRootWindowOrAnyChildHovered()` in favor of using `IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `SetNextWindowContentWidth() in favor of using `SetNextWindowContentSize()`. Kept redirection function (will obsolete). +- Renamed `ImGuiTextBuffer::append()` helper to `appendf()`, and `appendv()` to `appendfv()` for consistency. If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. +- ImDrawList: Removed 'bool anti_aliased = true' final parameter of `ImDrawList::AddPolyline()` and `ImDrawList::AddConvexPolyFilled()`. Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. +- Style, ImDrawList: Renamed `style.AntiAliasedShapes` to `style.AntiAliasedFill` for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags. +- Style, Begin: Removed `ImGuiWindowFlags_ShowBorders` window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. `style.FrameBorderSize`, `style.WindowBorderSize`, `style.PopupBorderSize`). + Use `ImGui::ShowStyleEditor()` to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. + It is recommended that you use the `StyleColorsClassic()`, `StyleColorsDark()`, `StyleColorsLight()` functions. Also see `ShowStyleSelector()`. +- Style: Removed `ImGuiCol_ComboBg` in favor of combo boxes using `ImGuiCol_PopupBg` for consistency. Combo are normal pop-ups. +- Style: Renamed `ImGuiCol_ChildWindowBg` to `ImGuiCol_ChildBg`. +- Style: Renamed `style.ChildWindowRounding` to `style.ChildRounding`, `ImGuiStyleVar_ChildWindowRounding` to `ImGuiStyleVar_ChildRounding`. +- Removed obsolete redirection functions: SetScrollPosHere() - marked obsolete in v1.42, July 2015. +- Removed obsolete redirection functions: GetWindowFont(), GetWindowFontSize() - marked obsolete in v1.48, March 2016. + +Other Changes: + +- Added `io.OptCursorBlink` option to allow disabling cursor blinking. (#1427) [renamed to io.ConfigCursorBlink in 1.63] +- Added `GetOverlayDrawList()` helper to quickly get access to a ImDrawList that will be rendered in front of every windows. +- Added `GetFrameHeight()` helper which returns `(FontSize + style.FramePadding.y * 2)`. +- Drag and Drop: Added Beta API to easily use drag and drop patterns between imgui widgets. + - Setup a source on a widget with `BeginDragDropSource()`, `SetDragDropPayload()`, `EndDragDropSource()` functions. + - Receive data with `BeginDragDropTarget()`, `AcceptDragDropPayload()`, `EndDragDropTarget()`. + - See ImGuiDragDropFlags for various options. + - The ColorEdit4() and ColorButton() widgets now support Drag and Drop. + - The API is tagged as Beta as it still may be subject to small changes. +- Drag and Drop: When drag and drop is active, tree nodes and collapsing header can be opened by hovering on them for 0.7 seconds. +- Renamed io.OSXBehaviors to io.OptMacOSXBehaviors. Should not affect users as the compile-time default is usually enough. (#473, #650) +- Style: Added StyleColorsDark() style. (#707) [@dougbinks] +- Style: Added StyleColorsLight() style. Best used with frame borders + thicker font than the default font. (#707) +- Style: Added style.PopupRounding setting. (#1112) +- Style: Added style.FrameBorderSize, style.WindowBorderSize, style.PopupBorderSize. Removed ImGuiWindowFlags_ShowBorders window flag! + Borders are now fully set up in the ImGuiStyle structure. Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031) +- Style: Various small changes to the classic style (most noticeably, buttons are now using blue shades). (#707) +- Style: Renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. +- Style: Renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. +- Style: Removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. (#707) +- Style: Made the ScaleAllSizes() helper rounds down every values so they are aligned on integers. +- Focus: Added SetItemDefaultFocus(), which in the current (master) branch behave the same as doing `if (IsWindowAppearing()) SetScrollHere()`. + In the navigation branch this will also set the default focus. Prefer using this when creating combo boxes with `BeginCombo()` so your code will be forward-compatible with gamepad/keyboard navigation features. (#787) +- Combo: Pop-up grows horizontally to accommodate for contents that is larger then the parent combo button. +- Combo: Added BeginCombo()/EndCombo() API which allows use to submit content of any form and manage your selection state without relying on indices. +- Combo: Added ImGuiComboFlags_PopupAlignLeft flag to BeginCombo() to prioritize keeping the pop-up on the left side (for small-button-looking combos). +- Combo: Added ImGuiComboFlags_HeightSmall, ImGuiComboFlags_HeightLarge, ImGuiComboFlags_HeightLargest to easily provide desired pop-up height. +- Combo: You can use SetNextWindowSizeConstraints() before BeginCombo() to specify specific pop-up width/height constraints. +- Combo: Offset popup position by border size so that a double border isn't so visible. (#707) +- Combo: Recycling windows by using a stack number instead of a unique id, wasting less memory (like menus do). +- InputText: Added ImGuiInputTextFlags_NoUndoRedo flag. (#1506, #1508) [@ibachar] +- Window: Fixed auto-resize allocating too much space for scrollbar when SizeContents is bigger than maximum window size (fixes c0547d3). (#1417) +- Window: Child windows with MenuBar use regular WindowPadding.y so layout look consistent as child or as a regular window. +- Window: Begin(): Fixed appending into a child window with a second Begin() from a different window stack querying the wrong window for the window->Collapsed test. +- Window: Calling IsItemActive(), IsItemHovered() etc. after a call to Begin() provides item data for the title bar, so you can easily test if the title bar is being hovered, etc. (#823) +- Window: Made it possible to use SetNextWindowPos() on a child window. +- Window: Fixed a one frame glitch. When an appearing window claimed the focus themselves, the title bar wouldn't use the focused color for one frame. +- Window: Added ImGuiWindowFlags_ResizeFromAnySide flag to resize from any borders or from the lower-left corner of a window. This requires your backend to honor GetMouseCursor() requests for full usability. (#822) +- Window: Sizing fixes when using SetNextWindowSize() on individual axises. +- Window: Hide new window for one frame until they calculate their size. Also fixes SetNextWindowPos() given a non-zero pivot. (#1694) +- Window: Made mouse wheel scrolling accommodate better to windows that are smaller than the scroll step. +- Window: SetNextWindowContentSize() adjust for the size of decorations (title bar/menu bar), but _not_ for borders are we consistently make borders not affect layout. + If you need a non-child window of an exact size with border enabled but zero window padding, you'll need to accommodate for the border size yourself. +- Window: Using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. (#1380, #1502) +- Window: Active Modal window always set the WantCaptureKeyboard flag. (#744) +- Window: Moving window doesn't use accumulating MouseDelta so straying out of imgui boundaries keeps moved imgui window at the same cursor-relative position. +- IsWindowFocused(): Added ImGuiFocusedFlags_ChildWindows flag to include child windows in the focused test. (#1382). +- IsWindowFocused(): Added ImGuiFocusedFlags_RootWindow flag to start focused test from the root (top-most) window. Obsolete IsRootWindowFocused(). (#1382) +- IsWindowHovered(): Added ImGuiHoveredFlags_ChildWindows flag to include child windows in the hovered test. (#1382). +- IsWindowHovered(): Added ImGuiHoveredFlags_RootWindow flag to start hovered test from the root (top-most) window. The combination of both flags obsoletes IsRootWindowOrAnyChildHovered(). (#1382) +- IsWindowHovered(): Fixed return value when an item is active to use the same logic as IsItemHovered(). (#1382, #1404) +- IsWindowHovered(): Always return true when current window is being moved. (#1382) +- Scrollbar: Fixed issues with vertical scrollbar flickering/appearing, typically when manually resizing and using a pattern of filling available height (e.g. full sized BeginChild). +- Scrollbar: Minor graphical fix for when scrollbar don't have enough visible space to display the full grab. +- Scrolling: Fixed padding and scrolling asymmetry where lower/right sides of a window wouldn't use WindowPadding properly + causing minor scrolling glitches. +- Tree: TreePush with zero arguments was ambiguous. Resolved by making it call TreePush(const void*). [@JasonWilkins] +- Tree: Renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. (#600, #1330) +- MenuBar: Fixed minor rendering issues on the right size when resizing a window very small and using rounded window corners. +- MenuBar: better software clipping to handle small windows, in particular child window don't have minimum constraints so we need to render clipped menus better. +- BeginMenu(): Tweaked the Arrow/Triangle displayed on child menu items. +- Columns: Clipping columns borders on Y axis on CPU because some Linux GPU drivers appears to be unhappy with triangle spanning large regions. (#125) +- Columns: Added ImGuiColumnsFlags_GrowParentContentsSize to internal API to restore old content sizes behavior (may be obsolete). (#1444, #125) +- Columns: Columns width is no longer lost when dragging a column to the right side of the window, until releasing the mouse button you have a chance to save them. (#1499, #125). [@ggtucker] +- Columns: Fixed dragging when using a same of columns multiple times in the frame. (#125) +- Indent(), Unindent(): Allow passing negative values. +- ColorEdit4(): Made IsItemActive() return true when picker pop-up is active. (#1489) +- ColorEdit4(): Tweaked tooltip so that the color button aligns more correctly with text. +- ColorEdit4(): Support drag and drop. Color buttons can be used as drag sources, and ColorEdit widgets as drag targets. (#143) +- ColorPicker4(): Fixed continuously returning true when holding mouse button on the sat/value/alpha locations. We only return true on value change. (#1489) +- NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger). +- NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423) +- ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from scratch. +- ImFont: Added GetDebugName() helper. +- ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect] +- ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. +- ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd] +- ImDrawList: Refactored to make ImDrawList independent of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some. +- ImDrawList: Exposed ImDrawCornerFlags, replaced occurrences of ~0 with an explicit ImDrawCornerFlags_All. NB: Inversed BotLeft (prev 1<<3, now 1<<2) and BotRight (prev 1<<2, now 1<<3). +- ImVector: Added ImVector::push_front() helper. +- ImVector: Added ImVector::contains() helper. +- ImVector: insert() uses grow_capacity() instead of using grow policy inconsistent with push_back(). +- Internals: Remove requirement to define IMGUI_DEFINE_PLACEMENT_NEW to use the IM_PLACEMENT_NEW macro. (#1103) +- Internals: ButtonBehavior: Fixed ImGuiButtonFlags_NoHoldingActiveID flag from incorrectly setting the ActiveIdClickOffset field. + This had no known effect within imgui code but could have affected custom drag and drop patterns. And it is more correct this way! (#1418) +- Internals: ButtonBehavior: Fixed ImGuiButtonFlags_AllowOverlapMode to avoid temporarily activating widgets on click before they have been correctly double-hovered. (#319, #600) +- Internals: Added SplitterBehavior() helper. (#319) +- Internals: Added IM_NEW(), IM_DELETE() helpers. (#484, #504, #1517) +- Internals: Basic refactor of the settings API which now allows external elements to be loaded/saved. +- Demo: Added ShowFontSelector() showing loaded fonts. +- Demo: Added ShowStyleSelector() to select among default styles. (#707) +- Demo: Renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). +- Demo: Style Editor: Added a "Simplified settings" sections with check-boxes for border size and frame rounding. (#707, #1019) +- Demo: Style Editor: Added combo box to select stock styles and select current font when multiple are loaded. (#707) +- Demo: Style Editor: Using local storage so Save/Revert button makes more sense without code passing its storage. Added horizontal scroll bar. Fixed Save/Revert button to be always accessible. (#1211) +- Demo: Console: Fixed context menu issue. (#1404) +- Demo: Console: Fixed incorrect positioning which was hidden by a minor scroll issue (this would affect people who copied the Console code as is). +- Demo: Constrained Resize: Added more test cases. (#1417) +- Demo: Custom Rendering: Fixed clipping rectangle extruding out of parent window. +- Demo: Layout: Removed unnecessary and misleading BeginChild/EndChild calls. +- Demo: The "Color Picker with Palette" demo supports drag and drop. (#143) +- Demo: Display better mouse cursor info for debugging backends. +- Demo: Stopped using rand() function in demo code. +- Examples: Added a handful of extra comments (about fonts, third-party libraries used in the examples, etc.). +- Examples: DirectX9: Handle loss of D3D9 device (D3DERR_DEVICELOST). (#1464) +- Examples: Added null_example/ which is helpful for quick testing on multiple compilers/settings without relying on graphics library. +- Fix for using alloca() in "Clang with Microsoft Codechain" mode. +- Various fixes, optimizations, comments. + + +----------------------------------------------------------------------- + VERSION 1.52 (2017-10-27) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.52 + +Breaking Changes: + +- IO: `io.MousePos` needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing, instead of ImVec2(-1,-1) as previously) This is needed so we can clear `io.MouseDelta` field when the mouse is made available again. +- Renamed `AlignFirstTextHeightToWidgets()` to `AlignTextToFramePadding()`. Kept inline redirection function (will obsolete). +- Obsoleted the legacy 5 parameters version of Begin(). Please avoid using it. If you need a transparent window background, uses `PushStyleColor()`. The old size parameter there was also misleading and equivalent to calling `SetNextWindowSize(size, ImGuiCond_FirstTimeEver)`. Kept inline redirection function (will obsolete). +- Obsoleted `IsItemHoveredRect()`, `IsMouseHoveringWindow()` in favor of using the newly introduced flags of `IsItemHovered()` and `IsWindowHovered()`. Kept inline redirection function (will obsolete). (#1382) +- Obsoleted 'SetNextWindowPosCenter()' in favor of using 1SetNextWindowPos()` with a pivot value which allows to do the same and more. Keep inline redirection function. +- Removed `IsItemRectHovered()`, `IsWindowRectHovered()` recently introduced in 1.51 which were merely the more consistent/correct names for the above functions which are now obsolete anyway. (#1382) +- Changed `IsWindowHovered()` default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. (#1382) +- Renamed imconfig.h's `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS` to `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` for consistency. +- Renamed ImFont::Glyph to ImFontGlyph. Kept redirection typedef (will obsolete). + +Other Changes: + +- ProgressBar: fixed rendering when straddling rounded area. (#1296) +- SliderFloat, DragFloat: Using scientific notation e.g. "%.1e" in the displayed format string doesn't mistakenly trigger rounding of the value. [@MomentsInGraphics] +- Combo, InputFloat, InputInt: Made the small button on the right side align properly with the equivalent colored button of ColorEdit4(). +- IO: Tweaked logic for `io.WantCaptureMouse` so it now outputs false when e.g. hovering over void while an InputText() is active. (#621) [@pdoane] +- IO: Fixed `io.WantTextInput` from mistakenly outputting true when an activated Drag or Slider was previously turned into an InputText(). (#1317) +- Misc: Added flags to `IsItemHovered()`, `IsWindowHovered()` to access advanced hovering-test behavior. Generally useful for pop-ups and drag and drop behaviors: (relates to ~#439, #1013, #143, #925) + - `ImGuiHoveredFlags_AllowWhenBlockedByPopup` + - `ImGuiHoveredFlags_AllowWhenBlockedByActiveItem` + - `ImGuiHoveredFlags_AllowWhenOverlapped` + - `ImGuiHoveredFlags_RectOnly` +- Input: Added `IsMousePosValid()` helper. +- Input: Added `GetKeyPressedAmount()` to easily measure press count when the repeat rate is faster than the frame rate. +- Input/Focus: Disabled TAB and Shift+TAB when CTRL key is held. +- CheckBox: Now rendering a tick mark instead of a full square. +- ColorEdit4: Added "Copy as..." option in context menu. (#346) +- ColorPicker: Improved ColorPicker hue wheel color interpolation. (#1313) [@thevaber] +- ColorButton: Reduced bordering artifact that would be particularly visible with an opaque Col_FrameBg and FrameRounding enabled. +- ColorButton: Fixed rendering color button with a checkerboard if the transparency comes from the global style.Alpha and not from the actual source color. +- TreeNode: Added `ImGuiTreeNodeFlags_FramePadding` flag to conveniently create a tree node with full padding at the beginning of a line, without having to call `AlignTextToFramePadding()`. +- Trees: Fixed calling `SetNextTreeNodeOpen()` on a collapsed window leaking to the first tree node item of the next frame. +- Layout: Horizontal layout is automatically enforced in a menu bar, so you can use non-MenuItem elements without calling SameLine(). +- Separator: Output a vertical separator when used inside a menu bar (or in general when horizontal layout is active, but that isn't exposed yet!). +- Window: Added `IsWindowAppearing()` helper (helpful e.g. as a condition before initializing some of your own things.). +- Window: Added pivot parameter to `SetNextWindowPos()`, making it possible to center or right align a window. Obsoleted `SetNextWindowPosCenter()`. +- Window: Fixed title bar color of top-most window under a modal window. +- Window: Fixed not being able to move a window by clicking on one of its child window. (#1337, #635) +- Window: Fixed `Begin()` auto-fit calculation code that predict the presence of a scrollbar so it works better when window size constraints are used. +- Window: Fixed calling `Begin()` more than once per frame setting `window_just_activated_by_user` which in turn would set enable the Appearing condition for that frame. +- Window: The implicit "Debug" window now uses a "Debug##Default" identifier instead of "Debug" to allow user creating a window called "Debug" without losing their custom flags. +- Window: Made the `ImGuiWindowFlags_NoMove` flag properly inherited from parent to child. In a setup with ParentWindow (no flag) -> Child (NoMove) -> SubChild (no flag), the user won't be able to move the parent window by clicking on SubChild. (#1381) +- Popups: Pop-ups can be closed with a right-click anywhere, without altering focus under the pop-up. (~#439) +- Popups: `BeginPopupContextItem()`, `BeginPopupContextWindow()` are now setup to allow reopening a context menu by right-clicking again. (~#439) +- Popups: `BeginPopupContextItem()` now supports a NULL string identifier and uses the last item ID if available. +- Popups: Added `OpenPopupOnItemClick()` helper which mimic `BeginPopupContextItem()` but doesn't do the BeginPopup(). +- MenuItem: Only activating on mouse release. [@Urmeli0815] (was already fixed in nav branch). +- MenuItem: Made tick mark thicker (thick mark?). +- MenuItem: Tweaks to be usable inside a menu bar (nb: it looks like a regular menu and thus is misleading, prefer using Button() and regular widgets in menu bar if you need to). (#1387) +- ImDrawList: Fixed a rare draw call merging bug which could lead to undisplayed triangles. (#1172, #1368) +- ImDrawList: Fixed a rare bug in `ChannelsMerge()` when all contents has been clipped, leading to an extraneous draw call being created. (#1172, #1368) +- ImFont: Added `AddGlyph()` building helper for use by custom atlas builders. +- ImFontAtlas: Added support for CustomRect API to submit custom rectangles to be packed into the atlas. You can map them as font glyphs, or use them for custom purposes. + After the atlas is built you can query the position of your rectangles in the texture and then copy your data there. You can use this features to create e.g. full color font-mapped icons. +- ImFontAtlas: Fixed fall-back handling when merging fonts, if a glyph was missing from the second font input it could have used a glyph from the first one. (#1349) [@inolen] +- ImFontAtlas: Fixed memory leak on build failure case when stbtt_InitFont failed (generally due to incorrect or supported font type). (#1391) (@Moka42) +- ImFontConfig: Added `RasterizerMultiply` option to alter the brightness of individual fonts at rasterization time, which may help increasing readability for some. +- ImFontConfig: Added `RasterizerFlags` to pass options to custom rasterizer (e.g. the [imgui_freetype](https://github.com/ocornut/imgui_club/tree/master/imgui_freetype) rasterizer in imgui_club has such options). +- ImVector: added resize() variant with initialization value. +- Misc: Changed the internal name formatting of child windows identifier to use slashes (instead of dots) as separator, more readable. +- Misc: Fixed compilation with `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` defined. +- Misc: Marked all format+va_list functions with format attribute so GCC/Clang can warn about misuses. +- Misc: Fixed compilation on NetBSD due to missing alloca.h (#1319) [@RyuKojiro] +- Misc: Improved warnings compilation for newer versions of Clang. (#1324) (@waywardmonkeys) +- Misc: Added `io.WantMoveMouse flags` (from Nav branch) and honored in Examples applications. Currently unused but trying to spread Examples applications code that supports it. +- Misc: Added `IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS` support in imconfig.h to allow user reimplementing the `ImFormatString()` functions e.g. to use stb_printf(). (#1038) +- Misc: [Windows] Fixed default Win32 `SetClipboardText()` handler leaving the Win32 clipboard handler unclosed on failure. [@pdoane] +- Style: Added `ImGuiStyle::ScaleAllSizes(float)` helper to make it easier to have application transition e.g. from low to high DPI with a matching style. +- Metrics: Draw window bounding boxes when hovering Pos/Size; List all draw layers; Trimming empty commands like Render() does. +- Examples: OpenGL3: Save and restore sampler state. (#1145) [@nlguillemot] +- Examples: OpenGL2, OpenGL3: Save and restore polygon mode. (#1307) [@JJscott] +- Examples: DirectX11: Allow creating device with feature level 10 since we don't really need much for that example. (#1333) +- Examples: DirectX9/10/12: Using the Win32 SetCapture/ReleaseCapture API to read mouse coordinates when they are out of bounds. (#1375) [@Gargaj, @ocornut] +- Tools: Fixed binary_to_compressed_c tool to return 0 when successful. (#1350) [@benvanik] +- Internals: Exposed more helpers and unfinished features in imgui_internal.h. (use at your own risk!). +- Internals: A bunch of internal refactoring, hopefully haven't broken anything! Merged a bunch of internal changes from the upcoming Navigation branch. +- Various tweaks, fixes and documentation changes. + +Beta Navigation Branch: +(Lots of work has been done toward merging the Beta Gamepad/Keyboard Navigation branch (#787) in master.) +(Please note that this branch is always kept up to date with master. If you are using the navigation branch, some of the changes include:) +- Nav: Added `#define IMGUI_HAS_NAV` in imgui.h to ease sharing code between both branches. (#787) +- Nav: MainMenuBar now releases focus when user gets out of the menu layer. (#787) +- Nav: When applying focus to a window with only menus, the menu layer is automatically activated. (#787) +- Nav: Added `ImGuiNavInput_KeyMenu` (~Alt key) aside from ImGuiNavInput_PadMenu input as it is one differentiator of pad vs keyboard that was detrimental to the keyboard experience. Although isn't officially supported, it makes the current experience better. (#787) +- Nav: Move requests now wrap vertically inside Menus and Pop-ups. (#787) +- Nav: Allow to collapse tree nodes with NavLeft and open them with NavRight. (#787, #1079). +- Nav: It's now possible to navigate sibling of a menu-bar while navigating inside one of their child. If a Left<>Right navigation request fails to find a match we forward the request to the root menu. (#787, #126) +- Nav: Fixed `SetItemDefaultFocus` from stealing default focus when we are initializing default focus for a menu bar layer. (#787) +- Nav: Support for fall-back horizontal scrolling with PadLeft/PadRight (nb: fall-back scrolling is only used to navigate windows that have no interactive items). (#787) +- Nav: Fixed tool-tip from being selectable in the window selection list. (#787) +- Nav: `CollapsingHeader(bool*)` variant: fixed for `IsItemHovered()` not working properly in the nav branch. (#600, #787) +- Nav: InputText: Fixed using Up/Down history callback feature when Nav is enabled. (#787) +- Nav: InputTextMultiline: Fixed navigation/selection. Disabled selecting all when activating a multi-line text editor. (#787) +- Nav: More consistently drawing a (thin) navigation rectangle hover filled frames such as tree nodes, collapsing header, menus. (#787) +- Nav: Various internal refactoring. + + +----------------------------------------------------------------------- + VERSION 1.51 (2017-08-24) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.51 + +Breaking Changes: + +Work on dear imgui has been gradually resuming. It means that fixes and new features should be tackled at a faster rate than last year. However, in order to move forward with the library and get rid of some cruft, I have taken the liberty to be a little bit more aggressive than usual with API breaking changes. Read the details below and search for those names in your code! In the grand scheme of things, those changes are small and should not affect everyone, but this is technically our most aggressive release so far in term of API breakage. If you want to be extra forward-facing, you can enable `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h to disable the obsolete names/redirection. + +- Renamed `IsItemHoveredRect()` to `IsItemRectHovered()`. Kept inline redirection function (will obsolete). +- Renamed `IsMouseHoveringWindow()` to `IsWindowRectHovered()` for consistency. Kept inline redirection function (will obsolete). +- Renamed `IsMouseHoveringAnyWindow()` to `IsAnyWindowHovered()` for consistency. Kept inline redirection function (will obsolete). +- Renamed `ImGuiCol_Columns***` enums to `ImGuiCol_Separator***`. Kept redirection enums (will obsolete). +- Renamed `ImGuiSetCond***` types and enums to `ImGuiCond***`. Kept redirection enums (will obsolete). +- Renamed `GetStyleColName()` to `GetStyleColorName()` for consistency. Unlikely to be used by end-user! +- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicitly to fix. +- Marked the weird `IMGUI_ONCE_UPON_A_FRAME` helper macro as obsolete. Prefer using the more explicit `ImGuiOnceUponAFrame`. +- Changed `ColorEdit4(const char* label, float col[4], bool show_alpha = true)` signature to `ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)`, where flags 0x01 is a safe no-op (hello dodgy backward compatibility!). The new `ColorEdit4`/`ColorPicker4` functions have lots of available flags! Check and run the demo window, under "Color/Picker Widgets", to understand the various new options. +- Changed signature of `ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)` to `ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))`. This function was rarely used and was very dodgy (no explicit ID!). +- Changed `BeginPopupContextWindow(bool also_over_items=true, const char* str_id=NULL, int mouse_button=1)` signature to `(const char* str_id=NULL, int mouse_button=1, bool also_over_items=true)`. This is perhaps the most aggressive change in this update, but note that the majority of users relied on default parameters completely, so this will affect only a fraction of users of this already rarely used function. +- Removed `IsPosHoveringAnyWindow()`, which was partly broken and misleading. In the vast majority of cases, people using that function wanted to use `io.WantCaptureMouse` flag. Replaced with IM_ASSERT + comment redirecting user to `io.WantCaptureMouse`. (#1237) +- Removed the old `ValueColor()` helpers, they are equivalent to calling `Text(label)` + `SameLine()` + `ColorButton()`. +- Removed `ColorEditMode()` and `ImGuiColorEditMode` type in favor of `ImGuiColorEditFlags` and parameters to the various Color*() functions. The `SetColorEditOptions()` function allows to initialize default but the user can still change them with right-click context menu. Commenting out your old call to `ColorEditMode()` may just be fine! + +Other Changes: + +- Added flags to `ColorEdit3()`, `ColorEdit4()`. The color edit widget now has a context-menu and access to the color picker. (#346) +- Added flags to `ColorButton()`. (#346) +- Added `ColorPicker3()`, `ColorPicker4()`. The API along with those of the updated `ColorEdit4()` was designed so you may use them in various situation and hopefully compose your own picker if required. There are a bunch of available flags, check the Demo window and comment for `ImGuiColorEditFlags_`. Some of the options it supports are: two color picker types (hue bar + sat/val rectangle, hue wheel + rotating sat/val triangle), display as u8 or float, lifting 0.0..1.0 constraints (currently rgba only), context menus, alpha bar, background checkerboard options, preview tooltip, basic revert. For simple use, calling the existing `ColorEdit4()` function as you did before will be enough, as you can now open the color picker from there. (#346) [@r-lyeh, @nem0, @thennequin, @dariomanesku and @ocornut] +- Added `SetColorEditOptions()` to set default color options (e.g. if you want HSV over RGBA, float over u8, select a default picker mode etc. at startup time without a user intervention. Note that the user can still change options with the context menu unless disabled with `ImGuiColorFlags_NoOptions` or explicitly enforcing a display type/picker mode etc.). +- Added user-facing `IsPopupOpen()` function. (#891) [@mkeeter] +- Added `GetColorU32(u32)` variant that perform the style alpha multiply without a floating-point round trip, and helps makes code more consistent when using ImDrawList APIs. +- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload. +- Added `GetStyleColorVec4(ImGuiCol idx)` which is equivalent to accessing `ImGui::GetStyle().Colors[idx]` (aka return the raw style color without alpha alteration). +- ImFontAtlas: Added `GlyphRangesBuilder` helper class, which makes it easier to build custom glyph ranges from your app/game localization data, or add into existing glyph ranges. +- ImFontAtlas: Added `TexGlyphPadding` option. (#1282) [@jadwallis] +- ImFontAtlas: Made it possible to override size of AddFontDefault() (even if it isn't really recommended!). +- ImDrawList: Added `GetClipRectMin()`, `GetClipRectMax()` helpers. +- Fixed Ini saving crash if the ImGuiWindowFlags_NoSavedSettings gets removed from a window after its creation (unlikely!). (#1000) +- Fixed `PushID()`/`PopID()` from marking parent window as Accessed (which needlessly woke up the root "Debug" window when used outside of a regular window). (#747) +- Fixed an assert when calling `CloseCurrentPopup()` twice in a row. [@nem0] +- Window size can be loaded from .ini data even if ImGuiWindowFlags_NoResize flag is set. (#1048, #1056) +- Columns: Added `SetColumnWidth()`. (#913) [@ggtucker] +- Columns: Dragging a column preserve its width by default. (#913) [@ggtucker] +- Columns: Fixed first column appearing wider than others. (#1266) +- Columns: Fixed allocating space on the right-most side with the assumption of a vertical scrollbar. The space is only allocated when needed. (#125, #913, #893, #1138) +- Columns: Fixed the right-most column from registering its content width to the parent window, which led to various issues when using auto-resizing window or e.g. horizontal scrolling. (#519, #125, #913) +- Columns: Refactored some of the columns code internally toward a better API (not yet exposed) + minor optimizations. (#913) [@ggtucker, @ocornut] +- Popups: Most pop-ups windows can be moved by the user after appearing (if they don't have explicit positions provided by caller, or e.g. sub-menu pop-up). The previous restriction was totally arbitrary. (#1252) +- Tooltip: `SetTooltip()` is expanded immediately into a window, honoring current font / styling setting. Add internal mechanism to override tooltips. (#862) +- PlotHistogram: bars are drawn based on zero-line, so negative values are going under. (#828) +- Scrolling: Fixed return values of `GetScrollMaxX()`, `GetScrollMaxY()` when both scrollbars were enabled. Tweak demo to display more data. (#1271) [@degracode] +- Scrolling: Fixes for Vertical Scrollbar not automatically getting enabled if enabled Horizontal Scrollbar straddle the vertical limit. (#1271, #246) +- Scrolling: `SetScrollHere()`, `SetScrollFromPosY()`: Fixed Y scroll aiming when Horizontal Scrollbar is enabled. (#665). +- [Windows] Clipboard: Fixed not closing Win32 clipboard on early open failure path. (#1264) +- Removed an unnecessary dependency on int64_t which failed on some older compilers. +- Demo: Rearranged everything under Widgets in a more consistent way. +- Demo: Columns: Added Horizontal Scrolling demo. Tweaked another Columns demo. (#519, #125, #913) +- Examples: OpenGL: Various makefiles for MINGW, Linux. (#1209, #1229, #1209) [@fr500, @acda] +- Examples: Enabled vsync by default in example applications, so it doesn't confuse people that the sample run at 2000+ fps and waste an entire CPU. (#1213, #1151). +- Various other small fixes, tweaks, comments, optimizations. + + +----------------------------------------------------------------------- + VERSION 1.50 (2017-06-02) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.50 + +Breaking Changes: + +- Added a void* user_data parameter to Clipboard function handlers. (#875) +- SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. +- Renamed ImDrawList::PathFill() - rarely used directly - to ImDrawList::PathFillConvex() for clarity and consistency. +- Removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. +- Style: style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. +- BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). + +Other Changes: + +- InputText(): Added support for CTRL+Backspace (delete word). +- InputText(): OSX uses Super+Arrows for home/end. Add Shortcut+Backspace support. (#650) [@michaelbartnett] +- InputText(): Got rid of individual OSX-specific options in ImGuiIO, added a single io.OSXBehaviors flag. (#473, #650) +- InputText(): Fixed pressing home key on last character when it isn't a trailing \n (#588, #815) +- InputText(): Fixed state corruption/crash bug in stb_textedit.h redo logic when exhausting undo/redo char buffer. (#715. #681) +- InputTextMultiline(): Fixed CTRL+DownArrow moving scrolling out of bounds. +- InputTextMultiline(): Scrollbar fix for when input and latched internal buffers differs in a way that affects vertical scrollbar existence. (#725) +- ImFormatString(): Fixed an overflow handling bug with implementation of vsnprintf() that do not return -1. (#793) +- BeginChild(const char*) now applies stack id to provided label, consistent with other widgets. (#894, #713) +- SameLine() with explicit X position is relative to left of group/columns. (ref #746, #125, #630) +- SliderInt(), SliderFloat() supports reverse direction (where v_min > v_max). (#854) +- SliderInt(), SliderFloat() better support for when v_min==v_max. (#919) +- SliderInt(), SliderFloat() enforces writing back value when interacting, to be consistent with other widgets. (#919) +- SliderInt, SliderFloat(): Fixed edge case where style.GrabMinSize being bigger than slider width can lead to a division by zero. (#919) +- Added IsRectVisible() variation with explicit start-end positions. (#768) [@thedmd] +- Fixed TextUnformatted() clipping bug in the large-text path when horizontal scroll has been applied. (#692, #246) +- Fixed minor text clipping issue in window title when using font straying above usual line. (#699) +- Fixed SetCursorScreenPos() fixed not adjusting CursorMaxPos as well. +- Fixed scrolling offset when using SetScrollY(), SetScrollFromPosY(), SetScrollHere() with menu bar. +- Fixed using IsItemActive() after EndGroup() or any widget using groups. (#840, #479) +- Fixed IsItemActive() lagging by one frame on initial widget activation. (#840) +- Fixed Separator() zero-height bounding box resulting in clipping when laying exactly on top line of clipping rectangle (#860) +- Fixed PlotLines() PlotHistogram() calling with values_count == 0. +- Fixed clicking on a window's void while staying still overzealously marking .ini settings as dirty. (#923) +- Fixed assert triggering when a window has zero rendering but has a callback. (#810) +- Scrollbar: Fixed rendering when sizes are negative to reduce glitches (which can happen with certain style settings and zero WindowMinSize). +- EndGroup(): Made IsItemHovered() work when an item was activated within the group. (#849) +- BulletText(): Fixed stopping to display formatted string after the '##' mark. +- Closing the focused window restore focus to the first active root window in descending z-order .(part of #727) +- Word-wrapping: Fixed a bug where we never wrapped after a 1 character word. [@sronsse] +- Word-wrapping: Fixed TextWrapped() overriding wrap position if one is already set. (#690) +- Word-wrapping: Fixed incorrect testing for negative wrap coordinates, they are perfectly legal. (#706) +- ImGuiListClipper: Fixed automatic-height calc path dumbly having user display element 0 twice. (#661, #716) +- ImGuiListClipper: Fix to behave within column. (#661, #662, #716) +- ImDrawList: Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. (BREAKING API) +- Columns: End() avoid calling Columns(1) if no columns set is open, not sure why it wasn't the case already (pros: faster, cons: exercise less code). +- ColorButton(): Fix ColorButton showing wrong hex value for alpha. (#1068) [@codecat] +- ColorEdit4(): better preserve inputting value out of 0..255 range, display then clamped in Hexadecimal form. +- Shutdown() clear out some remaining pointers for sanity. (#836) +- Added IMGUI_USE_BGRA_PACKED_COLOR option in imconfig.h (#767, #844) [@thedmd] +- Style: Removed the inconsistent shadow under RenderCollapseTriangle() (~#707) +- Style: Added ButtonTextAlign, ImGuiStyleVar_ButtonTextAlign. (#842) +- ImFont: Allowing to use up to 0xFFFE glyphs in same font (increased from previous 0x8000). +- ImFont: Added GetGlyphRangesThai() helper. [@nProtect] +- ImFont: CalcWordWrapPositionA() fixed font scaling with fallback character. +- ImFont: Calculate and store the approximate texture surface to get an idea of how costly each source font is. +- ImFontConfig: Added GlyphOffset to explicitly offset glyphs at font build time, useful for merged fonts. Removed MergeGlyphCenterV. (BREAKING API) +- Clarified asserts in CheckStacksSize() when there is a stack mismatch. +- Context: Support for #define-ing GImGui and IMGUI_SET_CURRENT_CONTEXT_FUNC to enable custom thread-based hackery (#586) +- Updated stb_truetype.h to 1.14 (added OTF support, removed warnings). (#883, #976) +- Updated stb_rect_pack.h to 0.10 (removed warnings). (#883) +- Added ImGuiMouseCursor_None enum value for convenient usage by app/backends. +- Clipboard: Added a void* user_data parameter to Clipboard function handlers. (#875) (BREAKING API) +- Internals: Refactor internal text alignment options to use ImVec2, removed ImGuiAlign. (#842, #222) +- Internals: Renamed ImLoadFileToMemory to ImFileLoadToMemory to be consistent with ImFileOpen + fix mismatching .h name. (#917) +- OS/Windows: Fixed Windows default clipboard handler leaving its buffer unfreed on application's exit. (#714) +- OS/Windows: No default IME handler when compiling for Windows using GCC. (#738) +- OS/Windows: Now using _wfopen() instead of fopen() to allow passing in paths/filenames with UTF-8 characters. (#917) +- Tools: binary_to_compressed_c: Avoid ?? trigraphs sequences in string outputs which break some older compilers. (#839) +- Demo: Added an extra 3-way columns demo. +- Demo: ShowStyleEditor: show font character map / grid in more details. +- Demo: Console: Fixed a completion bug when multiple candidates are equals and match until the end. +- Demo: Fixed 1-byte off overflow in the ShowStyleEditor() combo usage. (#783) [@bear24rw] +- Examples: Accessing ImVector fields directly, feel less stl-ey. (#810) +- Examples: OpenGL*: Saving/restoring existing scissor rectangle for completeness. (#807) +- Examples: OpenGL*: Saving/restoring active texture number (the value modified by glActiveTexture). (#1087, #1088, #1116) +- Examples: OpenGL*: Saving/restoring separate color/alpha blend functions correctly. (#1120) [@greggman] +- Examples: OpenGL2: Uploading font texture as RGBA32 to increase compatibility with users shaders for beginners. (#824) +- Examples: Vulkan: Countless fixes and improvements. (#785, #804, #910, #1017, #1039, #1041, #1042, #1043, #1080) [@martty, @Loftilus, @ParticlePeter, @SaschaWillems] +- Examples: DirectX9/10/10: Only call SetCursor(NULL) is io.MouseDrawCursor is set. (#585, #909) +- Examples: DirectX9: Explicitly setting viewport to match that other examples are doing. (#937) +- Examples: GLFW+OpenGL3: Fixed Shutdown() calling GL functions with NULL parameters if NewFrame was never called. (#800) +- Examples: GLFW+OpenGL2: Renaming opengl_example/ to opengl2_example/ for clarity. +- Examples: SDL+OpenGL: explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) +- Examples: SDL2: Added build .bat files for Win32. +- Added various links to language/engine bindings. +- Various other minor fixes, tweaks, comments, optimizations. + + +----------------------------------------------------------------------- + VERSION 1.49 (2016-05-09) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.49 + +Breaking Changes: + +- Renamed `SetNextTreeNodeOpened()` to `SetNextTreeNodeOpen()` for consistency, no redirection. +- Removed confusing set of `GetInternalState()`, `GetInternalStateSize()`, `SetInternalState()` functions. Now using `CreateContext()`, `DestroyContext()`, `GetCurrentContext()`, `SetCurrentContext()`. If you were using multiple contexts the change should be obvious and trivial. +- Obsoleted old signature of `CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false)`, as extra parameters were badly designed and rarely used. Most uses were using 1 parameter and shouldn't affect you. You can replace the "default_open = true" flag in new API with `CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen)`. +- Changed `ImDrawList::PushClipRect(ImVec4 rect)` to `ImDraw::PushClipRect(ImVec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false)`. Note that higher-level `ImGui::PushClipRect()` is preferable because it will clip at logic/widget level, whereas `ImDrawList::PushClipRect()` only affect your renderer. +- Title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore (see #655). If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. + This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color. (Or If this is confusing, just pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color.) + + ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) + { + float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)); + float k = title_bg_col.w / new_a; + return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); + } + +Other changes: + +- New version of ImGuiListClipper helper calculates item height automatically. See comments and demo code. (#662, #661, #660) +- Added SetNextWindowSizeConstraints() to enable basic min/max and programmatic size constraints on window. Added demo. (#668) +- Added PushClipRect()/PopClipRect() (previously part of imgui_internal.h). Changed ImDrawList::PushClipRect() prototype. (#610) +- Added IsRootWindowOrAnyChildHovered() helper. (#615) +- Added TreeNodeEx() functions. (#581, #600, #190) +- Added ImGuiTreeNodeFlags_Selected flag to display TreeNode as "selected". (#581, #190) +- Added ImGuiTreeNodeFlags_AllowOverlapMode flag. (#600) +- Added ImGuiTreeNodeFlags_NoTreePushOnOpen flag (#590). +- Added ImGuiTreeNodeFlags_NoAutoOpenOnLog flag (previously private). +- Added ImGuiTreeNodeFlags_DefaultOpen flag (previously private). +- Added ImGuiTreeNodeFlags_OpenOnDoubleClick flag. +- Added ImGuiTreeNodeFlags_OpenOnArrow flag. +- Added ImGuiTreeNodeFlags_Leaf flag, always opened, no arrow, for convenience. For simple use case prefer using TreeAdvanceToLabelPos()+Text(). +- Added ImGuiTreeNodeFlags_Bullet flag, to add a bullet to Leaf node or replace Arrow with a bullet. +- Added TreeAdvanceToLabelPos(), GetTreeNodeToLabelSpacing() helpers. (#581, #324) +- Added CreateContext()/DestroyContext()/GetCurrentContext()/SetCurrentContext(). Obsoleted nearly identical GetInternalState()/SetInternalState() functions. (#586, #269) +- Added NewLine() to undo a SameLine() and as a shy reminder that horizontal layout support hasn't been implemented yet. +- Added IsItemClicked() helper. (#581) +- Added CollapsingHeader() variant with close button. (#600) +- Fixed MenuBar missing lower border when borders are enabled. +- InputText(): Fixed clipping of cursor rendering in case it gets out of the box (which can be forced w/ ImGuiInputTextFlags_NoHorizontalScroll. (#601) +- Style: Changed default IndentSpacing from 22 to 21. (#581, #324) +- Style: Fixed TitleBg/TitleBgActive color being rendered above WindowBg color, which was inconsistent and causing visual artifact. (#655) + This broke the meaning of TitleBg and TitleBgActive. Only affect values where Alpha<1.0f. Fixed default theme. Read comments in "API BREAKING CHANGES" section to convert. +- Relative rendering of order of Child windows creation is preserved, to allow more control with overlapping children. (#595) +- Fixed GetWindowContentRegionMax() being off by ScrollbarSize amount when explicit SizeContents is set. +- Indent(), Unindent(): optional non-default indenting width. (#324, #581) +- Bullet(), BulletText(): Slightly bigger. Less polygons. +- ButtonBehavior(): fixed subtle old bug when a repeating button would also return true on mouse release (barely noticeable unless RepeatRate is set to be very slow). (#656) +- BeginMenu(): a menu that becomes disabled while open gets closed down, facilitate user's code. (#126) +- BeginGroup(): fixed using within Columns set. (#630) +- Fixed a lag in reading the currently hovered window when dragging a window. (#635) +- Obsoleted 4 parameters version of CollapsingHeader(). Refactored code into TreeNodeBehavior. (#600, #579) +- Scrollbar: minor fix for top-right rounding of scrollbar background when window has menu bar but no title bar. +- MenuItem(): the check mark renders in disabled color when menu item is disabled. +- Fixed clipping rectangle floating point representation to ensure renderer-side float point operations yield correct results in typical DirectX/GL settings. (#582, 597) +- Fixed GetFrontMostModalRootWindow(), fixing missing fade-out when a combo pop was used stacked over a modal window. (#604) +- ImDrawList: Added AddQuad(), AddQuadFilled() helpers. +- ImDrawList: AddText() refactor, moving some code to ImFont, reserving less unused vertices when large vertical clipping occurs. +- ImFont: Added RenderChar() helper. +- ImFont: Added AddRemapChar() helper. (#609) +- ImFontConfig: Clarified persistence requirement of GlyphRanges array. (#651) +- ImGuiStorage: Added bool helper functions for completeness. +- AddFontFromMemoryCompressedTTF(): Fix ImFontConfig propagation. (#587) +- Renamed majority of use of the word "opened" to "open" for clarity. Renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(). (#625, #579) +- Examples: OpenGL3: Saving/restoring glActiveTexture() state. (#602) +- Examples: DirectX9: save/restore all device state. +- Examples: DirectX9: Removed dependency on d3dx9.h, d3dx9.lib, dxguid.lib so it can be used in a DirectXMath.h only environment. (#611) +- Examples: DirectX10/X11: Apply depth-stencil state (no use of depth buffer). (#640, #636) +- Examples: DirectX11/X11: Added comments on removing dependency on D3DCompiler. (#638) +- Examples: SDL: Initialize video+timer subsystem only. +- Examples: Apple/iOS: lowered XCode project deployment target from 10.7 to 10.11. (#598, #575) + + +----------------------------------------------------------------------- + VERSION 1.48 (2016-04-09) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.48 + +Breaking Changes: + +- Consistently honoring exact width passed to PushItemWidth() (when positive), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346) +- Style: removed `style.WindowFillAlphaDefault` which was confusing and redundant, baked alpha into `ImGuiCol_WindowBg` color. If you had a custom WindowBg color but didn't change WindowFillAlphaDefault, multiply WindowBg alpha component by 0.7. Renamed `ImGuiCol_TooltipBg` to `ImGuiCol_PopupBG`, applies to other types of pop-ups. `bg_alpha` parameter of 5-parameters version of Begin() is an override. (#337) +- InputText(): Added BufTextLen field in ImGuiTextEditCallbackData. Requesting user to update it if the buffer is modified in the callback. Added a temporary length-check assert to minimize panic for the 3 people using the callback. (#541) +- Renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). (#340) + +Other Changes: + +- Consistently honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346) +- Fixed clipping of child windows within parent not taking account of child outer clipping boundaries (including scrollbar, etc.). (#506) +- TextUnformatted(): Fixed rare crash bug with large blurb of text (2k+) not finished with a '\n' and fully above the clipping Y line. (#535) +- IO: Added 'KeySuper' field to hold CMD keyboard modifiers for OS X. Updated all examples accordingly. (#473) +- Added ImGuiWindowFlags_ForceVerticalScrollbar, ImGuiWindowFlags_ForceHorizontalScrollbar flags. (#476) +- Added IM_COL32 macros to generate a U32 packed color, convenient for direct use of ImDrawList api. (#346) +- Added GetFontTexUvWhitePixel() helper, convenient for direct use of ImDrawList api. +- Selectable(): Added ImGuiSelectableFlags_AllowDoubleClick flag to allow user reacting on double-click. (@zapolnov) (#516) +- Begin(): made the close button explicitly set the boolean to false instead of toggling it. (#499) +- BeginChild()/EndChild(): fixed incorrect layout to allow widgets submitted after an auto-fitted child window. (#540) +- BeginChild(): Added ImGuiWindowFlags_AlwaysUseWindowPadding flag to ensure non-bordered child window uses window padding. (#462) +- Fixed InputTextMultiLine(), ListBox(), BeginChildFrame(), ProgressBar(): outer frame not honoring bordering. (#462, #503) +- Fixed Image(), ImageButtion() rendering a rectangle 1 px too large on each axis. (#457) +- SetItemAllowOverlap(): Promoted from imgui_internal.h to public imgui.h api. (#517) +- Combo(): Right-most button stays highlighted when pop-up is open. +- Combo(): Display pop-up above if there's isn't enough space below / or select largest side. (#505) +- DragFloat(), SliderFloat(), InputFloat(): fixed cases of erroneously returning true repeatedly after a text input modification (e.g. "0.0" --> "0.000" would keep returning true). (#564) +- DragFloat(): Always apply value when mouse is held/widget active, so that an always-resetting variable (e.g. non saved local) can be passed. +- InputText(): OS X friendly behaviors: Word movement uses ALT key; Shortcuts uses CMD key; Double-clicking text select a single word; Jumping to next word sets cursor to end of current word instead of beginning of current word. (@zhiayang), (#473) +- InputText(): Added BufTextLen in ImGuiTextEditCallbackData. Requesting user to maintain it if buffer is modified. Zero-ing structure properly before use. (#541) +- CheckboxFlags(): Added support for testing/setting multiple flags at the same time. (@DMartinek) (#555) +- TreeNode(), CollapsingHeader() fixed not being able to use "##" sequence in a formatted label. +- ColorEdit4(): Empty label doesn't add InnerSpacing.x, matching behavior of other widgets. (#346) +- ColorEdit4(): Removed unnecessary calls to scanf() when idle in hexadecimal edit mode. +- BeginPopupContextItem(), BeginPopupContextWindow(): added early out optimization. +- CaptureKeyboardFromApp() / CaptureMouseFromApp(): added argument to allow clearing the capture flag. (#533) +- ImDrawList: Fixed index-overflow check broken by AddText() casting current index back to ImDrawIdx. (#514) +- ImDrawList: Fixed incorrect removal of trailing draw command if it is a callback command. +- ImDrawList: Allow windows with only a callback only to be functional. (#524) +- ImDrawList: Fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. (#457) +- ImDrawList: Fixed ImDrawList::AddCircle() to fit precisely within bounding box like AddCircleFilled() and AddRectFilled(). (#457) +- ImDrawList: AddCircle(), AddRect() takes optional thickness parameter. +- ImDrawList: Added AddTriangle(). +- ImDrawList: Added PrimQuadUV() helper to ease custom rendering of textured quads (require primitive reserve). +- ImDrawList: Allow AddText(ImFont\* font, float font_size, ...) variant to take NULL/0.0f as default. +- ImFontAtlas: heuristic increase default texture width up for large number of glyphs. (#491) +- ImTextBuffer: Fixed empty() helper which was utterly broken. +- Metrics: allow to inspect individual triangles in draw calls. +- Demo: added more draw primitives in the Custom Rendering example. (#457) +- Demo: extra comments and example for PushItemWidth(-1) patterns. +- Demo: InputText password demo filters out blanks. (#515) +- Demo: Fixed malloc/free mismatch and leak when destructing demo console, if it has been used. (@fungos) (#536) +- Demo: plot code doesn't use ImVector to avoid heap allocation and be more friendly to custom allocator users. (#538) +- Fixed compilation on DragonFly BSD (@mneumann) (#563) +- Examples: Vulkan: Added a Vulkan example (@Loftilus) (#549) +- Examples: DX10, DX11: Saving/restoring most device state so dropping render function in your codebase shouldn't have DX device side-effects. (#570) +- Examples: DX10, DX11: Fixed ImGui_ImplDX??_NewFrame() from recreating device objects if render isn't called (g_pVB not set). +- Examples: OpenGL3: Fix BindVertexArray/BindBuffer order. (@nlguillemot) (#527) +- Examples: OpenGL: skip rendering and calling glViewport() if we have zero-fixed buffer. (#486) +- Examples: SDL2+OpenGL3: Fix context creation options. Made ImGui_ImplSdlGL3_NewFrame() signature match GL2 one. (#468, #463) +- Examples: SDL2+OpenGL2/3: Fix for high-dpi displays. (@nickgravelyn) +- Various extra comments and clarification in the code. +- Various other fixes and optimizations. + + +----------------------------------------------------------------------- + VERSION 1.47 (2015-12-25) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.47 + +Changes: + +- Rebranding "ImGui" -> "dear imgui" as an optional first name to reduce ambiguity with IMGUI term. (#21) +- Added ProgressBar(). (#333) +- InputText(): Added ImGuiInputTextFlags_Password mode: hide display, disable logging/copying to clipboard. (#237, #363, #374) +- Added GetColorU32() helper to retrieve color given enum with global alpha and extra applied. +- Added ImGuiIO::ClearInputCharacters() superfluous helper. +- Fixed ImDrawList draw command merging bug where using PopClipRect() along with PushTextureID()/PopTextureID() functions + would occasionally restore an incorrect clipping rectangle. +- Fixed ImDrawList draw command merging so PushTextureID(XXX)/PopTextureID()/PushTextureID(XXX) sequence are now properly merged. +- Fixed large popups positioning issues when their contents on either axis is larger than DisplaySize, + and WindowPadding < DisplaySafeAreaPadding. +- Fixed border rendering in various situations when using non-pixel aligned glyphs. +- Fixed border rendering of windows to always contain the border within the window. +- Fixed Shutdown() leaking font atlas data if NewFrame() was never called. (#396, #303) +- Fixed int>void\* warnings for 64-bit architectures with fancy warnings enabled. +- Renamed the dubious Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. +- InputText(): Fixed and better handling of using keyboard while mouse button if being held and dragging. (#429) +- InputText(): Replace OS IME (Input Method Editor) cursor on top-left when we are not text editing. +- TreeNode(), CollapsingHeader(), Bullet(), BulletText(): various sizing and layout fixes to better support laying out + multiple item with different height on same line. (#414, #282) +- Begin(): Initial window creation with ImGuiWindowFlags_NoBringToFrontOnFocus flag pushes it at the front of global window list. +- BeginPopupContextWindow() and BeginPopupContextVoid() reopen window on subsequent click. (#439) +- ColorEdit4(): Fixed broken tooltip on hovering the color button. (actually fixes #373, #380) +- ImageButton(): uses FrameRounding up to a maximum of available framing size. (#394) +- Columns: Fixed bug with indentation within columns, also making code a bit shorter/faster. (#414, #125) +- Columns: Columns set with no implicit id include the columns count within the id to reduce collisions. (#125) +- Columns: Removed one unnecessary allocation when columns are not used by a window. (#125) +- ImFontAtlas: Tweaked GetGlyphRangesJapanese() so it is easier to modify. +- ImFontAtlas: Updated stb_rect_pack.h to 0.08. +- Metrics: Fixed computing ImDrawCmd bounding box when the draw buffer have been unindexed. +- Demo: Added a simple "Property Editor" demo applet. (#125, #414) +- Demo: Fixed assertion in "Custom Rendering" demo when holding both mouse buttons. (#393) +- Demo: Lots of extra comments, fixes. +- Demo: Tweaks to Style Editor. +- Examples: Not clearing input data/tex data in atlas (will be required for dynamic atlas anyway). +- Examples: Added /Zi (output debug information) to Win32 batch files. +- Examples: Various fixes for resizing window and recreating graphic context. +- Examples: OpenGL2/3: Save/restore viewport as part of default render function. (#392, #441). +- Examples; OpenGL3: Fixed gl3w.c for Linux when compiled with a C++ compiler. (#411) +- Examples: DirectX: Removed assumption about Unicode build in example main.cpp. (#399) +- Examples: DirectX10: Added DirectX10 example. (#424) +- Examples: DirectX11: Downgraded requirement from shader model 5.0 to 4.0. (#420) +- Examples: DirectX11: Removed Debug flag from graphics context. (#415) +- Examples: Added SDL+OpenGL3 example. (#356) + + +----------------------------------------------------------------------- + VERSION 1.46 (2015-10-18) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.46 + +Changes: + +- Begin*(): added ImGuiWindowFlags_NoFocusOnAppearing flag. (#314) +- Begin*(): added ImGuiWindowFlags_NoBringToFrontOnFocus flag. +- Added GetDrawData() alternative to setting a Render function pointer in ImGuiIO structure. +- Added SetClipboardText(), GetClipboardText() helper shortcuts that user code can call directly without reading + from the ImGuiIO structure (to match MemAlloc/MemFree) +- Fixed handling of malformed UTF-8 at the end of a non-zero terminated string range. +- Fixed mouse click detection when passing DeltaTime 0.0. (#338) +- Fixed IsKeyReleased() and IsMouseReleased() returning true on the first frame. +- Fixed using SetNextWindow\* functions on Modal windows with a ImGuiSetCond_Appearing condition. (#377) +- IsMouseHoveringRect(): Added 'bool clip' parameter to disable clipping provided rectangle. (#316) +- InputText(): added ImGuiInputTextFlags_ReadOnly flag. (#211) +- InputText(): lose cursor/undo-stack when reactivating focus is buffer has changed size. +- InputText(): fixed ignoring text inputs when ALT or ALTGR are pressed. (#334) +- InputText(): fixed mouse-dragging not tracking the cursor when text doesn't fit. (#339) +- InputText(): fixed cursor pixel-perfect alignment when horizontally scrolling. +- InputText(): fixed crash when passing a buf_size==0 (which can be of use for read-only selectable text boxes). (#360) +- InputFloat() fixed explicit precision modifier, both display and input were broken. +- PlotHistogram(): improved rendering of histogram with a lot of values. +- Dummy(): creates an item so functions such as IsItemHovered() can be used. +- BeginChildFrame() helper: added the extra_flags parameter. +- Scrollbar: fixed rounding of background + child window consistenly have ChildWindowBg color under ScrollbarBg fill. (#355). +- Scrollbar: background color less translucent in default style so it works better when changing background color. +- Scrollbar: fixed minor rendering offset when borders are enabled. (#365) +- ImDrawList: fixed 1 leak per ImDrawList using the ChannelsSplit() API (via Columns). (#318) +- ImDrawList: fixed rectangle rendering glitches with width/height <= 1/2 and rounding enabled. +- ImDrawList: AddImage() uv parameters default to (0,0) and (1,1). +- ImFontAtlas: Added TexDesiredWidth and tweaked default cheapo best-width choice. (#327) +- ImFontAtlas: Added GetGlyphRangesKorean() helper to retrieve unicode ranges for Korean. (#348) +- ImGuiTextFilter::Draw() helper return bool and build when filter is modified. +- ImGuiTextBuffer: added c_str() helper. +- ColorEdit4(): fixed hovering the color button always showing 1.0 alpha. (#373) +- ColorConvertFloat4ToU32() round the floats instead of truncating them. +- Window: Fixed window lower-right clipping limit so it plays more friendly with both OpenGL and DirectX coordinates. +- Internal: Extracted a EndFrame() function out of Render() but kept it internal/private + clarified some asserts. (#335) +- Internal: Added missing IMGUI_API definitions in imgui_internal.h (#326) +- Internal: ImLoadFileToMemory() return void\* instead of taking void*\* + allow optional int\* file_size. +- Demo: Horizontal scrollbar demo allows to enable simultanaeous scrollbars on both axises. +- Tools: binary_to_compressed_c.cpp: added -nocompress option. +- Examples: Added example for the Marmalade platform. +- Examples: Added batch files to build Windows examples with VS. +- Examples: OpenGL3: Saving/restoring more GL state correctly. (#347) +- Examples: OpenGL2/3: Added msys2/mingw64 target to Makefiles. + + +----------------------------------------------------------------------- + VERSION 1.45 (2015-09-01) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.45 + +Breaking Changes: + +- With the addition of better horizontal scrolling primitives I had to make some consistency fixes. + `GetCursorPos()` `SetCursorPos()` `GetContentRegionMax()` `GetWindowContentRegionMin()` `GetWindowContentRegionMax()` + are now incorporating the scrolling amount. They were incorrectly not incorporating this amount previously. + It PROBABLY shouldn't break anything, but that depends on how you used them. Namely: + - If you always used SetCursorPos() with values relative to GetCursorPos() there shouldn't be a problem. + However if you used absolute coordinates, note that SetCursorPosY(100.0f) will put you at +100 from the initial Y position (which may be scrolled out of the view), NOT at +100 from the window top border. Since there wasn't any official scrolling value on X axis (past just manually moving the cursor) this can only affect you if you used to set absolute coordinates on the Y axis which is hopefully rare/unlikely, and trivial to fix. + - The value of GetWindowContentRegionMax() isn't necessarily close to GetWindowWidth() if horizontally scrolling. + Previously they were roughly interchangeable (roughly because the content region exclude window padding). + +Other Changes: + +- Added Horizontal Scrollbar via ImGuiWindowFlags_HorizontalScroll (#246). +- Added GetScrollX(), GetScrollX(), GetScrollMaxX() apis (#246). +- Added SetNextWindowContentSize(), SetNextWindowContentWidth() to explicitly set the content size of a window, which + define the range of scrollbar. When set explicitly it also define the base value from which widget width are derived. +- Added IO.WantTextInput telling when ImGui is expecting text input, so that e.g. OS on-screen keyboard can be enabled. +- Added printf attribute to printf-like text formatting functions (Clang/GCC). +- Added GetMousePosOnOpeningCurrentPopup() helper. +- Added GetContentRegionAvailWidth() helper. +- Malformed UTF-8 data don't terminate string, output 0xFFFD instead (#307). +- ImDrawList: Added AddBezierCurve(), PathBezierCurveTo() API for cubic bezier curves (#311). +- ImDrawList: Allow to override ImDrawIdx type (#292). +- ImDrawList: Added an assert on overflowing index value (#292). +- ImDrawList: Fixed issues with channels split/merge. Now functional without manually adding a draw cmd. Added comments. +- ImDrawData: Added ScaleClipRects() helper useful when rendering scaled. (#287). +- Fixed Bullet() inconsistent layout behaviour when clipped. +- Fixed IsWindowHovered() not taking account of window hoverability (may be disabled because of a popup). +- Fixed InvisibleButton() not honoring negative size consistently with other widgets that do so. +- Fixed OpenPopup() accessing current window, effectively opening "Debug" when called from an empty window stack. +- TreeNode(): Fixed IsItemHovered() result being inconsistent with interaction visuals (#282). +- TreeNode(): Fixed mouse interaction padding past the node label being accounted for in layout (#282). +- BeginChild(): Passing a ImGuiWindowFlags_NoMove inhibits moving parent window from this child. +- BeginChild() fixed missing rounding for child sizes which leaked into layout and have items misaligned. +- Begin(): Removed default name = "Debug" parameter. We already have a "Debug" window pushed to the stack in the first place so it's not really a useful default. +- Begin(): Minor fixes with windows main clipping rectangle (e.g. child window with border). +- Begin(): Window flags are only read on the first call of the frame. Subsequent calls ignore flags, which allows appending to a window without worryin about flags. +- InputText(): ignore character input when ctrl/alt are held. (Normally those text input are ignored by most wrappers.) (#279). +- Demo: Fixed incorrectly formed string passed to Combo (#298). +- Demo: Added simple Log demo. +- Demo: Added horizontal scrolling example + enabled in console, log and child examples (#246). +- Style: made scrollbars rounded by default. Because nice. Minor menu bar background alpha tweak. (#246) +- Metrics: display indices along with triangles count (#299) and some internal state. +- ImGuiTextFilter::PassFilter() supports string range. Added [] helper to ImGuiTextBuffer. +- ImGuiTextFilter::Draw() default parameter width=0.0f for no override, allow override with negative values. +- Examples: OpenGL2/OpenGL3: fix for retina displays. Default font current lack crispness. +- Examples: OpenGL2/OpenGL3: save/restore more GL state correctly. +- Examples: DirectX9/DirectX11: resizing buffers dynamically (#299). +- Examples: DirectX9/DirectX11: added missing middle mouse button to Windows event handler. +- Examples: DirectX11: fix for Visual Studio 2015 presumably shipping with an updated version of DX11. +- Examples: iOS: fixed missing files in project. + + +----------------------------------------------------------------------- + VERSION 1.44 (2015-08-08) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.44 + +Breaking Changes: + +- imgui.cpp has been split intro extra files: imgui_demo.cpp, imgui_draw.cpp, imgui_internal.h. + Add the two extra .cpp to your project or #include them from another .cpp file. (#219) + +Other Changes: + +- Internal data structure and several useful functions are now exposed in imgui_internal.h. This should make it easier + and more natural to extend ImGui. However please note that none of the content in imgui_internal.h is guaranteed + for forward-compatibility and code using those types/functions may occasionally break. (#219) +- All sample code is in imgui_demo.cpp. Please keep this file in your project and consider allowing your code to call + the ShowTestWindow() function as de-facto guide to ImGui features. It will be stripped out by the linker when unused. +- Added GetContentRegionAvail() helper (basically GetContentRegionMax() - GetCursorPos()). +- Added ImGuiWindowFlags_NoInputs for totally input-passthru window. +- Button(): honor negative size consistently with other widgets that do so (width -100 to align the button 100 pixels + before the right-most position of the contents region). +- InputTextMultiline(): honor negative size consistently with other widgets that do so. +- Combo() clamp popup to lower edge of visible area. +- InputInt(): value doesn't pass through an int>float>int casting chain, fix handling lost of precision with "large" integer. +- InputInt() allow hexadecimal input (awkwardly via ImGuiInputTextFlags_CharsHexadecimal but we will allow format + string in InputInt* later). +- Checkbox(), RadioButton(): fixed scaling of checkbox and radio button for the filling of "active" visual. +- Columns: never assume horizontal space for scrollbar if NoScrollbar flag is explicitly set. +- Slider: fixed using FramePadding between frame and grab visual. Scaling that spacing would look odd. +- Fixed lower-right resize grip hit box not scaling along with its rendered size (#287) +- ImDrawList: Fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (v1.43) being off by an extra PI for no reason. +- ImDrawList: Added ImDrawList::AddText() shorthand helper. +- ImDrawList: Add missing support for anti-aliased thick-lines (#133, also ref #288) +- ImFontAtlas: Added AddFontFromMemoryCompressedBase85TTF() to load base85 encoded font string. Default font encoded + as base85 saves ~100 lines / 26 KB of source code. Added base85 output to the binary_to_compressed_c tool. +- Build fix for MinGW (#276). +- Examples: OpenGL3: Fixed running on script core profiles for OSX (#277). +- Examples: OpenGL3: Simplified code using glBufferData for vertices as well (#277, #278) +- Examples: DirectX11: Clear font texture view to ensure Release() doesn't get called twice (#290). +- Updated to stb_truetype 1.07 (back to vanilla version as our minor changes are now in master & fix unlikely assert + with odd fonts (#280) + + +----------------------------------------------------------------------- + VERSION 1.43 (2015-07-17) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.43 + +Breaking Changes: + +- This is a rather important release and we unfortunately had to break the rendering API. + ImGui now requires you to render indexed vertices instead of non-indexed ones. The fix should be very easy. + Sorry for that! This change is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost. + Each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles + using indices from the index buffer. +- If you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update + your copy and you can ignore the rest. +- The signature of the io.RenderDrawListsFn handler has changed + From: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) + To: ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data) + With: argument 'cmd_lists' -> 'draw_data->CmdLists' + argument 'cmd_lists_count' -> 'draw_data->CmdListsCount' + ImDrawList 'commands' -> 'CmdBuffer' + ImDrawList 'vtx_buffer' -> 'VtxBuffer' + ImDrawList n/a -> 'IdxBuffer' (new) + ImDrawCmd 'vtx_count' -> 'ElemCount' + ImDrawCmd 'clip_rect' -> 'ClipRect' + ImDrawCmd 'user_callback' -> 'UserCallback' + ImDrawCmd 'texture_id' -> 'TextureId' +- If you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index + the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! + Refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. Please upgrade! + +Other Changes: + +- Added anti-aliasing on lines and shapes based on primitives by @MikkoMononen (#133). + Between the use of indexed-rendering and the fact that the entire rendering codebase has been optimized and massaged + enough, with anti-aliasing enabled ImGui 1.43 is now running FASTER than 1.41. + Made some extra effort in making the code run faster in your typical Debug build. +- Anti-aliasing can be disabled in the ImGuiStyle structure via the AntiAliasedLines/AntiAliasedShapes fields for further gains. +- ImDrawList: Added AddPolyline(), AddConvexPolyFilled() with optional anti-aliasing. +- ImDrawList: Added stateful path building and stroking API. PathLineTo(), PathArcTo(), PathRect(), PathFill(), PathStroke() + with optional anti-aliasing. +- ImDrawList: Added AddRectFilledMultiColor() helper. +- ImDrawList: Added multi-channel rendering so out of order elements can be rendered in separate channels and then merged + back together (used by columns). +- ImDrawList: Fixed merging draw commands when equal clip rectangles are in the two first commands. +- ImDrawList: Fixed window draw lists not destructed properly on Shutdown(). +- ImDrawData: Added DeIndexAllBuffers() helper. +- Added lots of new font options ImFontAtlas::AddFont() and the new ImFontConfig structure. + - Added support for oversampling (ImFontConfig: OversampleH, OversampleV) and sub-pixel positioning (ImFontConfig: PixelSnapH). + Oversampling allows sub-pixel positioning but can also be used as a way to get some leeway with scaling fonts without re-rasterizing. + - Added GlyphExtraSpacing option to add extra horizontal spacing between characters (#242). + - Added MergeMode option to merge glyphs from different font inputs into a same font (#182, #232). + - Added FontDataOwnedByAtlas option to keep ownership from the TTF data buffer and request the atlas to make a copy (#220). +- Updated to stb_truetype 1.06 (+ minor mods) with better font rasterization. +- InputText: Added ImGuiInputTextFlags_NoHorizontalScroll flag. +- InputText: Added ImGuiInputTextFlags_AlwaysInsertMode flag. +- InputText: Added HasSelection() helper in ImGuiTextEditCallbackData as a clarification. +- InputText: Fix for using END key on a multi-line text editor (#275) +- Columns: Dispatch render of each column in a sub-draw list and merge on closure, saving a lot of draw calls! (#125) +- Popups: Fixed Combo boxes inside menus. (#272) +- Style: Added GrabRounding setting to make the sliders etc. grabs rounded. +- Changed SameLine() parameters from int to float. +- Fixed incorrect assert triggering when code stole ActiveID from user moving a window by calling e.g. SetKeyboardFocusHere(). +- Fixed CollapsingHeader() label rendering outside its frame in columns context where ClipRect max isn't aligned with the + right-side of the header. +- Metrics window: calculate bounding box of actual vertices when hovering a draw list. +- Examples: Showing more information in the Fonts section. +- Examples: Added a gratuitous About window. +- Examples: Updated all examples code (OpenGL/DX9/DX11/SDL/Allegro/iOS) to use indexed rendering. +- Examples: Fixed the SDL2 example to support Unicode text input (#274). + + +----------------------------------------------------------------------- + VERSION 1.42 (2015-07-08) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.42 + +Breaking Changes: + +- Renamed SetScrollPosHere() to SetScrollHere(). Kept inline redirection function (will obsolete). +- Renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion and make scrolling API consistent, + because positions (e.g. cursor position) are not equivalent to scrolling amount. +- Removed obsolete GetDefaultFontData() function that would assert anyway. + If you are updating from <1.30 you'll get a compile error instead of an assertion. (obsoleted 2015/01/11) + +Other Changes: + +- Added SDL2 example application (courtesy of @CedricGuillemet) +- Added iOS example application (courtesy of @joeld42) +- Added Allegro 5 example application (courtesy of @bggd) +- Added TitleBgActive color in style so focused window is made visible. (#253) +- Added CaptureKeyboardFromApp() / CaptureMouseFromApp() to manually enforce inputs capturing. +- Added DragFloatRange2() DragIntRange2() helpers. (#76) +- Added a Y centering ratio to SetScrollFromCursorPos() which can be used to aim the top or bottom of the window. (#150) +- Added SetScrollY(), SetScrollFromPos(), GetCursorStartPos() for manual scrolling manipulations. (#150). +- Added GetKeyIndex() helper for converting from ImGuiKey_\* enum to user's keycodes. Basically pulls from io.KeysMap[]. +- Added missing ImGuiKey_PageUp, ImGuiKey_PageDown so more UI code can be written without referring to implementation-side keycodes. +- MenuItem() can be activated on release. (#245) +- Allowing NewFrame() with DeltaTime==0.0f to not assert. +- Fixed IsMouseDragging(). (#260) +- Fixed PlotLines(), PlotHistogram() using incorrect hovering test so they would show their tooltip even when there is + a popup between mouse and the graph. +- Fixed window padding being reported incorrectly for child windows with borders when parent have no borders. +- Fixed a bug with TextUnformatted() clipping of long text blob when clipping y1 line sits on the first line of text. (#257) +- Fixed text baseline alignment of small button (no padding) after regular buttons. +- Fixed ListBoxHeader() not honoring negative sizes the same way as BeginChild() or BeginChildFrame(). (#263) +- Fixed warnings for more pedantic compiler settings (#258). +- ImVector<> cannot be re-defined anymore, cannot be replaced with std::vector<>. Allowed us to clean up and optimize + lots of code. Yeah! (#262) +- ImDrawList: store pointer to their owner name for easier auditing/debugging. +- Examples: added scroll tracking example with SetScrollFromCursorPos(). +- Examples: metrics windows render clip rectangle when hovering over a draw call. +- Lots of small optimization (particularly to run faster on unoptimized builds) and tidying up. +- Added font links in extra_fonts/ + instructions for using compressed fonts in C array. + + +----------------------------------------------------------------------- + VERSION 1.41 (2015-06-26) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.41 + +Breaking Changes: + +- Changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent). + Only makes a difference when texture have transparency. +- Changed Selectable() API from (label, selected, size) to (label, selected, flags, size). + Size override should be used very rarely so hopefully it doesn't affect many people. Sorry! + +Other Changes: + +- Added InputTextMultiline() multi-line text editor, vertical scrolling, selection, optimized enough to handle rather + big chunks of text in stateless context (thousands of lines are ok), option for allowing Tab to be input, option + for validating with Return or Ctrl+Return (#200). +- Added modal window API, BeginPopupModal(), follows the popup api scheme. Modal windows can be closed by clicking + outside. By default the rest of the screen is dimmed (using ImGuiCol_ModalWindowDarkening). Modal windows can be stacked. +- Added GetGlyphRangesCyrillic() helper (#237). +- Added SetNextWindowPosCenter() to center a window prior to knowing its size. (#249) +- Added IsWindowHovered() helper. +- Added IsMouseReleased(), IsKeyReleased() helpers to allow to user to avoid tracking them. (#248) +- Allow Set*WindowSize() calls to be used with popups. +- Window: AutoFit can be triggered on each axis separately via SetNextWindowSize(), etc. +- Window: fixed scrolling with mouse wheel while window was collapsed. +- Window: fixed mouse wheel scroll issues. +- DragFloat(), SliderFloat(): Fixed rounding of negative numbers which sometime made the negative lower bound unreachable. +- InputText(): lifted character count limit. +- InputText(): fixes in case of using per-window font scaling. +- Selectable(), MenuItem(): do not use frame rounding for hovering/selection. +- Selectable(): Added flag ImGuiSelectableFlags_DontClosePopups. +- Selectable(): Added flag ImGuiSelectableFlags_SpanAllColumns (#125). +- Combo(): Fixed issue with activating a Combo() not taking active id (#241). +- ColorButton(), ColorEdit4(): fix to ensure that the colored square stays square when non-default padding settings are used. +- BeginChildFrame(): returns bool like BeginChild() for clipping. +- SetScrollPosHere(): takes account of item height + more accurate centering + fixed precision issue. +- ImFont: ignoring '\r'. +- ImFont: added GetCharAdvance() helper. Exposed font Ascent and font Descent. +- ImFont: additional rendering optimizations. +- Metrics windows display storage size. + + +----------------------------------------------------------------------- + VERSION 1.40 (2015-05-31) +----------------------------------------------------------------------- + +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.40 + +Breaking Changes: + +- The BeginPopup() API (introduced in 1.37) had to be changed to allow for stacked popups and menus. + Use OpenPopup() to toggle the opened state and BeginPopup() to append.** +- The third parameter of Button(), 'repeat_if_held' has been removed. While it's been very rarely used, + some code will possibly break if you didn't rely on the default parameter. + Use PushButtonRepeat()/PopButtonRepeat() to configure repeat. +- Renamed IsRectClipped() to !IsRectVisible() for consistency (opposite return value!). Kept inline redirection function (will obsolete) +- Renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline indirection function (will obsolete). + +Other Changes: + +- Menus: Added a menu system! Menus are typically populated with menu items and sub-menus, but you can add any sort of + widgets in them (buttons, text inputs, sliders, etc.). (#126) +- Menus: Added MenuItem() to append a menu item. Optional shortcut display, acts a button & toggle with checked/unchecked state, + disabled mode. Menu items can be used in any window. +- Menus: Added BeginMenu() to append a sub-menu. Note that you generally want to add sub-menu inside a popup or a menu-bar. + They will work inside a normal window but it will be a bit unusual. +- Menus: Added BeginMenuBar() to append to window menu-bar (set ImGuiWindowFlags_MenuBar to enable). +- Menus: Added BeginMainMenuBar() helper to append to a fullscreen main menu-bar. +- Popups: Support for stacked popups. Each popup level inhibit inputs to lower levels. The menus system is based on this. (#126). +- Popups: Added BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid() to create a popup window on mouse-click. +- Popups: Popups have borders by default (#197), attenuated border alpha in default theme. +- Popups & Tooltip: Fit within display. Handling various positioning/sizing/scrolling edge cases. Better hysteresis when moving + in corners. Tooltip always tries to stay away from mouse-cursor. +- Added ImGuiStorage::GetVoidPtrRef() for manipulating stored void*. +- Added IsKeyDown() IsMouseDown() as convenience and for consistency with existing functions (instead of reading them from IO structures). +- Added Dummy() helper to advance layout by a given size. Unlike InvisibleButton() this doesn't catch any click. +- Added configurable io.KeyRepeatDelay, io.KeyRepeatRate keyboard and mouse repeat rate. +- Added PushButtonRepeat() / PopButtonRepeat() to enable hold-button-to-repeat press on any button. +- Removed the third 'repeat' parameter of Button(). +- Added IsAnyItemHovered() helper. +- Added GetItemsLineHeightWithSpacing() helper. +- Added ImGuiListClipper helper for clipping large list of evenly sized items, to avoid using CalcListClipping() directly. +- Separator: within group start on group horizontal offset. (#205) +- InputText: Fixed incorrect edit state after text buffer is appended to by user via the callback. (#206) +- InputText: CTRL+letter-key shortcuts (e.g. CTRL+C/V/X) makes sure only CTRL is pressed. (#214) +- InputText: Fixed cursor generating a zero-width wire-frame rectangle turning into a division by zero (would go unnoticed + unless you trapped exceptions). +- InputFloatN/InputIntN: Flags parameter added to match scalar versions. (#218) +- Selectable: Horizontal filling not declared to ItemSize() so Selectable(),SameLine() works and we can better auto-fit the window. +- Selectable: Handling text baseline alignment for line that aren't of text height. +- Combo: Empty label doesn't add ItemInnerSpacing alignment, matching other widgets. +- EndGroup: Carries the text base offset from the last line of the group (sort of incorrect but better than nothing, + should use the first line of the group, will implement in the future). +- Columns: distinguish columns-set ID from other widgets as a convenience, added asserts and sailors. +- ListBox: ListBox() function only use public API to encourage creating custom versions. ListBoxHeader() can return false. +- ListBox: Uses ImGuiListClipper and assume items of matching height, so large lists can be handled. +- Plot: overlay label clipped within frame when not fitting. +- Window: Added ImGuiSetCond_Appearing to test the hidden->visible transition in SetWindow***/SetNextWindow*** functions. +- Window: Auto-fitting cancel out one worth of vertical spacing for vertical symmetry (like what group and tooltip do). +- Window: Default item width for auto-resizing windows expressed as a factor of font height, scales better with different font. +- Window: Fixed auto-fit calculation mismatch of whether a scrollbar will be added by maximum height clamping. Also honor NoScrollBar in the case of height clamping, not adding extra horizontal space. +- Window: Hovering require to hover same child window. Reverted 860cf57 (December 3). Might break something if you have + child overlapping items in parent window. +- Window: Fixed appending multiple times to an existing child via multiple BeginChild/EndChild calls to same child name. + Allows a simple form of out-of-order appending. +- Window: Fixed auto-filling child window using WindowMinSize at their minimum size, irrelevant. +- Metrics: Added io.MetricsActiveWindows counter. (#213. +- Metrics: Added io.MetricsAllocs counter (number of active memory allocations). +- Metrics: ShowMetricsWindow() shows popups stack, allocations. +- Style: Added style.DisplayWindowPadding to prevent windows from reaching edges of display (similar to style.DisplaySafeAreaPadding which is still in effect and also affect popups/tooltips). +- Style: Removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). +- Style: Added style.ScrollbarRounding. (#212) +- Style: Added ImGuiCol_TextDisabled for disabled text. Added TextDisabled() helper. +- Style: Added style.WindowTitleAlign alignment options, to e.g. center title on windows. (#222) +- ImVector: tweak growth strategy, matches vector from VS2010. +- ImFontAtlas: Added ClearFonts(), making the different clear funcs more explicit. (#224) +- ImFontAtlas: Fixed appending new fonts without clearing existing fonts. Clearing input data left to application. (#224) +- ImDrawList: Merge draw command better, cases of multiple Begin/End gets merged properly. +- Store common stacked settings contiguously in memory to avoid heap allocation for unused features, and reduce cache misses. +- Shutdown() tests for g.IO.Fonts not being NULL to ease use of multiple ImGui contexts. (#207) +- Added IMGUI_DISABLE_OBSOLETE_FUNCTIONS define to disable the functions that are meant to be removed. +- Examples: Added ? marks with tooltips next to various widgets. Added more comments in the demo window. +- Examples: Added Menu-bar example. +- Examples: Added Simple Layout example. +- Examples: AutoResize demo doesn't use TextWrapped(). +- Examples: Console example uses standard malloc/free, makes more sense as a copy & pastable example. +- Examples: DirectX9/11: Fixed key mapping for down arrow. +- Examples: DirectX9/11: hide OS cursor if ImGui is drawing it. (#155) +- Examples: DirectX11: explicitly set rasterizer state. +- Examples: OpenGL3: Add conditional compilation of forward compat as required by glfw on OSX. (#229) +- Fixed build with Visual Studio 2008 (possibly earlier versions as well). +- Other fixes, comments, tweaks. + + +----------------------------------------------------------------------- + +For older version, see https://github.com/ocornut/imgui/releases + diff --git a/libultraship/libultraship/Lib/ImGui/docs/EXAMPLES.md b/libultraship/libultraship/Lib/ImGui/docs/EXAMPLES.md new file mode 100644 index 000000000..94f78dcdd --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/EXAMPLES.md @@ -0,0 +1,242 @@ +_(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md or view this file with any Markdown viewer)_ + +## Dear ImGui: Examples + +**The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of +platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder (see [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md)). + +The purpose of Examples is to showcase integration with backends, let you try Dear ImGui, and guide you toward +integrating Dear ImGui in your own application/game/engine. +**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.** + +You can find Windows binaries for some of those example applications at: + http://www.dearimgui.org/binaries + + +### Getting Started + +Integration in a typical existing application, should take <20 lines when using standard backends. + + At initialization: + call ImGui::CreateContext() + call ImGui_ImplXXXX_Init() for each backend. + + At the beginning of your frame: + call ImGui_ImplXXXX_NewFrame() for each backend. + call ImGui::NewFrame() + + At the end of your frame: + call ImGui::Render() + call ImGui_ImplXXXX_RenderDrawData() for your Renderer backend. + + At shutdown: + call ImGui_ImplXXXX_Shutdown() for each backend. + call ImGui::DestroyContext() + +Example (using [backends/imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp) + [backends/imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)): + + // Create a Dear ImGui context, setup some options + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable some options + + // Initialize Platform + Renderer backends (here: using imgui_impl_win32.cpp + imgui_impl_dx11.cpp) + ImGui_ImplWin32_Init(my_hwnd); + ImGui_ImplDX11_Init(my_d3d_device, my_d3d_device_context); + + // Application main loop + while (true) + { + // Beginning of frame: update Renderer + Platform backend, start Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // Any application code here + ImGui::Text("Hello, world!"); + + // End of frame: render Dear ImGui + ImGui::Render(); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + // Swap + g_pSwapChain->Present(1, 0); + } + + // Shutdown + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + +Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. +Please read the comments and instruction at the top of each file. +Please read FAQ at http://www.dearimgui.org/faq + +If you are using any of the backends provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h) +files to your project and use as-in. Each imgui_impl_xxxx.cpp file comes with its own individual +Changelog, so if you want to update them later it will be easier to catch up with what changed. + + +### Examples Applications + +[example_allegro5/](https://github.com/ocornut/imgui/blob/master/examples/example_allegro5/)
      +Allegro 5 example.
      += main.cpp + imgui_impl_allegro5.cpp + +[example_android_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_android_opengl3/)
      +Android + OpenGL3 (ES) example.
      += main.cpp + imgui_impl_android.cpp + imgui_impl_opengl3.cpp + +[example_apple_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_metal/)
      +OSX & iOS + Metal example.
      += main.m + imgui_impl_osx.mm + imgui_impl_metal.mm
      +It is based on the "cross-platform" game template provided with Xcode as of Xcode 9. +(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends. +You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.) + +[example_apple_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl2/)
      +OSX + OpenGL2 example.
      += main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp
      +(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends. + You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.) + +[example_emscripten_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_emscripten_opengl3/)
      +Emcripten + SDL2 + OpenGL3+/ES2/ES3 example.
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp
      +Note that other examples based on SDL or GLFW + OpenGL could easily be modified to work with Emscripten. +We provide this to make the Emscripten differences obvious, and have them not pollute all other examples. + +[example_emscripten_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_emscripten_wgpu/)
      +Emcripten + GLFW + WebGPU example.
      += main.cpp + imgui_impl_glfw.cpp + imgui_impl_wgpu.cpp + +[example_glfw_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_metal/)
      +GLFW (Mac) + Metal example.
      += main.mm + imgui_impl_glfw.cpp + imgui_impl_metal.mm + +[example_glfw_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_opengl2/)
      +GLFW + OpenGL2 example (legacy, fixed pipeline).
      += main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp
      +**DO NOT USE THIS IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
      +This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. +If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to +make things more complicated, will require your code to reset many OpenGL attributes to their initial +state, and might confuse your GPU driver. One star, not recommended. + +[example_glfw_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_opengl3/)
      +GLFW (Win32, Mac, Linux) + OpenGL3+/ES2/ES3 example (modern, programmable pipeline).
      += main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
      +This uses more modern OpenGL calls and custom shaders.
      +This may actually also work with OpenGL 2.x contexts!
      +Prefer using that if you are using modern OpenGL in your application (anything with shaders). + +[example_glfw_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_vulkan/)
      +GLFW (Win32, Mac, Linux) + Vulkan example.
      += main.cpp + imgui_impl_glfw.cpp + imgui_impl_vulkan.cpp
      +This is quite long and tedious, because: Vulkan. +For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp. + +[example_glut_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_glut_opengl2/)
      +GLUT (e.g., FreeGLUT on Linux/Windows, GLUT framework on OSX) + OpenGL2 example.
      += main.cpp + imgui_impl_glut.cpp + imgui_impl_opengl2.cpp
      +Note that GLUT/FreeGLUT is largely obsolete software, prefer using GLFW or SDL. + +[example_null/](https://github.com/ocornut/imgui/blob/master/examples/example_null/)
      +Null example, compile and link imgui, create context, run headless with no inputs and no graphics output.
      += main.cpp
      +This is used to quickly test compilation of core imgui files in as many setups as possible. +Because this application doesn't create a window nor a graphic context, there's no graphics output. + +[example_sdl_directx11/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_directx11/)
      +SDL2 + DirectX11 example, Windows only.
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_dx11.cpp
      +This to demonstrate usage of DirectX with SDL. + +[example_sdl_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_metal/)
      +SDL2 (Mac) + Metal example.
      += main.mm + imgui_impl_sdl.cpp + imgui_impl_metal.mm + +[example_sdl_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_opengl2/)
      +SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline).
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp
      +**DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
      +This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. +If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to +make things more complicated, will require your code to reset many OpenGL attributes to their initial +state, and might confuse your GPU driver. One star, not recommended. + +[example_sdl_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_opengl3/)
      +SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example.
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp
      +This uses more modern OpenGL calls and custom shaders.
      +This may actually also work with OpenGL 2.x contexts!
      + +[example_sdl_sdlrenderer/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_sdlrenderer/)
      +SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer (most graphics backends are supported underneath)
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_sdlrenderer.cpp
      +This requires SDL 2.0.17+ (expected to release November 2021)
      +We do not really recommend using SDL_Renderer as it is a rather primitive API. + +[example_sdl_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_vulkan/)
      +SDL2 (Win32, Mac, Linux, etc.) + Vulkan example.
      += main.cpp + imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp
      +This is quite long and tedious, because: Vulkan.
      +For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp. + +[example_win32_directx9/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx9/)
      +DirectX9 example, Windows only.
      += main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp + +[example_win32_directx10/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx10/)
      +DirectX10 example, Windows only.
      += main.cpp + imgui_impl_win32.cpp + imgui_impl_dx10.cpp + +[example_win32_directx11/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx11/)
      +DirectX11 example, Windows only.
      += main.cpp + imgui_impl_win32.cpp + imgui_impl_dx11.cpp + +[example_win32_directx12/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx12/)
      +DirectX12 example, Windows only.
      += main.cpp + imgui_impl_win32.cpp + imgui_impl_dx12.cpp
      +This is quite long and tedious, because: DirectX12. + + +### Miscallaneous + +**Building** + +Unfortunately nowadays it is still tedious to create and maintain portable build files using external +libraries (the kind we're using here to create a window and render 3D triangles) without relying on +third party software and build systems. For most examples here we choose to provide: + - Makefiles for Linux/OSX + - Batch files for Visual Studio 2008+ + - A .sln project file for Visual Studio 2012+ + - Xcode project files for the Apple examples +Please let us know if they don't work with your setup! +You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those +directly with a command-line compiler. + +If you are interested in using Cmake to build and links examples, see: + https://github.com/ocornut/imgui/pull/1713 and https://github.com/ocornut/imgui/pull/3027 + +**About mouse cursor latency** + +Dear ImGui has no particular extra lag for most behaviors, +e.g. the last value passed to 'io.AddMousePosEvent()' before NewFrame() will result in windows being moved +to the right spot at the time of EndFrame()/Render(). At 60 FPS your experience should be pleasant. + +However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated +path and will feel smoother than the majority of contents rendered via regular graphics API (including, +but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane +as the mouse, that disconnect may be jarring to particularly sensitive users. +You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor +using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a +regularly rendered software cursor. +However, rendering a mouse cursor at 60 FPS will feel sluggish so you likely won't want to enable that at +all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_ +when an interactive drag is in progress. + +Note that some setup or GPU drivers are likely to be causing extra display lag depending on their settings. +If you feel that dragging windows feels laggy and you are not sure what the cause is: try to build a simple +drawing a flat 2D shape directly under the mouse cursor! + diff --git a/libultraship/libultraship/Lib/ImGui/docs/FAQ.md b/libultraship/libultraship/Lib/ImGui/docs/FAQ.md new file mode 100644 index 000000000..06d51ef41 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/FAQ.md @@ -0,0 +1,676 @@ +# FAQ (Frequenty Asked Questions) + +You may link to this document using short form: + https://www.dearimgui.org/faq +or its real address: + https://github.com/ocornut/imgui/blob/master/docs/FAQ.md +or view this file with any Markdown viewer. + + +## Index + +| **Q&A: Basics** | +:---------------------------------------------------------- | +| [Where is the documentation?](#q-where-is-the-documentation) | +| [What is this library called?](#q-what-is-this-library-called) | +| [Which version should I get?](#q-which-version-should-i-get) | +| **Q&A: Integration** | +| **[How to get started?](#q-how-to-get-started)** | +| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-my-application)** | +| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) | +| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) | +| [I integrated Dear ImGui in my engine and little squares are showing instead of text...](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) | +| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | +| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | +| **Q&A: Usage** | +| **[About the ID Stack system..
      Why is my widget not reacting when I click on it?
      How can I have widgets with an empty label?
      How can I have multiple widgets with the same label?
      How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** | +| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| +| [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) | +| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) | +| [How can I display custom shapes? (using low-level ImDrawList API)](#q-how-can-i-display-custom-shapes-using-low-level-imdrawlist-api) | +| **Q&A: Fonts, Text** | +| [How should I handle DPI in my application?](#q-how-should-i-handle-dpi-in-my-application) | +| [How can I load a different font than the default?](#q-how-can-i-load-a-different-font-than-the-default) | +| [How can I easily use icons in my application?](#q-how-can-i-easily-use-icons-in-my-application) | +| [How can I load multiple fonts?](#q-how-can-i-load-multiple-fonts) | +| [How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?](#q-how-can-i-display-and-input-non-latin-characters-such-as-chinese-japanese-korean-cyrillic) | +| **Q&A: Concerns** | +| [Who uses Dear ImGui?](#q-who-uses-dear-imgui) | +| [Can you create elaborate/serious tools with Dear ImGui?](#q-can-you-create-elaborateserious-tools-with-dear-imgui) | +| [Can you reskin the look of Dear ImGui?](#q-can-you-reskin-the-look-of-dear-imgui) | +| [Why using C++ (as opposed to C)?](#q-why-using-c-as-opposed-to-c) | +| **Q&A: Community** | +| [How can I help?](#q-how-can-i-help) | + + +# Q&A: Basics + +### Q: Where is the documentation? + +**This library is poorly documented at the moment and expects the user to be acquainted with C/C++.** +- The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links. +- Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them. +- See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function. The demo covers most features of Dear ImGui, so you can read the code and see its output. +- See documentation: [Backends](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md), [Examples](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md), [Fonts](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md). +- See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h). +- The [Glossary](https://github.com/ocornut/imgui/wiki/Glossary) page may be useful. +- The [Issues](https://github.com/ocornut/imgui/issues) and [Discussions](https://github.com/ocornut/imgui/discussions) sections can be searched for past questions and issues. +- Your programming IDE is your friend, find the type or function declaration to find comments associated with it. +- The `ImGui::ShowMetricsWindow()` function exposes lots of internal information and tools. Although it is primary designed as a debugging tool, having access to that information tends to help understands concepts. + +##### [Return to Index](#index) + +--- + +### Q. What is this library called? + +**This library is called Dear ImGui**. Please refer to it as Dear ImGui (not ImGui, not IMGUI). + +(The library misleadingly started its life in 2014 as "ImGui" due to the fact that I didn't give it a proper name when I released 1.0, and had no particular expectation that it would take off. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations e.g. Unity uses it own implementation of the IMGUI paradigm. To reduce the ambiguity without affecting existing code bases, I have decided in December 2015 a fully qualified name "Dear ImGui" for this library. + +##### [Return to Index](#index) + +--- + +### Q: Which version should I get? +I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported. + +You may use the [docking](https://github.com/ocornut/imgui/tree/docking) branch which includes: +- [Docking features](https://github.com/ocornut/imgui/issues/2109) +- [Multi-viewport features](https://github.com/ocornut/imgui/issues/1542) + +Many projects are using this branch and it is kept in sync with master regularly. + +##### [Return to Index](#index) + +---- + +# Q&A: Integration + +### Q: How to get started? + +Read [EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md).
      +Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md).
      +Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp).
      +The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links. + +For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). + +##### [Return to Index](#index) + +--- + +### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application? + +You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure. +- When `io.WantCaptureMouse` is set, you need to discard/hide the mouse inputs from your underlying application. +- When `io.WantCaptureKeyboard` is set, you need to discard/hide the keyboard inputs from your underlying application. +- When `io.WantTextInput` is set, you can notify your OS/engine to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). + +Important: you should always pass your mouse/keyboard inputs to Dear ImGui, regardless of the value `io.WantCaptureMouse`/`io.WantCaptureKeyboard`. This is because e.g. we need to detect that you clicked in the void to unfocus its own windows, and other reasons. + +```cpp +void MyLowLevelMouseButtonHandler(int button, bool down) +{ + // (1) ALWAYS forward mouse data to ImGui! This is automatic with default backends. With your own backend: + ImGuiIO& io = ImGui::GetIO(); + io.AddMouseButtonEvent(button, down); + + // (2) ONLY forward mouse data to your underlying app/game. + if (!io.WantCaptureMouse) + my_game->HandleMouseData(...); +} +``` + + +**Note:** The `io.WantCaptureMouse` is more correct that any manual attempt to "check if the mouse is hovering a window" (don't do that!). It handle mouse dragging correctly (both dragging that started over your application or over a Dear ImGui window) and handle e.g. popup and modal windows blocking inputs. + +**Note:** Those flags are updated by `ImGui::NewFrame()`. However it is generally more correct and easier that you poll flags from the previous frame, then submit your inputs, then call `NewFrame()`. If you attempt to do the opposite (which is generally harder) you are likely going to submit your inputs after `NewFrame()`, and therefore too late. + +**Note:** If you are using a touch device, you may find use for an early call to `UpdateHoveredWindowAndCaptureFlags()` to correctly dispatch your initial touch. We will work on better out-of-the-box touch support in the future. + +**Note:** Text input widget releases focus on the "KeyDown" event of the Return key, so the subsequent "KeyUp" event that your application receive will typically have `io.WantCaptureKeyboard == false`. Depending on your application logic it may or not be inconvenient to receive that KeyUp event. You might want to track which key-downs were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) + +##### [Return to Index](#index) + +--- + +### Q: How can I enable keyboard or gamepad controls? +- The gamepad/keyboard navigation is fairly functional and keeps being improved. The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. Gamepad support is particularly useful to use Dear ImGui on a game console (e.g. PS4, Switch, XB1) without a mouse connected! +- Keyboard: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard` to enable. +- Gamepad: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad` to enable (with a supporting backend). +- See [Control Sheets for Gamepads](http://www.dearimgui.org/controls_sheets) (reference PNG/PSD for PS4, XB1, Switch gamepads). +- See `USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) for more details. + +##### [Return to Index](#index) + +--- + +### Q: How can I use this on a machine without mouse, keyboard or screen? (input share, remote display) +- You can share your computer mouse seamlessly with your console/tablet/phone using solutions such as [Synergy](https://symless.com/synergy) +This is the preferred solution for developer productivity. +In particular, the [micro-synergy-client repository](https://github.com/symless/micro-synergy-client) has simple +and portable source code (uSynergy.c/.h) for a small embeddable client that you can use on any platform to connect +to your host computer, based on the Synergy 1.x protocol. Make sure you download the Synergy 1 server on your computer. +Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-like protocols. +- Game console users: consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. +- You may also use a third party solution such as [netImgui](https://github.com/sammyfreg/netImgui), [Remote ImGui](https://github.com/JordiRos/remoteimgui) or [imgui-ws](https://github.com/ggerganov/imgui-ws) which sends the vertices to render over the local network, allowing you to use Dear ImGui even on a screen-less machine. See [Wiki](https://github.com/ocornut/imgui/wiki) index for most details. +- For touch inputs, you can increase the hit box of widgets (via the `style.TouchPadding` setting) to accommodate for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimizing for screen real-estate and precision. + +##### [Return to Index](#index) + +--- + +### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text... +Your renderer is not using the font texture correctly or it hasn't been uploaded to the GPU. +- If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md). +- If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states. + +##### [Return to Index](#index) + +--- + +### Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around... +### Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries... +You are probably mishandling the clipping rectangles in your render function. +Each draw command needs the triangle rendered using the clipping rectangle provided in the ImDrawCmd structure (`ImDrawCmd->CllipRect`). +Rectangles provided by Dear ImGui are defined as +`(x1=left,y1=top,x2=right,y2=bottom)` +and **NOT** as +`(x1,y1,width,height)` +Refer to rendering backends in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder for references of how to handle the `ClipRect` field. + +##### [Return to Index](#index) + +--- + +# Q&A: Usage + +### Q: About the ID Stack system... +### Q: Why is my widget not reacting when I click on it? +### Q: How can I have widgets with an empty label? +### Q: How can I have multiple widgets with the same label? +### Q: How can I have multiple windows with the same label? + +A primer on labels and the ID Stack... + +Dear ImGui internally needs to uniquely identify UI elements. +Elements that are typically not clickable (such as calls to the Text functions) don't need an ID. +Interactive widgets (such as calls to Button buttons) need a unique ID. + +**Unique ID are used internally to track active widgets and occasionally associate state to widgets.
      +Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.** + +Since Dear ImGui 1.85 you can use `Demo>Tools>Stack Tool` or call `ImGui::ShowStackToolWindow()`. The tool display intermediate values leading to the creation of a unique ID, making things easier to debug and understand. + +![Stack tool](https://user-images.githubusercontent.com/8225057/136235657-a0ea5665-dcd1-423f-9be6-dc3f8ced8f12.png) + +- Unique ID are often derived from a string label and at minimum scoped within their host window: +```cpp +Begin("MyWindow"); +Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK") +Button("Cancel"); // Label = "Cancel", ID = hash of ("MyWindow", "Cancel") +End(); +``` +- Other elements such as tree nodes, etc. also pushes to the ID stack: +```cpp +Begin("MyWindow"); +if (TreeNode("MyTreeNode")) +{ + Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "MyTreeNode", "OK") + TreePop(); +} +End(); +``` +- Two items labeled "OK" in different windows or different tree locations won't collide: +```cpp +Begin("MyFirstWindow"); +Button("OK"); // Label = "OK", ID = hash of ("MyFirstWindow", "OK") +End(); +Begin("MyOtherWindow"); +Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK") +End(); +``` + +- If you have a same ID twice in the same location, you'll have a conflict: +```cpp +Begin("MyWindow"); +Button("OK"); +Button("OK"); // ERROR: ID collision with the first button! Interacting with either button will trigger the first one. +Button(""); // ERROR: ID collision with Begin("MyWindow")! +End(); +``` +Fear not! this is easy to solve and there are many ways to solve it! + +- Solving ID conflict in a simple/local context: +When passing a label you can optionally specify extra ID information within string itself. +Use "##" to pass a complement to the ID that won't be visible to the end-user. +This helps solving the simple collision cases when you know e.g. at compilation time which items +are going to be created: +```cpp +Begin("MyWindow"); +Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play") +Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from other buttons +Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo2") // Different from other buttons +Button("##foo"); // Label = "", ID = hash of ("MyWindow", "##foo") // Different from window +End(); +``` +- If you want to completely hide the label, but still need an ID: +```cpp +Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox! +``` +- Occasionally/rarely you might want change a label while preserving a constant ID. This allows +you to animate labels. For example you may want to include varying information in a window title bar, +but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID: +```cpp +Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID") +Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same ID, different label + +sprintf(buf, "My game (%f FPS)###MyGame", fps); +Begin(buf); // Variable title, ID = hash of "MyGame" +``` +- Solving ID conflict in a more general manner: +Use `PushID()` / `PopID()` to create scopes and manipulate the ID stack, as to avoid ID conflicts +within the same window. This is the most convenient way of distinguishing ID when iterating and +creating many UI elements programmatically. +You can push a pointer, a string or an integer value into the ID stack. +Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack. +At each level of the stack we store the seed used for items at this level of the ID stack. +```cpp +Begin("Window"); +for (int i = 0; i < 100; i++) +{ + PushID(i); // Push i to the id tack + Button("Click"); // Label = "Click", ID = hash of ("Window", i, "Click") + PopID(); +} +for (int i = 0; i < 100; i++) +{ + MyObject* obj = Objects[i]; + PushID(obj); + Button("Click"); // Label = "Click", ID = hash of ("Window", obj pointer, "Click") + PopID(); +} +for (int i = 0; i < 100; i++) +{ + MyObject* obj = Objects[i]; + PushID(obj->Name); + Button("Click"); // Label = "Click", ID = hash of ("Window", obj->Name, "Click") + PopID(); +} +End(); +``` +- You can stack multiple prefixes into the ID stack: +```cpp +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", my_ptr, "Click") + PopID(); +PopID(); +``` +- Tree nodes implicitly creates a scope for you by calling `PushID()`: +```cpp +Button("Click"); // Label = "Click", ID = hash of (..., "Click") +if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag) +{ + Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click") + TreePop(); +} +``` + +When working with trees, ID are used to preserve the open/close state of each tree node. +Depending on your use cases you may want to use strings, indices or pointers as ID. +- e.g. when following a single pointer that may change over time, 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. See what makes more sense in your situation! + +##### [Return to Index](#index) + +--- + +### Q: How can I display an image? What is ImTextureID, how does it work? + +Short explanation: +- Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki). +- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures. +- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as ImTextureID (void*) value. +- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason). + +**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.** + +Long explanation: +- Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder we provide functions for popular graphics API (OpenGL, DirectX, etc.). +- Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API. + We carry the information to identify a "texture" in the ImTextureID type. +ImTextureID is nothing more that a void*, aka 4/8 bytes worth of data: just enough to store 1 pointer or 1 integer of your choice. +Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function. +- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using: +```cpp +OpenGL: +- ImTextureID = GLuint +- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp +``` +```cpp +DirectX9: +- ImTextureID = LPDIRECT3DTEXTURE9 +- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp +``` +```cpp +DirectX11: +- ImTextureID = ID3D11ShaderResourceView* +- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp +``` +```cpp +DirectX12: +- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE +- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp +``` +For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID. +Whereas in the DirectX11 example backend we store a pointer to ID3D11ShaderResourceView inside ImTextureID, which is a higher-level structure tying together both the texture and information about its format and how to read it. + +- If you have a custom engine built over e.g. OpenGL, instead of passing GLuint around you may decide to use a high-level data type to carry information about the texture as well as how to display it (shaders, etc.). The decision of what to use as ImTextureID can always be made better knowing how your codebase is designed. If your engine has high-level data types for "textures" and "material" then you may want to use them. +If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a rendering engine over them, keeping the default ImTextureID representation suggested by the example backends is probably the best choice. +(Advanced users may also decide to keep a low-level type in ImTextureID, and use ImDrawList callback and pass information to their renderer) + +User code may do: +```cpp +// Cast our texture type to ImTextureID / void* +MyTexture* texture = g_CoffeeTableTexture; +ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height)); +``` +The renderer function called after ImGui::Render() will receive that same value that the user code passed: +```cpp +// Cast ImTextureID / void* stored in the draw command as our texture type +MyTexture* texture = (MyTexture*)pcmd->GetTexID(); +MyEngineBindTexture2D(texture); +``` +Once you understand this design you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui. +This is by design and is actually a good thing, because it means your code has full control over your data types and how you display them. +If you want to display an image file (e.g. PNG file) into the screen, please refer to documentation and tutorials for the graphics API you are using. + +Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11. + +C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTextureID / void*, and vice-versa. +Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID / void*. +Examples: +```cpp +GLuint my_tex = XXX; +void* my_void_ptr; +my_void_ptr = (void*)(intptr_t)my_tex; // cast a GLuint into a void* (we don't take its address! we literally store the value inside the pointer) +my_tex = (GLuint)(intptr_t)my_void_ptr; // cast a void* into a GLuint + +ID3D11ShaderResourceView* my_dx11_srv = XXX; +void* my_void_ptr; +my_void_ptr = (void*)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque void* +my_dx11_srv = (ID3D11ShaderResourceView*)my_void_ptr; // cast a void* into a ID3D11ShaderResourceView* +``` +Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated. + +##### [Return to Index](#index) + +--- + +### Q: How can I use my own math types instead of ImVec2/ImVec4? + +You can edit [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) and setup the `IM_VEC2_CLASS_EXTRA`/`IM_VEC4_CLASS_EXTRA` macros to add implicit type conversions. +This way you'll be able to use your own types everywhere, e.g. passing `MyVector2` or `glm::vec2` to ImGui functions instead of `ImVec2`. + +##### [Return to Index](#index) + +--- + +### Q: How can I interact with standard C++ types (such as std::string and std::vector)? +- Being highly portable (backends/bindings for several languages, frameworks, programming style, obscure or older platforms/compilers), and aiming for compatibility & performance suitable for every modern real-time game engines, dear imgui does not use any of std C++ types. We use raw types (e.g. char* instead of std::string) because they adapt to more use cases. +- To use ImGui::InputText() with a std::string or any resizable string class, see [misc/cpp/imgui_stdlib.h](https://github.com/ocornut/imgui/blob/master/misc/cpp/imgui_stdlib.h). +- To use combo boxes and list boxes with `std::vector` or any other data structure: the `BeginCombo()/EndCombo()` API +lets you iterate and submit items yourself, so does the `ListBoxHeader()/ListBoxFooter()` API. +Prefer using them over the old and awkward `Combo()/ListBox()` api. +- Generally for most high-level types you should be able to access the underlying data type. +You may write your own one-liner wrappers to facilitate user code (tip: add new functions in ImGui:: namespace from your code). +- Dear ImGui applications often need to make intensive use of strings. It is expected that many of the strings you will pass +to the API are raw literals (free in C/C++) or allocated in a manner that won't incur a large cost on your application. +Please bear in mind that using `std::string` on applications with large amount of UI may incur unsatisfactory performances. +Modern implementations of `std::string` often include small-string optimization (which is often a local buffer) but those +are not configurable and not the same across implementations. +- If you are finding your UI traversal cost to be too large, make sure your string usage is not leading to excessive amount +of heap allocations. Consider using literals, statically sized buffers and your own helper functions. A common pattern +is that you will need to build lots of strings on the fly, and their maximum length can be easily be scoped ahead. +One possible implementation of a helper to facilitate printf-style building of strings: https://github.com/ocornut/Str +This is a small helper where you can instance strings with configurable local buffers length. Many game engines will +provide similar or better string helpers. + +##### [Return to Index](#index) + +--- + +### Q: How can I display custom shapes? (using low-level ImDrawList API) + +- You can use the low-level `ImDrawList` api to render shapes within a window. +```cpp +ImGui::Begin("My shapes"); + +ImDrawList* draw_list = ImGui::GetWindowDrawList(); + +// Get the current ImGui cursor position +ImVec2 p = ImGui::GetCursorScreenPos(); + +// Draw a red circle +draw_list->AddCircleFilled(ImVec2(p.x + 50, p.y + 50), 30.0f, IM_COL32(255, 0, 0, 255), 16); + +// Draw a 3 pixel thick yellow line +draw_list->AddLine(ImVec2(p.x, p.y), ImVec2(p.x + 100.0f, p.y + 100.0f), IM_COL32(255, 255, 0, 255), 3.0f); + +// Advance the ImGui cursor to claim space in the window (otherwise the window will appear small and needs to be resized) +ImGui::Dummy(ImVec2(200, 200)); + +ImGui::End(); +``` +![ImDrawList usage](https://raw.githubusercontent.com/wiki/ocornut/imgui/tutorials/CustomRendering01.png) + +- Refer to "Demo > Examples > Custom Rendering" in the demo window and read the code of `ShowExampleAppCustomRendering()` in `imgui_demo.cpp` from more examples. +- To generate colors: you can use the macro `IM_COL32(255,255,255,255)` to generate them at compile time, or use `ImGui::GetColorU32(IM_COL32(255,255,255,255))` or `ImGui::GetColorU32(ImVec4(1.0f,1.0f,1.0f,1.0f))` to generate a color that is multiplied by the current value of `style.Alpha`. +- Math operators: if you have setup `IM_VEC2_CLASS_EXTRA` in `imconfig.h` to bind your own math types, you can use your own math types and their natural operators instead of ImVec2. ImVec2 by default doesn't export any math operators in the public API. You may use `#define IMGUI_DEFINE_MATH_OPERATORS` `#include "imgui_internal.h"` to use the internally defined math operators, but instead prefer using your own math library and set it up in `imconfig.h`. +- You can use `ImGui::GetBackgroundDrawList()` or `ImGui::GetForegroundDrawList()` to access draw lists which will be displayed behind and over every other dear imgui windows (one bg/fg drawlist per viewport). This is very convenient if you need to quickly display something on the screen that is not associated to a dear imgui window. +- You can also create your own empty window and draw inside it. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags (The `ImGuiWindowFlags_NoDecoration` flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse). Then you can retrieve the ImDrawList* via `GetWindowDrawList()` and draw to it in any way you like. +- You can create your own ImDrawList instance. You'll need to initialize them with `ImGui::GetDrawListSharedData()`, or create your own instancing `ImDrawListSharedData`, and then call your renderer function with your own ImDrawList or ImDrawData data. +- Looking for fun? The [ImDrawList coding party 2020](https://github.com/ocornut/imgui/issues/3606) thread is full of "don't do this at home" extreme uses of the ImDrawList API. + +##### [Return to Index](#index) + +--- + +# Q&A: Fonts, Text + +### Q: How should I handle DPI in my application? + +The short answer is: obtain the desired DPI scale, load your fonts resized with that scale (always round down fonts size to nearest integer), and scale your Style structure accordingly using `style.ScaleAllSizes()`. + +Your application may want to detect DPI change and reload the fonts and reset style between frames. + +Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead. + +Down the line Dear ImGui will provide a variety of standardized reference values to facilitate using this. + +Applications in the `examples/` folder are not DPI aware partly because they are unable to load a custom font from the file-system (may change that in the future). + +The reason DPI is not auto-magically solved in stock examples is that we don't yet have a satisfying solution for the "multi-dpi" problem (using the `docking` branch: when multiple viewport windows are over multiple monitors using different DPI scale). The current way to handle this on the application side is: +- Create and maintain one font atlas per active DPI scale (e.g. by iterating `platform_io.Monitors[]` before `NewFrame()`). +- Hook `platform_io.OnChangedViewport()` to detect when a `Begin()` call makes a Dear ImGui window change monitor (and therefore DPI). +- In the hook: swap atlas, swap style with correctly sized one, remap the current font from one atlas to the other (may need to maintain a remapping table of your fonts at variying DPI scale). + +This approach is relatively easy and functional but come with two issues: +- It's not possibly to reliably size or position a window ahead of `Begin()` without knowing on which monitor it'll land. +- Style override may be lost during the `Begin()` call crossing monitor boundaries. You may need to do some custom scaling mumbo-jumbo if you want your `OnChangedViewport()` handler to preserve style overrides. + +Please note that if you are not using multi-viewports with multi-monitors using different DPI scale, you can ignore all of this and use the simpler technique recommended at the top. + +### Q: How can I load a different font than the default? +Use the font atlas to load the TTF/OTF file you want: + +```cpp +ImGuiIO& io = ImGui::GetIO(); +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); +io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() +``` + +Default is ProggyClean.ttf, monospace, rendered at size 13, embedded in dear imgui's source code. + +(Tip: monospace fonts are convenient because they allow to facilitate horizontal alignment directly at the string level.) + +(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about font loading.) + +New programmers: remember that in C/C++ and most programming languages if you want to use a +backslash \ within a string literal, you need to write it double backslash "\\": + +```cpp +io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escaping the M here!) +io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT (Windows only) +io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT +``` + +##### [Return to Index](#index) + +--- + +### Q: How can I easily use icons in my application? +The most convenient and practical way is to merge an icon font such as FontAwesome inside you +main font. Then you can refer to icons within your strings. +You may want to see `ImFontConfig::GlyphMinAdvanceX` to make your icon look monospace to facilitate alignment. +(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file for more details about icons font loading.) +With some extra effort, you may use colorful icon by registering custom rectangle space inside the font atlas, +and copying your own graphics data into it. See docs/FONTS.md about using the AddCustomRectFontGlyph API. + +##### [Return to Index](#index) + +--- + +### Q: How can I load multiple fonts? +Use the font atlas to pack them into a single texture: +(Read the [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md) file and the code in ImFontAtlas for more details.) + +```cpp +ImGuiIO& io = ImGui::GetIO(); +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 + +// Options +ImFontConfig config; +config.OversampleH = 2; +config.OversampleV = 1; +config.GlyphOffset.y -= 1.0f; // Move everything by 1 pixels up +config.GlyphExtraSpacing.x = 1.0f; // Increase spacing between characters +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, &config); + +// Combine multiple fonts into one (e.g. for icon fonts) +static ImWchar ranges[] = { 0xf000, 0xf3ff, 0 }; +ImFontConfig config; +config.MergeMode = true; +io.Fonts->AddFontDefault(); +io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); // Merge icon font +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge japanese glyphs +``` + +##### [Return to Index](#index) + +--- + +### Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? +When loading a font, pass custom Unicode ranges to specify the glyphs to load. + +```cpp +// Add default Japanese ranges +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); + +// Or create your own custom ranges (e.g. for a game you can feed your entire game script and only build the characters the game need) +ImVector ranges; +ImFontGlyphRangesBuilder builder; +builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters) +builder.AddChar(0x7262); // Add a specific character +builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges +builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", 16.0f, NULL, ranges.Data); +``` + +All your strings needs to use UTF-8 encoding. In C++11 you can encode a string literal in UTF-8 +by using the u8"hello" syntax. Specifying literal in your source code using a local code page +(such as CP-923 for Japanese or CP-1251 for Cyrillic) will NOT work! +Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. + +Text input: it is up to your application to pass the right character code by calling `io.AddInputCharacter()`. +The applications in examples/ are doing that. +Windows: you can use the WM_CHAR or WM_UNICHAR or WM_IME_CHAR message (depending if your app is built using Unicode or MultiByte mode). +You may also use MultiByteToWideChar() or ToUnicode() to retrieve Unicode codepoints from MultiByte characters or keyboard state. +Windows: if your language is relying on an Input Method Editor (IME), you can write your HWND to ImGui::GetMainViewport()->PlatformHandleRaw +in order for the default the default implementation of io.SetPlatformImeDataFn() to set your Microsoft IME position correctly. + +##### [Return to Index](#index) + +--- + +# Q&A: Concerns + +### Q: Who uses Dear ImGui? + +You may take a look at: + +- [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) +- [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) +- [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) +- [Gallery](https://github.com/ocornut/imgui/issues/4451) + +##### [Return to Index](#index) + +--- + +### Q: Can you create elaborate/serious tools with Dear ImGui? + +Yes. People have written game editors, data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library. + +Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient and powerful. + +Dear ImGui is built to be efficient and scalable toward the needs for AAA-quality applications running all day. The IMGUI paradigm offers different opportunities for optimization that the more typical RMGUI paradigm. + +##### [Return to Index](#index) + +--- + +### Q: Can you reskin the look of Dear ImGui? + +Somehow. You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimized to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. Dear ImGui is NOT designed to create user interface for games, although with ingenious use of the low-level API you can do it. + +A reasonably skinned application may look like (screenshot from [#2529](https://github.com/ocornut/imgui/issues/2529#issuecomment-524281119)) +![minipars](https://user-images.githubusercontent.com/314805/63589441-d9794f00-c5b1-11e9-8d96-cfc1b93702f7.png) + +##### [Return to Index](#index) + +--- + +### Q: Why using C++ (as opposed to C)? + +Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost insanity/quagmire. Dear ImGui doesn't use any C++ header file. Dear ImGui uses a very small subset of C++11 features. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. + +There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/cimgui/cimgui) by Sonoro1234 and Stephan Dilly. It is designed for creating bindings to other languages. If possible, I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for various third-party bindings. + +##### [Return to Index](#index) + +--- + +# Q&A: Community + +### Q: How can I help? +- Businesses: please reach out to `contact AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people working on this project. +- Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). +- If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help! +- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. +You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/4451). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and help other teams and programmers with taking decisions. +- If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR. + +##### [Return to Index](#index) + diff --git a/libultraship/libultraship/Lib/ImGui/docs/FONTS.md b/libultraship/libultraship/Lib/ImGui/docs/FONTS.md new file mode 100644 index 000000000..de7a1c997 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/FONTS.md @@ -0,0 +1,397 @@ +_(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/FONTS.md or view this file with any Markdown viewer)_ + +## Dear ImGui: Using Fonts + +The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer), +a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions. + +You may also load external .TTF/.OTF files. +In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) folder you can find a few suggested fonts, provided as a convenience. + +**Also read the FAQ:** https://www.dearimgui.org/faq (there is a Fonts section!) + +## Index +- [Readme First](#readme-first) +- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application) +- [Fonts Loading Instructions](#font-loading-instructions) +- [Using Icon Fonts](#using-icon-fonts) +- [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype) +- [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis) +- [Using Custom Glyph Ranges](#using-custom-glyph-ranges) +- [Using Custom Colorful Icons](#using-custom-colorful-icons) +- [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code) +- [About filenames](#about-filenames) +- [Credits/Licenses For Fonts Included In Repository](#creditslicenses-for-fonts-included-in-repository) +- [Font Links](#font-links) + +--------------------------------------- + ## Readme First + +- You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts. + +![imgui_capture_0008](https://user-images.githubusercontent.com/8225057/135429892-0e41ef8d-33c5-4991-bcf6-f997a0bcfd6b.png) + +- All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. + +- Make sure your font ranges data are persistent (available during the calls to `GetTexDataAsAlpha8()`/`GetTexDataAsRGBA32()/`Build()`. + +- Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.: +```cpp +u8"hello" +u8"こんにちは" // this will be encoded as UTF-8 +``` + +##### [Return to Index](#index) + +## How should I handle DPI in my application? + +See [FAQ entry](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-should-i-handle-dpi-in-my-application). + +##### [Return to Index](#index) + + +## Font Loading Instructions + +**Load default font:** +```cpp +ImGuiIO& io = ImGui::GetIO(); +io.Fonts->AddFontDefault(); +``` + + +**Load .TTF/.OTF file with:** +```cpp +ImGuiIO& io = ImGui::GetIO(); +io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); +``` +If you get an assert stating "Could not load font file!", your font filename is likely incorrect. Read "[About filenames](#about-filenames)" carefully. + + +**Load multiple fonts:** +```cpp +// Init +ImGuiIO& io = ImGui::GetIO(); +ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); +ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels); +``` +```cpp +// In application loop: select font at runtime +ImGui::Text("Hello"); // use the default font (which is the first loaded font) +ImGui::PushFont(font2); +ImGui::Text("Hello with another font"); +ImGui::PopFont(); +``` + + +**For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):** +```cpp +ImFontConfig config; +config.OversampleH = 2; +config.OversampleV = 1; +config.GlyphExtraSpacing.x = 1.0f; +ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config); +``` + + +**Combine multiple fonts into one:** +```cpp +// Load a first font +ImFont* font = io.Fonts->AddFontDefault(); + +// Add character ranges and merge into the previous font +// The ranges array is not copied by the AddFont* functions and is used lazily +// so ensure it is available at the time of building or calling GetTexDataAsRGBA32(). +static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // Will not be copied by AddFont* so keep in scope. +ImFontConfig config; +config.MergeMode = true; +io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 18.0f, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge into first font +io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 18.0f, &config, icons_ranges); // Merge into first font +io.Fonts->Build(); +``` + +**Add a fourth parameter to bake specific font ranges only:** + +```cpp +// Basic Latin, Extended Latin +io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesDefault()); + +// Default + Selection of 2500 Ideographs used by Simplified Chinese +io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); + +// Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs +io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); +``` +See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges. + + +**Example loading and using a Japanese font:** + +```cpp +ImGuiIO& io = ImGui::GetIO(); +io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); +``` +```cpp +ImGui::Text(u8"こんにちは!テスト %d", 123); +if (ImGui::Button(u8"ロード")) +{ + // do stuff +} +ImGui::InputText("string", buf, IM_ARRAYSIZE(buf)); +ImGui::SliderFloat("float", &f, 0.0f, 1.0f); +``` + +![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02_jp.png) +
      _(settings: Dark style (left), Light style (right) / Font: NotoSansCJKjp-Medium, 20px / Rounding: 5)_ + +**Font Atlas too large?** + +- If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API. The typical result of failing to upload a texture is if every glyphs appears as white rectangles. +- Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours. + +Some solutions: + +1. Reduce glyphs ranges by calculating them from source localization data. + You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win! +2. You may reduce oversampling, e.g. `font_config.OversampleH = 2`, this will largely reduce your texture size. + Note that while OversampleH = 2 looks visibly very close to 3 in most situations, with OversampleH = 1 the quality drop will be noticeable. +3. Set `io.Fonts.TexDesiredWidth` to specify a texture width to minimize texture height (see comment in `ImFontAtlas::Build()` function). +4. Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two. +5. Read about oversampling [here](https://github.com/nothings/stb/blob/master/tests/oversample). +6. To support the extended range of unicode beyond 0xFFFF (e.g. emoticons, dingbats, symbols, shapes, ancient languages, etc...) add `#define IMGUI_USE_WCHAR32`in your `imconfig.h`. + +##### [Return to Index](#index) + +## Using Icon Fonts + +Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application. +A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without having to change fonts back and forth. + +To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: https://github.com/juliettef/IconFontCppHeaders. + +So you can use `ICON_FA_SEARCH` as a string that will render as a "Search" icon. + +Example Setup: +```cpp +// Merge icons into default tool font +#include "IconsFontAwesome.h" +ImGuiIO& io = ImGui::GetIO(); +io.Fonts->AddFontDefault(); + +ImFontConfig config; +config.MergeMode = true; +config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced +static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; +io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); +``` +Example Usage: +```cpp +// Usage, e.g. +ImGui::Text("%s among %d items", ICON_FA_SEARCH, count); +ImGui::Button(ICON_FA_SEARCH " Search"); +// C string _literals_ can be concatenated at compilation time, e.g. "hello" " world" +// ICON_FA_SEARCH is defined as a string literal so this is the same as "A" "B" becoming "AB" +``` +See Links below for other icons fonts and related tools. + +Here's an application using icons ("Avoyd", https://www.avoyd.com): +![avoyd](https://user-images.githubusercontent.com/8225057/81696852-c15d9e80-9464-11ea-9cab-2a4d4fc84396.jpg) + +##### [Return to Index](#index) + +## Using FreeType Rasterizer (imgui_freetype) + +- Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read. +- There is an implementation of the ImFontAtlas builder using FreeType that you can use in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder. +- FreeType supports auto-hinting which tends to improve the readability of small fonts. +- Read documentation in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder. +- Correct sRGB space blending will have an important effect on your font rendering quality. + +##### [Return to Index](#index) + +## Using Colorful Glyphs/Emojis + +- Rendering of colored emojis is only supported by imgui_freetype with FreeType 2.10+. +- You will need to load fonts with the `ImGuiFreeTypeBuilderFlags_LoadColor` flag. +- Emojis are frequently encoded in upper Unicode layers (character codes >0x10000) and will need dear imgui compiled with `IMGUI_USE_WCHAR32`. +- Not all types of color fonts are supported by FreeType at the moment. +- Stateful Unicode features such as skin tone modifiers are not supported by the text renderer. + +![colored glyphs](https://user-images.githubusercontent.com/8225057/106171241-9dc4ba80-6191-11eb-8a69-ca1467b206d1.png) + +```cpp +io.Fonts->AddFontFromFileTTF("../../../imgui_dev/data/fonts/NotoSans-Regular.ttf", 16.0f); +static ImWchar ranges[] = { 0x1, 0x1FFFF, 0 }; +static ImFontConfig cfg; +cfg.OversampleH = cfg.OversampleV = 1; +cfg.MergeMode = true; +cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_LoadColor; +io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ranges); +``` + +##### [Return to Index](#index) + +## Using Custom Glyph Ranges + +You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. +```cpp +ImVector ranges; +ImFontGlyphRangesBuilder builder; +builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters) +builder.AddChar(0x7262); // Add a specific character +builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges +builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) + +io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); +io.Fonts->Build(); // Build the atlas while 'ranges' is still in scope and not deleted. +``` + +##### [Return to Index](#index) + +## Using Custom Colorful Icons + +As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)** + +- You can use the `ImFontAtlas::AddCustomRect()` and `ImFontAtlas::AddCustomRectFontGlyph()` api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build()`. +- You can then use `ImFontAtlas::GetCustomRectByIndex(int)` to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles. +- This API is beta because it is likely to change in order to support multi-dpi (multiple viewports on multiple monitors with varying DPI scale). + +#### Pseudo-code: +```cpp +// Add font, then register two custom 13x13 rectangles mapped to glyph 'a' and 'b' of this font +ImFont* font = io.Fonts->AddFontDefault(); +int rect_ids[2]; +rect_ids[0] = io.Fonts->AddCustomRectFontGlyph(font, 'a', 13, 13, 13+1); +rect_ids[1] = io.Fonts->AddCustomRectFontGlyph(font, 'b', 13, 13, 13+1); + +// Build atlas +io.Fonts->Build(); + +// Retrieve texture in RGBA format +unsigned char* tex_pixels = NULL; +int tex_width, tex_height; +io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height); + +for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++) +{ + int rect_id = rects_ids[rect_n]; + if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) + { + // Fill the custom rectangle with red pixels (in reality you would draw/copy your bitmap data here!) + for (int y = 0; y < rect->Height; y++) + { + ImU32* p = (ImU32*)tex_pixels + (rect->Y + y) * tex_width + (rect->X); + for (int x = rect->Width; x > 0; x--) + *p++ = IM_COL32(255, 0, 0, 255); + } + } +} +``` + +##### [Return to Index](#index) + +## Using Font Data Embedded In Source Code + +- Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code. +- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool. +- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)). +- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger. + +Then load the font with: +```cpp +ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); +``` +or +```cpp +ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); +``` + +##### [Return to Index](#index) + +## About filenames + +**Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_.** + +Two things to watch for: +- Make sure your IDE/debugger settings starts your executable from the right working directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it oftens start from the folder where object or executable files are stored. +```cpp +// Relative filename depends on your Working Directory when running your program! +io.Fonts->AddFontFromFileTTF("MyImage01.jpg", ...); + +// Load from the parent folder of your Working Directory +io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); +``` +- In C/C++ and most programming languages if you want to use a backslash `\` within a string literal, you need to write it double backslash `\\`. At it happens, Windows uses backslashes as a path separator, so be mindful. +```cpp +io.Fonts->AddFontFromFileTTF("MyFiles\MyImage01.jpg", ...); // This is INCORRECT!! +io.Fonts->AddFontFromFileTTF("MyFiles\\MyImage01.jpg", ...); // This is CORRECT +``` +In some situations, you may also use `/` path separator under Windows. + +##### [Return to Index](#index) + +## Credits/Licenses For Fonts Included In Repository + +Some fonts files are available in the `misc/fonts/` folder: + +**Roboto-Medium.ttf**, by Christian Robetson +
      Apache License 2.0 +
      https://fonts.google.com/specimen/Roboto + +**Cousine-Regular.ttf**, by Steve Matteson +
      Digitized data copyright (c) 2010 Google Corporation. +
      Licensed under the SIL Open Font License, Version 1.1 +
      https://fonts.google.com/specimen/Cousine + +**DroidSans.ttf**, by Steve Matteson +
      Apache License 2.0 +
      https://www.fontsquirrel.com/fonts/droid-sans + +**ProggyClean.ttf**, by Tristan Grimmer +
      MIT License +
      (recommended loading setting: Size = 13.0, GlyphOffset.y = +1) +
      http://www.proggyfonts.net/ + +**ProggyTiny.ttf**, by Tristan Grimmer +
      MIT License +
      (recommended loading setting: Size = 10.0, GlyphOffset.y = +1) +
      http://www.proggyfonts.net/ + +**Karla-Regular.ttf**, by Jonathan Pinhorn +
      SIL OPEN FONT LICENSE Version 1.1 + +##### [Return to Index](#index) + +## Font Links + +#### ICON FONTS + +- C/C++ header for icon fonts (#define with code points to use in source code string literals) https://github.com/juliettef/IconFontCppHeaders +- FontAwesome https://fortawesome.github.io/Font-Awesome +- OpenFontIcons https://github.com/traverseda/OpenFontIcons +- Google Icon Fonts https://design.google.com/icons/ +- Kenney Icon Font (Game Controller Icons) https://github.com/nicodinh/kenney-icon-font +- IcoMoon - Custom Icon font builder https://icomoon.io/app + +#### REGULAR FONTS + +- Google Noto Fonts (worldwide languages) https://www.google.com/get/noto/ +- Open Sans Fonts https://fonts.google.com/specimen/Open+Sans +- (Japanese) M+ fonts by Coji Morishita http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html + +#### MONOSPACE FONTS + +Pixel Perfect: +- Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperbounds.net +- Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font (also include an .inl file to use directly in dear imgui.) + +Regular: +- Google Noto Mono Fonts https://www.google.com/get/noto/ +- Typefaces for source code beautification https://github.com/chrissimpkins/codeface +- Programmation fonts http://s9w.github.io/font_compare/ +- Inconsolata http://www.levien.com/type/myfonts/inconsolata.html +- Adobe Source Code Pro: Monospaced font family for ui & coding environments https://github.com/adobe-fonts/source-code-pro +- Monospace/Fixed Width Programmer's Fonts http://www.lowing.org/fonts/ + +Or use Arial Unicode or other Unicode fonts provided with Windows for full characters coverage (not sure of their licensing). + +##### [Return to Index](#index) diff --git a/libultraship/libultraship/Lib/ImGui/docs/README.md b/libultraship/libultraship/Lib/ImGui/docs/README.md new file mode 100644 index 000000000..6569f454b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/README.md @@ -0,0 +1,243 @@ +Dear ImGui +===== +[![Build Status](https://github.com/ocornut/imgui/workflows/build/badge.svg)](https://github.com/ocornut/imgui/actions?workflow=build) [![Static Analysis Status](https://github.com/ocornut/imgui/workflows/static-analysis/badge.svg)](https://github.com/ocornut/imgui/actions?workflow=static-analysis) + + +(This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using Dear ImGui, please consider reaching out.) + +Businesses: support continued development and maintenance via invoiced technical support, maintenance, sponsoring contracts: +
        _E-mail: contact @ dearimgui dot com_ + +Individuals: support continued development and maintenance [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). + +Also see [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) page. + +---- + +Dear ImGui is a **bloat-free graphical user interface library for C++**. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). + +Dear ImGui is designed to **enable fast iterations** and to **empower programmers** to create **content creation tools and visualization / debug tools** (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries. + +Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard. + +| [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Integration](#integration) | +:----------------------------------------------------------: | +| [Upcoming changes](#upcoming-changes) - [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - [Sponsors](#sponsors) - [Credits](#credits) - [License](#license) | +| [Wiki](https://github.com/ocornut/imgui/wiki) - [Languages & frameworks backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) | + +### Usage + +**The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily compile in your application/engine. They are all the files in the root folder of the repository (imgui*.cpp, imgui*.h). + +**No specific build process is required**. You can add the .cpp files to your existing project. + +You will need a backend to integrate Dear ImGui in your app. The backend passes mouse/keyboard/gamepad inputs and variety of settings to Dear ImGui, and is in charge of rendering the resulting vertices. + +**Backends for a variety of graphics api and rendering platforms** are provided in the [backends/](https://github.com/ocornut/imgui/tree/master/backends) folder, along with example applications in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder. See the [Integration](#integration) section of this document for details. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui. + +After Dear ImGui is setup in your application, you can use it from \_anywhere\_ in your program loop: + +Code: +```cpp +ImGui::Text("Hello, world %d", 123); +if (ImGui::Button("Save")) + MySaveFunction(); +ImGui::InputText("string", buf, IM_ARRAYSIZE(buf)); +ImGui::SliderFloat("float", &f, 0.0f, 1.0f); +``` +Result: +
      ![sample code output (dark)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v175/capture_readme_styles_0001.png) ![sample code output (light)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v175/capture_readme_styles_0002.png) +
      _(settings: Dark style (left), Light style (right) / Font: Roboto-Medium, 16px)_ + +Code: +```cpp +// Create a window called "My First Tool", with a menu bar. +ImGui::Begin("My First Tool", &my_tool_active, ImGuiWindowFlags_MenuBar); +if (ImGui::BeginMenuBar()) +{ + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ } + if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Do stuff */ } + if (ImGui::MenuItem("Close", "Ctrl+W")) { my_tool_active = false; } + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); +} + +// Edit a color (stored as ~4 floats) +ImGui::ColorEdit4("Color", my_color); + +// Plot some values +const float my_values[] = { 0.2f, 0.1f, 1.0f, 0.5f, 0.9f, 2.2f }; +ImGui::PlotLines("Frame Times", my_values, IM_ARRAYSIZE(my_values)); + +// Display contents in a scrolling region +ImGui::TextColored(ImVec4(1,1,0,1), "Important Stuff"); +ImGui::BeginChild("Scrolling"); +for (int n = 0; n < 50; n++) + ImGui::Text("%04d: Some text", n); +ImGui::EndChild(); +ImGui::End(); +``` +Result: +
      ![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v180/code_sample_04_color.gif) + +Dear ImGui allows you to **create elaborate tools** as well as very short-lived ones. On the extreme side of short-livedness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. + +### How it works + +Check out the Wiki's [About the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize superfluous state duplication, state synchronization and state retention from the user's point of view. It is less error prone (less code and less bugs) than traditional retained-mode interfaces, and lends itself to create dynamic user interfaces. + +Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes required to render them is fairly small. Because Dear ImGui doesn't know or touch graphics state directly, you can call its functions anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate Dear ImGui with your existing codebase. + +_A common misunderstanding is to mistake immediate mode gui for immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes as the gui functions are called. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ + +### Releases & Changelogs + +See [Releases](https://github.com/ocornut/imgui/releases) page. +Reading the changelogs is a good way to keep up to date with the things Dear ImGui has to offer, and maybe will give you ideas of some features that you've been ignoring until now! + +### Demo + +Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. + +![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png) + +You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: +- [imgui-demo-binaries-20210331.zip](https://www.dearimgui.org/binaries/imgui-demo-binaries-20210331.zip) (Windows, 1.83 WIP, built 2021/03/31, master branch) or [older demo binaries](https://www.dearimgui.org/binaries). + +The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.org/faq)). + +### Integration + +On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more of the imgui_impl_xxxx files instead of rewriting them: this will be less work for you and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so. + +Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui in your custom engine. **Make sure to spend time reading the [FAQ](https://www.dearimgui.org/faq), comments, and some of the examples/ application!** + +Officially maintained backends/bindings (in repository): +- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU. +- Platforms: GLFW, SDL2, Win32, Glut, OSX, Android. +- Frameworks: Allegro5, Emscripten. + +[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page: +- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift... +- Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GLEQ, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS & Switch (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SDL_Renderer, SFML, Sokol, Unity, Unreal Engine 4, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets. +- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages. + +[Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page: +- Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos etc. + +Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas. + +### Upcoming Changes + +Some of the goals for 2022 are: +- Work on Docking (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch) +- Work on Multi-Viewport / Multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback) +- Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787)) +- Work on automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435)) +- Make the examples look better, improve styles, improve font support, make the examples hi-DPI and multi-DPI aware. + +### Gallery + +For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/4451)! + +For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page. + +Custom engine +[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) + +Custom engine +[![screenshot tool](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white_preview.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white.png) + +[Tracy Profiler](https://github.com/wolfpld/tracy) +![tracy profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v176/tracy_profiler.png) + +### Support, Frequently Asked Questions (FAQ) + +See: [Frequently Asked Questions (FAQ)](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) where common questions are answered. + +See: [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, articles. + +See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) to read/learn about the Immediate Mode GUI paradigm. + +Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). + +For other questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully. + +Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_). + +**Which version should I get?** + +We occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported. + +Advanced users may want to use the `docking` branch with [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features. This branch is kept in sync with master regularly. + +**Who uses Dear ImGui?** + +See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/4451)! + +How to help +----------- + +**How can I help?** + +- See [GitHub Forum/issues](https://github.com/ocornut/imgui/issues) and [Github Discussions](https://github.com/ocornut/imgui/discussions). +- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it. +- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas. +- Have your company financially support this project (please reach by e-mail) + +**How can I help financing further development of Dear ImGui?** + +See [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) page. + +Sponsors +-------- + +Ongoing Dear ImGui development is currently financially supported by users and private sponsors: + +*Platinum-chocolate sponsors* +- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1) + +*Double-chocolate sponsors* +- [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui), [Supercell](https://supercell.com) + +*Chocolate sponsors* +- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Adobe](https://www.adobe.com/products/medium.html), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Epic](https://www.unrealengine.com/en-US/megagrants), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [RAD Game Tools](http://www.radgametools.com/) + +*Salty-caramel sponsors* +- [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [O-Net Communications (USA)](http://en.o-netcom.com) + +Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors. +From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. + +**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** + +Dear ImGui is using software and services provided free of charge for open source projects: +- [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis. +- [GitHub actions](https://github.com/features/actions) for continuous integration systems. +- [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis. + +Credits +------- + +Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](https://www.mediamolecule.com) and first used internally on the game [Tearaway](https://tearaway.mediamolecule.com) (PS Vita). + +Recurring contributors (2020): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups), Ben Carter [@ShironekoBen](https://github.com/ShironekoBen). +A large portion of work on automation systems, regression tests and other features are currently unpublished. + +Sponsoring, support contracts and other B2B transactions are hosted and handled by [Lizardcube](https://www.lizardcube.com). + +Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it." + +Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license). + +Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain). + +Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub. + +License +------- + +Dear ImGui is licensed under the MIT License, see [LICENSE.txt](https://github.com/ocornut/imgui/blob/master/LICENSE.txt) for more information. diff --git a/libultraship/libultraship/Lib/ImGui/docs/TODO.txt b/libultraship/libultraship/Lib/ImGui/docs/TODO.txt new file mode 100644 index 000000000..3c130945a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/docs/TODO.txt @@ -0,0 +1,445 @@ +dear imgui +ISSUES & TODO LIST + +Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues/XXXX +The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point they usually exist on the github issue tracker). +It's mostly a bunch of personal notes, probably incomplete. Feel free to query if you have any questions. + + - doc/test: add a proper documentation+regression testing system (#435) + - doc/test: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.). + - doc/tips: tips of the day: website? applet in imgui_club? + - doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki + + - window: preserve/restore relative focus ordering (persistent or not) (#2304) -> also see docking reference to same #. + - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) + - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. + - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. + - window: begin with *p_open == false could return false. + - window: get size/pos helpers given names (see discussion in #249) + - window: a collapsed window can be stuck behind the main menu bar? + - window: when window is very small, prioritize resize button over close button. + - window: detect extra End() call that pop the "Debug" window out and assert at End() call site instead of at end of frame. + - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. + - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - window: expose contents size. (#1045) + - window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call. + - window: GetWindowSize() returns (0,0) when not calculated? (#1045) + - window: investigate better auto-positioning for new windows. + - window: top most window flag? (#2574) + - window/size: manually triggered auto-fit (double-click on grip) shouldn't resize window down to viewport size? + - window/size: how to allow to e.g. auto-size vertically to fit contents, but be horizontally resizable? Assuming SetNextWindowSize() is modified to treat -1.0f on each axis as "keep as-is" (would be good but might break erroneous code): Problem is UpdateWindowManualResize() and lots of code treat (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) together. + - window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false. + - window/child: background options for child windows, border option (disable rounding). + - window/child: allow resizing of child windows (possibly given min/max for each axis?.) + - window/child: the first draw command of a child window could be moved into the current draw command of the parent window (unless child+tooltip?). + - window/child: border could be emitted in parent as well. + - window/child: allow SetNextWindowContentSize() to work on child windows. + - window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero. + - window/tabbing: add a way to signify that a window or docked window requires attention (e.g. blinking title bar). + - window/id_stack: add e.g. window->GetIDFromPath() with support for leading / and ../ (#1390, #331) + ! scrolling: exposing horizontal scrolling with Shift+Wheel even when scrollbar is disabled expose lots of issues (#2424, #1463) + - scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse) + - scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. + - scrolling: forward mouse wheel scrolling to parent window when at the edge of scrolling limits? (useful for listbox,tables?) + - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) + - scrolling/style: shadows on scrollable areas to denote that there is more contents (see e.g. DaVinci Resolve ui) + + - drawdata: make it easy to clone (or swap?) a full ImDrawData so user can easily save that data if they use threaded rendering. (e.g. #2646) + ! drawlist: add calctextsize func to facilitate consistent code from user pov (currently need to use ImGui or ImFont alternatives!) + - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. + - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). + - drawlist: primitives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api + - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally + - drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4(). + - drawlist: would be good to be able to deep copy of ImDrawData (we have a deep copy of ImDrawList now). + - drawlist: rendering: provide a way for imgui to output to a single/global vertex buffer, re-order indices only at the end of the frame (ref: https://gist.github.com/floooh/10388a0afbe08fce9e617d8aefa7d302) + - drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API). + - drawlist: AddRect vs AddLine position confusing (#2441) + - drawlist: channel splitter should be external helper and not stored in ImDrawList. + - drawlist: Add quadratic bezier curves? (#3127) + - drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962) + - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. + - drawlist/opt: thick AA line could be doable in same number of triangles as 1.0 AA line by storing gradient+full color in atlas. + + - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. + - 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? + + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) + - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. + - widgets: add visuals for Disabled/ReadOnly mode and expose publicly (#211) + - widgets: add always-allow-overlap mode. This should perhaps be the default? one problem is that highlight after mouse-wheel scrolling gets deferred, makes scrolling more flickery. + - widgets: start exposing PushItemFlag() and ImGuiItemFlags + - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 + - widgets: activate by identifier (trigger button, focus given id) + - widgets: a way to represent "mixed" values, so e.g. all values replaced with *, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed) (#2644) + - widgets: checkbox: checkbox with custom glyph inside frame. + - widgets: coloredit: keep reporting as active when picker is on? + - widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow. + - selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported. + - selectable: generic BeginSelectable()/EndSelectable() mechanism. + - selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection) + + - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. + - input text: preserve scrolling when unfocused? + - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) + - input text: expose CursorPos in char filter event (#816) + - input text: try usage idiom of using InputText with data only exposed through get/set accessors, without extraneous copy/alloc. (#3009) + - input text: access public fields via a non-callback API e.g. InputTextGetState("xxx") that may return NULL if not active. + - input text: flag to disable live update of the user buffer (also applies to float/int text input) (#701) + - input text: hover tooltip could show unclamped text + - input text: support for INSERT key to toggle overwrite mode. currently disabled because stb_textedit behavior is unsatisfactory on multi-line. (#2863) + - input text: option to Tab after an Enter validation. + - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text. + - input text: add flag (e.g. ImGuiInputTextFlags_EscapeClearsBuffer) to clear instead of revert. what to do with focus? (also see #2890) + - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) + - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it. + - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. + - input text: decorrelate layout from inputs - e.g. what's the easiest way to implement a nice IP/Mac address input editor? + - input text: global callback system so user can plug in an expression evaluator easily. (#1691) + - input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature) + - input text: a way to preview completion (e.g. disabled text completing from the cursor) + - input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there. + - input text: a way for the user to provide syntax coloring. + - input text: Shift+TAB with ImGuiInputTextFlags_AllowTabInput could eat preceding blanks, up to tab_count. + - input text: facilitate patterns like if (InputText(..., obj.get_string_ref()) { obj.set_string(...); } relying on internally held buffer. + - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). + - input text multi-line: support for cut/paste without selection (cut/paste the current line) + - input text multi-line: line numbers? status bar? (follow up on #200) + - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) + - input text multi-line: better horizontal scrolling support (#383, #1224) + - input text multi-line: single call to AddText() should be coarse clipped on InputTextEx() end. + - 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 + + - layout: helper or a way to express ImGui::SameLine(ImGui::GetCursorStartPos().x + ImGui::CalcItemWidth() + ImGui::GetStyle().ItemInnerSpacing.x); in a simpler manner. + - layout, font: horizontal tab support, A) text mode: forward only tabs (e.g. every 4 characters/N pixels from pos x1), B) manual mode: explicit tab stops acting as mini columns, no clipping (for menu items, many kind of uses, also vaguely relate to #267, #395) + - layout: horizontal layout helper (#97) + - layout: horizontal flow until no space left (#404) + - 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. + - layout: vertical alignment of mixed height items (e.g. buttons) within a same line (#1284) + - layout: null layout mode were items are not rendered but user can query GetItemRectMin()/Max/Size. + - layout: (R&D) local multi-pass layout mode. + - layout: (R&D) bind authored layout data (created by an off-line tool), items fetch their pos/size at submission, self-optimize data structures to stable linear access. + + - group: BeginGroup() needs a border option. (~#1496) + - group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable? + - group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550) + +!- color: the color conversion helpers/types are a mess and needs sorting out. + - color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h + + - plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not! + - plot: PlotLines() should use the polygon-stroke facilities, less vertices (currently issues with averaging normals) + - 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: option/feature: draw the zero line + - plot: option/feature: draw grid, vertical markers + - plot: option/feature: draw unit + - 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) + + - clipper: ability to disable the clipping through a simple flag/bool. + - clipper: ability to run without knowing full count in advance. + - clipper: horizontal clipping support. (#2580) + + - separator: expose flags (#759) + - separator: take indent into consideration (optional) + - separator: width, thickness, centering (#1643) + - splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) + + - docking: merge docking branch (#2109) + - docking: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304) + - docking: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8) + - docking: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode? + - docking: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions. + - docking: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished. + - docking: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized. + - docking: B~ central node resizing behavior incorrect. + - docking: B: changing title font/style per-window is not supported as dock nodes are created in NewFrame. + - docking: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary) + - docking: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level? + - docking: B- single visible node part of a hidden split hierarchy (OnlyNodeWithWindows != NULL) should show a normal title bar (not a tab bar) + - docking: B~ SetNextWindowDock() calls (with conditional) -> defer everything to DockContextUpdate (repro: Documents->[X]Windows->Dock 1 elsewhere->Click Redock All + - docking: B~ tidy up tab list popup buttons features (available with manual tab-bar, see ImGuiTabBarFlags_NoTabListPopupButton code, not used by docking nodes) + - docking: B- SetNextWindowDockId(0) with a second Begin() in the frame will asserts + - docking: B: resize grip drawn in host window typically appears under scrollbar. + - docking: B: resize grip auto-resize on multiple node hierarchy doesn't make much sense or should be improved? + - docking: B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4) + - docking: B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.) + - docking: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff. + - docking: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar() + - docking: B- tab bar: make selected tab always shows its full title? + - docking: B- hide close button on single tab bar? + - docking: B- nav: design interactions so nav controls can dock/undock + - docking: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?) + - docking: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node! + - docking: B- allow dragging a non-floating dock node by clicking on the title-bar-looking section (not just the collapse/menu button) + - docking: B- option to remember undocked window size? (instead of keeping their docked size) (relate to #2104) + - docking: C- nav: CTRL+TAB highlighting tabs shows the mismatch between focus-stack and tab-order (not visible in VS because it doesn't highlight the tabs) + - docking: C- after a dock/undock, the Scrollbar Status update in Begin() should use an updated e.g. size_y_for_scrollbars to avoid a 1 frame scrollbar flicker. + + - tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work + - tabs: close button tends to overlap unsaved-document star + - tabs: consider showing the star at the same spot as the close button, like VS Code does. + - tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing. + - tabs: persistent order/focus in BeginTabBar() api (#261, #351) + - tabs: TabItem could honor SetNextItemWidth()? + - tabs: explicit api (even if internal) to cleanly manipulate tab order. + - tabs: Mouse wheel over tab bar could scroll? (#2702) + + - image/image button: misalignment on padded/bordered button? + - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? + - image button: not taking an explicit id can be problematic. (#2464, #1390) + - button: provide a button that looks framed. (?) + - slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see TempInputTextScalar) + - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() + - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946) + - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. + - slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign) + - slider: relative dragging? + precision dragging + - slider: step option (#1183) + - slider: style: fill % of the bar instead of positioning a drag. + - knob: rotating knob widget (#942) + - drag float: support for reversed drags (min > max) (removed is_locked, also see fdc526e) + - drag float: up/down axis + - drag float: power != 0.0f with current value being outside the range keeps the value stuck. + - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) + + - combo: use clipper: make it easier to disable clipper with a single flag. + - combo: flag for BeginCombo to not return true when unchanged (#1182) + - combo: a way/helper to customize the combo preview (#1658) -> exeperimental BeginComboPreview() + - combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203) + - listbox: multiple selection. + - listbox: unselect option (#1208) + - listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) (wip stash) + - listbox: user may want to initial scroll to focus on the one selected value? + - listbox: expose hovered item for a simplified ListBox api + - listbox: keyboard navigation. + - listbox: disable capturing mouse wheel if the listbox has no scrolling. (#1681) + - listbox: scrolling should track modified selection. + - listbox: future api should allow to enable horizontal scrolling (#2510) + +!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) + - modals: make modal title bar blink when trying to click outside the modal + - modals: technically speaking, we could make Begin() with ImGuiWindowFlags_Modal work without involving popup. May help untangle a few things, as modals are more like regular windows than popups. + - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) + - popups: clicking outside (to close popup) and holding shouldn't drag window below. + - popups: add variant using global identifier similar to Begin/End (#402) + - popups: border options. richer api like BeginChild() perhaps? (#197) + - popups: flags could be reworked to allow both mouse buttons as index (0..5 and as flags using higher-bit) allowing to or them. + - popups/modals: although it is sometimes convenient that popups/modals lifetime is owned by imgui, we could also a bool-owned-by-user api as long as Begin() return value testing is enforced. + + - tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction. + - tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. + - tooltip: tooltips with delay timers? or general timer policy? (instantaneous vs timed): IsItemHovered() with timer + implicit aabb-id for items with no ID. (#1485) + - tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers. + + - menus: menu bars inside modal windows are acting weird. + - status-bar: add a per-window status bar helper similar to what menu-bar does. + - shortcuts: local-style shortcut api, e.g. parse "&Save" + - shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu + - shortcuts: programmatically access shortcuts "Focus("&Save")) + - menus: hovering a disabled BeginMenu or MenuItem won't close another menu + - menus: menu-bar: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin) + - menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer. + - menus: could merge draw call in most cases (how about storing an optional aabb in ImDrawCmd to move the burden of merging in a single spot). + - menus: would be nice if the Selectable() supported horizontal alignment (must be given the equivalent of WorkRect.Max.x matching the position of the shortcut column) + + - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? + - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? + - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) + - tree node: tweak color scheme to distinguish headers from selected tree node (#581) + - tree node: leaf/non-leaf highlight mismatch. + - tree node: flag to disable formatting and/or detect "%s" + - tree node/opt: could avoid formatting when clipped (flag assuming we don't care about width/height, assume single line height? format only %s/%c to be able to count height?) + + - settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes? + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437) + - settings/persistence: helpers to make TreeNodeBehavior persist (even during dev!) - may need to store some semantic and/or data type in ImGuiStoragePair + + - style: better default styles. (#707) + - style: PushStyleVar: allow direct access to individual float X/Y elements. + - style: add a highlighted text color (for headers, etc.) + - style: border types: out-screen, in-screen, etc. (#447) + - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) + - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. + - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). + - style: global scale setting. + - style: FramePadding could be different for up vs down (#584) + - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle + - style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223) + - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. + - style editor: color child window height expressed in multiple of line height. + + - log: improve logging of ArrowButton, ListBox, TabItem + - log: carry on indent / tree depth when opening a child window + - log: enabling log ends up pushing and growing vertices buffers because we don't distinguish layout vs render clipping + - 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. + - log: obsolete LogButtons() all together. + - log: LogButtons() options for specifying depth and/or hiding depth slider + + - filters: set a current filter that tree node can automatically query to hide themselves + - filters: handle wild-cards (with implicit leading/trailing *), reg-exprs + - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) + + - drag and drop: fix/support/options for overlapping drag sources. + - drag and drop: focus drag target window on hold (even without open) + - drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725) + - drag and drop: drag source on a group object (would need e.g. an invisible button covering group in EndGroup) https://twitter.com/paniq/status/1121446364909535233 + - drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov. (see 2018/01/11 post in #143) + - drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725) + - drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637) + - drag and drop: make it easier and provide a demo to have tooltip both are source and target site, with a more detailed one on target site (tooltip ordering problem) + - drag and drop: demo with reordering nodes (in a list, or a tree node). (#143) + - drag and drop: test integrating with os drag and drop (make it easy to do a naive WM_DROPFILE integration) + - drag and drop: allow for multiple payload types. (#143) + - drag and drop: make payload optional? payload promise? (see 2018/01/11 post in #143) + - drag and drop: (#143) "both an in-process pointer and a promise to generate a serialized version, for whether the drag ends inside or outside the same process" + - drag and drop: feedback when hovering a region blocked by modal (mouse cursor "NO"?) + + - node/graph editors (#306) (also see https://github.com/ocornut/imgui/wiki#node-editors) + - pie menus patterns (#434) + - markup: simple markup language for color change? (#902) + + - text: selectable text (for copy) as a generic feature (ItemFlags?) + - text: proper alignment options in imgui_internal.h + - text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #? + - text: provided a framed text helper, e.g. https://pastebin.com/1Laxy8bT + - text: refactor TextUnformatted (or underlying function) to more explicitly request if we need width measurement or not + - text/layout/tabs: \t pulling position from base pos + step, or offset array (e.g. could be used in text edit, menus for simple icon+text alignment, etc.) + - text link/url button: underlined. should api expose an ID or use text contents as ID? which colors enum to use? + - text/wrapped: should be a more first-class citizen, e.g. wrapped text within a Selectable with known width. + - text/wrapped: custom separator for text wrapping. (#3002) + - text/wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + + - font: arbitrary line spacing. (#2945) + - font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype) + - font: free the Alpha buffer if user only requested RGBA. +!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). + - font: for the purpose of RenderTextEllipsis(), it might be useful that CalcTextSizeA() can ignore the trailing padding? + - font: a CalcTextHeight() helper could run faster than CalcTextSize().y + - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX + - font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data + - font: remove ID from CustomRect registration, it seems unnecessary! + - font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575) + - font: PushFontSize API (#1018) + - font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite? + - font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width + - font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs. + - font/demo: demonstrate use of ImFontGlyphRangesBuilder. + - font/atlas: add a missing Glyphs.reserve() + - font/atlas: incremental updates + - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. + - font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise + - font/draw: need to be able to specify wrap start position. + - font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349. + - font/draw: fix for drawing 16k+ visible characters in same call. + - font/draw: underline, squiggle line rendering helpers. + - font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line. + - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? + - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) + - font: fix AddRemapChar() to work before atlas has been built. + - font: support for unicode codepoints higher than 0xFFFF? (pr #2815) + - font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF. + - font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer? + - font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8? + + - nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?) + - nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ? + ! nav: never clear NavId on some setup (e.g. gamepad centric) + - nav: scroll up/down if possible when move request fails + - nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable. + - nav: code to focus child-window on restoring NavId appears to have issue: e.g. when focus change is implicit because of window closure. + - nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view? + - nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window" + - nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping(). + - nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch) + - nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) + - nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem + - nav: NavFlattened: init requests don't work properly on flattened siblings. + - nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings. + - nav: NavFlattened: ESC on a flattened child should select something. + - nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child. + - nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..). + - nav: simulate right-click or context activation? (SHIFT+F10) + - nav/popup: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys, default validation button, etc. + - nav/treenode: left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?) + - nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons. + - nav/menus: allow pressing Menu to leave a sub-menu. + - nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB) or last focused window menu bar? + - nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it? + - nav/menus: main menu bar currently cannot restore a NULL focus. Could save NavWindow at the time of being focused, similarly to what popup do? + - nav/menus: Alt,Up could open the first menu (e.g. "File") currently it tends to nav into the window/collapse menu. Do do that we would need custom transition? + - nav/windowing: configure fade-in/fade-out delay on Ctrl+Tab? + - nav/windowing: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering. + - nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied + - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) + + - viewport: make it possible to have no main/hosting viewport + - viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without + on a custom e.g. Win32 bindings. It prevents newly dragged-out viewports from taking the focus, which makes ALT+F4 more ambiguous. + - viewport: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front. + - viewport: with platform decoration enabled, platform may force constraint (e.g. minimum size) + - viewport: use getfocus/setfocus api to synchronize imgui<>platform focus better (e.g imgui-side ctrl-tab can focus os window, OS initial setup and alt-tab can focus imgui window etc.) + - viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for. + - viewport: implicit/fallback Debug window can hog a zombie viewport (harmless, noisy?) > could at least clear out the reference on a per session basis? + - viewport: need to clarify how to use GetMousePos() from a user point of view. + - platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport. + - platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set + - platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it). + - platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32). + + - inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors. + - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) + - inputs: support track pad style scrolling & slider edit. + - inputs/io: backspace and arrows in the context of a text input could use system repeat rate. + - inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808) + - inputs/scrolling: support for smooth scrolling (#2462, #2569) + + - misc: idle: expose "woken up" boolean (set by inputs) and/or animation time (for cursor blink) for backend to be able stop refreshing easily. + - misc: idle: if cursor blink if the _only_ visible animation, core imgui could rewrite vertex alpha to avoid CPU pass on ImGui:: calls. + - misc: idle: if cursor blink if the _only_ visible animation, could even expose a dirty rectangle that optionally can be leverage by some app to render in a smaller viewport, getting rid of much pixel shading cost. + - misc: no way to run a root-most GetID() with ImGui:: api since there's always a Debug window in the stack. (mentioned in #2960) + - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?) + - misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682) + - misc: use more size_t in public api? + - misc: possible compile-time support for string view/range instead of char* would e.g. facilitate usage with Rust (#683) + - misc: possible compile-time support for wchar_t instead of char*? + + - remote: make a system like RemoteImGui first-class citizen/project (#75) + + - demo: find a way to demonstrate textures in the examples application, as it such a common issue for new users. + - demo: demonstrate using PushStyleVar() in more details. + - demo: add vertical separator demo + - demo: add virtual scrolling example? + - demo: demonstrate Plot offset + - demo: window size constraint: square demo is broken when resizing from edges (#1975), would need to rework the callback system to solve this + + - examples: window minimize, maximize (#583) + - examples: provide a zero frame-rate/idle example. + - examples: dx11/dx12: try to use new swapchain blit models (#2970) + - backends: move to backends/ folder? + - backends: report it better when not able to create texture? + - backends: apple: example_apple should be using modern GL3. + - backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) + - backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900) + - backends: opengl: could use a single vertex buffer and glBufferSubData for uploads? + - backends: opengl: explicitly disable GL_STENCIL_TEST in bindings. + - backends: vulkan: viewport: support for synchronized swapping of multiple swap chains. + - backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0 + - backends: mscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42) + + - bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) + + - optimization: replace vsnprintf with stb_printf? using IMGUI_USE_STB_SPRINTF.(#1038) + - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. + - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) + - optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering. + - optimization: use another hash function than crc32, e.g. FNV1a + - 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 diff --git a/libultraship/libultraship/Lib/ImGui/examples/README.txt b/libultraship/libultraship/Lib/ImGui/examples/README.txt new file mode 100644 index 000000000..6db2f3c48 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/README.txt @@ -0,0 +1,9 @@ +See BACKENDS and EXAMPLES files in the docs/ folder, or on the web at: https://github.com/ocornut/imgui/tree/master/docs + +Backends = Helper code to facilitate integration with platforms/graphics api (used by Examples + should be used by your app). +Examples = Standalone applications showcasing integration with platforms/graphics api. + +Some Examples have extra README files in their respective directory, please check them too! + +Once Dear ImGui is running (in either examples or your own application/game/engine), +run and refer to ImGui::ShowDemoWindow() in imgui_demo.cpp for the end-user API. diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/README.md new file mode 100644 index 000000000..d6d812eab --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/README.md @@ -0,0 +1,36 @@ + +# Configuration + +Dear ImGui outputs 16-bit vertex indices by default. +Allegro doesn't support them natively, so we have two solutions: convert the indices manually in imgui_impl_allegro5.cpp, or compile dear imgui with 32-bit indices. +You can either modify imconfig.h that comes with Dear ImGui (easier), or set a C++ preprocessor option IMGUI_USER_CONFIG to find to a filename. +We are providing `imconfig_allegro5.h` that enables 32-bit indices. +Note that the backend supports _BOTH_ 16-bit and 32-bit indices, but 32-bit indices will be slightly faster as they won't require a manual conversion. + +# How to Build + +### On Ubuntu 14.04+ and macOS + +```bash +g++ -DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" -I .. -I ../.. main.cpp ../../backends/imgui_impl_allegro5.cpp ../../imgui*.cpp -lallegro -lallegro_main -lallegro_primitives -o allegro5_example +``` + +On macOS, install Allegro with homebrew: `brew install allegro`. + +### On Windows with Visual Studio's CLI + +You may install Allegro using vcpkg: +``` +git clone https://github.com/Microsoft/vcpkg +cd vcpkg +bootstrap-vcpkg.bat +vcpkg install allegro5 --triplet=x86-windows ; for win32 +vcpkg install allegro5 --triplet=x64-windows ; for win64 +vcpkg integrate install ; register include / libs in Visual Studio +``` + +Build: +``` +set ALLEGRODIR=path_to_your_allegro5_folder +cl /Zi /MD /I %ALLEGRODIR%\include /DIMGUI_USER_CONFIG=\"examples/example_allegro5/imconfig_allegro5.h\" /I .. /I ..\.. main.cpp ..\..\backends\imgui_impl_allegro5.cpp ..\..\imgui*.cpp /link /LIBPATH:%ALLEGRODIR%\lib allegro-5.0.10-monolith-md.lib user32.lib +``` diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj new file mode 100644 index 000000000..69b0ece30 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj @@ -0,0 +1,180 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {73F235B5-7D31-4FC6-8682-DDC5A097B9C1} + example_allegro5 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + + + true + %(AdditionalLibraryDirectories) + opengl32.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + + + true + %(AdditionalLibraryDirectories) + opengl32.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + false + + + true + true + true + %(AdditionalLibraryDirectories) + opengl32.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + false + + + true + true + true + %(AdditionalLibraryDirectories) + opengl32.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj.filters new file mode 100644 index 000000000..7fea78b3c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/example_allegro5.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + imgui + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/imconfig_allegro5.h b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/imconfig_allegro5.h new file mode 100644 index 000000000..35afa67fd --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/imconfig_allegro5.h @@ -0,0 +1,11 @@ +//----------------------------------------------------------------------------- +// COMPILE-TIME OPTIONS FOR DEAR IMGUI ALLEGRO 5 EXAMPLE +// See imconfig.h for the full template +// Because Allegro doesn't support 16-bit vertex indices, we enable the compile-time option of imgui to use 32-bit indices +//----------------------------------------------------------------------------- + +#pragma once + +// Use 32-bit vertex indices because Allegro doesn't support 16-bit ones +// This allows us to avoid converting vertices format at runtime +#define ImDrawIdx int diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/main.cpp new file mode 100644 index 000000000..6306fdce3 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_allegro5/main.cpp @@ -0,0 +1,145 @@ +// Dear ImGui: standalone example application for Allegro 5 +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// On Windows, you can install Allegro5 using vcpkg: +// git clone https://github.com/Microsoft/vcpkg +// cd vcpkg +// bootstrap - vcpkg.bat +// vcpkg install allegro5 --triplet=x86-windows ; for win32 +// vcpkg install allegro5 --triplet=x64-windows ; for win64 +// vcpkg integrate install ; register include and libs in Visual Studio + +#include +#include +#include +#include "imgui.h" +#include "imgui_impl_allegro5.h" + +int main(int, char**) +{ + // Setup Allegro + al_init(); + al_install_keyboard(); + al_install_mouse(); + al_init_primitives_addon(); + al_set_new_display_flags(ALLEGRO_RESIZABLE); + ALLEGRO_DISPLAY* display = al_create_display(1280, 720); + al_set_window_title(display, "Dear ImGui Allegro 5 example"); + ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplAllegro5_Init(display); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool running = true; + while (running) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + ALLEGRO_EVENT ev; + while (al_get_next_event(queue, &ev)) + { + ImGui_ImplAllegro5_ProcessEvent(&ev); + if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + running = false; + if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) + { + ImGui_ImplAllegro5_InvalidateDeviceObjects(); + al_acknowledge_resize(display); + ImGui_ImplAllegro5_CreateDeviceObjects(); + } + } + + // Start the Dear ImGui frame + ImGui_ImplAllegro5_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + al_clear_to_color(al_map_rgba_f(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w)); + ImGui_ImplAllegro5_RenderDrawData(ImGui::GetDrawData()); + al_flip_display(); + } + + // Cleanup + ImGui_ImplAllegro5_Shutdown(); + ImGui::DestroyContext(); + al_destroy_event_queue(queue); + al_destroy_display(display); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/CMakeLists.txt b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/CMakeLists.txt new file mode 100644 index 000000000..63531f4dc --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.6) + +project(ImGuiExample) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_library(${CMAKE_PROJECT_NAME} SHARED + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_demo.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_draw.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_tables.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../imgui_widgets.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../backends/imgui_impl_android.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../backends/imgui_impl_opengl3.cpp + ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c +) + +set(CMAKE_SHARED_LINKER_FLAGS + "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate" +) + +target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE + IMGUI_IMPL_OPENGL_ES3 +) + +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../backends + ${ANDROID_NDK}/sources/android/native_app_glue +) + +target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE + android + EGL + GLESv3 + log +) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/.gitignore b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/.gitignore new file mode 100644 index 000000000..3c7a61910 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/.gitignore @@ -0,0 +1,12 @@ +.cxx +.externalNativeBuild +build/ +*.iml + +.idea +.gradle +local.properties + +# Android Studio puts a Gradle wrapper here, that we don't want: +gradle/ +gradlew* diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/build.gradle b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/build.gradle new file mode 100644 index 000000000..aa7f0eadd --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 29 + buildToolsVersion "30.0.3" + ndkVersion "21.4.7075529" + defaultConfig { + applicationId "imgui.example.android" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') + } + } + + externalNativeBuild { + cmake { + path "../../CMakeLists.txt" + } + } +} +repositories { + mavenCentral() +} +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/AndroidManifest.xml b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..c4009e529 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/java/MainActivity.kt b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/java/MainActivity.kt new file mode 100644 index 000000000..896a88c8b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/app/src/main/java/MainActivity.kt @@ -0,0 +1,40 @@ +package imgui.example.android + +import android.app.NativeActivity +import android.os.Bundle +import android.content.Context +import android.view.inputmethod.InputMethodManager +import android.view.KeyEvent +import java.util.concurrent.LinkedBlockingQueue + +class MainActivity : NativeActivity() { + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + fun showSoftInput() { + val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.showSoftInput(this.window.decorView, 0) + } + + fun hideSoftInput() { + val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(this.window.decorView.windowToken, 0) + } + + // Queue for the Unicode characters to be polled from native code (via pollUnicodeChar()) + private var unicodeCharacterQueue: LinkedBlockingQueue = LinkedBlockingQueue() + + // We assume dispatchKeyEvent() of the NativeActivity is actually called for every + // KeyEvent and not consumed by any View before it reaches here + override fun dispatchKeyEvent(event: KeyEvent): Boolean { + if (event.action == KeyEvent.ACTION_DOWN) { + unicodeCharacterQueue.offer(event.getUnicodeChar(event.metaState)) + } + return super.dispatchKeyEvent(event) + } + + fun pollUnicodeChar(): Int { + return unicodeCharacterQueue.poll() ?: 0 + } +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/build.gradle b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/build.gradle new file mode 100644 index 000000000..59f9c78e4 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/build.gradle @@ -0,0 +1,24 @@ +buildscript { + ext.kotlin_version = '1.4.31' + repositories { + google() + mavenCentral() + + } + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/settings.gradle b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/settings.gradle new file mode 100644 index 000000000..e7b4def49 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/android/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/main.cpp new file mode 100644 index 000000000..5ab690348 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_android_opengl3/main.cpp @@ -0,0 +1,369 @@ +// dear imgui: standalone example application for Android + OpenGL ES 3 +// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include "imgui.h" +#include "imgui_impl_android.h" +#include "imgui_impl_opengl3.h" +#include +#include +#include +#include +#include + +// Data +static EGLDisplay g_EglDisplay = EGL_NO_DISPLAY; +static EGLSurface g_EglSurface = EGL_NO_SURFACE; +static EGLContext g_EglContext = EGL_NO_CONTEXT; +static struct android_app* g_App = NULL; +static bool g_Initialized = false; +static char g_LogTag[] = "ImGuiExample"; + +// Forward declarations of helper functions +static int ShowSoftKeyboardInput(); +static int PollUnicodeChars(); +static int GetAssetData(const char* filename, void** out_data); + +void init(struct android_app* app) +{ + if (g_Initialized) + return; + + g_App = app; + ANativeWindow_acquire(g_App->window); + + // Initialize EGL + // This is mostly boilerplate code for EGL... + { + g_EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (g_EglDisplay == EGL_NO_DISPLAY) + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "%s", "eglGetDisplay(EGL_DEFAULT_DISPLAY) returned EGL_NO_DISPLAY"); + + if (eglInitialize(g_EglDisplay, 0, 0) != EGL_TRUE) + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "%s", "eglInitialize() returned with an error"); + + const EGLint egl_attributes[] = { EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; + EGLint num_configs = 0; + if (eglChooseConfig(g_EglDisplay, egl_attributes, nullptr, 0, &num_configs) != EGL_TRUE) + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "%s", "eglChooseConfig() returned with an error"); + if (num_configs == 0) + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "%s", "eglChooseConfig() returned 0 matching config"); + + // Get the first matching config + EGLConfig egl_config; + eglChooseConfig(g_EglDisplay, egl_attributes, &egl_config, 1, &num_configs); + EGLint egl_format; + eglGetConfigAttrib(g_EglDisplay, egl_config, EGL_NATIVE_VISUAL_ID, &egl_format); + ANativeWindow_setBuffersGeometry(g_App->window, 0, 0, egl_format); + + const EGLint egl_context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; + g_EglContext = eglCreateContext(g_EglDisplay, egl_config, EGL_NO_CONTEXT, egl_context_attributes); + + if (g_EglContext == EGL_NO_CONTEXT) + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "%s", "eglCreateContext() returned EGL_NO_CONTEXT"); + + g_EglSurface = eglCreateWindowSurface(g_EglDisplay, egl_config, g_App->window, NULL); + eglMakeCurrent(g_EglDisplay, g_EglSurface, g_EglSurface, g_EglContext); + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + + // Disable loading/saving of .ini file from disk. + // FIXME: Consider using LoadIniSettingsFromMemory() / SaveIniSettingsToMemory() to save in appropriate location for Android. + io.IniFilename = NULL; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplAndroid_Init(g_App->window); + ImGui_ImplOpenGL3_Init("#version 300 es"); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + // - Android: The TTF files have to be placed into the assets/ directory (android/app/src/main/assets), we use our GetAssetData() helper to retrieve them. + + // We load the default font with increased size to improve readability on many devices with "high" DPI. + // FIXME: Put some effort into DPI awareness. + // Important: when calling AddFontFromMemoryTTF(), ownership of font_data is transfered by Dear ImGui by default (deleted is handled by Dear ImGui), unless we set FontDataOwnedByAtlas=false in ImFontConfig + ImFontConfig font_cfg; + font_cfg.SizePixels = 22.0f; + io.Fonts->AddFontDefault(&font_cfg); + //void* font_data; + //int font_data_size; + //ImFont* font; + //font_data_size = GetAssetData("Roboto-Medium.ttf", &font_data); + //font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 16.0f); + //IM_ASSERT(font != NULL); + //font_data_size = GetAssetData("Cousine-Regular.ttf", &font_data); + //font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 15.0f); + //IM_ASSERT(font != NULL); + //font_data_size = GetAssetData("DroidSans.ttf", &font_data); + //font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 16.0f); + //IM_ASSERT(font != NULL); + //font_data_size = GetAssetData("ProggyTiny.ttf", &font_data); + //font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 10.0f); + //IM_ASSERT(font != NULL); + //font_data_size = GetAssetData("ArialUni.ttf", &font_data); + //font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Arbitrary scale-up + // FIXME: Put some effort into DPI awareness + ImGui::GetStyle().ScaleAllSizes(3.0f); + + g_Initialized = true; +} + +void tick() +{ + ImGuiIO& io = ImGui::GetIO(); + if (g_EglDisplay == EGL_NO_DISPLAY) + return; + + // Our state + static bool show_demo_window = true; + static bool show_another_window = false; + static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Poll Unicode characters via JNI + // FIXME: do not call this every frame because of JNI overhead + PollUnicodeChars(); + + // Open on-screen (soft) input if requested by Dear ImGui + static bool WantTextInputLast = false; + if (io.WantTextInput && !WantTextInputLast) + ShowSoftKeyboardInput(); + WantTextInputLast = io.WantTextInput; + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplAndroid_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + eglSwapBuffers(g_EglDisplay, g_EglSurface); +} + +void shutdown() +{ + if (!g_Initialized) + return; + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplAndroid_Shutdown(); + ImGui::DestroyContext(); + + if (g_EglDisplay != EGL_NO_DISPLAY) + { + eglMakeCurrent(g_EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (g_EglContext != EGL_NO_CONTEXT) + eglDestroyContext(g_EglDisplay, g_EglContext); + + if (g_EglSurface != EGL_NO_SURFACE) + eglDestroySurface(g_EglDisplay, g_EglSurface); + + eglTerminate(g_EglDisplay); + } + + g_EglDisplay = EGL_NO_DISPLAY; + g_EglContext = EGL_NO_CONTEXT; + g_EglSurface = EGL_NO_SURFACE; + ANativeWindow_release(g_App->window); + + g_Initialized = false; +} + +static void handleAppCmd(struct android_app* app, int32_t appCmd) +{ + switch (appCmd) + { + case APP_CMD_SAVE_STATE: + break; + case APP_CMD_INIT_WINDOW: + init(app); + break; + case APP_CMD_TERM_WINDOW: + shutdown(); + break; + case APP_CMD_GAINED_FOCUS: + break; + case APP_CMD_LOST_FOCUS: + break; + } +} + +static int32_t handleInputEvent(struct android_app* app, AInputEvent* inputEvent) +{ + return ImGui_ImplAndroid_HandleInputEvent(inputEvent); +} + +void android_main(struct android_app* app) +{ + app->onAppCmd = handleAppCmd; + app->onInputEvent = handleInputEvent; + + while (true) + { + int out_events; + struct android_poll_source* out_data; + + // Poll all events. If the app is not visible, this loop blocks until g_Initialized == true. + while (ALooper_pollAll(g_Initialized ? 0 : -1, NULL, &out_events, (void**)&out_data) >= 0) + { + // Process one event + if (out_data != NULL) + out_data->process(app, out_data); + + // Exit the app by returning from within the infinite loop + if (app->destroyRequested != 0) + { + // shutdown() should have been called already while processing the + // app command APP_CMD_TERM_WINDOW. But we play save here + if (!g_Initialized) + shutdown(); + + return; + } + } + + // Initiate a new frame + tick(); + } +} + +// Unfortunately, there is no way to show the on-screen input from native code. +// Therefore, we call ShowSoftKeyboardInput() of the main activity implemented in MainActivity.kt via JNI. +static int ShowSoftKeyboardInput() +{ + JavaVM* java_vm = g_App->activity->vm; + JNIEnv* java_env = NULL; + + jint jni_return = java_vm->GetEnv((void**)&java_env, JNI_VERSION_1_6); + if (jni_return == JNI_ERR) + return -1; + + jni_return = java_vm->AttachCurrentThread(&java_env, NULL); + if (jni_return != JNI_OK) + return -2; + + jclass native_activity_clazz = java_env->GetObjectClass(g_App->activity->clazz); + if (native_activity_clazz == NULL) + return -3; + + jmethodID method_id = java_env->GetMethodID(native_activity_clazz, "showSoftInput", "()V"); + if (method_id == NULL) + return -4; + + java_env->CallVoidMethod(g_App->activity->clazz, method_id); + + jni_return = java_vm->DetachCurrentThread(); + if (jni_return != JNI_OK) + return -5; + + return 0; +} + +// Unfortunately, the native KeyEvent implementation has no getUnicodeChar() function. +// Therefore, we implement the processing of KeyEvents in MainActivity.kt and poll +// the resulting Unicode characters here via JNI and send them to Dear ImGui. +static int PollUnicodeChars() +{ + JavaVM* java_vm = g_App->activity->vm; + JNIEnv* java_env = NULL; + + jint jni_return = java_vm->GetEnv((void**)&java_env, JNI_VERSION_1_6); + if (jni_return == JNI_ERR) + return -1; + + jni_return = java_vm->AttachCurrentThread(&java_env, NULL); + if (jni_return != JNI_OK) + return -2; + + jclass native_activity_clazz = java_env->GetObjectClass(g_App->activity->clazz); + if (native_activity_clazz == NULL) + return -3; + + jmethodID method_id = java_env->GetMethodID(native_activity_clazz, "pollUnicodeChar", "()I"); + if (method_id == NULL) + return -4; + + // Send the actual characters to Dear ImGui + ImGuiIO& io = ImGui::GetIO(); + jint unicode_character; + while ((unicode_character = java_env->CallIntMethod(g_App->activity->clazz, method_id)) != 0) + io.AddInputCharacter(unicode_character); + + jni_return = java_vm->DetachCurrentThread(); + if (jni_return != JNI_OK) + return -5; + + return 0; +} + +// Helper to retrieve data placed into the assets/ directory (android/app/src/main/assets) +static int GetAssetData(const char* filename, void** outData) +{ + int num_bytes = 0; + AAsset* asset_descriptor = AAssetManager_open(g_App->activity->assetManager, filename, AASSET_MODE_BUFFER); + if (asset_descriptor) + { + num_bytes = AAsset_getLength(asset_descriptor); + *outData = IM_ALLOC(num_bytes); + int64_t num_bytes_read = AAsset_read(asset_descriptor, *outData, num_bytes); + AAsset_close(asset_descriptor); + IM_ASSERT(num_bytes_read == num_bytes); + } + return num_bytes; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/README.md new file mode 100644 index 000000000..c13df2f1c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/README.md @@ -0,0 +1,10 @@ +# iOS / OSX Metal example + +## Introduction + +This example shows how to integrate Dear ImGui with Metal. It is based on the "cross-platform" game template provided with Xcode as of Xcode 9. + +Consider basing your work off the example_glfw_metal/ or example_sdl_metal/ examples. They are better supported and will be portable unlike this one. + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj new file mode 100644 index 000000000..4bb4fc288 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj @@ -0,0 +1,503 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; }; + 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; + 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; + 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; }; + 8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */; }; + 8309BDA5253CCC070045E2A1 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDA0253CCBC10045E2A1 /* main.mm */; }; + 8309BDA8253CCC080045E2A1 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDA0253CCBC10045E2A1 /* main.mm */; }; + 8309BDBB253CCCAD0045E2A1 /* imgui_impl_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */; }; + 8309BDBE253CCCB60045E2A1 /* imgui_impl_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */; }; + 8309BDBF253CCCB60045E2A1 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */; }; + 8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8309BDC5253CCCFE0045E2A1 /* AppKit.framework */; }; + 8309BDFC253CDAB30045E2A1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8309BDF7253CDAAE0045E2A1 /* LaunchScreen.storyboard */; }; + 8309BE04253CDAB60045E2A1 /* MainMenu.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8309BDFA253CDAAE0045E2A1 /* MainMenu.storyboard */; }; + 83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9E420EB46B900295997 /* Metal.framework */; }; + 83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9E620EB46BD00295997 /* MetalKit.framework */; }; + 83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9EA20EB471700295997 /* MetalKit.framework */; }; + 83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9EB20EB471700295997 /* Metal.framework */; }; + 83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0120EB54E700295997 /* imgui_draw.cpp */; }; + 83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0120EB54E700295997 /* imgui_draw.cpp */; }; + 83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0220EB54E700295997 /* imgui_demo.cpp */; }; + 83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0220EB54E700295997 /* imgui_demo.cpp */; }; + 83BBEA0920EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; }; + 83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; + 07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; + 07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; + 5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; + 8307E7C420E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8307E7DA20E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 8309BDA0253CCBC10045E2A1 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; + 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_metal.mm; path = ../../backends/imgui_impl_metal.mm; sourceTree = ""; }; + 8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../../backends/imgui_impl_osx.mm; sourceTree = ""; }; + 8309BDC5253CCCFE0045E2A1 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 8309BDF7253CDAAE0045E2A1 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 8309BDF8253CDAAE0045E2A1 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; + 8309BDFA253CDAAE0045E2A1 /* MainMenu.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MainMenu.storyboard; sourceTree = ""; }; + 8309BDFB253CDAAE0045E2A1 /* Info-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = ""; }; + 83BBE9E420EB46B900295997 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; }; + 83BBE9E620EB46BD00295997 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = DEVELOPER_DIR; }; + 83BBE9E820EB46C100295997 /* ModelIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ModelIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/ModelIO.framework; sourceTree = DEVELOPER_DIR; }; + 83BBE9EA20EB471700295997 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; + 83BBE9EB20EB471700295997 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + 83BBE9EE20EB471C00295997 /* ModelIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ModelIO.framework; path = System/Library/Frameworks/ModelIO.framework; sourceTree = SDKROOT; }; + 83BBEA0020EB54E700295997 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 83BBEA0120EB54E700295997 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = ""; }; + 83BBEA0220EB54E700295997 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = ""; }; + 83BBEA0320EB54E700295997 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 83BBEA0420EB54E700295997 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8307E7C120E9F9C900473790 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */, + 83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */, + 83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8307E7D720E9F9C900473790 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */, + 83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */, + 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */, + 83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8307E7B520E9F9C700473790 = { + isa = PBXGroup; + children = ( + 83BBE9F020EB544400295997 /* imgui */, + 8309BD9E253CCBA70045E2A1 /* example */, + 8307E7C520E9F9C900473790 /* Products */, + 83BBE9E320EB46B800295997 /* Frameworks */, + ); + sourceTree = ""; + }; + 8307E7C520E9F9C900473790 /* Products */ = { + isa = PBXGroup; + children = ( + 8307E7C420E9F9C900473790 /* example_apple_metal.app */, + 8307E7DA20E9F9C900473790 /* example_apple_metal.app */, + ); + name = Products; + sourceTree = ""; + }; + 8309BD9E253CCBA70045E2A1 /* example */ = { + isa = PBXGroup; + children = ( + 8309BDF6253CDAAE0045E2A1 /* iOS */, + 8309BDF9253CDAAE0045E2A1 /* macOS */, + 8309BDA0253CCBC10045E2A1 /* main.mm */, + ); + name = example; + sourceTree = ""; + }; + 8309BDF6253CDAAE0045E2A1 /* iOS */ = { + isa = PBXGroup; + children = ( + 8309BDF7253CDAAE0045E2A1 /* LaunchScreen.storyboard */, + 8309BDF8253CDAAE0045E2A1 /* Info-iOS.plist */, + ); + path = iOS; + sourceTree = ""; + }; + 8309BDF9253CDAAE0045E2A1 /* macOS */ = { + isa = PBXGroup; + children = ( + 8309BDFA253CDAAE0045E2A1 /* MainMenu.storyboard */, + 8309BDFB253CDAAE0045E2A1 /* Info-macOS.plist */, + ); + path = macOS; + sourceTree = ""; + }; + 83BBE9E320EB46B800295997 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 05318E0E274C397200A8DE2E /* GameController.framework */, + 8309BDC5253CCCFE0045E2A1 /* AppKit.framework */, + 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */, + 83BBE9EE20EB471C00295997 /* ModelIO.framework */, + 83BBE9EB20EB471700295997 /* Metal.framework */, + 83BBE9EA20EB471700295997 /* MetalKit.framework */, + 83BBE9E820EB46C100295997 /* ModelIO.framework */, + 83BBE9E620EB46BD00295997 /* MetalKit.framework */, + 83BBE9E420EB46B900295997 /* Metal.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 83BBE9F020EB544400295997 /* imgui */ = { + isa = PBXGroup; + children = ( + 5079822D257677DB0038A28D /* imgui_tables.cpp */, + 8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */, + 8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */, + 83BBEA0420EB54E700295997 /* imconfig.h */, + 83BBEA0320EB54E700295997 /* imgui.cpp */, + 83BBEA0020EB54E700295997 /* imgui.h */, + 83BBEA0220EB54E700295997 /* imgui_demo.cpp */, + 83BBEA0120EB54E700295997 /* imgui_draw.cpp */, + 07A82ED62139413C0078D120 /* imgui_internal.h */, + 07A82ED72139413C0078D120 /* imgui_widgets.cpp */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8307E7C320E9F9C900473790 /* example_apple_metal_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8307E7F020E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_ios" */; + buildPhases = ( + 8307E7C020E9F9C900473790 /* Sources */, + 8307E7C120E9F9C900473790 /* Frameworks */, + 8307E7C220E9F9C900473790 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = example_apple_metal_ios; + productName = "imguiex iOS"; + productReference = 8307E7C420E9F9C900473790 /* example_apple_metal.app */; + productType = "com.apple.product-type.application"; + }; + 8307E7D920E9F9C900473790 /* example_apple_metal_macos */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8307E7F320E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_macos" */; + buildPhases = ( + 8307E7D620E9F9C900473790 /* Sources */, + 8307E7D720E9F9C900473790 /* Frameworks */, + 8307E7D820E9F9C900473790 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = example_apple_metal_macos; + productName = "imguiex macOS"; + productReference = 8307E7DA20E9F9C900473790 /* example_apple_metal.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8307E7B620E9F9C700473790 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1200; + ORGANIZATIONNAME = "Warren Moore"; + TargetAttributes = { + 8307E7C320E9F9C900473790 = { + CreatedOnToolsVersion = 9.4.1; + ProvisioningStyle = Automatic; + }; + 8307E7D920E9F9C900473790 = { + CreatedOnToolsVersion = 9.4.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 8307E7B920E9F9C700473790 /* Build configuration list for PBXProject "example_apple_metal" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8307E7B520E9F9C700473790; + productRefGroup = 8307E7C520E9F9C900473790 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8307E7C320E9F9C900473790 /* example_apple_metal_ios */, + 8307E7D920E9F9C900473790 /* example_apple_metal_macos */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8307E7C220E9F9C900473790 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BDFC253CDAB30045E2A1 /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8307E7D820E9F9C900473790 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BE04253CDAB60045E2A1 /* MainMenu.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8307E7C020E9F9C900473790 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BDBB253CCCAD0045E2A1 /* imgui_impl_metal.mm in Sources */, + 83BBEA0920EB54E700295997 /* imgui.cpp in Sources */, + 83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */, + 83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */, + 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */, + 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */, + 8309BDA5253CCC070045E2A1 /* main.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8307E7D620E9F9C900473790 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8309BDBE253CCCB60045E2A1 /* imgui_impl_metal.mm in Sources */, + 8309BDBF253CCCB60045E2A1 /* imgui_impl_osx.mm in Sources */, + 83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */, + 83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */, + 83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */, + 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */, + 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */, + 8309BDA8253CCC080045E2A1 /* main.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 8307E7EE20E9F9C900473790 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + }; + name = Debug; + }; + 8307E7EF20E9F9C900473790 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + }; + name = Release; + }; + 8307E7F120E9F9C900473790 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios"; + PRODUCT_NAME = example_apple_metal; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../**"; + }; + name = Debug; + }; + 8307E7F220E9F9C900473790 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios"; + PRODUCT_NAME = example_apple_metal; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../**"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8307E7F420E9F9C900473790 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.12; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos"; + PRODUCT_NAME = example_apple_metal; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../**"; + }; + name = Debug; + }; + 8307E7F520E9F9C900473790 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.12; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos"; + PRODUCT_NAME = example_apple_metal; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../**"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8307E7B920E9F9C700473790 /* Build configuration list for PBXProject "example_apple_metal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8307E7EE20E9F9C900473790 /* Debug */, + 8307E7EF20E9F9C900473790 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8307E7F020E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8307E7F120E9F9C900473790 /* Debug */, + 8307E7F220E9F9C900473790 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8307E7F320E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_macos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8307E7F420E9F9C900473790 /* Debug */, + 8307E7F520E9F9C900473790 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8307E7B620E9F9C700473790 /* Project object */; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/Info-iOS.plist b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/Info-iOS.plist new file mode 100644 index 000000000..93ef078d0 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/Info-iOS.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + imgui + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + metal + + UIRequiresFullScreen + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/LaunchScreen.storyboard b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/LaunchScreen.storyboard new file mode 100644 index 000000000..12c52cfbf --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/iOS/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/Info-macOS.plist b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/Info-macOS.plist new file mode 100644 index 000000000..6f4a2b236 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/Info-macOS.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + imgui + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSMainStoryboardFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/MainMenu.storyboard b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/MainMenu.storyboard new file mode 100644 index 000000000..38ad432b0 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/macOS/MainMenu.storyboard @@ -0,0 +1,93 @@ + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/main.mm b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/main.mm new file mode 100644 index 000000000..d92fc6b3c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_metal/main.mm @@ -0,0 +1,343 @@ +// Dear ImGui: standalone example application for OSX + Metal. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#import + +#if TARGET_OS_OSX +#import +#else +#import +#endif + +#import +#import + +#include "imgui.h" +#include "imgui_impl_metal.h" +#if TARGET_OS_OSX +#include "imgui_impl_osx.h" +@interface AppViewController : NSViewController +@end +#else +@interface AppViewController : UIViewController +@end +#endif + +@interface AppViewController () +@property (nonatomic, readonly) MTKView *mtkView; +@property (nonatomic, strong) id device; +@property (nonatomic, strong) id commandQueue; +@end + +//----------------------------------------------------------------------------------- +// AppViewController +//----------------------------------------------------------------------------------- + +@implementation AppViewController + +-(instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + + _device = MTLCreateSystemDefaultDevice(); + _commandQueue = [_device newCommandQueue]; + + if (!self.device) + { + NSLog(@"Metal is not supported"); + abort(); + } + + // Setup Dear ImGui context + // FIXME: This example doesn't have proper cleanup... + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Renderer backend + ImGui_ImplMetal_Init(_device); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + return self; +} + +-(MTKView *)mtkView +{ + return (MTKView *)self.view; +} + +-(void)loadView +{ + self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 720)]; +} + +-(void)viewDidLoad +{ + [super viewDidLoad]; + + self.mtkView.device = self.device; + self.mtkView.delegate = self; + +#if TARGET_OS_OSX + // Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view + NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect + options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways + owner:self + userInfo:nil]; + [self.view addTrackingArea:trackingArea]; + + ImGui_ImplOSX_Init(self.view); + +#endif +} + +-(void)drawInMTKView:(MTKView*)view +{ + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize.x = view.bounds.size.width; + io.DisplaySize.y = view.bounds.size.height; + +#if TARGET_OS_OSX + CGFloat framebufferScale = view.window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor; +#else + CGFloat framebufferScale = view.window.screen.scale ?: UIScreen.mainScreen.scale; +#endif + io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale); + + io.DeltaTime = 1 / float(view.preferredFramesPerSecond ?: 60); + + id commandBuffer = [self.commandQueue commandBuffer]; + + MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor; + if (renderPassDescriptor == nil) + { + [commandBuffer commit]; + return; + } + + // Start the Dear ImGui frame + ImGui_ImplMetal_NewFrame(renderPassDescriptor); +#if TARGET_OS_OSX + ImGui_ImplOSX_NewFrame(view); +#endif + ImGui::NewFrame(); + + // Our state (make them static = more or less global) as a convenience to keep the example terse. + static bool show_demo_window = true; + static bool show_another_window = false; + static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + [renderEncoder pushDebugGroup:@"Dear ImGui rendering"]; + ImGui_ImplMetal_RenderDrawData(draw_data, commandBuffer, renderEncoder); + [renderEncoder popDebugGroup]; + [renderEncoder endEncoding]; + + // Present + [commandBuffer presentDrawable:view.currentDrawable]; + [commandBuffer commit]; +} + +-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size +{ +} + +//----------------------------------------------------------------------------------- +// Input processing +//----------------------------------------------------------------------------------- + +#if TARGET_OS_OSX + +// Forward Mouse events to Dear ImGui OSX backend. +-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } + +#else + +// This touch mapping is super cheesy/hacky. We treat any touch on the screen +// as if it were a depressed left mouse button, and we don't bother handling +// multitouch correctly at all. This causes the "cursor" to behave very erratically +// when there are multiple active touches. But for demo purposes, single-touch +// interaction actually works surprisingly well. +-(void)updateIOWithTouchEvent:(UIEvent *)event +{ + UITouch *anyTouch = event.allTouches.anyObject; + CGPoint touchLocation = [anyTouch locationInView:self.view]; + ImGuiIO &io = ImGui::GetIO(); + io.AddMousePosEvent(touchLocation.x, touchLocation.y); + + BOOL hasActiveTouch = NO; + for (UITouch *touch in event.allTouches) + { + if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) + { + hasActiveTouch = YES; + break; + } + } + io.AddMouseButtonEvent(0, hasActiveTouch); +} + +-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self updateIOWithTouchEvent:event]; } +-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self updateIOWithTouchEvent:event]; } +-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self updateIOWithTouchEvent:event]; } +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self updateIOWithTouchEvent:event]; } + +#endif + +@end + +//----------------------------------------------------------------------------------- +// AppDelegate +//----------------------------------------------------------------------------------- + +#if TARGET_OS_OSX + +@interface AppDelegate : NSObject +@property (nonatomic, strong) NSWindow *window; +@end + +@implementation AppDelegate + +-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender +{ + return YES; +} + +-(instancetype)init +{ + if (self = [super init]) + { + NSViewController *rootViewController = [[AppViewController alloc] initWithNibName:nil bundle:nil]; + self.window = [[NSWindow alloc] initWithContentRect:NSZeroRect + styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable + backing:NSBackingStoreBuffered + defer:NO]; + self.window.contentViewController = rootViewController; + [self.window orderFront:self]; + [self.window center]; + [self.window becomeKeyWindow]; + } + return self; +} + +@end + +#else + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation AppDelegate + +-(BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + UIViewController *rootViewController = [[AppViewController alloc] init]; + self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; + return YES; +} + +@end + +#endif + +//----------------------------------------------------------------------------------- +// Application main() function +//----------------------------------------------------------------------------------- + +#if TARGET_OS_OSX + +int main(int argc, const char * argv[]) +{ + return NSApplicationMain(argc, argv); +} + +#else + +int main(int argc, char * argv[]) +{ + @autoreleasepool + { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} + +#endif diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj b/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj new file mode 100644 index 000000000..a168373d4 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj @@ -0,0 +1,332 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05E31B57274EF0360083FCB6 /* GameController.framework */; }; + 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82EDA213941D00078D120 /* imgui_widgets.cpp */; }; + 4080A99820B02D340036BA46 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A98A20B02CD90036BA46 /* main.mm */; }; + 4080A9A220B034280036BA46 /* imgui_impl_opengl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */; }; + 4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */; }; + 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A720B0343C0036BA46 /* imgui.cpp */; }; + 4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */; }; + 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */; }; + 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B220B034E40036BA46 /* Cocoa.framework */; }; + 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B420B034EA0036BA46 /* OpenGL.framework */; }; + 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822F257677FC0038A28D /* imgui_tables.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 4080A96920B029B00036BA46 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 05E31B57274EF0360083FCB6 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; + 07A82EDA213941D00078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; + 4080A96B20B029B00036BA46 /* example_osx_opengl2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_osx_opengl2; sourceTree = BUILT_PRODUCTS_DIR; }; + 4080A98A20B02CD90036BA46 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; }; + 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_impl_opengl2.cpp; path = ../../backends/imgui_impl_opengl2.cpp; sourceTree = ""; }; + 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../../backends/imgui_impl_osx.mm; sourceTree = ""; }; + 4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl2.h; path = ../../backends/imgui_impl_opengl2.h; sourceTree = ""; }; + 4080A9A120B034280036BA46 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../backends/imgui_impl_osx.h; sourceTree = ""; }; + 4080A9A520B0343C0036BA46 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; + 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = ""; }; + 4080A9A720B0343C0036BA46 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 4080A9A820B0343C0036BA46 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = ""; }; + 4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 5079822F257677FC0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4080A96820B029B00036BA46 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */, + 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */, + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4080A96220B029B00036BA46 = { + isa = PBXGroup; + children = ( + 5079822F257677FC0038A28D /* imgui_tables.cpp */, + 4080A9AC20B0343C0036BA46 /* imconfig.h */, + 4080A9A720B0343C0036BA46 /* imgui.cpp */, + 4080A9A820B0343C0036BA46 /* imgui.h */, + 07A82EDA213941D00078D120 /* imgui_widgets.cpp */, + 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */, + 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */, + 4080A9A520B0343C0036BA46 /* imgui_internal.h */, + 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */, + 4080A9A020B034280036BA46 /* imgui_impl_opengl2.h */, + 4080A9A120B034280036BA46 /* imgui_impl_osx.h */, + 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */, + 4080A98A20B02CD90036BA46 /* main.mm */, + 4080A96C20B029B00036BA46 /* Products */, + 4080A9B120B034E40036BA46 /* Frameworks */, + ); + sourceTree = ""; + }; + 4080A96C20B029B00036BA46 /* Products */ = { + isa = PBXGroup; + children = ( + 4080A96B20B029B00036BA46 /* example_osx_opengl2 */, + ); + name = Products; + sourceTree = ""; + }; + 4080A9B120B034E40036BA46 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 05E31B57274EF0360083FCB6 /* GameController.framework */, + 4080A9B420B034EA0036BA46 /* OpenGL.framework */, + 4080A9B220B034E40036BA46 /* Cocoa.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4080A96A20B029B00036BA46 /* example_osx_opengl2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl2" */; + buildPhases = ( + 4080A96720B029B00036BA46 /* Sources */, + 4080A96820B029B00036BA46 /* Frameworks */, + 4080A96920B029B00036BA46 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = example_osx_opengl2; + productName = example_osx_opengl2; + productReference = 4080A96B20B029B00036BA46 /* example_osx_opengl2 */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4080A96320B029B00036BA46 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = ImGui; + TargetAttributes = { + 4080A96A20B029B00036BA46 = { + CreatedOnToolsVersion = 9.3.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl2" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4080A96220B029B00036BA46; + productRefGroup = 4080A96C20B029B00036BA46 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4080A96A20B029B00036BA46 /* example_osx_opengl2 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 4080A96720B029B00036BA46 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4080A99820B02D340036BA46 /* main.mm in Sources */, + 4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */, + 4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */, + 4080A9A220B034280036BA46 /* imgui_impl_opengl2.cpp in Sources */, + 4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */, + 4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */, + 50798230257677FD0038A28D /* imgui_tables.cpp in Sources */, + 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4080A97020B029B00036BA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 4080A97120B029B00036BA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 4080A97320B029B00036BA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 10.12; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = ../..; + }; + name = Debug; + }; + 4080A97420B029B00036BA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 10.12; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = ../..; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4080A97020B029B00036BA46 /* Debug */, + 4080A97120B029B00036BA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4080A97320B029B00036BA46 /* Debug */, + 4080A97420B029B00036BA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4080A96320B029B00036BA46 /* Project object */; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/main.mm b/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/main.mm new file mode 100644 index 000000000..8d0ddd18a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_apple_opengl2/main.mm @@ -0,0 +1,271 @@ +// Dear ImGui: standalone example application for OSX + OpenGL2, using legacy fixed pipeline +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#import +#import +#import + +#include "imgui.h" +#include "imgui_impl_opengl2.h" +#include "imgui_impl_osx.h" + +//----------------------------------------------------------------------------------- +// AppView +//----------------------------------------------------------------------------------- + +@interface AppView : NSOpenGLView +{ + NSTimer* animationTimer; +} +@end + +@implementation AppView + +-(void)prepareOpenGL +{ + [super prepareOpenGL]; + +#ifndef DEBUG + GLint swapInterval = 1; + [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + if (swapInterval == 0) + NSLog(@"Error: Cannot set swap interval."); +#endif +} + +-(void)initialize +{ + // Setup Dear ImGui context + // FIXME: This example doesn't have proper cleanup... + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplOSX_Init(self); + ImGui_ImplOpenGL2_Init(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); +} + +-(void)updateAndDrawDemoView +{ + // Start the Dear ImGui frame + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplOSX_NewFrame(self); + ImGui::NewFrame(); + + // Our state (make them static = more or less global) as a convenience to keep the example terse. + static bool show_demo_window = true; + static bool show_another_window = false; + static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + + [[self openGLContext] makeCurrentContext]; + GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + glViewport(0, 0, width, height); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui_ImplOpenGL2_RenderDrawData(draw_data); + + // Present + [[self openGLContext] flushBuffer]; + + if (!animationTimer) + animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES]; +} + +-(void)reshape { [super reshape]; [[self openGLContext] update]; [self updateAndDrawDemoView]; } +-(void)drawRect:(NSRect)bounds { [self updateAndDrawDemoView]; } +-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; } +-(void)dealloc { animationTimer = nil; } + +//----------------------------------------------------------------------------------- +// Input processing +//----------------------------------------------------------------------------------- + +// Forward Mouse/Keyboard events to Dear ImGui OSX backend. +// Other events are registered via addLocalMonitorForEventsMatchingMask() +-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } + +@end + +//----------------------------------------------------------------------------------- +// AppDelegate +//----------------------------------------------------------------------------------- + +@interface AppDelegate : NSObject +@property (nonatomic, readonly) NSWindow* window; +@end + +@implementation AppDelegate +@synthesize window = _window; + +-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +{ + return YES; +} + +-(NSWindow*)window +{ + if (_window != nil) + return (_window); + + NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 720.0); + + _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:YES]; + [_window setTitle:@"Dear ImGui OSX+OpenGL2 Example"]; + [_window setAcceptsMouseMovedEvents:YES]; + [_window setOpaque:YES]; + [_window makeKeyAndOrderFront:NSApp]; + + return (_window); +} + +-(void)setupMenu +{ + NSMenu* mainMenuBar = [[NSMenu alloc] init]; + NSMenu* appMenu; + NSMenuItem* menuItem; + + appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL2 Example"]; + menuItem = [appMenu addItemWithTitle:@"Quit Dear ImGui OSX+OpenGL2 Example" action:@selector(terminate:) keyEquivalent:@"q"]; + [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand]; + + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:appMenu]; + + [mainMenuBar addItem:menuItem]; + + appMenu = nil; + [NSApp setMainMenu:mainMenuBar]; +} + +-(void)dealloc +{ + _window = nil; +} + +-(void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + // Make the application a foreground application (else it won't receive keyboard events) + ProcessSerialNumber psn = {0, kCurrentProcess}; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + // Menu + [self setupMenu]; + + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + AppView* view = [[AppView alloc] initWithFrame:self.window.frame pixelFormat:format]; + format = nil; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [view setWantsBestResolutionOpenGLSurface:YES]; +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + [self.window setContentView:view]; + + if ([view openGLContext] == nil) + NSLog(@"No OpenGL Context!"); + + [view initialize]; +} + +@end + +//----------------------------------------------------------------------------------- +// Application main() function +//----------------------------------------------------------------------------------- + +int main(int argc, const char* argv[]) +{ + @autoreleasepool + { + NSApp = [NSApplication sharedApplication]; + AppDelegate* delegate = [[AppDelegate alloc] init]; + [[NSApplication sharedApplication] setDelegate:delegate]; + [NSApp run]; + } + return NSApplicationMain(argc, argv); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/Makefile new file mode 100644 index 000000000..b2933e108 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/Makefile @@ -0,0 +1,91 @@ +# +# Makefile to use with emscripten +# See https://emscripten.org/docs/getting_started/downloads.html +# for installation instructions. +# +# This Makefile assumes you have loaded emscripten's environment. +# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead) +# +# Running `make` will produce three files: +# - web/index.html +# - web/index.js +# - web/index.wasm +# +# All three are needed to run the demo. + +CC = emcc +CXX = em++ +WEB_DIR = web +EXE = $(WEB_DIR)/index.html +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) +CPPFLAGS = +LDFLAGS = +EMS = + +##--------------------------------------------------------------------- +## EMSCRIPTEN OPTIONS +##--------------------------------------------------------------------- + +# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only) +EMS += -s USE_SDL=2 +EMS += -s DISABLE_EXCEPTION_CATCHING=1 +LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1 + +# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877) +#EMS += -s BINARYEN_TRAP_MODE=clamp +#EMS += -s SAFE_HEAP=1 ## Adds overhead + +# Emscripten allows preloading a file or folder to be accessible at runtime. +# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts" +# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html +# (Default value is 0. Set to 1 to enable file-system and include the misc/fonts/ folder as part of the build.) +USE_FILE_SYSTEM ?= 0 +ifeq ($(USE_FILE_SYSTEM), 0) +LDFLAGS += -s NO_FILESYSTEM=1 +CPPFLAGS += -DIMGUI_DISABLE_FILE_FUNCTIONS +endif +ifeq ($(USE_FILE_SYSTEM), 1) +LDFLAGS += --no-heap-copy --preload-file ../../misc/fonts@/fonts +endif + +##--------------------------------------------------------------------- +## FINAL BUILD FLAGS +##--------------------------------------------------------------------- + +CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +#CPPFLAGS += -g +CPPFLAGS += -Wall -Wformat -Os $(EMS) +LDFLAGS += --shell-file shell_minimal.html $(EMS) + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(EXE) + +$(WEB_DIR): + mkdir $@ + +serve: all + python3 -m http.server -d $(WEB_DIR) + +$(EXE): $(OBJS) $(WEB_DIR) + $(CXX) -o $@ $(OBJS) $(LDFLAGS) + +clean: + rm -rf $(OBJS) $(WEB_DIR) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/README.md new file mode 100644 index 000000000..e2b19e44b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/README.md @@ -0,0 +1,26 @@ +## How to Build + +- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions + +- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools. + +- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup. + +- Then build using `make` while in the `example_emscripten_opengl3/` directory. + +## How to Run + +To run on a local machine: +- `make serve` will use Python3 to spawn a local webserver, you can then browse http://localhost:8000 to access your build. +- Otherwise, generally you will need a local webserver: + - Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):
      +_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and can’t load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers you’ll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_ + - Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details. + - You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses). + - You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`. + - If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only). + +## Obsolete features: + +- Emscripten 2.0 (August 2020) obsoleted the fastcomp backend, only llvm is supported. +- Emscripten 1.39.0 (October 2019) obsoleted the `BINARYEN_TRAP_MODE=clamp` compilation flag which was required with version older than 1.39.0 to avoid rendering artefacts. See [#2877](https://github.com/ocornut/imgui/issues/2877) for details. If you use an older version, uncomment this line in the Makefile: `#EMS += -s BINARYEN_TRAP_MODE=clamp` diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/main.cpp new file mode 100644 index 000000000..9e1b37b3b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/main.cpp @@ -0,0 +1,175 @@ +// Dear ImGui: standalone example application for Emscripten, using SDL2 + OpenGL3 +// (Emscripten is a C++-to-javascript compiler, used to publish executables for the web. See https://emscripten.org/) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// This is mostly the same code as the SDL2 + OpenGL3 example, simply with the modifications needed to run on Emscripten. +// It is possible to combine both code into a single source file that will compile properly on Desktop and using Emscripten. +// See https://github.com/ocornut/imgui/pull/2492 as an example on how to do just that. + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_opengl3.h" +#include +#include +#include +#include + +// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally. +// Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this. +SDL_Window* g_Window = NULL; +SDL_GLContext g_GLContext = NULL; + +// For clarity, our main loop code is declared at the end. +static void main_loop(void*); + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // For the browser using Emscripten, we are going to use WebGL1 with GL ES2. See the Makefile. for requirement details. + // It is very likely the generated file won't work in many browsers. Firefox is the only sure bet, but I have successfully + // run this code on Chrome for Android for example. + const char* glsl_version = "#version 100"; + //const char* glsl_version = "#version 300 es"; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + // Create window with graphics context + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + g_Window = SDL_CreateWindow("Dear ImGui Emscripten example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + g_GLContext = SDL_GL_CreateContext(g_Window); + if (!g_GLContext) + { + fprintf(stderr, "Failed to initialize WebGL context!\n"); + return 1; + } + SDL_GL_SetSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + + // For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file. + // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage. + io.IniFilename = NULL; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForOpenGL(g_Window, g_GLContext); + ImGui_ImplOpenGL3_Init(glsl_version); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + // - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details. + //io.Fonts->AddFontDefault(); +#ifndef IMGUI_DISABLE_FILE_FUNCTIONS + io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); +#endif + + // This function call won't return, and will engage in an infinite loop, processing events from the browser, and dispatching them. + emscripten_set_main_loop_arg(main_loop, NULL, 0, true); +} + +static void main_loop(void* arg) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that. + + // Our state (make them static = more or less global) as a convenience to keep the example terse. + static bool show_demo_window = true; + static bool show_another_window = false; + static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + // Capture events here, based on io.WantCaptureMouse and io.WantCaptureKeyboard + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + SDL_GL_MakeCurrent(g_Window, g_GLContext); + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + SDL_GL_SwapWindow(g_Window); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/shell_minimal.html b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/shell_minimal.html new file mode 100644 index 000000000..514385d7c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_opengl3/shell_minimal.html @@ -0,0 +1,64 @@ + + + + + + Dear ImGui Emscripten example + + + + + + {{{ SCRIPT }}} + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/Makefile new file mode 100644 index 000000000..5c79f0c77 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/Makefile @@ -0,0 +1,88 @@ +# +# Makefile to use with emscripten +# See https://emscripten.org/docs/getting_started/downloads.html +# for installation instructions. +# +# This Makefile assumes you have loaded emscripten's environment. +# (On Windows, you may need to execute emsdk_env.bat or encmdprompt.bat ahead) +# +# Running `make` will produce three files: +# - web/index.html (current stored in the repository) +# - web/index.js +# - web/index.wasm +# +# All three are needed to run the demo. + +CC = emcc +CXX = em++ +WEB_DIR = web +EXE = $(WEB_DIR)/index.js +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_wgpu.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) +CPPFLAGS = +LDFLAGS = +EMS = + +##--------------------------------------------------------------------- +## EMSCRIPTEN OPTIONS +##--------------------------------------------------------------------- + +# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only) +EMS += -s DISABLE_EXCEPTION_CATCHING=1 +LDFLAGS += -s USE_GLFW=3 -s USE_WEBGPU=1 +LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1 + +# Emscripten allows preloading a file or folder to be accessible at runtime. +# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts" +# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html +# (Default value is 0. Set to 1 to enable file-system and include the misc/fonts/ folder as part of the build.) +USE_FILE_SYSTEM ?= 0 +ifeq ($(USE_FILE_SYSTEM), 0) +LDFLAGS += -s NO_FILESYSTEM=1 +CPPFLAGS += -DIMGUI_DISABLE_FILE_FUNCTIONS +endif +ifeq ($(USE_FILE_SYSTEM), 1) +LDFLAGS += --no-heap-copy --preload-file ../../misc/fonts@/fonts +endif + +##--------------------------------------------------------------------- +## FINAL BUILD FLAGS +##--------------------------------------------------------------------- + +CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +#CPPFLAGS += -g +CPPFLAGS += -Wall -Wformat -Os $(EMS) +#LDFLAGS += --shell-file shell_minimal.html +LDFLAGS += $(EMS) + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(EXE) + +$(WEB_DIR): + mkdir $@ + +serve: all + python3 -m http.server -d $(WEB_DIR) + +$(EXE): $(OBJS) $(WEB_DIR) + $(CXX) -o $@ $(OBJS) $(LDFLAGS) + +clean: + rm -f $(EXE) $(OBJS) $(WEB_DIR)/*.js $(WEB_DIR)/*.wasm $(WEB_DIR)/*.wasm.pre diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/README.md new file mode 100644 index 000000000..c4c4dec76 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/README.md @@ -0,0 +1,24 @@ +## How to Build + +- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions + +- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools. + +- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup. + +- Then build using `make` while in the `example_emscripten_wgpu/` directory. + +- Requires recent Emscripten as WGPU is still a work-in-progress API. + +## How to Run + +To run on a local machine: +- Make sure your browse supports WGPU and it is enabled. WGPU is still WIP not enabled by default in most browser. +- `make serve` will use Python3 to spawn a local webserver, you can then browse http://localhost:8000 to access your build. +- Otherwise, generally you will need a local webserver: + - Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):
      +_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and can’t load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers you’ll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_ + - Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details. + - You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses). + - You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`. + - If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only). diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/main.cpp new file mode 100644 index 000000000..d11d906c8 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_emscripten_wgpu/main.cpp @@ -0,0 +1,245 @@ +// Dear ImGui: standalone example application for Emscripten, using GLFW + WebGPU +// (Emscripten is a C++-to-javascript compiler, used to publish executables for the web. See https://emscripten.org/) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_wgpu.h" +#include +#include +#include +#include +#include +#include +#include + +// Global WebGPU required states +static WGPUDevice wgpu_device = NULL; +static WGPUSurface wgpu_surface = NULL; +static WGPUSwapChain wgpu_swap_chain = NULL; +static int wgpu_swap_chain_width = 0; +static int wgpu_swap_chain_height = 0; + +// States tracked across render frames +static bool show_demo_window = true; +static bool show_another_window = false; +static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + +// Forward declarations +static bool init_wgpu(); +static void main_loop(void* window); +static void print_glfw_error(int error, const char* description); +static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*); + +int main(int, char**) +{ + glfwSetErrorCallback(print_glfw_error); + if (!glfwInit()) + return 1; + + // Make sure GLFW does not initialize any graphics context. + // This needs to be done explicitly later + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+WebGPU example", NULL, NULL); + if (!window) + { + glfwTerminate(); + return 1; + } + + // Initialize the WebGPU environment + if (!init_wgpu()) + { + if (window) + glfwDestroyWindow(window); + glfwTerminate(); + return 1; + } + glfwShowWindow(window); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file. + // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage. + io.IniFilename = NULL; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOther(window, true); + ImGui_ImplWGPU_Init(wgpu_device, 3, WGPUTextureFormat_RGBA8Unorm); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + // - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details. + //io.Fonts->AddFontDefault(); +#ifndef IMGUI_DISABLE_FILE_FUNCTIONS + io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); +#endif + + // This function will directly return and exit the main function. + // Make sure that no required objects get cleaned up. + // This way we can use the browsers 'requestAnimationFrame' to control the rendering. + emscripten_set_main_loop_arg(main_loop, window, 0, false); + + return 0; +} + +static bool init_wgpu() +{ + wgpu_device = emscripten_webgpu_get_device(); + if (!wgpu_device) + return false; + + wgpuDeviceSetUncapturedErrorCallback(wgpu_device, print_wgpu_error, NULL); + + // Use C++ wrapper due to misbehavior in Emscripten. + // Some offset computation for wgpuInstanceCreateSurface in JavaScript + // seem to be inline with struct alignments in the C++ structure + wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {}; + html_surface_desc.selector = "#canvas"; + + wgpu::SurfaceDescriptor surface_desc = {}; + surface_desc.nextInChain = &html_surface_desc; + + // Use 'null' instance + wgpu::Instance instance = {}; + wgpu_surface = instance.CreateSurface(&surface_desc).Release(); + + return true; +} + +static void main_loop(void* window) +{ + glfwPollEvents(); + + int width, height; + glfwGetFramebufferSize((GLFWwindow*) window, &width, &height); + + // React to changes in screen size + if (width != wgpu_swap_chain_width && height != wgpu_swap_chain_height) + { + ImGui_ImplWGPU_InvalidateDeviceObjects(); + + if (wgpu_swap_chain) + wgpuSwapChainRelease(wgpu_swap_chain); + + wgpu_swap_chain_width = width; + wgpu_swap_chain_height = height; + + WGPUSwapChainDescriptor swap_chain_desc = {}; + swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment; + swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm; + swap_chain_desc.width = width; + swap_chain_desc.height = height; + swap_chain_desc.presentMode = WGPUPresentMode_Fifo; + wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc); + + ImGui_ImplWGPU_CreateDeviceObjects(); + } + + // Start the Dear ImGui frame + ImGui_ImplWGPU_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + + WGPURenderPassColorAttachment color_attachments = {}; + color_attachments.loadOp = WGPULoadOp_Clear; + color_attachments.storeOp = WGPUStoreOp_Store; + color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain); + WGPURenderPassDescriptor render_pass_desc = {}; + render_pass_desc.colorAttachmentCount = 1; + render_pass_desc.colorAttachments = &color_attachments; + render_pass_desc.depthStencilAttachment = NULL; + + WGPUCommandEncoderDescriptor enc_desc = {}; + WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(wgpu_device, &enc_desc); + + WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_desc); + ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), pass); + wgpuRenderPassEncoderEndPass(pass); + + WGPUCommandBufferDescriptor cmd_buffer_desc = {}; + WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc); + WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device); + wgpuQueueSubmit(queue, 1, &cmd_buffer); +} + +static void print_glfw_error(int error, const char* description) +{ + printf("Glfw Error %d: %s\n", error, description); +} + +static void print_wgpu_error(WGPUErrorType error_type, const char* message, void*) +{ + const char* error_type_lbl = ""; + switch (error_type) + { + case WGPUErrorType_Validation: error_type_lbl = "Validation"; break; + case WGPUErrorType_OutOfMemory: error_type_lbl = "Out of memory"; break; + case WGPUErrorType_Unknown: error_type_lbl = "Unknown"; break; + case WGPUErrorType_DeviceLost: error_type_lbl = "Device lost"; break; + default: error_type_lbl = "Unknown"; + } + printf("%s error: %s\n", error_type_lbl, message); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/Makefile new file mode 100644 index 000000000..a174bc8f2 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/Makefile @@ -0,0 +1,46 @@ +# +# You will need GLFW (http://www.glfw.org): +# brew install glfw +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_glfw_metal +IMGUI_DIR = ../.. +SOURCES = main.mm +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) + +LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore +LIBS += -L/usr/local/lib -L/opt/homebrew/lib +LIBS += -lglfw + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include +CXXFLAGS += -Wall -Wformat +CFLAGS = $(CXXFLAGS) + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +all: $(EXE) + @echo Build complete + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/main.mm b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/main.mm new file mode 100644 index 000000000..2776ba2e7 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_metal/main.mm @@ -0,0 +1,172 @@ +// Dear ImGui: standalone example application for GLFW + Metal, using programmable pipeline +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_metal.h" +#include + +#define GLFW_INCLUDE_NONE +#define GLFW_EXPOSE_NATIVE_COCOA +#include +#include + +#import +#import + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Setup window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Create window with graphics context + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Metal example", NULL, NULL); + if (window == NULL) + return 1; + + id device = MTLCreateSystemDefaultDevice(); + id commandQueue = [device newCommandQueue]; + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplMetal_Init(device); + + NSWindow *nswin = glfwGetCocoaWindow(window); + CAMetalLayer *layer = [CAMetalLayer layer]; + layer.device = device; + layer.pixelFormat = MTLPixelFormatBGRA8Unorm; + nswin.contentView.layer = layer; + nswin.contentView.wantsLayer = YES; + + MTLRenderPassDescriptor *renderPassDescriptor = [MTLRenderPassDescriptor new]; + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f}; + + // Main loop + while (!glfwWindowShouldClose(window)) + { + @autoreleasepool + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + int width, height; + glfwGetFramebufferSize(window, &width, &height); + layer.drawableSize = CGSizeMake(width, height); + id drawable = [layer nextDrawable]; + + id commandBuffer = [commandQueue commandBuffer]; + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]); + renderPassDescriptor.colorAttachments[0].texture = drawable.texture; + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + [renderEncoder pushDebugGroup:@"ImGui demo"]; + + // Start the Dear ImGui frame + ImGui_ImplMetal_NewFrame(renderPassDescriptor); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder); + + [renderEncoder popDebugGroup]; + [renderEncoder endEncoding]; + + [commandBuffer presentDrawable:drawable]; + [commandBuffer commit]; + } + } + + // Cleanup + ImGui_ImplMetal_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/Makefile new file mode 100644 index 000000000..5c19a27f1 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/Makefile @@ -0,0 +1,81 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need GLFW (http://www.glfw.org): +# Linux: +# apt-get install libglfw-dev +# Mac OS X: +# brew install glfw +# MSYS2: +# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_glfw_opengl2 +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS += `pkg-config --cflags glfw3` + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib + #LIBS += -lglfw3 + LIBS += -lglfw + + CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS += `pkg-config --cflags glfw3` + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/build_win32.bat new file mode 100644 index 000000000..a0a75f906 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_glfw_opengl2 +@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj new file mode 100644 index 000000000..faf6d9a5a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + example_glfw_opengl2 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + + + true + ..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + + + true + ..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + ..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + ..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters new file mode 100644 index 000000000..69b285d1a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + imgui + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/main.cpp new file mode 100644 index 000000000..8cc32328d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl2/main.cpp @@ -0,0 +1,181 @@ +// Dear ImGui: standalone example application for GLFW + OpenGL2, using legacy fixed pipeline +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the example_glfw_opengl2/ folder** +// See imgui_impl_glfw.cpp for details. + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl2.h" +#include +#ifdef __APPLE__ +#define GL_SILENCE_DEPRECATION +#endif +#include + +// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. +// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. +// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#pragma comment(lib, "legacy_stdio_definitions") +#endif + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL2 example", NULL, NULL); + if (window == NULL) + return 1; + glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL2_Init(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + // Start the Dear ImGui frame + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + + // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), + // you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below. + //GLint last_program; + //glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + //glUseProgram(0); + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + //glUseProgram(last_program); + + // Update and Render additional Platform Windows + // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. + // For this specific demo app we could also call glfwMakeContextCurrent(window) directly) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + GLFWwindow* backup_current_context = glfwGetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(backup_current_context); + } + + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/Makefile new file mode 100644 index 000000000..672a7059c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/Makefile @@ -0,0 +1,89 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need GLFW (http://www.glfw.org): +# Linux: +# apt-get install libglfw-dev +# Mac OS X: +# brew install glfw +# MSYS2: +# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_glfw_opengl3 +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) +LINUX_GL_LIBS = -lGL + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## OPENGL ES +##--------------------------------------------------------------------- + +## This assumes a GL ES library available in the system, e.g. libGLESv2.so +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_ES2 +# LINUX_GL_LIBS = -lGLESv2 + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3` + + CXXFLAGS += `pkg-config --cflags glfw3` + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib + #LIBS += -lglfw3 + LIBS += -lglfw + + CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS += `pkg-config --cflags glfw3` + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/build_win32.bat new file mode 100644 index 000000000..4ba58d8c9 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_glfw_opengl3 +@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj new file mode 100644 index 000000000..7721c8ffa --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4a1fb5ea-22f5-42a8-ab92-1d2df5d47fb9} + example_glfw_opengl3 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + + + true + ..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + + + true + ..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + ..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + ..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters new file mode 100644 index 000000000..fd2f80714 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj.filters @@ -0,0 +1,64 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + imgui + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/main.cpp new file mode 100644 index 000000000..f6f19079f --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_opengl3/main.cpp @@ -0,0 +1,195 @@ +// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" +#include +#if defined(IMGUI_IMPL_OPENGL_ES2) +#include +#endif +#include // Will drag system OpenGL headers + +// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. +// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. +// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#pragma comment(lib, "legacy_stdio_definitions") +#endif + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Decide GL+GLSL versions +#if defined(IMGUI_IMPL_OPENGL_ES2) + // GL ES 2.0 + GLSL 100 + const char* glsl_version = "#version 100"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); +#elif defined(__APPLE__) + // GL 3.2 + GLSL 150 + const char* glsl_version = "#version 150"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac +#else + // GL 3.0 + GLSL 130 + const char* glsl_version = "#version 130"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only +#endif + + // Create window with graphics context + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL); + if (window == NULL) + return 1; + glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init(glsl_version); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. + // For this specific demo app we could also call glfwMakeContextCurrent(window) directly) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + GLFWwindow* backup_current_context = glfwGetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(backup_current_context); + } + + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/CMakeLists.txt b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/CMakeLists.txt new file mode 100644 index 000000000..55a804027 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/CMakeLists.txt @@ -0,0 +1,44 @@ +# Example usage: +# mkdir build +# cd build +# cmake -g "Visual Studio 14 2015" .. + +cmake_minimum_required(VERSION 2.8) +project(imgui_example_glfw_vulkan C CXX) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) +endif() + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES") + +# GLFW +set(GLFW_DIR ../../../glfw) # Set this to point to an up-to-date GLFW repo +option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF) +option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF) +option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF) +option(GLFW_INSTALL "Generate installation target" OFF) +option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) +add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL) +include_directories(${GLFW_DIR}/include) + +# Dear ImGui +set(IMGUI_DIR ../../) +include_directories(${IMGUI_DIR} ${IMGUI_DIR}/backends ..) + +# Libraries +find_package(Vulkan REQUIRED) +#find_library(VULKAN_LIBRARY + #NAMES vulkan vulkan-1) +#set(LIBRARIES "glfw;${VULKAN_LIBRARY}") +set(LIBRARIES "glfw;Vulkan::Vulkan") + +# Use vulkan headers from glfw: +include_directories(${GLFW_DIR}/deps) + +file(GLOB sources *.cpp) + +add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp) +target_link_libraries(example_glfw_vulkan ${LIBRARIES}) +target_compile_definitions(example_glfw_vulkan PUBLIC -DImTextureID=ImU64) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win32.bat new file mode 100644 index 000000000..82f01112d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win32.bat @@ -0,0 +1,14 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. + +@set OUT_EXE=example_glfw_vulkan +@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib + +@set OUT_DIR=Debug +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% + +@set OUT_DIR=Release +mkdir %OUT_DIR% +cl /nologo /Zi /MD /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win64.bat b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win64.bat new file mode 100644 index 000000000..0bf7936c6 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/build_win64.bat @@ -0,0 +1,13 @@ +@REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler. + +@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib + +@set OUT_DIR=Debug +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% + +@set OUT_DIR=Release +mkdir %OUT_DIR% +cl /nologo /Zi /MD /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj new file mode 100644 index 000000000..ed8fe9663 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj @@ -0,0 +1,185 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80} + example_glfw_vulkan + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + %VULKAN_SDK%\lib32;..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + %VULKAN_SDK%\lib;..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + true + true + %VULKAN_SDK%\lib32;..\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) + false + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + true + true + %VULKAN_SDK%\lib;..\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters new file mode 100644 index 000000000..adc3365ce --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + imgui + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/main.cpp new file mode 100644 index 000000000..1054805f8 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glfw_vulkan/main.cpp @@ -0,0 +1,580 @@ +// Dear ImGui: standalone example application for Glfw + Vulkan +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. +// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// You will use those if you want to use this rendering backend in your engine/app. +// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by +// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. +// Read comments in imgui_impl_vulkan.h. + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_vulkan.h" +#include // printf, fprintf +#include // abort +#define GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_VULKAN +#include +#include + +// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. +// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. +// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#pragma comment(lib, "legacy_stdio_definitions") +#endif + +//#define IMGUI_UNLIMITED_FRAME_RATE +#ifdef _DEBUG +#define IMGUI_VULKAN_DEBUG_REPORT +#endif + +static VkAllocationCallbacks* g_Allocator = NULL; +static VkInstance g_Instance = VK_NULL_HANDLE; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static uint32_t g_QueueFamily = (uint32_t)-1; +static VkQueue g_Queue = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; + +static ImGui_ImplVulkanH_Window g_MainWindowData; +static int g_MinImageCount = 2; +static bool g_SwapChainRebuild = false; + +static void check_vk_result(VkResult err) +{ + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); + if (err < 0) + abort(); +} + +#ifdef IMGUI_VULKAN_DEBUG_REPORT +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +{ + (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments + fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + return VK_FALSE; +} +#endif // IMGUI_VULKAN_DEBUG_REPORT + +static void SetupVulkan(const char** extensions, uint32_t extensions_count) +{ + VkResult err; + + // Create Vulkan Instance + { + VkInstanceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.enabledExtensionCount = extensions_count; + create_info.ppEnabledExtensionNames = extensions; +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // Enabling validation layers + const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; + create_info.enabledLayerCount = 1; + create_info.ppEnabledLayerNames = layers; + + // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) + const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); + memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); + extensions_ext[extensions_count] = "VK_EXT_debug_report"; + create_info.enabledExtensionCount = extensions_count + 1; + create_info.ppEnabledExtensionNames = extensions_ext; + + // Create Vulkan Instance + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); + check_vk_result(err); + free(extensions_ext); + + // Get the function pointer (required for any extensions) + auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); + + // Setup the debug report callback + VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; + debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + debug_report_ci.pfnCallback = debug_report; + debug_report_ci.pUserData = NULL; + err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); + check_vk_result(err); +#else + // Create Vulkan Instance without any debug feature + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); + check_vk_result(err); + IM_UNUSED(g_DebugReport); +#endif + } + + // Select GPU + { + uint32_t gpu_count; + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); + check_vk_result(err); + IM_ASSERT(gpu_count > 0); + + VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); + check_vk_result(err); + + // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers + // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple + // dedicated GPUs) is out of scope of this sample. + int use_gpu = 0; + for (int i = 0; i < (int)gpu_count; i++) + { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(gpus[i], &properties); + if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + { + use_gpu = i; + break; + } + } + + g_PhysicalDevice = gpus[use_gpu]; + free(gpus); + } + + // Select graphics queue family + { + uint32_t count; + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); + VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); + for (uint32_t i = 0; i < count; i++) + if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + g_QueueFamily = i; + break; + } + free(queues); + IM_ASSERT(g_QueueFamily != (uint32_t)-1); + } + + // Create Logical Device (with 1 queue) + { + int device_extension_count = 1; + const char* device_extensions[] = { "VK_KHR_swapchain" }; + const float queue_priority[] = { 1.0f }; + VkDeviceQueueCreateInfo queue_info[1] = {}; + queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info[0].queueFamilyIndex = g_QueueFamily; + queue_info[0].queueCount = 1; + queue_info[0].pQueuePriorities = queue_priority; + VkDeviceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); + create_info.pQueueCreateInfos = queue_info; + create_info.enabledExtensionCount = device_extension_count; + create_info.ppEnabledExtensionNames = device_extensions; + err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); + check_vk_result(err); + vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); + } + + // Create Descriptor Pool + { + VkDescriptorPoolSize pool_sizes[] = + { + { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } + }; + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); + pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); + pool_info.pPoolSizes = pool_sizes; + err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); + check_vk_result(err); + } +} + +// All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. +// Your real engine/app may not use them. +static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) +{ + wd->Surface = surface; + + // Check for WSI support + VkBool32 res; + vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); + if (res != VK_TRUE) + { + fprintf(stderr, "Error no WSI support on physical device 0\n"); + exit(-1); + } + + // Select Surface Format + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); + + // Select Present Mode +#ifdef IMGUI_UNLIMITED_FRAME_RATE + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; +#else + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; +#endif + wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); + //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); + + // Create SwapChain, RenderPass, Framebuffer, etc. + IM_ASSERT(g_MinImageCount >= 2); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); +} + +static void CleanupVulkan() +{ + vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); + +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // Remove the debug report callback + auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); +#endif // IMGUI_VULKAN_DEBUG_REPORT + + vkDestroyDevice(g_Device, g_Allocator); + vkDestroyInstance(g_Instance, g_Allocator); +} + +static void CleanupVulkanWindow() +{ + ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); +} + +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) +{ + VkResult err; + + VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + { + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking + check_vk_result(err); + + err = vkResetFences(g_Device, 1, &fd->Fence); + check_vk_result(err); + } + { + err = vkResetCommandPool(g_Device, fd->CommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(fd->CommandBuffer, &info); + check_vk_result(err); + } + { + VkRenderPassBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = wd->RenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = wd->Width; + info.renderArea.extent.height = wd->Height; + info.clearValueCount = 1; + info.pClearValues = &wd->ClearValue; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } + + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); + + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + { + VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &image_acquired_semaphore; + info.pWaitDstStageMask = &wait_stage; + info.commandBufferCount = 1; + info.pCommandBuffers = &fd->CommandBuffer; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &render_complete_semaphore; + + err = vkEndCommandBuffer(fd->CommandBuffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); + check_vk_result(err); + } +} + +static void FramePresent(ImGui_ImplVulkanH_Window* wd) +{ + if (g_SwapChainRebuild) + return; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &render_complete_semaphore; + info.swapchainCount = 1; + info.pSwapchains = &wd->Swapchain; + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores +} + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup GLFW window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Vulkan example", NULL, NULL); + + // Setup Vulkan + if (!glfwVulkanSupported()) + { + printf("GLFW: Vulkan Not Supported\n"); + return 1; + } + uint32_t extensions_count = 0; + const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); + SetupVulkan(extensions, extensions_count); + + // Create Window Surface + VkSurfaceKHR surface; + VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &surface); + check_vk_result(err); + + // Create Framebuffers + int w, h; + glfwGetFramebufferSize(window, &w, &h); + ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; + SetupVulkanWindow(wd, surface, w, h); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForVulkan(window, true); + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Instance = g_Instance; + init_info.PhysicalDevice = g_PhysicalDevice; + init_info.Device = g_Device; + init_info.QueueFamily = g_QueueFamily; + init_info.Queue = g_Queue; + init_info.PipelineCache = g_PipelineCache; + init_info.DescriptorPool = g_DescriptorPool; + init_info.Subpass = 0; + init_info.MinImageCount = g_MinImageCount; + init_info.ImageCount = wd->ImageCount; + init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + init_info.Allocator = g_Allocator; + init_info.CheckVkResultFn = check_vk_result; + ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Upload Fonts + { + // Use any command queue + VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; + VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; + + err = vkResetCommandPool(g_Device, command_pool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(command_buffer, &begin_info); + check_vk_result(err); + + ImGui_ImplVulkan_CreateFontsTexture(command_buffer); + + VkSubmitInfo end_info = {}; + end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + end_info.commandBufferCount = 1; + end_info.pCommandBuffers = &command_buffer; + err = vkEndCommandBuffer(command_buffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); + check_vk_result(err); + + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplVulkan_DestroyFontUploadObjects(); + } + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + glfwPollEvents(); + + // Resize swap chain? + if (g_SwapChainRebuild) + { + int width, height; + glfwGetFramebufferSize(window, &width, &height); + if (width > 0 && height > 0) + { + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; + } + } + + // Start the Dear ImGui frame + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* main_draw_data = ImGui::GetDrawData(); + const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f); + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; + if (!main_is_minimized) + FrameRender(wd, main_draw_data); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + // Present Main Platform Window + if (!main_is_minimized) + FramePresent(wd); + } + + // Cleanup + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplVulkan_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + CleanupVulkanWindow(); + CleanupVulkan(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/Makefile new file mode 100644 index 000000000..a980f56fb --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/Makefile @@ -0,0 +1,75 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# Linux: +# apt-get install freeglut3-dev +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_glut_opengl2 +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += -lGL -lglut + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework GLUT + LIBS += -L/usr/local/lib -L/opt/local/lib + + CXXFLAGS += -I/usr/local/include -I/opt/local/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lgdi32 -lopengl32 -limm32 +ifeq ($(shell pkg-config freeglut --exists 2> /dev/null && echo yes || echo no),yes) + CXXFLAGS += $(shell pkg-config freeglut --cflags) + LIBS += $(shell pkg-config freeglut --libs) +else + LIBS += -lglut +endif + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj new file mode 100644 index 000000000..4c9d00f5c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F90D0333-5FB1-440D-918D-DD39A1B5187E} + example_glut_opengl2 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) + + + true + $(GLUT_ROOT_PATH)/lib;%(AdditionalLibraryDirectories) + opengl32.lib;freeglut.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) + + + true + $(GLUT_ROOT_PATH)/lib/x64;%(AdditionalLibraryDirectories) + opengl32.lib;freeglut.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) + false + + + true + true + true + $(GLUT_ROOT_PATH)/lib;%(AdditionalLibraryDirectories) + opengl32.lib;freeglut.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) + false + + + true + true + true + $(GLUT_ROOT_PATH)/lib/x64;%(AdditionalLibraryDirectories) + opengl32.lib;freeglut.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters new file mode 100644 index 000000000..3c017ba94 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + imgui + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/main.cpp new file mode 100644 index 000000000..faf551233 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_glut_opengl2/main.cpp @@ -0,0 +1,156 @@ +// Dear ImGui: standalone example application for GLUT/FreeGLUT + OpenGL2, using legacy fixed pipeline +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!! +// !!! Nowadays, prefer using GLFW or SDL instead! + +// On Windows, you can install Freeglut using vcpkg: +// git clone https://github.com/Microsoft/vcpkg +// cd vcpkg +// bootstrap - vcpkg.bat +// vcpkg install freeglut --triplet=x86-windows ; for win32 +// vcpkg install freeglut --triplet=x64-windows ; for win64 +// vcpkg integrate install ; register include and libs in Visual Studio + +#include "imgui.h" +#include "imgui_impl_glut.h" +#include "imgui_impl_opengl2.h" +#ifdef __APPLE__ + #include +#else + #include +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4505) // unreferenced local function has been removed +#endif + +// Our state +static bool show_demo_window = true; +static bool show_another_window = false; +static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + +void my_display_code() +{ + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } +} + +void glut_display_func() +{ + // Start the Dear ImGui frame + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplGLUT_NewFrame(); + + my_display_code(); + + // Rendering + ImGui::Render(); + ImGuiIO& io = ImGui::GetIO(); + glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound, but prefer using the GL3+ code. + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + + glutSwapBuffers(); + glutPostRedisplay(); +} + +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + +int main(int argc, char** argv) +{ + // Create GLUT window + glutInit(&argc, argv); +#ifdef __FREEGLUT_EXT_H__ + glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); +#endif + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE); + glutInitWindowSize(1280, 720); + glutCreateWindow("Dear ImGui GLUT+OpenGL2 Example"); + + // Setup GLUT display function + // We will also call ImGui_ImplGLUT_InstallFuncs() to get all the other functions installed for us, + // otherwise it is possible to install our own functions and call the imgui_impl_glut.h functions ourselves. + glutDisplayFunc(glut_display_func); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplGLUT_Init(); + ImGui_ImplGLUT_InstallFuncs(); + ImGui_ImplOpenGL2_Init(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + glutMainLoop(); + + // Cleanup + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplGLUT_Shutdown(); + ImGui::DestroyContext(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_null/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_null/Makefile new file mode 100644 index 000000000..9208e8a08 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_null/Makefile @@ -0,0 +1,92 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# Important: This is a "null backend" application, with no visible output or interaction! +# This is used for testing purpose and continuous integration, and has little use for end-user. +# + +# Options +WITH_EXTRA_WARNINGS ?= 0 +WITH_FREETYPE ?= 0 + +EXE = example_null +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) + +CXXFLAGS += -I$(IMGUI_DIR) +CXXFLAGS += -g -Wall -Wformat +LIBS = + +# We use the WITH_EXTRA_WARNINGS flag on our CI setup to eagerly catch zealous warnings +ifeq ($(WITH_EXTRA_WARNINGS), 1) + CXXFLAGS += -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros +endif + +# We use the WITH_FREETYPE flag on our CI setup to test compiling misc/freetype/imgui_freetype.cpp +# (only supported on Linux, and note that the imgui_freetype code currently won't be executed) +ifeq ($(WITH_FREETYPE), 1) + SOURCES += $(IMGUI_DIR)/misc/freetype/imgui_freetype.cpp + CXXFLAGS += $(shell pkg-config --cflags freetype2) + LIBS += $(shell pkg-config --libs freetype2) +endif + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + ifeq ($(WITH_EXTRA_WARNINGS), 1) + CXXFLAGS += -Wextra -Wpedantic + ifeq ($(shell $(CXX) -v 2>&1 | grep -c "clang version"), 1) + CXXFLAGS += -Wshadow -Wsign-conversion + endif + endif + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + ifeq ($(WITH_EXTRA_WARNINGS), 1) + CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-c++11-long-long -Wno-poison-system-directories + endif + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + ifeq ($(WITH_EXTRA_WARNINGS), 1) + CXXFLAGS += -Wextra -Wpedantic + endif + LIBS += -limm32 + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/misc/freetype/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_null/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_null/build_win32.bat new file mode 100644 index 000000000..0cdfdc93b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_null/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. %* *.cpp ..\..\*.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_null/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_null/main.cpp new file mode 100644 index 000000000..72381f0af --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_null/main.cpp @@ -0,0 +1,37 @@ +// dear imgui: "null" example application +// (compile and link imgui, create context, run headless with NO INPUTS, NO GRAPHICS OUTPUT) +// This is useful to test building, but you cannot interact with anything here! +#include "imgui.h" +#include + +int main(int, char**) +{ + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + + // Build atlas + unsigned char* tex_pixels = NULL; + int tex_w, tex_h; + io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h); + + for (int n = 0; n < 20; n++) + { + printf("NewFrame() %d\n", n); + io.DisplaySize = ImVec2(1920, 1080); + io.DeltaTime = 1.0f / 60.0f; + ImGui::NewFrame(); + + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::ShowDemoWindow(NULL); + + ImGui::Render(); + } + + printf("DestroyContext()\n"); + ImGui::DestroyContext(); + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/build_win32.bat new file mode 100644 index 000000000..b93082704 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_sdl_directx11 +@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" +@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib shell32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj new file mode 100644 index 000000000..ac636d2f3 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9E1987E3-1F19-45CA-B9C9-D31E791836D8} + example_sdl_directx11 + 8.1 + example_sdl_directx11 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj.filters new file mode 100644 index 000000000..15fc85335 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/example_sdl_directx11.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {0587d7a3-f2ce-4d56-b84f-a0005d3bfce6} + + + {08e36723-ce4f-4cff-9662-c40801cf1acf} + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + sources + + + imgui + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/main.cpp new file mode 100644 index 000000000..ac45b32dc --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_directx11/main.cpp @@ -0,0 +1,249 @@ +// Dear ImGui: standalone example application for SDL2 + DirectX 11 +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_dx11.h" +#include +#include +#include +#include + +// Data +static ID3D11Device* g_pd3dDevice = NULL; +static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; +static IDXGISwapChain* g_pSwapChain = NULL; +static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void CreateRenderTarget(); +void CleanupRenderTarget(); + +// Main code +int main(int, char**) +{ + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + HWND hwnd = (HWND)wmInfo.info.win.window; + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + return 1; + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForD3D(window); + ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) + { + // Release all outstanding references to the swap chain's buffers before resizing. + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); + CreateRenderTarget(); + } + } + + // Start the Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync + } + + // Cleanup + ImGui_ImplDX11_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + return false; + + CreateRenderTarget(); + return true; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } + if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } +} + +void CreateRenderTarget() +{ + ID3D11Texture2D* pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); + pBackBuffer->Release(); +} + +void CleanupRenderTarget() +{ + if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/Makefile new file mode 100644 index 000000000..042bb04cc --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/Makefile @@ -0,0 +1,47 @@ +# +# You will need SDL2 (http://www.libsdl.org): +# brew install sdl2 +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_sdl_metal +IMGUI_DIR = ../.. +SOURCES = main.mm +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) + +LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore +LIBS += `sdl2-config --libs` +LIBS += -L/usr/local/lib + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include +CXXFLAGS += `sdl2-config --cflags` +CXXFLAGS += -Wall -Wformat +CFLAGS = $(CXXFLAGS) + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +all: $(EXE) + @echo Build complete + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/main.mm b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/main.mm new file mode 100644 index 000000000..caa86e644 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_metal/main.mm @@ -0,0 +1,181 @@ +// Dear ImGui: standalone example application for SDL2 + Metal +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_metal.h" +#include +#include + +#import +#import + +int main(int, char**) +{ + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail. + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); + + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + if (window == NULL) + { + printf("Error creating window: %s\n", SDL_GetError()); + return -2; + } + + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + if (renderer == NULL) + { + printf("Error creating renderer: %s\n", SDL_GetError()); + return -3; + } + + // Setup Platform/Renderer backends + CAMetalLayer* layer = (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(renderer); + layer.pixelFormat = MTLPixelFormatBGRA8Unorm; + ImGui_ImplMetal_Init(layer.device); + ImGui_ImplSDL2_InitForMetal(window); + + id commandQueue = [layer.device newCommandQueue]; + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new]; + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f}; + + // Main loop + bool done = false; + while (!done) + { + @autoreleasepool + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + int width, height; + SDL_GetRendererOutputSize(renderer, &width, &height); + layer.drawableSize = CGSizeMake(width, height); + id drawable = [layer nextDrawable]; + + id commandBuffer = [commandQueue commandBuffer]; + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]); + renderPassDescriptor.colorAttachments[0].texture = drawable.texture; + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + [renderEncoder pushDebugGroup:@"ImGui demo"]; + + // Start the Dear ImGui frame + ImGui_ImplMetal_NewFrame(renderPassDescriptor); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder); + + [renderEncoder popDebugGroup]; + [renderEncoder endEncoding]; + + [commandBuffer presentDrawable:drawable]; + [commandBuffer commit]; + } + } + + // Cleanup + ImGui_ImplMetal_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/Makefile new file mode 100644 index 000000000..92e0554bb --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/Makefile @@ -0,0 +1,79 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need SDL2 (http://www.libsdl.org): +# Linux: +# apt-get install libsdl2-dev +# Mac OS X: +# brew install sdl2 +# MSYS2: +# pacman -S mingw-w64-i686-SDL2 +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_sdl_opengl2 +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += -lGL -ldl `sdl2-config --libs` + + CXXFLAGS += `sdl2-config --cflags` + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs` + LIBS += -L/usr/local/lib -L/opt/local/lib + + CXXFLAGS += `sdl2-config --cflags` + CXXFLAGS += -I/usr/local/include -I/opt/local/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` + + CXXFLAGS += `pkg-config --cflags sdl2` + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/README.md new file mode 100644 index 000000000..2bf4d03ad --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/README.md @@ -0,0 +1,29 @@ + +# How to Build + +- On Windows with Visual Studio's IDE + +Use the provided project file (.vcxproj). Add to solution (imgui_examples.sln) if necessary. + +- On Windows with Visual Studio's CLI + +``` +set SDL2_DIR=path_to_your_sdl2_folder +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl2.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries +# or for 64-bit: +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl2.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl +``` diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/build_win32.bat new file mode 100644 index 000000000..47529e289 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_sdl_opengl2 +@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib shell32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj new file mode 100644 index 000000000..d22a67bae --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741} + example_sdl_opengl2 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj.filters new file mode 100644 index 000000000..2253b8656 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/main.cpp new file mode 100644 index 000000000..d3aaa6838 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl2/main.cpp @@ -0,0 +1,182 @@ +// Dear ImGui: standalone example application for SDL2 + OpenGL +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the example_sdl_opengl3/ folder** +// See imgui_impl_sdl.cpp for details. + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_opengl2.h" +#include +#include +#include + +// Main code +int main(int, char**) +{ + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + SDL_GLContext gl_context = SDL_GL_CreateContext(window); + SDL_GL_MakeCurrent(window, gl_context); + SDL_GL_SetSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForOpenGL(window, gl_context); + ImGui_ImplOpenGL2_Init(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. + // For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow(); + SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + SDL_GL_MakeCurrent(backup_current_window, backup_current_context); + } + + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_GL_DeleteContext(gl_context); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/Makefile new file mode 100644 index 000000000..1b8ab4227 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/Makefile @@ -0,0 +1,91 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need SDL2 (http://www.libsdl.org): +# Linux: +# apt-get install libsdl2-dev +# Mac OS X: +# brew install sdl2 +# MSYS2: +# pacman -S mingw-w64-i686-SDL2 +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_sdl_opengl3 +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) +LINUX_GL_LIBS = -lGL + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## OPENGL ES +##--------------------------------------------------------------------- + +## This assumes a GL ES library available in the system, e.g. libGLESv2.so +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_ES2 +# LINUX_GL_LIBS = -lGLESv2 +## If you're on a Raspberry Pi and want to use the legacy drivers, +## use the following instead: +# LINUX_GL_LIBS = -L/opt/vc/lib -lbrcmGLESv2 + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += $(LINUX_GL_LIBS) -ldl `sdl2-config --libs` + + CXXFLAGS += `sdl2-config --cflags` + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs` + LIBS += -L/usr/local/lib -L/opt/local/lib + + CXXFLAGS += `sdl2-config --cflags` + CXXFLAGS += -I/usr/local/include -I/opt/local/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` + + CXXFLAGS += `pkg-config --cflags sdl2` + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/README.md new file mode 100644 index 000000000..06d4b2d33 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/README.md @@ -0,0 +1,29 @@ + +# How to Build + +- On Windows with Visual Studio's IDE + +Use the provided project file (.vcxproj). Add to solution (imgui_examples.sln) if necessary. + +- On Windows with Visual Studio's CLI + +``` +set SDL2_DIR=path_to_your_sdl2_folder +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl3.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries +# or for 64-bit: +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl3.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -ldl +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -framework CoreFoundation +``` diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/build_win32.bat new file mode 100644 index 000000000..20851bff6 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_sdl_opengl3 +@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib shell32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj new file mode 100644 index 000000000..ace041df2 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {BBAEB705-1669-40F3-8567-04CF6A991F4C} + example_sdl_opengl3 + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj.filters new file mode 100644 index 000000000..c8dbeae4c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj.filters @@ -0,0 +1,64 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/main.cpp new file mode 100644 index 000000000..e88d94258 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_opengl3/main.cpp @@ -0,0 +1,203 @@ +// Dear ImGui: standalone example application for SDL2 + OpenGL +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_opengl3.h" +#include +#include +#if defined(IMGUI_IMPL_OPENGL_ES2) +#include +#else +#include +#endif + +// Main code +int main(int, char**) +{ + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Decide GL+GLSL versions +#if defined(IMGUI_IMPL_OPENGL_ES2) + // GL ES 2.0 + GLSL 100 + const char* glsl_version = "#version 100"; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#elif defined(__APPLE__) + // GL 3.2 Core + GLSL 150 + const char* glsl_version = "#version 150"; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); +#else + // GL 3.0 + GLSL 130 + const char* glsl_version = "#version 130"; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#endif + + // Create window with graphics context + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + SDL_GLContext gl_context = SDL_GL_CreateContext(window); + SDL_GL_MakeCurrent(window, gl_context); + SDL_GL_SetSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForOpenGL(window, gl_context); + ImGui_ImplOpenGL3_Init(glsl_version); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. + // For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow(); + SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + SDL_GL_MakeCurrent(backup_current_window, backup_current_context); + } + + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_GL_DeleteContext(gl_context); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/Makefile b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/Makefile new file mode 100644 index 000000000..5667789af --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/Makefile @@ -0,0 +1,79 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need SDL2 (http://www.libsdl.org): +# Linux: +# apt-get install libsdl2-dev +# Mac OS X: +# brew install sdl2 +# MSYS2: +# pacman -S mingw-w64-i686-SDL2 +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_sdl_sdlrenderer +IMGUI_DIR = ../.. +SOURCES = main.cpp +SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlrenderer.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) +UNAME_S := $(shell uname -s) + +CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends +CXXFLAGS += -g -Wall -Wformat +LIBS = + +##--------------------------------------------------------------------- +## BUILD FLAGS PER PLATFORM +##--------------------------------------------------------------------- + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS += -lGL -ldl `sdl2-config --libs` + + CXXFLAGS += `sdl2-config --cflags` + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs` + LIBS += -L/usr/local/lib -L/opt/local/lib + + CXXFLAGS += `sdl2-config --cflags` + CXXFLAGS += -I/usr/local/include -I/opt/local/include + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(OS), Windows_NT) + ECHO_MESSAGE = "MinGW" + LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` + + CXXFLAGS += `pkg-config --cflags sdl2` + CFLAGS = $(CXXFLAGS) +endif + +##--------------------------------------------------------------------- +## BUILD RULES +##--------------------------------------------------------------------- + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:$(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/README.md b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/README.md new file mode 100644 index 000000000..209f15acf --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/README.md @@ -0,0 +1,25 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2_DIR=path_to_your_sdl2_folder +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_sdlrenderer.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /subsystem:console +# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries +# or for 64-bit: +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_sdlrenderer.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib /subsystem:console +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_sdlrenderer.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_sdlrenderer.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl +``` diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/build_win32.bat new file mode 100644 index 000000000..6c1b5fde0 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_sdl_sdlrenderer_ +@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj new file mode 100644 index 000000000..4d502ab67 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741} + example_sdl_sdlrenderer + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) + + + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj.filters new file mode 100644 index 000000000..01e98fcbc --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/main.cpp new file mode 100644 index 000000000..582b5a150 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_sdlrenderer/main.cpp @@ -0,0 +1,161 @@ +// Dear ImGui: standalone example application for SDL2 + SDL_Renderer +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// Important to understand: SDL_Renderer is an _optional_ component of SDL. We do not recommend you use SDL_Renderer +// because it provide a rather limited API to the end-user. We provide this backend for the sake of completeness. +// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_sdlrenderer.h" +#include +#include + +#if !SDL_VERSION_ATLEAST(2,0,17) +#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function +#endif + +// Main code +int main(int, char**) +{ + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + + // Setup SDL_Renderer instance + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); + if (renderer == NULL) + { + SDL_Log("Error creating SDL_Renderer!"); + return false; + } + //SDL_RendererInfo info; + //SDL_GetRendererInfo(renderer, &info); + //SDL_Log("Current SDL_Renderer: %s", info.name); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForSDLRenderer(window, renderer); + ImGui_ImplSDLRenderer_Init(renderer); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + // Start the Dear ImGui frame + ImGui_ImplSDLRenderer_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255)); + SDL_RenderClear(renderer); + ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); + SDL_RenderPresent(renderer); + } + + // Cleanup + ImGui_ImplSDLRenderer_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/build_win32.bat new file mode 100644 index 000000000..d4a718841 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/build_win32.bat @@ -0,0 +1,10 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. + +@set OUT_EXE=example_sdl_vulkan +@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I %VULKAN_SDK%\include +@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 /libpath:%VULKAN_SDK%\lib32 SDL2.lib SDL2main.lib shell32.lib vulkan-1.lib + +@set OUT_DIR=Debug +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj new file mode 100644 index 000000000..fc69ca70b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj @@ -0,0 +1,185 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3} + example_sdl_vulkan + 8.1 + + + + Application + true + MultiByte + v140 + + + Application + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + Application + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + %VULKAN_SDK%\lib32;%SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + vulkan-1.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + %VULKAN_SDK%\lib;%SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + vulkan-1.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + true + true + %VULKAN_SDK%\lib32;%SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) + vulkan-1.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) + false + ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + + + true + true + true + %VULKAN_SDK%\lib;%SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) + vulkan-1.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj.filters new file mode 100644 index 000000000..063a5936f --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + sources + + + imgui + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/main.cpp new file mode 100644 index 000000000..ade262718 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_sdl_vulkan/main.cpp @@ -0,0 +1,581 @@ +// Dear ImGui: standalone example application for SDL2 + Vulkan +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. +// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// You will use those if you want to use this rendering backend in your engine/app. +// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by +// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. +// Read comments in imgui_impl_vulkan.h. + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_vulkan.h" +#include // printf, fprintf +#include // abort +#include +#include +#include + +//#define IMGUI_UNLIMITED_FRAME_RATE +#ifdef _DEBUG +#define IMGUI_VULKAN_DEBUG_REPORT +#endif + +static VkAllocationCallbacks* g_Allocator = NULL; +static VkInstance g_Instance = VK_NULL_HANDLE; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static uint32_t g_QueueFamily = (uint32_t)-1; +static VkQueue g_Queue = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; + +static ImGui_ImplVulkanH_Window g_MainWindowData; +static uint32_t g_MinImageCount = 2; +static bool g_SwapChainRebuild = false; + +static void check_vk_result(VkResult err) +{ + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); + if (err < 0) + abort(); +} + +#ifdef IMGUI_VULKAN_DEBUG_REPORT +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +{ + (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments + fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + return VK_FALSE; +} +#endif // IMGUI_VULKAN_DEBUG_REPORT + +static void SetupVulkan(const char** extensions, uint32_t extensions_count) +{ + VkResult err; + + // Create Vulkan Instance + { + VkInstanceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.enabledExtensionCount = extensions_count; + create_info.ppEnabledExtensionNames = extensions; +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // Enabling validation layers + const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; + create_info.enabledLayerCount = 1; + create_info.ppEnabledLayerNames = layers; + + // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) + const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); + memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); + extensions_ext[extensions_count] = "VK_EXT_debug_report"; + create_info.enabledExtensionCount = extensions_count + 1; + create_info.ppEnabledExtensionNames = extensions_ext; + + // Create Vulkan Instance + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); + check_vk_result(err); + free(extensions_ext); + + // Get the function pointer (required for any extensions) + auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); + + // Setup the debug report callback + VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; + debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + debug_report_ci.pfnCallback = debug_report; + debug_report_ci.pUserData = NULL; + err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); + check_vk_result(err); +#else + // Create Vulkan Instance without any debug feature + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); + check_vk_result(err); + IM_UNUSED(g_DebugReport); +#endif + } + + // Select GPU + { + uint32_t gpu_count; + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); + check_vk_result(err); + IM_ASSERT(gpu_count > 0); + + VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); + check_vk_result(err); + + // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers + // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple + // dedicated GPUs) is out of scope of this sample. + int use_gpu = 0; + for (int i = 0; i < (int)gpu_count; i++) + { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(gpus[i], &properties); + if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + { + use_gpu = i; + break; + } + } + + g_PhysicalDevice = gpus[use_gpu]; + free(gpus); + } + + // Select graphics queue family + { + uint32_t count; + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); + VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); + for (uint32_t i = 0; i < count; i++) + if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + g_QueueFamily = i; + break; + } + free(queues); + IM_ASSERT(g_QueueFamily != (uint32_t)-1); + } + + // Create Logical Device (with 1 queue) + { + int device_extension_count = 1; + const char* device_extensions[] = { "VK_KHR_swapchain" }; + const float queue_priority[] = { 1.0f }; + VkDeviceQueueCreateInfo queue_info[1] = {}; + queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info[0].queueFamilyIndex = g_QueueFamily; + queue_info[0].queueCount = 1; + queue_info[0].pQueuePriorities = queue_priority; + VkDeviceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); + create_info.pQueueCreateInfos = queue_info; + create_info.enabledExtensionCount = device_extension_count; + create_info.ppEnabledExtensionNames = device_extensions; + err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); + check_vk_result(err); + vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); + } + + // Create Descriptor Pool + { + VkDescriptorPoolSize pool_sizes[] = + { + { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } + }; + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); + pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); + pool_info.pPoolSizes = pool_sizes; + err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); + check_vk_result(err); + } +} + +// All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. +// Your real engine/app may not use them. +static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) +{ + wd->Surface = surface; + + // Check for WSI support + VkBool32 res; + vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); + if (res != VK_TRUE) + { + fprintf(stderr, "Error no WSI support on physical device 0\n"); + exit(-1); + } + + // Select Surface Format + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); + + // Select Present Mode +#ifdef IMGUI_UNLIMITED_FRAME_RATE + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; +#else + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; +#endif + wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); + //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); + + // Create SwapChain, RenderPass, Framebuffer, etc. + IM_ASSERT(g_MinImageCount >= 2); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); +} + +static void CleanupVulkan() +{ + vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); + +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // Remove the debug report callback + auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); +#endif // IMGUI_VULKAN_DEBUG_REPORT + + vkDestroyDevice(g_Device, g_Allocator); + vkDestroyInstance(g_Instance, g_Allocator); +} + +static void CleanupVulkanWindow() +{ + ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); +} + +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) +{ + VkResult err; + + VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + { + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking + check_vk_result(err); + + err = vkResetFences(g_Device, 1, &fd->Fence); + check_vk_result(err); + } + { + err = vkResetCommandPool(g_Device, fd->CommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(fd->CommandBuffer, &info); + check_vk_result(err); + } + { + VkRenderPassBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = wd->RenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = wd->Width; + info.renderArea.extent.height = wd->Height; + info.clearValueCount = 1; + info.pClearValues = &wd->ClearValue; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } + + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); + + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + { + VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &image_acquired_semaphore; + info.pWaitDstStageMask = &wait_stage; + info.commandBufferCount = 1; + info.pCommandBuffers = &fd->CommandBuffer; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &render_complete_semaphore; + + err = vkEndCommandBuffer(fd->CommandBuffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); + check_vk_result(err); + } +} + +static void FramePresent(ImGui_ImplVulkanH_Window* wd) +{ + if (g_SwapChainRebuild) + return; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &render_complete_semaphore; + info.swapchainCount = 1; + info.pSwapchains = &wd->Swapchain; + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores +} + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); + + // Setup Vulkan + uint32_t extensions_count = 0; + SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, NULL); + const char** extensions = new const char*[extensions_count]; + SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions); + SetupVulkan(extensions, extensions_count); + delete[] extensions; + + // Create Window Surface + VkSurfaceKHR surface; + VkResult err; + if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0) + { + printf("Failed to create Vulkan surface.\n"); + return 1; + } + + // Create Framebuffers + int w, h; + SDL_GetWindowSize(window, &w, &h); + ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; + SetupVulkanWindow(wd, surface, w, h); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons; + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForVulkan(window); + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Instance = g_Instance; + init_info.PhysicalDevice = g_PhysicalDevice; + init_info.Device = g_Device; + init_info.QueueFamily = g_QueueFamily; + init_info.Queue = g_Queue; + init_info.PipelineCache = g_PipelineCache; + init_info.DescriptorPool = g_DescriptorPool; + init_info.Subpass = 0; + init_info.MinImageCount = g_MinImageCount; + init_info.ImageCount = wd->ImageCount; + init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + init_info.Allocator = g_Allocator; + init_info.CheckVkResultFn = check_vk_result; + ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Upload Fonts + { + // Use any command queue + VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; + VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; + + err = vkResetCommandPool(g_Device, command_pool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(command_buffer, &begin_info); + check_vk_result(err); + + ImGui_ImplVulkan_CreateFontsTexture(command_buffer); + + VkSubmitInfo end_info = {}; + end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + end_info.commandBufferCount = 1; + end_info.pCommandBuffers = &command_buffer; + err = vkEndCommandBuffer(command_buffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); + check_vk_result(err); + + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplVulkan_DestroyFontUploadObjects(); + } + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + // Resize swap chain? + if (g_SwapChainRebuild) + { + int width, height; + SDL_GetWindowSize(window, &width, &height); + if (width > 0 && height > 0) + { + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; + } + } + + // Start the Dear ImGui frame + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* main_draw_data = ImGui::GetDrawData(); + const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f); + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; + if (!main_is_minimized) + FrameRender(wd, main_draw_data); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + // Present Main Platform Window + if (!main_is_minimized) + FramePresent(wd); + } + + // Cleanup + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplVulkan_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + CleanupVulkanWindow(); + CleanupVulkan(); + + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/build_win32.bat new file mode 100644 index 000000000..fd742239c --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_win32_directx10 +@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" +@set SOURCES=main.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\backends\imgui_impl_dx10.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d10.lib d3dcompiler.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj new file mode 100644 index 000000000..e71cb0a79 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj @@ -0,0 +1,171 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {345A953E-A004-4648-B442-DC5F9F11068C} + example_win32_directx10 + 8.1 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + + + true + d3d10.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + + + true + d3d10.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + false + + + true + true + true + d3d10.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + false + + + true + true + true + d3d10.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters new file mode 100644 index 000000000..11ad8f90f --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/example_win32_directx10.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {0587d7a3-f2ce-4d56-b84f-a0005d3bfce6} + + + {08e36723-ce4f-4cff-9662-c40801cf1acf} + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + sources + + + imgui + + + imgui + + + sources + + + sources + + + imgui + + + imgui + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/main.cpp new file mode 100644 index 000000000..33bad3872 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx10/main.cpp @@ -0,0 +1,261 @@ +// Dear ImGui: standalone example application for DirectX 10 +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_win32.h" +#include "imgui_impl_dx10.h" +#include +#include +#include + +// Data +static ID3D10Device* g_pd3dDevice = NULL; +static IDXGISwapChain* g_pSwapChain = NULL; +static ID3D10RenderTargetView* g_mainRenderTargetView = NULL; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void CreateRenderTarget(); +void CleanupRenderTarget(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Main code +int main(int, char**) +{ + // Create application window + //ImGui_ImplWin32_EnableDpiAwareness(); + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; + ::RegisterClassEx(&wc); + HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX10 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + return 1; + } + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX10_Init(g_pd3dDevice); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + MSG msg; + while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + // Start the Dear ImGui frame + ImGui_ImplDX10_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dDevice->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); + g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); + ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync + } + + ImGui_ImplDX10_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + //createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG; + if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK) + return false; + + CreateRenderTarget(); + return true; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } +} + +void CreateRenderTarget() +{ + ID3D10Texture2D* pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); + pBackBuffer->Release(); +} + +void CleanupRenderTarget() +{ + if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } +} + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0); + CreateRenderTarget(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/build_win32.bat new file mode 100644 index 000000000..b1cf7d1cb --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/build_win32.bat @@ -0,0 +1,9 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_win32_directx11 +@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" +@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj new file mode 100644 index 000000000..273d351cb --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj @@ -0,0 +1,170 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9F316E83-5AE5-4939-A723-305A94F48005} + example_win32_directx11 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + + + true + d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + + + true + d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + false + + + true + true + true + d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories); + false + + + true + true + true + d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters new file mode 100644 index 000000000..02cf18cab --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/example_win32_directx11.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {0587d7a3-f2ce-4d56-b84f-a0005d3bfce6} + + + {08e36723-ce4f-4cff-9662-c40801cf1acf} + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + sources + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + imgui + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/main.cpp new file mode 100644 index 000000000..d6378d804 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx11/main.cpp @@ -0,0 +1,283 @@ +// Dear ImGui: standalone example application for DirectX 11 +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_win32.h" +#include "imgui_impl_dx11.h" +#include +#include + +// Data +static ID3D11Device* g_pd3dDevice = NULL; +static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; +static IDXGISwapChain* g_pSwapChain = NULL; +static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void CreateRenderTarget(); +void CleanupRenderTarget(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Main code +int main(int, char**) +{ + // Create application window + //ImGui_ImplWin32_EnableDpiAwareness(); + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; + ::RegisterClassEx(&wc); + HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX11 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + return 1; + } + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + //io.ConfigViewportsNoDefaultParent = true; + //io.ConfigDockingAlwaysTabBar = true; + //io.ConfigDockingTransparentPayload = true; + //io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: Experimental. THIS CURRENTLY DOESN'T WORK AS EXPECTED. DON'T USE IN USER APP! + //io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI: Experimental. + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + MSG msg; + while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + // Start the Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync + } + + // Cleanup + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + return false; + + CreateRenderTarget(); + return true; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } + if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } +} + +void CreateRenderTarget() +{ + ID3D11Texture2D* pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); + pBackBuffer->Release(); +} + +void CleanupRenderTarget() +{ + if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } +} + +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers +#endif + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0); + CreateRenderTarget(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + case WM_DPICHANGED: + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) + { + //const int dpi = HIWORD(wParam); + //printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f); + const RECT* suggested_rect = (RECT*)lParam; + ::SetWindowPos(hWnd, NULL, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE); + } + break; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/build_win32.bat new file mode 100644 index 000000000..48dadb299 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/build_win32.bat @@ -0,0 +1,9 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@REM Important: to build on 32-bit systems, the DX12 backends needs '#define ImTextureID ImU64', so we pass it here. +@set OUT_DIR=Debug +@set OUT_EXE=example_win32_directx12 +@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" +@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp +@set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib +mkdir Debug +cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj new file mode 100644 index 000000000..3fed30d94 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {b4cf9797-519d-4afe-a8f4-5141a6b521d3} + example_win32_directx12 + 10.0.18362.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + true + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories) + ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + true + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters new file mode 100644 index 000000000..91fc7343d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/example_win32_directx12.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {fb3d294f-51ec-478e-a627-25831c80fefd} + + + {4f33ddea-9910-456d-b868-4267eb3c2b19} + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + sources + + + imgui + + + imgui + + + sources + + + sources + + + imgui + + + imgui + + + + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/main.cpp new file mode 100644 index 000000000..acb4eb136 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx12/main.cpp @@ -0,0 +1,483 @@ +// Dear ImGui: standalone example application for DirectX 12 +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// Important: to compile on 32-bit systems, the DirectX12 backend requires code to be compiled with '#define ImTextureID ImU64'. +// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. +// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file. + +#include "imgui.h" +#include "imgui_impl_win32.h" +#include "imgui_impl_dx12.h" +#include +#include +#include + +#ifdef _DEBUG +#define DX12_ENABLE_DEBUG_LAYER +#endif + +#ifdef DX12_ENABLE_DEBUG_LAYER +#include +#pragma comment(lib, "dxguid.lib") +#endif + +struct FrameContext +{ + ID3D12CommandAllocator* CommandAllocator; + UINT64 FenceValue; +}; + +// Data +static int const NUM_FRAMES_IN_FLIGHT = 3; +static FrameContext g_frameContext[NUM_FRAMES_IN_FLIGHT] = {}; +static UINT g_frameIndex = 0; + +static int const NUM_BACK_BUFFERS = 3; +static ID3D12Device* g_pd3dDevice = NULL; +static ID3D12DescriptorHeap* g_pd3dRtvDescHeap = NULL; +static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = NULL; +static ID3D12CommandQueue* g_pd3dCommandQueue = NULL; +static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; +static ID3D12Fence* g_fence = NULL; +static HANDLE g_fenceEvent = NULL; +static UINT64 g_fenceLastSignaledValue = 0; +static IDXGISwapChain3* g_pSwapChain = NULL; +static HANDLE g_hSwapChainWaitableObject = NULL; +static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; +static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {}; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void CreateRenderTarget(); +void CleanupRenderTarget(); +void WaitForLastSubmittedFrame(); +FrameContext* WaitForNextFrameResources(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Main code +int main(int, char**) +{ + // Create application window + //ImGui_ImplWin32_EnableDpiAwareness(); + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; + ::RegisterClassEx(&wc); + HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + return 1; + } + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT, + DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap, + g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), + g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + MSG msg; + while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + // Start the Dear ImGui frame + ImGui_ImplDX12_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + + FrameContext* frameCtx = WaitForNextFrameResources(); + UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex(); + frameCtx->CommandAllocator->Reset(); + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx]; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + g_pd3dCommandList->Reset(frameCtx->CommandAllocator, NULL); + g_pd3dCommandList->ResourceBarrier(1, &barrier); + + // Render Dear ImGui graphics + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], clear_color_with_alpha, 0, NULL); + g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); + g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); + ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList); + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + g_pd3dCommandList->ResourceBarrier(1, &barrier); + g_pd3dCommandList->Close(); + + g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(NULL, (void*)g_pd3dCommandList); + } + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync + + UINT64 fenceValue = g_fenceLastSignaledValue + 1; + g_pd3dCommandQueue->Signal(g_fence, fenceValue); + g_fenceLastSignaledValue = fenceValue; + frameCtx->FenceValue = fenceValue; + } + + WaitForLastSubmittedFrame(); + + // Cleanup + ImGui_ImplDX12_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC1 sd; + { + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = NUM_BACK_BUFFERS; + sd.Width = 0; + sd.Height = 0; + sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + sd.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + sd.Scaling = DXGI_SCALING_STRETCH; + sd.Stereo = FALSE; + } + + // [DEBUG] Enable debug interface +#ifdef DX12_ENABLE_DEBUG_LAYER + ID3D12Debug* pdx12Debug = NULL; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&pdx12Debug)))) + pdx12Debug->EnableDebugLayer(); +#endif + + // Create device + D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; + if (D3D12CreateDevice(NULL, featureLevel, IID_PPV_ARGS(&g_pd3dDevice)) != S_OK) + return false; + + // [DEBUG] Setup debug interface to break on any warnings/errors +#ifdef DX12_ENABLE_DEBUG_LAYER + if (pdx12Debug != NULL) + { + ID3D12InfoQueue* pInfoQueue = NULL; + g_pd3dDevice->QueryInterface(IID_PPV_ARGS(&pInfoQueue)); + pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true); + pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true); + pInfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, true); + pInfoQueue->Release(); + pdx12Debug->Release(); + } +#endif + + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + desc.NumDescriptors = NUM_BACK_BUFFERS; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + desc.NodeMask = 1; + if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK) + return false; + + SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart(); + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) + { + g_mainRenderTargetDescriptor[i] = rtvHandle; + rtvHandle.ptr += rtvDescriptorSize; + } + } + + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = 1; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)) != S_OK) + return false; + } + + { + D3D12_COMMAND_QUEUE_DESC desc = {}; + desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + desc.NodeMask = 1; + if (g_pd3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&g_pd3dCommandQueue)) != S_OK) + return false; + } + + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) + if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK) + return false; + + if (g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_frameContext[0].CommandAllocator, NULL, IID_PPV_ARGS(&g_pd3dCommandList)) != S_OK || + g_pd3dCommandList->Close() != S_OK) + return false; + + if (g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&g_fence)) != S_OK) + return false; + + g_fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (g_fenceEvent == NULL) + return false; + + { + IDXGIFactory4* dxgiFactory = NULL; + IDXGISwapChain1* swapChain1 = NULL; + if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK) + return false; + if (dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1) != S_OK) + return false; + if (swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK) + return false; + swapChain1->Release(); + dxgiFactory->Release(); + g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS); + g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject(); + } + + CreateRenderTarget(); + return true; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->SetFullscreenState(false, NULL); g_pSwapChain->Release(); g_pSwapChain = NULL; } + if (g_hSwapChainWaitableObject != NULL) { CloseHandle(g_hSwapChainWaitableObject); } + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) + if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = NULL; } + if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; } + if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = NULL; } + if (g_pd3dRtvDescHeap) { g_pd3dRtvDescHeap->Release(); g_pd3dRtvDescHeap = NULL; } + if (g_pd3dSrvDescHeap) { g_pd3dSrvDescHeap->Release(); g_pd3dSrvDescHeap = NULL; } + if (g_fence) { g_fence->Release(); g_fence = NULL; } + if (g_fenceEvent) { CloseHandle(g_fenceEvent); g_fenceEvent = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + +#ifdef DX12_ENABLE_DEBUG_LAYER + IDXGIDebug1* pDebug = NULL; + if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&pDebug)))) + { + pDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_SUMMARY); + pDebug->Release(); + } +#endif +} + +void CreateRenderTarget() +{ + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) + { + ID3D12Resource* pBackBuffer = NULL; + g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, g_mainRenderTargetDescriptor[i]); + g_mainRenderTargetResource[i] = pBackBuffer; + } +} + +void CleanupRenderTarget() +{ + WaitForLastSubmittedFrame(); + + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) + if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = NULL; } +} + +void WaitForLastSubmittedFrame() +{ + FrameContext* frameCtx = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT]; + + UINT64 fenceValue = frameCtx->FenceValue; + if (fenceValue == 0) + return; // No fence was signaled + + frameCtx->FenceValue = 0; + if (g_fence->GetCompletedValue() >= fenceValue) + return; + + g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent); + WaitForSingleObject(g_fenceEvent, INFINITE); +} + +FrameContext* WaitForNextFrameResources() +{ + UINT nextFrameIndex = g_frameIndex + 1; + g_frameIndex = nextFrameIndex; + + HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, NULL }; + DWORD numWaitableObjects = 1; + + FrameContext* frameCtx = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT]; + UINT64 fenceValue = frameCtx->FenceValue; + if (fenceValue != 0) // means no fence was signaled + { + frameCtx->FenceValue = 0; + g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent); + waitableObjects[1] = g_fenceEvent; + numWaitableObjects = 2; + } + + WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE); + + return frameCtx; +} + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + WaitForLastSubmittedFrame(); + CleanupRenderTarget(); + HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT); + assert(SUCCEEDED(result) && "Failed to resize swapchain."); + CreateRenderTarget(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/build_win32.bat b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/build_win32.bat new file mode 100644 index 000000000..bbd4b13ca --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/build_win32.bat @@ -0,0 +1,8 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +@set OUT_DIR=Debug +@set OUT_EXE=example_win32_directx9 +@set INCLUDES=/I..\.. /I..\..\backends /I "%DXSDK_DIR%/Include" +@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx9.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp +@set LIBS=/LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d9.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj new file mode 100644 index 000000000..e01eca146 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj @@ -0,0 +1,171 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4165A294-21F2-44CA-9B38-E3F935ABADF5} + example_win32_directx9 + 8.1 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + + + true + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + d3d9.lib;%(AdditionalDependencies) + Console + + + + + Level4 + Disabled + ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + + + true + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + d3d9.lib;%(AdditionalDependencies) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false + + + true + true + true + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + d3d9.lib;%(AdditionalDependencies) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false + + + true + true + true + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + d3d9.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters new file mode 100644 index 000000000..9493970b6 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/example_win32_directx9.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {a82cba23-9de0-45c2-b1e3-2eb1666702de} + + + + + sources + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + + sources + + + diff --git a/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/main.cpp b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/main.cpp new file mode 100644 index 000000000..462883c19 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/example_win32_directx9/main.cpp @@ -0,0 +1,269 @@ +// Dear ImGui: standalone example application for DirectX 9 +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#include "imgui.h" +#include "imgui_impl_dx9.h" +#include "imgui_impl_win32.h" +#include +#include + +// Data +static LPDIRECT3D9 g_pD3D = NULL; +static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; +static D3DPRESENT_PARAMETERS g_d3dpp = {}; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void ResetDevice(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Main code +int main(int, char**) +{ + // Create application window + //ImGui_ImplWin32_EnableDpiAwareness(); + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; + ::RegisterClassEx(&wc); + HWND hwnd = ::CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + return 1; + } + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + //io.ConfigViewportsNoAutoMerge = true; + //io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX9_Init(g_pd3dDevice); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + MSG msg; + while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + // Start the Dear ImGui frame + ImGui_ImplDX9_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::EndFrame(); + g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*clear_color.w*255.0f), (int)(clear_color.y*clear_color.w*255.0f), (int)(clear_color.z*clear_color.w*255.0f), (int)(clear_color.w*255.0f)); + g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); + if (g_pd3dDevice->BeginScene() >= 0) + { + ImGui::Render(); + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + g_pd3dDevice->EndScene(); + } + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); + + // Handle loss of D3D9 device + if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) + ResetDevice(); + } + + ImGui_ImplDX9_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) + return false; + + // Create the D3DDevice + ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); + g_d3dpp.Windowed = TRUE; + g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // Need to use an explicit format with alpha if needing per-pixel alpha composition. + g_d3dpp.EnableAutoDepthStencil = TRUE; + g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync + //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate + if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) + return false; + + return true; +} + +void CleanupDeviceD3D() +{ + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } +} + +void ResetDevice() +{ + ImGui_ImplDX9_InvalidateDeviceObjects(); + HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); + if (hr == D3DERR_INVALIDCALL) + IM_ASSERT(0); + ImGui_ImplDX9_CreateDeviceObjects(); +} + +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers +#endif + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + g_d3dpp.BackBufferWidth = LOWORD(lParam); + g_d3dpp.BackBufferHeight = HIWORD(lParam); + ResetDevice(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + case WM_DPICHANGED: + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) + { + //const int dpi = HIWORD(wParam); + //printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f); + const RECT* suggested_rect = (RECT*)lParam; + ::SetWindowPos(hWnd, NULL, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE); + } + break; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/imgui_examples.sln b/libultraship/libultraship/Lib/ImGui/examples/imgui_examples.sln new file mode 100644 index 000000000..d68f69ecb --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/imgui_examples.sln @@ -0,0 +1,128 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx9", "example_win32_directx9\example_win32_directx9.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "example_win32_directx10\example_win32_directx10.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl3", "example_glfw_opengl3\example_glfw_opengl3.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_vulkan", "example_glfw_vulkan\example_glfw_vulkan.vcxproj", "{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_opengl2", "example_sdl_opengl2\example_sdl_opengl2.vcxproj", "{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_opengl3", "example_sdl_opengl3\example_sdl_opengl3.vcxproj", "{BBAEB705-1669-40F3-8567-04CF6A991F4C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_vulkan", "example_sdl_vulkan\example_sdl_vulkan.vcxproj", "{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_directx11", "example_sdl_directx11\example_sdl_directx11.vcxproj", "{9E1987E3-1F19-45CA-B9C9-D31E791836D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.ActiveCfg = Debug|Win32 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.Build.0 = Debug|Win32 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|x64.ActiveCfg = Debug|x64 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|x64.Build.0 = Debug|x64 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.ActiveCfg = Release|Win32 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.Build.0 = Release|Win32 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|x64.ActiveCfg = Release|x64 + {4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|x64.Build.0 = Release|x64 + {345A953E-A004-4648-B442-DC5F9F11068C}.Debug|Win32.ActiveCfg = Debug|Win32 + {345A953E-A004-4648-B442-DC5F9F11068C}.Debug|Win32.Build.0 = Debug|Win32 + {345A953E-A004-4648-B442-DC5F9F11068C}.Debug|x64.ActiveCfg = Debug|x64 + {345A953E-A004-4648-B442-DC5F9F11068C}.Debug|x64.Build.0 = Debug|x64 + {345A953E-A004-4648-B442-DC5F9F11068C}.Release|Win32.ActiveCfg = Release|Win32 + {345A953E-A004-4648-B442-DC5F9F11068C}.Release|Win32.Build.0 = Release|Win32 + {345A953E-A004-4648-B442-DC5F9F11068C}.Release|x64.ActiveCfg = Release|x64 + {345A953E-A004-4648-B442-DC5F9F11068C}.Release|x64.Build.0 = Release|x64 + {9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.Build.0 = Debug|Win32 + {9F316E83-5AE5-4939-A723-305A94F48005}.Debug|x64.ActiveCfg = Debug|x64 + {9F316E83-5AE5-4939-A723-305A94F48005}.Debug|x64.Build.0 = Debug|x64 + {9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.ActiveCfg = Release|Win32 + {9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32 + {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.ActiveCfg = Release|x64 + {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.Build.0 = Release|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.Build.0 = Debug|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.ActiveCfg = Debug|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.Build.0 = Debug|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.ActiveCfg = Release|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.Build.0 = Release|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.ActiveCfg = Release|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.Build.0 = Release|x64 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|x64.ActiveCfg = Debug|x64 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|x64.Build.0 = Debug|x64 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|x64.ActiveCfg = Release|x64 + {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|x64.Build.0 = Release|x64 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.Build.0 = Debug|Win32 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|x64.ActiveCfg = Debug|x64 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|x64.Build.0 = Debug|x64 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.ActiveCfg = Release|Win32 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.Build.0 = Release|Win32 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|x64.ActiveCfg = Release|x64 + {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|x64.Build.0 = Release|x64 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|Win32.ActiveCfg = Debug|Win32 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|Win32.Build.0 = Debug|Win32 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|x64.ActiveCfg = Debug|x64 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|x64.Build.0 = Debug|x64 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|Win32.ActiveCfg = Release|Win32 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|Win32.Build.0 = Release|Win32 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|x64.ActiveCfg = Release|x64 + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|x64.Build.0 = Release|x64 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|Win32.ActiveCfg = Debug|Win32 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|Win32.Build.0 = Debug|Win32 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|x64.ActiveCfg = Debug|x64 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|x64.Build.0 = Debug|x64 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|Win32.ActiveCfg = Release|Win32 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|Win32.Build.0 = Release|Win32 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|x64.ActiveCfg = Release|x64 + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|x64.Build.0 = Release|x64 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|Win32.ActiveCfg = Debug|Win32 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|Win32.Build.0 = Debug|Win32 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|x64.ActiveCfg = Debug|x64 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|x64.Build.0 = Debug|x64 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|Win32.ActiveCfg = Release|Win32 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|Win32.Build.0 = Release|Win32 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|x64.ActiveCfg = Release|x64 + {BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|x64.Build.0 = Release|x64 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|Win32.ActiveCfg = Debug|Win32 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|Win32.Build.0 = Debug|Win32 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|x64.ActiveCfg = Debug|x64 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|x64.Build.0 = Debug|x64 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|Win32.ActiveCfg = Release|Win32 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|Win32.Build.0 = Release|Win32 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.ActiveCfg = Release|x64 + {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.Build.0 = Release|x64 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|Win32.Build.0 = Debug|Win32 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|x64.ActiveCfg = Debug|x64 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|x64.Build.0 = Debug|x64 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|Win32.ActiveCfg = Release|Win32 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|Win32.Build.0 = Release|Win32 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|x64.ActiveCfg = Release|x64 + {9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/COPYING.txt b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/COPYING.txt new file mode 100644 index 000000000..b30c70158 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/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/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3.h b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3.h new file mode 100644 index 000000000..f8ca3d61a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3.h @@ -0,0 +1,4227 @@ +/************************************************************************* + * GLFW 3.2 - 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 + *************************************************************************/ + +/*! @file glfw3.h + * @brief The header of the GLFW 3 API. + * + * This is the header file of the GLFW 3 API. It defines all its types and + * declares all its functions. + * + * For more information about how to use this file, see @ref build_include. + */ +/*! @defgroup context Context reference + * + * This is the reference documentation for OpenGL and OpenGL ES context related + * functions. For more task-oriented information, see the @ref context_guide. + */ +/*! @defgroup vulkan Vulkan reference + * + * This is the reference documentation for Vulkan related functions and types. + * For more task-oriented information, see the @ref vulkan_guide. + */ +/*! @defgroup init Initialization, version and error reference + * + * This is the reference documentation for initialization and termination of + * the library, version management and error handling. For more task-oriented + * information, see the @ref intro_guide. + */ +/*! @defgroup input Input reference + * + * This is the reference documentation for input related functions and types. + * For more task-oriented information, see the @ref input_guide. + */ +/*! @defgroup monitor Monitor reference + * + * This is the reference documentation for monitor related functions and types. + * For more task-oriented information, see the @ref monitor_guide. + */ +/*! @defgroup window Window reference + * + * This is the reference documentation for window related functions and types, + * including creation, deletion and event polling. For more task-oriented + * information, see the @ref window_guide. + */ + + +/************************************************************************* + * Compiler- and platform-specific preprocessor work + *************************************************************************/ + +/* If we are we on Windows, we want a single define for it. + */ +#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) + #define _WIN32 +#endif /* _WIN32 */ + +/* It is customary to use APIENTRY for OpenGL function pointer declarations on + * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. + */ +#ifndef APIENTRY + #ifdef _WIN32 + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif +#endif /* APIENTRY */ + +/* Some Windows OpenGL headers need this. + */ +#if !defined(WINGDIAPI) && defined(_WIN32) + #define WINGDIAPI __declspec(dllimport) + #define GLFW_WINGDIAPI_DEFINED +#endif /* WINGDIAPI */ + +/* Some Windows GLU headers need this. + */ +#if !defined(CALLBACK) && defined(_WIN32) + #define CALLBACK __stdcall + #define GLFW_CALLBACK_DEFINED +#endif /* CALLBACK */ + +/* Most Windows GLU headers need wchar_t. + * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include +#include + +/* Include the chosen client API headers. + */ +#if defined(__APPLE__) + #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_VULKAN) + #include + #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 */ + #define GLFWAPI __declspec(dllimport) +#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 + + +/************************************************************************* + * 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 2 +/*! @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 Boolean values + * @{ */ +/*! @brief One. + * + * One. Seriously. You don't _need_ to use this symbol in your code. It's + * just semantic sugar for the number 1. You can use `1` or `true` or `_True` + * or `GL_TRUE` or whatever you want. + */ +#define GLFW_TRUE 1 +/*! @brief Zero. + * + * Zero. Seriously. You don't _need_ to use this symbol in your code. It's + * just just semantic sugar for the number 0. You can use `0` or `false` or + * `_False` or `GL_FALSE` or whatever you want. + */ +#define GLFW_FALSE 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 must not be called unless the + * library is [initialized](@ref intro_init). + * + * @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. + * + * @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. + * + * @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. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_INVALID_VALUE 0x00010004 +/*! @brief A memory allocation failed. + * + * A memory allocation failed. + * + * @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 API on the system. + * + * GLFW could not find support for the requested API on the system. + * + * @analysis The installed graphics driver does not support the requested + * 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 support 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. Older graphics drivers do not support Vulkan. + */ +#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 context + * or framebuffer hints) is not available on this machine. + * + * @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. + * + * @analysis A bug or configuration error in GLFW, the underlying operating + * system or its drivers, or a lack of required resources. Report the issue 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. + * + * @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 +/*! @brief The specified window does not have an OpenGL or OpenGL ES context. + * + * A window that does not have an OpenGL or OpenGL ES context was passed to + * a function that requires it to have one. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_NO_WINDOW_CONTEXT 0x0001000A +/*! @} */ + +#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_MAXIMIZED 0x00020008 + +#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_CONTEXT_NO_ERROR 0x0002200A + +#define GLFW_NO_API 0 +#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. + * + * @sa @ref context_glext + * @sa glfwGetProcAddress + * + * @since Added in version 3.0. + + * @ingroup context + */ +typedef void (*GLFWglproc)(void); + +/*! @brief Vulkan API function pointer type. + * + * Generic function pointer used for returning Vulkan API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref vulkan_proc + * @sa glfwGetInstanceProcAddress + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +typedef void (*GLFWvkproc)(void); + +/*! @brief Opaque monitor object. + * + * Opaque monitor object. + * + * @see @ref monitor_object + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef struct GLFWmonitor GLFWmonitor; + +/*! @brief Opaque window object. + * + * Opaque window object. + * + * @see @ref window_object + * + * @since Added in version 3.0. + * + * @ingroup window + */ +typedef struct GLFWwindow GLFWwindow; + +/*! @brief Opaque cursor object. + * + * Opaque cursor object. + * + * @see @ref cursor_object + * + * @since Added in version 3.1. + * + * @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 @ref error_handling + * @sa glfwSetErrorCallback + * + * @since Added in version 3.0. + * + * @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 @ref window_pos + * @sa glfwSetWindowPosCallback + * + * @since Added in version 3.0. + * + * @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 @ref window_size + * @sa glfwSetWindowSizeCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @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 @ref window_close + * @sa glfwSetWindowCloseCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @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 @ref window_refresh + * @sa glfwSetWindowRefreshCallback + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * + * @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 `GLFW_TRUE` if the window was given input focus, or + * `GLFW_FALSE` if it lost it. + * + * @sa @ref window_focus + * @sa glfwSetWindowFocusCallback + * + * @since Added in version 3.0. + * + * @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 `GLFW_TRUE` if the window was iconified, or + * `GLFW_FALSE` if it was restored. + * + * @sa @ref window_iconify + * @sa glfwSetWindowIconifyCallback + * + * @since Added in version 3.0. + * + * @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 @ref window_fbsize + * @sa glfwSetFramebufferSizeCallback + * + * @since Added in version 3.0. + * + * @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 @ref input_mouse_button + * @sa glfwSetMouseButtonCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle and modifier mask parameters. + * + * @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 cursor x-coordinate, relative to the left edge of + * the client area. + * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the + * client area. + * + * @sa @ref cursor_pos + * @sa glfwSetCursorPosCallback + * + * @since Added in version 3.0. Replaces `GLFWmouseposfun`. + * + * @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 `GLFW_TRUE` if the cursor entered the window's client + * area, or `GLFW_FALSE` if it left it. + * + * @sa @ref cursor_enter + * @sa glfwSetCursorEnterCallback + * + * @since Added in version 3.0. + * + * @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 @ref scrolling + * @sa glfwSetScrollCallback + * + * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. + * + * @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 @ref input_key + * @sa glfwSetKeyCallback + * + * @since Added in version 1.0. + * @glfw3 Added window handle, scancode and modifier mask parameters. + * + * @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 @ref input_char + * @sa glfwSetCharCallback + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter. + * + * @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 @ref input_char + * @sa glfwSetCharModsCallback + * + * @since Added in version 3.1. + * + * @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] paths The UTF-8 encoded file and/or directory path names. + * + * @sa @ref path_drop + * @sa glfwSetDropCallback + * + * @since Added in version 3.1. + * + * @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 @ref monitor_event + * @sa glfwSetMonitorCallback + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); + +/*! @brief The function signature for joystick configuration callbacks. + * + * This is the function signature for joystick configuration callback + * functions. + * + * @param[in] joy The joystick that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. + * + * @sa @ref joystick_event + * @sa glfwSetJoystickCallback + * + * @since Added in version 3.2. + * + * @ingroup input + */ +typedef void (* GLFWjoystickfun)(int,int); + +/*! @brief Video mode type. + * + * This describes a single video mode. + * + * @sa @ref monitor_modes + * @sa glfwGetVideoMode glfwGetVideoModes + * + * @since Added in version 1.0. + * @glfw3 Added refresh rate member. + * + * @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 @ref monitor_gamma + * @sa glfwGetGammaRamp glfwSetGammaRamp + * + * @since Added in version 3.0. + * + * @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. + * + * @sa @ref cursor_custom + * + * @since Added in version 2.1. + * @glfw3 Removed format and bytes-per-pixel members. + */ +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 `GLFW_TRUE` immediately. + * + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark @osx 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). + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa glfwTerminate + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark This function may be called before @ref glfwInit. + * + * @warning The contexts of any remaining windows must not be current on any + * other thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref intro_init + * @sa glfwInit + * + * @since Added in version 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`. + * + * @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`. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa glfwGetVersionString + * + * @since Added in version 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. It should not be confused with the OpenGL or OpenGL + * ES version string, queried with `glGetString`. + * + * __Do not use the version string__ to parse the GLFW library version. The + * @ref glfwGetVersion function provides the version of the running library + * binary in numerical format. + * + * @return The ASCII encoded GLFW version string. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @pointer_lifetime The returned string is static and compile-time generated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref intro_version + * @sa glfwGetVersion + * + * @since Added in version 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. + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref error_handling + * + * @since Added in version 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. The primary monitor is always first in the returned array. If no + * monitors were found, this function returns `NULL`. + * + * @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 no monitors were found or + * if an [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_monitors + * @sa @ref monitor_event + * @sa glfwGetPrimaryMonitor + * + * @since Added in version 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 task bar or global menu bar are located. + * + * @return The primary monitor, or `NULL` if no monitors were found or if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @remark The primary monitor is always first in the array returned by @ref + * glfwGetMonitors. + * + * @sa @ref monitor_monitors + * @sa glfwGetMonitors + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @win32 calculates the returned physical size from the + * current resolution and system DPI instead of querying the monitor EDID data. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_event + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa glfwGetVideoMode + * + * @since Added in version 1.0. + * @glfw3 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_modes + * @sa glfwGetVideoModes + * + * @since Added in version 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. The value must be a finite + * number greater than zero. + * + * @param[in] monitor The monitor whose gamma ramp to set. + * @param[in] gamma The desired exponent. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark Gamma ramp sizes other than 256 are not supported by all platforms + * or graphics hardware. + * + * @remark @win32 The gamma ramp size must be 256. + * + * @pointer_lifetime The specified gamma ramp is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_gamma + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa glfwWindowHint + * + * @since Added in version 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. + * + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. + * + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hints + * @sa glfwDefaultWindowHints + * + * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. + * + * @ingroup window + */ +GLFWAPI void glfwWindowHint(int hint, int value); + +/*! @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, see @ref + * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. + * + * To create a full screen window, you need to specify the monitor the window + * will cover. If no monitor is specified, the window will be windowed mode. + * 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 is not + * iconified, 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. + * + * As long as at least one full screen window is not iconified, 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` for + * 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @win32 Window creation will fail if the Microsoft GDI software + * OpenGL implementation is the only one available. + * + * @remark @win32 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. + * + * @remark @win32 The context to share resources with must not be current on + * any other thread. + * + * @remark @osx 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. + * + * @remark @osx 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). + * + * @remark @osx On OS X 10.10 and later the window frame will not be rendered + * at full resolution on Retina displays unless the `NSHighResolutionCapable` + * key is enabled in the application bundle's `Info.plist`. For more + * information, see + * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) + * in the Mac Developer Library. The GLFW test and example programs use + * a custom `Info.plist` template for this, which can be found as + * `CMake/MacOSXBundleInfo.plist.in` in the source tree. + * + * @remark @x11 There is no mechanism for setting the window icon yet. + * + * @remark @x11 Some window managers will not respect the placement of + * initially hidden windows. + * + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * a window to reach its requested state. This means you may not be able to + * query the final size, position or other attributes directly after window + * creation. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa glfwDestroyWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @note The context of the specified window must not be current on any other + * thread when this function is called. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_creation + * @sa glfwCreateWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_close + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @osx The window title will not be updated until the next time you + * process events. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_title + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); + +/*! @brief Sets the icon for the specified window. + * + * This function sets the icon of the specified window. If passed an array of + * candidate images, those of or closest to the sizes desired by the system are + * selected. If no images are specified, the window reverts to its default + * icon. + * + * The desired image sizes varies depending on platform and system settings. + * The selected images will be rescaled as needed. Good sizes include 16x16, + * 32x32 and 48x48. + * + * @param[in] window The window whose icon to set. + * @param[in] count The number of images in the specified array, or zero to + * revert to the default window icon. + * @param[in] images The images to create the icon from. This is ignored if + * count is zero. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @remark @osx 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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_icon + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); + +/*! @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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa glfwSetWindowPos + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * @sa glfwGetWindowPos + * + * @since Added in version 1.0. + * @glfw3 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa glfwSetWindowSize + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); + +/*! @brief Sets the size limits of the specified window. + * + * This function sets the size limits of the client area of the specified + * window. If the window is full screen, the size limits only take effect if + * once it is made windowed. If the window is not resizable, this function + * does nothing. + * + * The size limits are applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] minwidth The minimum width, in screen coordinates, of the client + * area, or `GLFW_DONT_CARE`. + * @param[in] minheight The minimum height, in screen coordinates, of the + * client area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the client + * area, or `GLFW_DONT_CARE`. + * @param[in] maxheight The maximum height, in screen coordinates, of the + * client area, or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa glfwSetWindowAspectRatio + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); + +/*! @brief Sets the aspect ratio of the specified window. + * + * This function sets the required aspect ratio of the client area of the + * specified window. If the window is full screen, the aspect ratio only takes + * effect once it is made windowed. If the window is not resizable, this + * function does nothing. + * + * The aspect ratio is specified as a numerator and a denominator and both + * values must be greater than zero. For example, the common 16:9 aspect ratio + * is specified as 16 and 9, respectively. + * + * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect + * ratio limit is disabled. + * + * The aspect ratio is applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] numer The numerator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * @param[in] denom The denominator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa glfwSetWindowSizeLimits + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); + +/*! @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 updates the resolution of its desired + * video mode and switches to the video mode closest to it, without affecting + * the window's context. As the context is unaffected, the bit depths of the + * framebuffer remain unchanged. + * + * If you wish to update the refresh rate of the desired video mode in addition + * to its resolution, see @ref glfwSetWindowMonitor. + * + * 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, in screen coordinates, of the window + * client area. + * @param[in] height The desired height, in screen coordinates, of the window + * client area. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * @sa glfwGetWindowSize + * @sa glfwSetWindowMonitor + * + * @since Added in version 1.0. + * @glfw3 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * @sa glfwSetFramebufferSizeCallback + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwRestoreWindow + * @sa glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 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) or maximized. 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwIconifyWindow + * @sa glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwRestoreWindow(GLFWwindow* window); + +/*! @brief Maximizes the specified window. + * + * This function maximizes the specified window if it was previously not + * maximized. If the window is already maximized, this function does nothing. + * + * If the specified window is a full screen window, this function does nothing. + * + * @param[in] window The window to maximize. + * + * @par Thread Safety + * This function may only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwIconifyWindow + * @sa glfwRestoreWindow + * + * @since Added in GLFW 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwMaximizeWindow(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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa glfwHideWindow + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_hide + * @sa glfwShowWindow + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI void glfwHideWindow(GLFWwindow* window); + +/*! @brief Brings the specified window to front and sets input focus. + * + * This function brings the specified window to front and sets input focus. + * The window should already be visible and not iconified. + * + * By default, both windowed and full screen mode windows are focused when + * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable + * this behavior. + * + * __Do not use this function__ to steal focus from other applications unless + * you are certain that is what the user wants. Focus stealing can be + * extremely disruptive. + * + * @param[in] window The window to give input focus. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwFocusWindow(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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa glfwSetWindowMonitor + * + * @since Added in version 3.0. + * + * @ingroup window + */ +GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); + +/*! @brief Sets the mode, monitor, video mode and placement of a window. + * + * This function sets the monitor that the window uses for full screen mode or, + * if the monitor is `NULL`, makes it windowed mode. + * + * When setting a monitor, this function updates the width, height and refresh + * rate of the desired video mode and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * + * When the monitor is `NULL`, the position, width and height are used to + * place the window client area. The refresh rate is ignored when no monitor + * is specified. + * + * If you only wish to update the resolution of a full screen window or the + * size of a windowed mode window, see @ref glfwSetWindowSize. + * + * When a window transitions from full screen to windowed mode, this function + * restores any previous window settings such as whether it is decorated, + * floating, resizable, has size or aspect ratio limits, etc.. + * + * @param[in] window The window whose monitor, size or video mode to set. + * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. + * @param[in] xpos The desired x-coordinate of the upper-left corner of the + * client area. + * @param[in] ypos The desired y-coordinate of the upper-left corner of the + * client area. + * @param[in] width The desired with, in screen coordinates, of the client area + * or video mode. + * @param[in] height The desired height, in screen coordinates, of the client + * area or video mode. + * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref window_full_screen + * @sa glfwGetWindowMonitor + * @sa glfwSetWindowSize + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @remark Framebuffer related hints are not window attributes. See @ref + * window_attribs_fb for more information. + * + * @remark Zero is a valid value for many window and context related + * attributes so you cannot use a return value of zero as an indication of + * errors. However, this function should not fail as long as it is passed + * valid arguments and the library has been [initialized](@ref intro_init). + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_attribs + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa glfwGetWindowUserPointer + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @sa @ref window_userptr + * @sa glfwSetWindowUserPointer + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_pos + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_size + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @osx Selecting Quit from the application menu will trigger the close + * callback for all windows. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_close + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_refresh + * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. + * + * @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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_fbsize + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa glfwWaitEvents + * @sa glfwWaitEventsTimeout + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa glfwPollEvents + * @sa glfwWaitEventsTimeout + * + * @since Added in version 2.5. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEvents(void); + +/*! @brief Waits with timeout 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, or until the specified timeout is reached. If + * 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. + * + * The timeout value must be a positive finite number. + * + * 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. + * + * @param[in] timeout The maximum amount of time, in seconds, to wait. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa glfwPollEvents + * @sa glfwWaitEvents + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEventsTimeout(double timeout); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref events + * @sa glfwWaitEvents + * + * @since Added in version 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa glfwSetInputMode + * + * @since Added in version 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 `GLFW_TRUE` to + * enable sticky keys, or `GLFW_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 + * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa glfwGetInputMode + * + * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. + * + * @ingroup input + */ +GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); + +/*! @brief Returns the localized name of the specified printable key. + * + * This function returns the localized name of the specified printable key. + * This is intended for displaying key bindings to the user. + * + * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise + * the scancode is ignored. If a non-printable key or (if the key is + * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is + * specified, this function returns `NULL`. + * + * This behavior allows you to pass in the arguments passed to the + * [key callback](@ref input_key) without modification. + * + * The printable keys are: + * - `GLFW_KEY_APOSTROPHE` + * - `GLFW_KEY_COMMA` + * - `GLFW_KEY_MINUS` + * - `GLFW_KEY_PERIOD` + * - `GLFW_KEY_SLASH` + * - `GLFW_KEY_SEMICOLON` + * - `GLFW_KEY_EQUAL` + * - `GLFW_KEY_LEFT_BRACKET` + * - `GLFW_KEY_RIGHT_BRACKET` + * - `GLFW_KEY_BACKSLASH` + * - `GLFW_KEY_WORLD_1` + * - `GLFW_KEY_WORLD_2` + * - `GLFW_KEY_0` to `GLFW_KEY_9` + * - `GLFW_KEY_A` to `GLFW_KEY_Z` + * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` + * - `GLFW_KEY_KP_DECIMAL` + * - `GLFW_KEY_KP_DIVIDE` + * - `GLFW_KEY_KP_MULTIPLY` + * - `GLFW_KEY_KP_SUBTRACT` + * - `GLFW_KEY_KP_ADD` + * - `GLFW_KEY_KP_EQUAL` + * + * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. + * @param[in] scancode The scancode of the key to query. + * @return The localized name of the key, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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 + * glfwGetKeyName, or until the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key_name + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetKeyName(int key, int scancode); + +/*! @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. + * + * __Do not use this function__ to implement [text input](@ref input_char). + * + * @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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 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`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa glfwSetCursorPos + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * the window focus event to arrive. This means you may not be able to set the + * cursor position directly after window creation. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * @sa glfwGetCursorPos + * + * @since Added in version 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, non-premultiplied 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwDestroyCursor + * @sa glfwCreateStandardCursor + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwCreateCursor + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * @sa glfwCreateCursor + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_object + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter and return value. + * + * @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_char + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_mouse_button + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. + * + * @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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_pos + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref cursor_enter + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref scrolling + * + * @since Added in version 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref path_drop + * + * @since Added in version 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 `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick + * + * @since Added in version 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. + * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * + * @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_axis + * + * @since Added in version 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`. + * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * + * @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_button + * + * @since Added in version 2.2. + * @glfw3 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. + * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * + * @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_name + * + * @since Added in version 3.0. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetJoystickName(int joy); + +/*! @brief Sets the joystick configuration callback. + * + * This function sets the joystick configuration callback, or removes the + * currently set callback. This is called when a joystick 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). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_event + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun); + +/*! @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwGetClipboardString + * + * @since Added in version 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. If the clipboard is empty or + * if its contents cannot be converted, `NULL` is returned and a @ref + * GLFW_FORMAT_UNAVAILABLE error is generated. + * + * @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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @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. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref clipboard + * @sa glfwSetClipboardString + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Reading of the + * internal timer offset is not atomic. + * + * @sa @ref time + * + * @since Added in version 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. The value must be a positive finite number less than + * or equal to 18446744073.0, which is approximately 584.5 years. + * + * @param[in] time The new value, in seconds. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @remark The upper limit of the timer is calculated as + * floor((264 - 1) / 109) and is due to implementations + * storing nanoseconds in 64 bits. The limit may be increased in the future. + * + * @thread_safety This function may be called from any thread. Writing of the + * internal timer offset is not atomic. + * + * @sa @ref time + * + * @since Added in version 2.2. + * + * @ingroup input + */ +GLFWAPI void glfwSetTime(double time); + +/*! @brief Returns the current value of the raw timer. + * + * This function returns the current value of the raw timer, measured in + * 1 / frequency seconds. To get the frequency, call @ref + * glfwGetTimerFrequency. + * + * @return The value of the timer, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa glfwGetTimerFrequency + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerValue(void); + +/*! @brief Returns the frequency, in Hz, of the raw timer. + * + * This function returns the frequency, in Hz, of the raw timer. + * + * @return The frequency of the timer, in Hz, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa glfwGetTimerValue + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerFrequency(void); + +/*! @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. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * @param[in] window The window whose context to make current, or `NULL` to + * detach the current context. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa glfwGetCurrentContext + * + * @since Added in version 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. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_current + * @sa glfwMakeContextCurrent + * + * @since Added in version 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 when + * rendering with OpenGL or OpenGL ES. If the swap interval is greater than + * zero, the GPU driver waits the specified number of screen updates before + * swapping the buffers. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see `vkQueuePresentKHR` instead. + * + * @param[in] window The window whose buffers to swap. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark __EGL:__ The context of the specified window must be current on the + * calling thread. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa glfwSwapInterval + * + * @since Added in version 1.0. + * @glfw3 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 OpenGL or OpenGL ES + * 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. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see the present mode of your swapchain instead. + * + * @param[in] interval The minimum number of screen updates to wait for + * until the buffers are swapped by @ref glfwSwapBuffers. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark This function is not called during context 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. + * + * @remark Some GPU drivers do not honor the requested swap interval, either + * because of a user setting that overrides the application's request or due to + * bugs in the driver. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref buffer_swap + * @sa glfwSwapBuffers + * + * @since Added in version 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 client API extension and 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. + * + * This function does not apply to Vulkan. If you are using Vulkan, see @ref + * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` + * and `vkEnumerateDeviceExtensionProperties` instead. + * + * @param[in] extension The ASCII encoded name of the extension. + * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` + * otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa glfwGetProcAddress + * + * @since Added in version 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 OpenGL or OpenGL ES + * [core 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. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and + * `vkGetDeviceProcAddr` instead. + * + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark The address of a given function is not guaranteed to be the same + * between contexts. + * + * @remark This function may return a non-`NULL` address despite the + * associated version or extension not being available. Always check the + * context version or extension string first. + * + * @pointer_lifetime The returned function pointer is valid until the context + * is destroyed or the library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref context_glext + * @sa glfwExtensionSupported + * + * @since Added in version 1.0. + * + * @ingroup context + */ +GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); + +/*! @brief Returns whether the Vulkan loader has been found. + * + * This function returns whether the Vulkan loader has been found. This check + * is performed by @ref glfwInit. + * + * The availability of a Vulkan loader does not by itself guarantee that window + * surface creation or even device creation is possible. Call @ref + * glfwGetRequiredInstanceExtensions to check whether the extensions necessary + * for Vulkan surface creation are available and @ref + * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of + * a physical device supports image presentation. + * + * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_support + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwVulkanSupported(void); + +/*! @brief Returns the Vulkan instance extensions required by GLFW. + * + * This function returns an array of names of Vulkan instance extensions required + * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the + * list will always contains `VK_KHR_surface`, so if you don't require any + * additional extensions you can pass this list directly to the + * `VkInstanceCreateInfo` struct. + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * If Vulkan is available but no set of extensions allowing window surface + * creation was found, this function returns `NULL`. You may still use Vulkan + * for off-screen rendering and compute work. + * + * @param[out] count Where to store the number of extensions in the returned + * array. This is set to zero if an error occurred. + * @return An array of ASCII encoded extension names, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @remarks Additional extensions may be required by future versions of GLFW. + * You should check if any extensions you wish to enable are already in the + * returned array, as it is an error to specify an extension more than once in + * the `VkInstanceCreateInfo` struct. + * + * @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 + * library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_ext + * @sa glfwCreateWindowSurface + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); + +#if defined(VK_VERSION_1_0) + +/*! @brief Returns the address of the specified Vulkan instance function. + * + * This function returns the address of the specified Vulkan core or extension + * function for the specified instance. If instance is set to `NULL` it can + * return any function exported from the Vulkan loader, including at least the + * following functions: + * + * - `vkEnumerateInstanceExtensionProperties` + * - `vkEnumerateInstanceLayerProperties` + * - `vkCreateInstance` + * - `vkGetInstanceProcAddr` + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * This function is equivalent to calling `vkGetInstanceProcAddr` with + * a platform-specific query of the Vulkan loader as a fallback. + * + * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve + * functions related to instance creation. + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @pointer_lifetime The returned function pointer is valid until the library + * is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_proc + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); + +/*! @brief Returns whether the specified queue family can present images. + * + * This function returns whether the specified queue family of the specified + * physical device supports presentation to the platform GLFW was built for. + * + * If Vulkan or the required window surface creation instance extensions are + * not available on the machine, or if the specified instance was not created + * with the required extensions, this function returns `GLFW_FALSE` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available and @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * @param[in] instance The instance that the physical device belongs to. + * @param[in] device The physical device that the queue family belongs to. + * @param[in] queuefamily The index of the queue family to query. + * @return `GLFW_TRUE` if the queue family supports presentation, or + * `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_present + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @brief Creates a Vulkan surface for the specified window. + * + * This function creates a Vulkan surface for the specified window. + * + * If the Vulkan loader was not found at initialization, this function returns + * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE + * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was + * found. + * + * If the required window surface creation instance extensions are not + * available or if the specified instance was not created with these extensions + * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * The window surface must be destroyed before the specified Vulkan instance. + * It is the responsibility of the caller to destroy the window surface. GLFW + * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the + * surface. + * + * @param[in] instance The Vulkan instance to create the surface in. + * @param[in] window The window to create the surface for. + * @param[in] allocator The allocator to use, or `NULL` to use the default + * allocator. + * @param[out] surface Where to store the handle of the surface. This is set + * to `VK_NULL_HANDLE` if an error occurred. + * @return `VK_SUCCESS` if successful, or a Vulkan error code if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remarks If an error occurs before the creation call is made, GLFW returns + * the Vulkan error code most appropriate for the error. Appropriate use of + * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should + * eliminate almost all occurrences of these errors. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_surface + * @sa glfwGetRequiredInstanceExtensions + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +#endif /*VK_VERSION_1_0*/ + + +/************************************************************************* + * 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/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3native.h b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3native.h new file mode 100644 index 000000000..9fa955e94 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/include/GLFW/glfw3native.h @@ -0,0 +1,456 @@ +/************************************************************************* + * GLFW 3.2 - 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 + *************************************************************************/ + +/*! @file glfw3native.h + * @brief The header of the native access functions. + * + * This is the header file of the native access functions. See @ref native for + * more information. + */ +/*! @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 may define exactly one + * window system API macro and zero or more context creation API macros. + * + * The chosen backends must match those the library was compiled for. Failure + * to do this will cause a link-time error. + * + * The available window API macros are: + * * `GLFW_EXPOSE_NATIVE_WIN32` + * * `GLFW_EXPOSE_NATIVE_COCOA` + * * `GLFW_EXPOSE_NATIVE_X11` + * * `GLFW_EXPOSE_NATIVE_WAYLAND` + * * `GLFW_EXPOSE_NATIVE_MIR` + * + * 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 +#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include +#elif defined(GLFW_EXPOSE_NATIVE_MIR) + #include +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WGL) + /* WGL is declared by windows.h */ +#endif +#if defined(GLFW_EXPOSE_NATIVE_NSGL) + /* NSGL is declared by Cocoa.h */ +#endif +#if defined(GLFW_EXPOSE_NATIVE_GLX) + #include +#endif +#if defined(GLFW_EXPOSE_NATIVE_EGL) + #include +#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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); + +/*! @brief Returns the `GLXWindow` of the specified window. + * + * @return The `GLXWindow` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) +/*! @brief Returns the `struct wl_display*` used by GLFW. + * + * @return The `struct wl_display*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); + +/*! @brief Returns the `struct wl_output*` of the specified monitor. + * + * @return The `struct wl_output*` of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the main `struct wl_surface*` of the specified window. + * + * @return The main `struct wl_surface*` of the specified window, or `NULL` if + * an [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_MIR) +/*! @brief Returns the `MirConnection*` used by GLFW. + * + * @return The `MirConnection*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI MirConnection* glfwGetMirDisplay(void); + +/*! @brief Returns the Mir output ID of the specified monitor. + * + * @return The Mir output ID of the specified monitor, or zero if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the `MirSurface*` of the specified window. + * + * @return The `MirSurface*` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI MirSurface* glfwGetMirWindow(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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 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. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.0. + * + * @ingroup native + */ +GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _glfw3_native_h_ */ + diff --git a/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/lib-vc2010-32/glfw3.lib b/libultraship/libultraship/Lib/ImGui/examples/libs/glfw/lib-vc2010-32/glfw3.lib new file mode 100644 index 0000000000000000000000000000000000000000..348abecfa98d6cfad9db67127eab8d5c72473539 GIT binary patch literal 187376 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 z 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 VEBwqml;Z2NCo|~pwK literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/ImGui/misc/fonts/DroidSans.ttf b/libultraship/libultraship/Lib/ImGui/misc/fonts/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..767c63ad000e3eea20f3cb7a43ba9f4154ed7a5d GIT binary patch literal 190044 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%0D=-PBu&{ zc#2hK`b9|l`YVeQ)TwH4>9GfoJGg(314d2G|L)$`XI0J})4S`nsccQ5WH7e*MgFP$ zB75IS%rBP;^WPA)fPBq=g(T)$IcZLzy>^{c=OBA6@7a~v>!gHdk~t-8x&55O3!O@P zo$4%dYVCCw+V@d=o#w1@erm6~JCjw3z3$=UsNlDKbpD>BlDbl^wd!*Am62;^Pu0iv z+I4!k>Gqm%xI5ThCnY?S>`Zj$*w0g(KJEs4o$B1^?y%QgoGfp+y-ssp_T-deq1DYP zNy@O->6~%C&|Y`v`VM>D!#OHBX-?Ies)nl5DpqH%E^jE$TvfYaOI_8PwGEkfX6EPS z7EjEaS6jQLx*~ISZQX|2y7Gpq+M3C8>T0W2XC7HzQ@^BQ&8F(|x|#K>Dr#0&)MZY} zjDNSZqOP8&GxH|r=IT%72j=Ul`pojohPv|A73<6EPR^{Y45*aXtj=6tz9n;IMP^;a znyUJSiaJVGRg<}@qOPHwbls-9s`}MctE3$DlS8@*rHdCJQS}AMR?#%;*Kgv& zw86qEs$9=6H|dHutgXnLxuJX&iT!3`X3zlnlXKTLG;EkQWy-0io;tZ)KQ+0wZq1Zx zlSloOg@?>8TXbaEB%Wmcp$ZnNkNXFd5;@omsX_0*zc8+6{DiFF9-m8tVIwOI=dDPfKNOnR+e-$`xjb$P0E-5RLF z2JS2QR>~=TU%?Z?6E$2(O)GU@W|E`%rO>Id^$dPzTG6yjh2{jQm-M)lU=_ItC#~mi zll>%-H-xVmD91EL$|;SKNXwbKw!abCXwRwnP{`e9x#M|F)^%M&YgD%>M?Ie`bPhqv z$`~<@}h)4;#dKk0JPV!*~aG1oau|jAAAI7~kphT=d3#YO=sNlo}mIZ4P%9J4c`sj&zQ4 zj;7^~A;NSlqvdhD$8~~pB0l5_+WPy>?anz)BO~Os&L5p~ol7|>^(J)EPUSflswC%Z z=PFL1`Kxn@^DXCmmF)b=`M|l^+2#DV^O4iy+~)j%HyEE~f3%hK+U4};3-sepoadca zoEJHD=4IzkwBFBHg!5D9hseMl-j4mb^Q!Y2efDSPFTC-vj{Z0qKCXrvZl#wt!U4iL zo8aJ6;M;ed&FIlB&gssX&Kb^w&bOUy&Q@o;bC%;f?>P_Q`LkuR>Z;OIH|H~FuS!?E zDzADvt%|i0s<-N+`m%*UKh<9iPy^K8v+^$2iK#r5&xnW;i`5atnvYaRaT3i^b&Oi(eBylS{LXnt z9jlh}lFISw1a%_ug%zq?tyHVjYE_{s)f%-{RjGCAWL3?aYmM`;s^t};jjGQ1z4HfE z?|heY88&go&8cd$+M-TVr#ruJ-co0*QjgRU->$9y^5$C)Q##U_FuR~-KxH= zZd13bo$5R4yXt%D4i+fxQvad8uYRDK)DP8N>TY$9x>q%`zU2mWzj{DD$O6WP)Whl# z^{9GGJd(qoe^KwL_thTtf%;JW zRei*{87-^~{#gB8{X>1CK2@Koy{Z*q)%!ZjD>Z*4`W4I=7zpvo^V>xTm_C-7W5EtUNr! zJ=5LlZgaQ0XSqAvv)yypRQFu>JokL}0{24qBKKnV68BQ~GWT-#3inF)D)(yl8uwau zeZJ1U-i^37xHq~txi`DFxVO6Bc5icUcXztqVRzo|xp%mCy1U%}aKG>Vz-@AW=-%bt z?cU?w>o&Xhx%aydxDUENavyRZb{}ycbsuvdcb{;7>^|v6-KX5A-Dliq-JiJ6xzD>V zxG%adxi7n~urc{h-T!ib=DzB_=KkD`xxa8yT5VYa)0Z-?f%Yv z$Njzg2ltQepWJuZG}w3l;=ad0gL~W$+z;Kqx*xg!?Y6job3bd-Vkr7 zH_T)0u9xYJ^hSB3y)oWcZ=5&Y%kr{0qiTXT(VN6M)Kk1%FVD;O3cNyZs#nCh#U);; zH_bc1JCIl658{lA8Qx59mN(m*hb57UVQ}7yA)z($?*np*8yBZ@~`v9pk*O#xt4o@vNY0Au%brq*nq?GF< zb!P3F+M0@!Q_D@-ZT70Fx>cLjS5{YS?zSp^oiuxOZ9~#3{z;j$s+{anR-0rFd6zeE zCrN6VrG9zWqj8ngj9b(H_Wzw`m!Ya6jEO4vVbz2Z8(QRG)I{nauGNqr~=4MS@MMX_D?o!pNl!fK1 zHZ@eFRO=*tVd8Vu2{$PVP5V^qBx#|vLpA@TEHb~ZF~47w@RRhKgqxH_=Jz$GeQU}$ z)YjvtZCG33mDQ~ADr(lG9&X#A*0#gprX6Z^(*5wYn`+jS*KJx~UB0QIdu`%f$`VtC zI#Y%v31rjj5^hqKm@?Fvf_hxMca!PeqiwD5YBg^jZECeiC&@?GRn@FX#z(GM)BWhgI(6Tac$a##<$_Hn?RHGO zgxyX}xIQ-FdQ1E|Wx1*AX*x+;9`aDyY2jsZb#2X>`m~u+7V}tnc$qr0On;PGUZK-& zhu2q^*RM6#wejopBNG}Z9la2WNQ$X`azkxRZGHFERm2JEaq{IZZD#d`wdMM8;wo>++S=qJtJbV9_l_#xlxj=kEnZvY%?69>s|=Z$rRkDiP@#CVT&YJDkY;reOrPiAId39@RQ;52(FV9QXiPu0KEq!kT^;-ofPI9d@e7a;C z6su>uVy4?XO|RK6^-Y@ovA*nDURhO@mz$ek5L`{o3$OCStN6Et;b&9BtD^9#IJ_ze zuS$cfqTKK*q)`;m$SVx<%L{YK3vBl z%()=UxggBBAk4WSY=eT3MnOoUAf!MQ5e!F3QJWK{-P-SMN#;RqVN~RVX2D4vJ{79DGtk09Ohgc=3E@+TpZ?H9OhgS z=3Eliw&8fJRXDZl(#Q*G#LGN2_$;@y zB;}Yjb>*0Kr<&v#JtCx>s*|qA1Ztq`slipsvF5=oI?*LW&~r<=>!_?YBv-Gj?!Ivo z!+_X}bwq4a)>qYtiBey&sP5GeZK|u) zpBCliTYluq_D@kBC&zcKsBggHYN%M<6-%^2Lg;JL8`feOnd|y)l~tz%*Xi|?rN(}d zJV$F)Ea17ba`QxKlIC|`MI64G2(cd6yD+R)SJc<9>!q!Ogn_VI!gcS2>pD^G73rr{ z)YS&nO0TTlR2RRYIKfS~`l`*rb$4C1@J<&pxJ$38stJE2C1r{r*QUDU+~?c-0-F}v zbgE5@Y+7v75}TIVbf!&bNjkS|?p&SDojcp6b0p2po2%*O=Fiff=N8P-^hq^+QcWkX zte{MuC)N4nm6`IA>gV(37MlF>=N5EbU0z>RUc0$U590KJt^sLb^5JW1>uQo~^}k2! ze>cg$x+DcA$J_#wBWXd>+S=NarOQ@URM(!WpDMIZ73Laxg;P!W3#Z!qB70wC>QPu^ z>QPvvOOabxq}!2HwpAE|CfQr(WEx*bV%JCf>lBsJ|+SQOCH?ZW4}U2+SHE&XCk zzu3|*w)BfF{bEbM*wQby^ouS1VoSf+(l563i!J?POTXCCFShhcEd3Hozr@lnvGhwU z{Sr&R#L_RZbW1GV5=*zl(k-!cODx?IOSi<*Ewyw?EgeiZ;jh9{OQ+P*DYf-1we(6Y zy;4iB)Y2=p^hzzgQcJJY(wk}PIn&m2rlmjA(w}MR&$RSsTKY3B{h5~jOiO>Jr9acs zpK0mOwDf0M`ZF#4S(g4ROMjN7Kg-geW$Dkd^k-T6vn>5tmi{bDf0m^`%hI>@?B)4#mr9a2gpJVCIvGnIy`g1J(IhOt$OMi}~UuNl- z+4`5+`j=VyWtM)KrC(<2UuNl-S^8y`ewn3TX6ct%`el}WnWbN5>07;7IM>pjYw6Fm z^ygaob1nV3mi}Bzf3BrJ*V3PB>Cd(Fjh@aeoNMXNwe*c1&z)-Z;8d$Er<(DC&kg;l zxrYAKTtk0quAx6Q*U+DuYv@nSHT0+E8v0Xn4gIOPrv6i{o}HR&=ugcx^`Dw&+J9=E zssGeGQ~#-XntooHkxx?nJ*oblH27YZk9%D{Qe8e$T|QD>K2lviQe8e$T|QD>K2qI2 zq`G{hx_o(MMm|X`eIuXTTlz*mxwrI%%quhUNownF-nPGyPws8|8~MyDGxAAl+uO(^_qM%_JaTXAYveIM*Ny`P zxpVu*<2BlT#yDJ=@R_!l<+DEV=frMl_n3}4$!9&ZAsXgnZo^Ev>u-bKn=iwk_6lrS z`M$cMvY~hI!Ak68K0A7L`%f0mmKjr*c~O@Y$*gJNE*(S^(|Yddy|vHx`|ilNE8|y#Rt$P?*ySUOMz0;eBXwccTK;Ol_Uysgx!FZ> zpFKZ&X;w}4tJ&{nznkOaypgjfb>W1ECj4Z=&nJ(WJZ8erb1U<|-)&Uk-l@MU+*`P} z#~AZh^kngz;IH@AlAFz6=^dJaP~k6oepbyvEA3zPL8k?O+4B#&+Wy@`M1>rtBb1VR4)hB)fZMjRsHkq`RgaHKS;{B{^FXN+SPUU z*B90=sBdn#a?|Qla!$E*^U^IJoiX@~r_Nlk?fmUmp0(_(56>QR&eq1O&%ODgKVEXm zrJ0w$aoLTRUwcKbE3UjU^U7oNuMC-(-|Wqv33(l@S;$ZyZtdTrLZH-GEIQ*z{!YqR9vARkHP-h3~=6-shCG3WU~%p3F{!1uo9w@ zwGi2?hFHRSh-_zWYt)$s=7R;TF=q+sQQ#Q9I~FWw9mesbJILp3a1Lk$=YsRV`K`yZ z`XQTH*KAfYWV2Esn>F@JoIA+lPOuC72lzht0cZyIf&0M&;6d;Zc%0w;7(7XyPl0E^ zbA0{+cnQ1$UIQ`kI@k@~1U|pn13q-JRnOL_>J9pWeqfBVMDbpuDsn1SF>4Gw)S>bsTc-Y$Mqw8_bB(&S3Siw^-{k8)JOf2&)x*T;`&|i z7w`|t{t3VRl=L&wy`-&92Fq-gxa{%bX0DqACW#p`Y_Kv%JuW4FSj0T;GYmIv8pa-Az0=-)sz5d(} zaF%!jxgX5+5I!5$+T@J@Bf)4e7K{hkU;>x~rhq(90E+ls377^B1P6f`U>2AI%E)^j zSito{um~&$@Vy7$drQGGupAr@P6V{AS4+7z@H_a!t0QIIpw|H3d8|4*oi#nDtJ_IW zbjHDxIUpYtg5uVQQ-WNTl1_uC4}~Kq_yGKs zwnG-Z0j&{l5a}V{P;eMH92^0T1V@8oz_H*sZ~~w#9%b=XfeNq&RDqMhdQeNA)W@r* zjRr_d>)O>(v%9GMeL!l6HgQj(Mz;Vdd18ql<})ev^Q13>cgQsvq=Mc+N^si6<`cQ48e|`ElO8>@e|N8W=PyhP#uTTH_^si6<`t+|)|N8W=PyhP1 ze|`Gbr+!e$bBw=K7H)d$FYPy_UU7vR%oP;efrp^ z1sdt&7=0Y0k7K%zQ)!WI;G|ZczV_*BpT73#YoEUM>1&_9_UUV%7Hg!hefrv`}kb+NaeT>1&_9_UUV%zV_*BpT73#YoEUM>1&_9_UUV% zzV_*BpT73#YoEUM>1&_9_UUV%zV_Sn^+1PKpyj32eTN<9X?1BypH}i|C7%}Y;d*Ha zX#t;FOHHH(J~i;Eflm#jq`p@M=4lE(+~mVeeQs9HXCO^mB}Uj?vFC`ZtM}Q;2 z(cl60-3{KPUk9K~hLMf{Bf)4e z7K{hkU;>x~rhq(90OGt6gEwOE2AUk+m=14D*Syga-P0S4f*;1{Z!@s5GO({QLO$8S z=Vt@@lU9q-YB5?Zrd#b6o_mt(r@%9`LXoypGO$rHXoVQ95Tg}hv_K47K7_AVa6=KvlMvY_CI7V$_)HX(KW7IZAZDZ6nMr~u%Hb!k@)HX(KW7HOX z>SQp!WiYm7=vo>HK%UxYybHMBmv;LJ-|b(M`Eb6`QdUDHaQ^-^(cSdpy22jr%f%}%J~08wnbn6JIS|0PSYMbs(`lb_mPGvGaFJXLM0_Q~7+c|N3ZtUQnVSx}E$#CXi$Ik`x zz`*lVgd=@yek+Hs!vA&V9zLBxM zk+Hs!v0gZG-+te1JaaqP3BCiq3%&>L0NCKfQ5uP(G!jQ?B#zSP+zb6?QfzW!DUHNZ z8i}Pe5=&`x9_G78z@y+X@HljT44&k>D0m7y4W0qd0`V`OBYgq91jN^Th4eKL1FwVK z;7!op2Tegzx&VA5?T_|E)8ory<4PQ+5#L2(F^y^{y*7+=1jyuiB;H_h3nIyxs`M~-_h=h*p$LYC05f&tfrAzO{2Pk z`>ROtw~5s>602z>R@10%g*I)9{cU|=@_e3q>Pu z4}8LBpMh3JBn4bFgU5)JN_?an$ig>T295>dPp=?d2gIkQ{Mc!Y+PB_DdKUL*1M#!r z7wmnB(==l9ORT0*``j0CEq?bU+~0}aw~On$!9CoI4-Ov?x5;qt=lTIs>O|Zo!+nVK zQBwNPeFIP@_m_ZvBxWQ2TijRQ!~F-`e@KeYP7J5f{h0J0fYFzDO(XG|Mvs_-*9(YG z-=F&d*oyy3CV|Od3djX{ zARiQfLQn)sz%+0mI0(!DvjDuJV+#vNCBCqbRALN^NF~m&nDhwJC8QE>IEqwa4ogWT z?m&Ox7fIZw5#LB+KaKcD68~w`aR~a*TSFL5(ud*wv_yRv_f?`D{MtE`eJ+T{gQMuc7&_3zh4CSE zY#2Wh9T-Cg$_N}q-$l`PQS@CDeHTUFMbUSS`}L1+YG#MyM58UL_NocSs~Cq5X)my!D*UVyHOwuv31m(fusX8a!hUtAYO(M3^oQ50Pi z3**ERV}M_EoM9U&v~`U5TvGZ^#~c{1!nngFT;I)i_mI*TI#x`3p;w~ll_+{8ie8E8 zSa4!&LSn)n@cf6QeKsLw$ z6Tn0;2}}l4KrYAw`Jez4f+A1?rhx;&L4a{4j0;Q5WC8aQH(5w3v6Drl5kjN=I7zveVn~#LXkWe2>B-TMfXYl!KKBs-Hl#2H*u_uYp`ABIDOT$M>V@PQX zE5k=hV^|n5EQ}b|MGPs8A*C@a3lpiau??g&hLrM7CZOC{5;3GSh9wchk`O7a#A2un zBRI$MnfSFUNZ}AH28nG+G|+dqkwP0Om8hVPluBgK$4Zdspo!LA!nMRn?je;}3H_lX zLT`{lA1T$5A*56yi1Fy{9_~Nj{zKBgl70kdrh#RHB_eQYsNoA1Rfnr;n6MLaBwMtC17^^sB^DP;$KKp!BbKJT3dF=1-xP%DR$JCqu!^pQ#*sT4^RDfIU{_T9nv zcrQqhj|BNhkdFk3^!P}RkM#IRkB{{DNRMyFEgz}ykqU{h$++bs6+TkoBNaYU;Ug6? zhtM(J+!K!N4f?=!eMvJ&=~cMg#Gtou4Tr(q!r4BY?ZeqVobAKeKAi2t*?u_oKpT$s z;b$R6lMgrfaFY)=`EV0w%Yr%J z5T0K^YIMHLQ;5!&xeC$wGG8G&U*;@C=gYi>=zN*G5S=gc7cscWw>n?uF+}IfT!!d; zpS>MBx4a|{*Or4QDIRD9PKv-u5jZJ=eisikihhs6RT1>N%*;p7?@{!76V{h_o-yZm zev74wo{wOOMXH{XmDx-PL05+5jZu1o{ysEqv-i4dY)N*%JyUMB;Q5BQ{ZXv40sm& zgz`T}`T}?f7|xEs*%3H90%u3y>A=}3SUX(+)&%-qEV2k(9a*O!9J z!ByZ|a6PyI+{*W~T_`orbNveV1)xrNmLfe7q$h&(L>Ld6@Fqoy0xvRxC4y!XjG2F5>%(dHxcfH&Pa{QWn8u^zjyb z#)=3QU4*eB!dMZ(qKhDbGOL>?fe|Z#5i5ZaJVhT*(Z^F1X^bF^5j;g7Pce{6nf(#7B_$2ofJb;v-h#BUa)gR^lU8;v-h#BUa)gR^lU8;v-h#BUa)gR^lU8 z;vG|ITo&5FB zuCOl|@-6$k==n0rqUWpFwI#53k0tVERv2Zl0w{wOKtzE+DcBA!1XqBo!7ss^Kvu)Z zN*GxM!|r0_YHX=oM(*(6*Y|+;FZKSt@o!~p*yWo2u3Z4ef@=Kn@ zN))L#wK$gRH^499l;L0$7z4(EERX{xg2^BkN`vAGjYR*zM?4V?*~P726s8u}`~KY+S65pmoq!#)cKURcuzVSH)Hp8}%Ll zO>KvY?fD`22>k%RXq!{)O|dl>0I~DL#uNLF@-h<3C@dqejK1P+$*3zMZcNwL%*~qm z8h*>yR+(5`&7czti+UOhNvtEWjP_>*{ethYdZ?eVaKy3^t41suv1Y`I5eo)d+IrbT z`XTs;o=O8^sfd*_7%Tt_fmj`j!4hy35G!LDSPmH9wN(KLx-N^B-SUvFHRvS=9v=GQohI9cF>kc=>ZNFwu7}yY&+&a z9qU43JhAD5Gmte)kMo-!gP(B!GN8p0*S4@?>O@9uu}O_RN_p^Q}B{7U|jG9Inp==YtEuMSKR===CzYxE3$$ zULb2`kSe`y=0VaQasLqMqoj!*n0Q}*1t0U>KLBN81dTC*8V^j?)C}Z$5Zpi?X%FZy z(!+sxJx7A00ez>voa0E*OpHvQzpiEj`NBzzPO`!w!Uz>(EoZReXQFNTStP79(wIxq=$A}J+#~Eq227| zmCRm(X`p-SH(b!l zW>uFu>2MFTfXvs#*Ue69ZE+-)$4Uk)>y9hBX7HK#DLZ)PY#=63R+Ww4O{J=WLGYBPI|kLyeabHM&u?KZx@9qa^& zzV?&cM}hEz_}uV>_PY%i;a4X_*FpA#MPiDnr; zeFW)9Krax@GCuoQ(s5usATOd>#($qcil0L?%lPqANX3`W1Lz{6S=y&plab*iPFHwI zRx_pJpLNIU>$s{Z9#5Xs`k2G)CtjYJnb5q*9=W{rq*o=+AP?eT&Rj4LNSyf)EUN{i zpBHNmJi^47^9u4K9{PVN?u^VmroM{U^B7K28wX^?w|Kavz^r`QcPx4%&u_s4?mQkX z@tJr$TD)M1NsA}kJ}!Mbb=bvsc%xf<7>5O-chb?iWcnteKKG&W$DI+i|pvLQ%_M@c#%DDCbXT0^yzlm?7C3Sq8 zci3C6)6riqxWe{~vEO%cYb~GGqIGt+iJr2KRyc!2{qy@DO+oyZ~MT zuYlJ;47?6@gEtu!dxGAeFX#uhfURH$xENdtE(ceEYr*y420(ty^0Y9^(?X=Mg&Cd} z^_SKbq+`0|DTA0acA(GfaB(a4^VhfSP7C5|xNMZ|- z#1?lC_z-;5+Cn6;g-Buxk;E1vi7m{0v@rA0!puhtGaoI?e6%q0(Zb9}3o{=rL>gO& zG`0|FY$4Lv;?Z_Q8e51owh(D-A=21Fq_M?25l|lXWpCdLi4oP+^j6#V;U+n6G3x9) zw)kZuKY9|jh2eK=Ubp72e?VDDnL`Mbd%`0P(S|7VrP{_-!en|2F3)@QR{{dDJV^z7gH z{!_4*Hv9=u*>}tIQlZU`7&lmCb4>HTIh3N^*A|T62A$!Vt*X)`Mv$`_1@5| zu%@}_B4hE(JH9@#^!Pg**p0-j%$snJll~Y!90~$!9Xk;oj$yIOySnC0II#kV$Ll!% zcCPV7i6i-p;=Z0yeuVF^J&7Or9o~jBBd~do5S}MiZDxgK=J!rw%Hsbp%fl!sZ$ZY) zC`tMd_m7f(O!^P-DOw!AR?prJASOJJ>srzcq|86)Smbk2mJXf zvc8DtD`V^aR%Wp(f)%^}y46|Y;oc36_TKFS{|`LdL5%a?tlBbO?bD&v*NYfiVB-e% zZ4v%$30B@*Fb~WJOTbaU#Li@`=9gPZaR6JWW0p_Rgkt1h17H!pyffULlH1-u4g z;B`P06EC;J$_(vc^+W=CgFc`y5N}J?#SA6Q1g!b)uu`L#&xm=49@iG0XU0Rxsth8x zSh5nIimxs<@hP!vB|a5jWqd35#BYd8`FPUtmBuC>C2Ner702omp8X88A}xC5M!1WH zS)WsmHM`SnMV;k3rt2l_i>y;d`e&>9EpVDSU$0ghcD?0As`d-isB-SJ=I%GA+ zZ@7O8ybaz5d%y?aL-1Gd5lCFwk%lFm4iZ;*^yfZU;W3zNJOVuW{jFX$>xT~InT6mm zum~Iu7K0-I{HIrjz=L{q$Wl^SA+ih{3zmc90A7k-Epj61Nniz_?e@7Fi>w%t)gle> zbAje^;Z$1XD_dRFjrD4jLie8ZnDo-uvBIjGTFDMv5;dqI#f#FB1J>FqJRY?PZ07oW zzPkb);Dy{?Pu;ue8HCmRW(|Pn6dn`5k1EsO`Bg-*a+JKx zyJ14<6d;k_(||;K&jee!K8qE~vI3bkNO~1AE9=y`e8)Rmiubj`2=HY*Bde0HRa;Bv0TXT6g2DsVN|*N}>o8`?2w>$hcyMzoJ4<smz;A8@ zH-VdhtU~($U7qi?w}j4#M;2l)B%T?#hRH)h|E#5t$- z<6gX<;(Lg!=XYlkA^ht5OKP{Tm4flTMC6U}mGq64V^WdhdN|)mRU=Z>_U-Yrc*eXz z9&IB{7t*)#HaTxU>UI8?aUHx>ZY0aRS#BgNqP~ShT*tHWmbsBG*(d+Ac|92%bWuoJ;L>Lv!%H8;=5=GxewN8~4((y<~hxd1x zbN;{io@|%I(N>QxGO8Gv(<2J!xwc=Cv9FaFSfpRY3JkQ-7h7?$l9GxZt^%D|24WQu zd+ls@Grh)O1bTTSkhKM}u3$XK1{1&}Fa_j+0#F9#0g2g4ycQmFlH0W1Sx{p1=G@$1 zl@Kv#BKGlj8d<6TPw#D)L0tkq7p*InKD`7_hkM-VH*w^>yTicY;0SOeI2s%S@R;;l zHYbptL|I-5?F6&aT1WpYJ`TlKw9mn+nG5ED`CtK9Om0xaYK=Nj#6OGjPTd#X(O}=} zraH4fZX@s8!A|h??Q$URP$%wkAim$eb~$Kk7p2fsT|gRO27npRV3z~&1NXhl!M?}j z`0kX6J0Zxp+|jlU>?yNCzcYJ^H~(3Y6YORnKA!AWDywk*Uus10!(`_G@xx^20P(|Q z=K%4;Waj|!!(`_GpBY!#IY8d;kljwj50jk(#1E651H=!Lode{357{|D{4m)8)#tr3 z*#*`2R+CncB3*ii%(bLw6mK2r$)we!w5#kYfb_?AM~(X_BK7~iT5^9HGVq=Lm0Gfh z@#E{=ZHzr-lz5D?_q5pLn}PUQyc;cVT8T|gtWodr43~eoy^s@a`RuPj(`%3Lf28GQ zCye-P;@7=*m+@L;b>=sFc>OE(@G>4*+kL$18C6aJTkx0yuME$Tn1k8Z%fvg(-d^lE zPn@F(%O!(YN87!=+InV9#2o_9tckcoBlgF1JhLY2nKcpj=xiS^>zRdbV0V~hLsMqLIW2#D>n$G40E^z8r|9YocE5BVN9Zc=@d3wY&UKo~SNQ6{+Za^u5mIDsqxo z+4VrIN_o%I#1QckIL#q$v-{ZWGN)-GX8Vh_e10S>zQRU)((TYTUIK4mGX}+N_b>ha zq4S>B>i=%DwM1SWc=4O{%k(z#%zV$6+dCszzfAP8({;=7i1z2{0~6U6ePFmwVsY^Z zcVcw=LTH(2bA*_jNKAx?vx#&Y*=w&85@T|KPLQ{Jg`>?r8~d2eMbm$?PleJ^f)qUy zu+?gWi%CV-p{3A%iP|yH8FB4s<_F{#mw>ifQZ%Hmz6GuWqU$2$sARUl>4wG#-{aSM z=n^8Um-0-o8^pDGKLhiAzbhI_W;o)%(Hu(zA^h?Z3w~q9z zp1aa{n%&!kHw{mi-P^9@UdCHF%g4-7$=q1Hz1z~EbWUIL7Ar>jE|?b!+E&g95?&8@ zF0crMJB>wFruGBy<}8J?|tbv5+8)(!{D(vU+DKftGS2k zzP2|JrxUs34JM@HCTwo@HP)xI$bJlu(oT<4!XNY9Q{4ZO^iA%64cMDj{SLo3l?YEa zKvctJ_QpMfYvw}T?EpS;caSnC$^Hwzdkf#+$-WA^_{{9PAg4hz+I6n7?}G30wu^q} z`Ej0k0zlh+5zBaGt;e%2qfz}Q*FOdS1%3u-J@p#j{hXBDRCxoUQL#g)dIPlIP5IY+ z_8TC*{9Eug_#Jo${2u%P{1N<#a=lAFKG%OCWsfYi2QBm=bpFa`{|){I{tnvDvjyWj zaWws|^Ex=;WO|Pn8Qf%cVHQq8ih1)QaVKWkuSRxamOX1^CuZ5VMs{M3!DX@&v+QBh z=w8cp1l$UU@4DXw!g=2ZP2etYH_w_~nq|Km*$E^HH%8&asLT77ngfOVo&rz9?a#Ds zbe|=Cf%}(v{*~6_UE0{CeKlv&uDr{%uic!@9$mDbOMAKRf%lf9k@3IbOBvkkLT@@Mz0%b;*QTm1iU_cmccXq;C$Kr8BVwRdNu0Px`y)oAxMM7 zLM0A*IFR_K#6BhNDKXDufy6o)6LgHToK#|)64xaDx6f05VR|v&KyRjlD z1}Dj!nVDY@4Toj_xmxZCo_P|y2HxT~Z-e*22jH(@FSTUVlk9cC{K>6QVhxgB3&h$V zS*zm=rY!nXt+yxxTr4Y%41Lj0fo|HxFZq?$MWTlS+E4S@vp~uq`bKn(=oz6cdZiZ- zO7Zu(+v}43>5VUr2FE>JTJT;g z#sL`vME^JGzKQGqCUk!jr-hkwujnfz!FTe)8U>@CsZ~&;7^7aiHovB(a3D2;i^CfE zjCN8ZpV2O;QGAD?#GQpqjpQwkM)z@^eS+VZ8u`>HsEto;d_A(ss3s$tsg2KQ<};f4 zjAo`b1GH?%oMDXFoM#Bk_$>P;NlAszqpF46{uR8wK9F?A&98P=QZ&a-EWP`{gIvP} zXpknxH($MsmG}zxzW}>Ie7&J?n~YE4-o2rwIf*u02h5lfqpyPTB<5n5BmJ^dl-d8x zj3?$aFWCppj3>d)r$(=s@xq+&)yy+SW0*CDVy(zn@iH@F=&UCF=%+6B1ImyuIa;?v-E{B8p{1Be|GBdPm0*fcXn%Ia8N9-HM z*|c zH0AuvY|dcF4)y(0Jo7RVZbtSPBfHW4)X|RYa;~PF(;#PS$~g^9jOH;$a~a8-7{!|y z!Ho`b=%F+uHeKtVh#j3}WNzYI2025s30)NN7?qt1&_`|G*bID(&gRYcH>Uh^w&)jo zTT`@+j7K}M@x)VT3T4&!GBO$n7a83dQLpj6$f=P}>_+b8B-nrOS!eUdGPYrFAg_UL z6?u*8SNtu#7WjNpe6EC@lsezhP4sSD=ZZHWqex)OMYSy_^7;xeBTBSWOT*~lXsCZh zF8gTNjE^cb|Hs=1GYvfV;TV`YuKP!e+>SLA4$Q0E+)&M?Z zjCDq`KJ@cfKHf#Cp-yeI1)*nCPk|CVMrqrgAM`NyJg3J?Gfsx1emFi3pd__mBd8aj zJkWW}h8%A=7Y^PfoC^X^D)6HI%{{0DJ@}2MWJb_`si)-3($aRj)1qw>Mia%JwVmiZ zI#25~_OZog6g$LtKif%(WnzPLrq>d6n(R<%q}51j z%u1^9ke=bYxE?bj*6YyP4cL=+A380jCAd2h+Y_|aX=W!&u`|$TVlCTvFHtb<-*vRo zqB;r@*Z57k*1;K=)s&EVW9`k0#dR(a&t0sni@`1+*44d0tg0uprf$OPj^cGk(A37V z5>5RY-z8dBVpR!0a7J=ME#ekaPz%}D*m$USqi@iHR+H)&93G5}TRwg0t7qwtz*{|o z>+OITuKR6pCzM2kw(SqG=Y1>(iBkFQAHbi$e}lh)xOXC&Qle45J-=AIkr?m)w~aFX zE3E42omkb_aB%2b*k8Y+_QIt>t;KTwygm#1E9k3$1HWkh41()y-+XCnb}6&8ZTI&2 zcUVa(qw`Lnbp?FX1jJJ&mZUvo(GNrrI$K4GRcj)s_(1Sj+p}`0BCGf}p zyES0nto{1x&u_d1?Sy}T<`Nkc+t|n;k#J%IQFb58z^h{pi1c~BkK4%`JIpkgS%!`3 zpPgk0W*E%uf}EMwsQ%0tMa10BFf`gYL1Tv*hEI5g`5)dkHRnDCaf5xG_h@Dt;%7dZ z=uouXY{M5j_p!6thC8vmI?gzJv2!71_Cd~u45CVA210D1Mr{k383@sR8^6R1ggH;L z?F>ZJ&Oq$*Y)KuNYC8kbXlEeWo;hjs?M6ET(fRq4Cf>0TUHr{DJM=saSV-3d9Pdj_f-cpJ|g=Toe33L^EO5 z&G<6J-9j6}#METwD~PEXpQbb46aPrRNB=mfXdv-zg4nkBH^#2$I3xEN-$~ntK8}r% z+1Qwq%U%667pu1@EpzU=W zi~GcyXkU_Ay-Xkdl+<{~!3>SxCO%My_a(lj#0G-eeVY+LYPbt9+lFT>JA<)zCg`lD zrgjp`ls=N$WfKF)CI*o0{(-#y1pXWRjr+fYPeA9j&epXa7}h+S)kW}R!a9+S$cT70 zjr3WtK1Al7WQNSF2|0swJCOLJS@$8HbNsxGcy!jR^N?60<99+VQJ<;daALTfeY^>3 z5_jG=Wi#9OWhp-mWr;BCs|2HUB*^H7n5G`+1rtfYMxrg~5v?C+d2~WtAGD7cU{le1 zGM6d3Ac`(9@}CeXNRa<1K1__>kVruk`8TtEaX(Wul_^b31#yj_Bxo8mR8X3jo^cgl z@_AsiP=^`R(4XuLMWJl8PRtoZ-v_g9;cO^#jIvroxYlPzZGZFWB8$S6veQQ5JbHXD zI~_Mht4cIGpcG@Zk<1_HxmQa~B1uBc%->x^dMl6!QsR6ZJ%a8sR9PRRDgU0d?VOuW z1Up6qJARsrlwwRUGKX<>baaQ31S8>ka_v|mvnxs45{WhqN@UtX;_4ksWMb+)C>8NG z9ZyfS-msiS=fhoM`H6Qcvq!A;SI=uL6U?@l`QHzm)3r7UT1H~~q7Owgynz z2a(dmy5CBR?gEBGP5py@euZa^tb~#p_It4Er4M5RvI774thsDU-SoikpbYg+ImuE8 zb2Yj7I=2B~pYjx36`Wog*quHc^iS_N4+ZA$1b6BDUo~X+893e{CPeZ9{1(u?;hVy8P2Q4?+{jNv1M(8IAZm z)>pK^8S8aFz`vxj3PwgzcATfYa@uIHq9s0Fv>l@oN6QGkZ~fTLsD(WERZ{F7S_y&1 zllozMT5V@6f_B=h4Ihct>b1{YWZV!A{k$B)-P5IgouO8fh|MME$ciR0qv5+;2jjMA zkNu5+jO*>SLpbWmcpujU5yvGqHeG#06k(*bnWVSH-;a-hzZ2~RO<7YbqwiUyX9HO) zYosvf^g_|SJh&H8&^IYU>p{}H!nj4LG zEUU)a+a;za0?WXxNBz7W`3psT~)usy*lyyxj(GkO^PD_TzU&oKOF-v3 zHy9PZxXyhe9LN4QuV6PThRiDVcwG6L73}+3!5+Lnkr+vnnV-Z}?8e6q-mQodEs%FB z%!+nd4J8pBiRPG?^8db7?Pm4s*SE6WV=YsJcYO7ZP>!4?)x=xA*{u0q!pS{L*jK-j zlUcK!1G%0~Iv0y*9+(dnppll49tDo!yJNv}-cn-yGy5AgIp+Y@FgmnT7))p?G4 z<_nyc02Us*j7HgIG|DccQFa-Pvdd`H@u9N^um&L9Ri-Z^Nk1@#b(!Np5i42b^yd<; zrvd8BIj`BA^P0^WO>#1Olinv|Bj3qhSz7_IAN#JD?9gW4#N+v^xR!Uih!Csm!42Rh zekX6be3$eN#x*k^%=<`O-wj<^uk{GuJ<9##{ProXsShKqyulL1^37)ClQ|=qE8>k4 z$}6W)e@ZGRQtu^|Q>i&2A)G^AfgG#@GM9V`*77#48^L+t0&oeqh0pKgH$?l8vnYNl zv-8~F&;0|WKLQW)%%h~wlggVRuj@#)M5&t?&3R{u&-ajuRsIq98~1+)pE%P!tS1jk zopB|Kg)K4PMn-vJzRnV?Y*{BNvERloJ%3%q?@GWla3DAc%mA~%98gBy^S}bG7lK7# zF@Rt7PB=?Rmx1NrcyJ=1y}Vk=MIU?h@MSO73rxokspK4s=?UjpOlRlF>2Q1{9A62? zS31YRUB{E20L2YXC1-k9dJWuv(Hxc}x-`X_<4I^8@m@m-9Q0aUSB# z^boZRsWdHj^W4bE%)ZFFM%)j6*_yPbOHP5w?n5`E`XWO0wP8EO2` z+2VZ6-)YW2oKKw7ozM6?(`i-8*{VF{IcKR9mE!DBT~rt6Y?a3OAm^was;9#&vFhub zr~0XW&V_228s=Q2MyL_a#cCw-e2E&T#yeN2iE5&AmC9AQ&ebYki}>_f6_xHN&}C%~o@qTh#)!z`0E=RZE@Q)pB-X-Kkcq)y@x8CA+aUscN;}xkuHi zGn{6%Rh{EJsm|qn*5}lP>Qd)Lbvf^w{#0GXP9Hy0*Q@KDU#J_@ZO-dzC$j#Q+C?1w z_v$X>{LiXcH9LP%52^>9_tZn`3Fmz!bI&d68TAwAWA!|d^iR~Q{CVmZ{3WS3)NfR> zdRx7#(v`2?QyFRxe*@HqsznV{AG@9!=BBtQD%(wS(^QU|i}2Dd>KyQjEks1kRpd$Bs$y~e#sEpl&hZ&k;*x4A!5$GUgB zPpCC+)Ma-H_i6WOwb^~veO7I8pL1VSr@1e?uc)o=f4M(X+ufhLud5yI?*FeMb4f`k z48Z9B{ilK8777s&5fKqVL_|aiaRVVDk_aMlapW4baVv;M?IG>`eo*t^s-ae+HV|B| zlQa0{XYg_Cr-s(Gu10ode|2d8?7xnzhtV+*&b&^H0I_p!?(e`|&rt(P}9zk#wn=CDHmaaF)!Za*|5lAkp+| zV!=6q{z#_Eo+P;}6JvUam05|N-9=hiG7c}?Z^Hd=iIq;maVMnFjPnU%l~v%`Q>2A$ z#`EboZ^PM&wnmaqFA+K0PHLH+_{***K5RWnV3EXwRe+CljNeb;}7u0 z`EwqeAM!kjp!a}}9-^jyg}xzI@-d0P;S1e2aDB4?hn-}?PPnZlLhh;K>?Du-E0H;l zDU#ii(`exqJOyFqRh(mC!!E>&tR)YShsk5)AUQ(b1FqBLOLBqyFZq=w!C&5Br!|3^ z$(k3!{q1&)(v0+emApkhAb%mBk*~@3iYa=3~bkQ->XT-+ECnP2%>r)Iy)6CRav(wTu zGPAOCauKNui;B%9rDf%oipr|$nmKc8>*md`Z)jYwu&J4J60)R!`ReP|tX+3KA?t70 zuyOOI8*kdO_2zBcZ@Kk1x7`kM7CA_2Z5d75gln0#V;Ld$AinS1HSS@1S6lbu-oB+h zgF|Fs<*F5T+;#Vr9?w(zru{CrTxo!hka*GrU0$R`bS~|p>*)jZS^6$LO~0eRGFS^+ zz;0(xvyWwNvMI6!vK_K#Wq*}@=fYfqT*_VcxV++W(KX1`=vwaD>bl)^kLy9#y6Qus-0A0k*)1KyzS!;NyYM z2fiQpxk|1IRE4Y3RCTJ2s@qljRYz18gQ9|Rf;xhB1w9>fQ5_9ysV4iTxM=e{MMjML;FqzaUWM;TI#K~dq*Nl>!U5UHnH%Ehb= z2Z3tQtVerF)c2(&UB%{Q5wjxjM<-X==2gUV{x%DG$JAt2U}N~mse7nn_Jc# z8=H_YeR{&C;jJ{VWJ^iujim;uB_USGXP*6%%*w7uY@LA^OQ>9-4gvuty_}=g=_CS7 zI!+#^N1-;FTp*oflg^X^a=Dz0CL{YOu3$#sv?QI(?2?su)(LS^Qrdo zy4`uPw)w@?PgcHouc^fpJT;`lPfizXnG>n>i;OF>XtY7|I`1s;_0Fxxtf^T(H)?Cu zb#2C`{G5m1ibynNB?nJVOi^>Mknv$vT+dD}I_dqAC zOn7T}xVzI+DM__IM>n!ld_09`)0B!|E$q~SuHj3QsoD z`!;U;a?>UnRP$gB{@A+5Y=3%e56#?jY{Q028#ZwKNf`ANTaG-I1i+e$&Ch%ZLF&RxJZs*~0h1MvUoI);F{f2hi@@hiD)->fT zFOk=}t~$KJl7D?-LUD0pZ;H}8IjS}>Jvq6mu4Cu?5PhH?i6|v0;6Vx42un0j5#(?) zJ-6?aC@s{$&rUq_pFL^jweQ|m#p<_}nX8MEifZ!uO1!H)2cNr+o@mu6%hRi^OPaIt za$7PpQ=2k$hU&^@FbP=&ICL zln0w#<<{N(%bNOb-nO!4v77DZ5_5k^3H^A{o$CzRhU(s@mK>y!&nzf?u&^gLXV$D7 zPBUnwM?kY2XBA=;*gRtUY%z_u?Po*9!zWlwDQJ-q6J(zxXqiT)!v>`Ifk4OOi!#uho;`uqxrY}%XajeOO}?fb+IvZw_M6s_svPo z3rKw{CakiecW&+CVlJG*9-)Joi0V(%7bU+jI_65|IL`~?9;g@p)si35WT!te_~RYq z9gOwF+%V#`JOVh!caKB@rGPOi9?)_p9Ew$SG~L0{gpOQY6_JKWy2JJv)uh;t&@@Kg zJDz?v|7*y{LWby0x)Rz#l!%1$@q_NPJxk5DXJ5$6do@2FJW-MWc)KNd0j?@nU1a1U znr1tqr&Dd8v$U`C&!!)LkNd$?*z=zt@5w|9jfYGA%T+GNp9+yLC4;3z$wsEN%R|Z< zMc3;~Q)W#L_XsGT-V>Es8yp@U9IVl>nGNRoP5CML8lNDa$qBl+%-poNQoSucJVB#L z2nSifmuoMPtpz?0k`6Lcv<@Yj)PZmu5k%0WkoyJcRpC0!1{o}QDg!;z#3l?Og?ojH zWzL?xz*Lo@&d~)X1jIkIwQ6%h>xmaW+MJn}v+Ut#x3|u`VeX6+SDAlWw0Ysi`m}r+ zR?}=Y%u0xh(}x77FI>KBWfMVoQ0a_i;dGxX$nm(*D{$i}&{XqvC8s7TA1D{eO_aQ6#$DqG2yiUVMfK*76 z`wz@mYZCc@R;yBqK&I7N&$ld@oi@90>Gbq(&lP3l<=ne#R(@{UE;h8F&{*N)QI#?n z1do^Qak6y z^S9m2)>$i+v-3Be-)_ln89Yei_i=r+;@@1sAF43$H$M=m1l2s=XtgwS`x8%Wf5Ec2 zbIo-fi`mcGb_+Il-0Nzqq++0h6cLj!H1Oer7u8RfZ|~ zBo~I`AT?Mlwqw9=J5N`&d%f7i;xh;Ig)8*`2X>VKlfTr8cuPh z=F-Q9w=!3onf_t;Cov54v_KX`xZ%3M6bM;j)N6F6rOx&`r$j;ji9y6h!~iM3K;i&T zK&eTx6_ElX)fLu<87g)P7t>e}1cy1lm79^Je9{=J18FRxp7c_X(u zj#nn|@&u75%t*0-Uz*}o^zQENjy0BJ*}1vdYuHfdf%YFk%pY?G@AOeJ?!V^Zbbs?$5?Q=a_7!s$Wfvdp~c z2^(@PYu?|)%4)Y%BqjEiSMOMRk_-r*44A zd+N%|>*(#ao@FamETg<8AaY|ChOxi{TZ5rl4<4#MQ-!kP@CBxXxp0$3KjhuAKHNw) z8NgSeGW@meyw|X6f9voP!fZQu_gP0Pg)hVt zDi=Mwuj$h>3lHvD_?LhEi_WC!HajGJgyTbWW+51Z+?CS>zGWTzo@)HO;tUu$L&I#h z*ld*10p7P5ebwj-yEoBDLzs%Xs=|ut65Cz$T^vhn$%XU_Sy7=aR93|MTkX5(4CLHg zrbrZdvS@u{`SLf|se<8>0*T)^n}3VicHF)J4_%^jY)|~}|8g2k_Koa*`&&E?sS#yOtYdh` z%sdJAB=#tckTr-Hg(XhvdG#e(!=~h=V3QOeMxCPPFdOlVny1bxE%J3fEh)7+KA*zo z)GCp9BB;_^jP04V%Oa-FYt3_u9VlyT-&Ih!IHzq^H8p0>jEU_DcAMW|J6=&gcU@6% za$r=<{Ax}EgN!aQUO(_gE``;DBVT~>lzM+G-X#-1nE3pvHS-e7g8WUE@=|8$tE!~; zRB!qF*2IJww$Jvj;_UJqOUomRz;80>eg|}`0G$VY$!DY)P7qD!wfa_g&(daD$_7#^ zm&~odel0y$o2{6h(DZ1lA*pQP&Hva8y3zpWTPIy2$RU4}xRw%G6HlynmuGpXOXKQS zuYBQlOGTfBmD78u|8Q+ZT>Q4b-&C;Zk(QFo^4xO3<8*xjy8OfnAlb3z=6zK$ge!O&f=G#FS)g7@N~GA$H6!MFxts_q;CaN#v;?iOcZWey zI7?CIqV26tjSbY)y_j3R^W0{ANcFy@Vd1aojWjBwJ0sI*%#$oMUlq^|W`O{QMJk1bavwXG z*gI!odG;!^#X>i?_BGqi(#iP+?e(8y0Q9f`T))8%fODRCz^D8j`TAmu#Wy4*F*KB( zv4t^9NL&d1xQrNoQ$s$&7n!u9gl81F zWIBNilOCoW{@WIfM`V7ahzkH32y#GyiBIHuB?@2x+Mlv4ma{#l&o&RI9EDX6zV?jm zBj9)D61>JXl1uCxuI03eJW5styTU3^$U;3{AY#?ak^DZPKcglfZq?ickWOxS_6jqz zBa%4lv?Y)=E7Q3d!BwO!De#69xrD>Gr(~UBXM(t$jY$lKu9a%0V+LrFYG_`SUILwo~k=t+8qEqT-DDOvGY7_j|BdzzPsE zX|ft+ia^u>5g-f(Os1&EiChE~3GUZ!ZShK@I#d;$mm2fZ+Up`K=cZO^y(oyBUq1Xn zQkbtI-M`$tqjt;ZHy140+f=O9)aUTEu$0$!(zBvE5H19zf<}OcMlW@-SR(2}gI%W5 zdk=g=&os2Umtp#$BG!BW+Azoa^NC!`otZC^ofExO#Xz=VD78M>%*x!YNrvdyru6K^ zuPm08viy#`=(xt~=pzM1rtDa~)>{)WyS;i&Zd_b!y2fi-WFv5d+rOd{C=*>cw@|P0EGsL&`|iBRc%NvspMJ8IMx|}qlx90s><<{V_MhoL=^1Vh zk%$QZ0U^TcQBy?@_;^xJWs9XRyOLQf3p?g7pozARSGJaaZ{rh)sEz#tRy8vJFS+%$ zd9T#ILO-<)(XF;{JQDIl4UN5un{o4h>tKJ*(xLME%6hs=@5h)8w9R%my#eDaw%wq8?EEwxmgNUQNM1?ENu__+Q0~Nbc z(#;l!QPqqDoH4UFPJPJShN?OF=j&s&r4ch49!mty z%Er3Mg7-6c%hE35LpW*|2#b)Snwy3$YIo$M*f4YW=HTebGqmOECLbLQo~`aRrG_ky zkR!{(cx1<-X2*jfH+eCCfpKn9ye1tciA0*t09;LP^_x3A_1R}5pG%69*T`!Y*j}0v zrLC`TtS_AJNzavM6?M<-$P12%Ei229jqjS--O^oZ<}zSplFXA%$J=&yPVJQ#p6rPJ zhR{&8dfGJg?Ng`5O`9h344oc2@+W9jBUcKSawV$JVV&@k`n)V?Y4RpWT&(r+jIZ^1 z-T2CCUxu`5)QZ0a85Um#id8=?5~b^Bxq6VEpAM{Z`fi+c2w=x0MaUfZa{)s| zLdQaxXtiVLsU0UE3GkV5^1)h!1_(PAs}iM_n<%Oi=?>GBM8QNoQR(cbM|_7Vnb7Y^ zVS*CJkeB^0fR_cHWjq4%dLsO(r}>VNI3dw& z7OHfgRKNrl01c#E2#nj>TFYdphy#<&e^ zP1HVM1Actg3K(Dgz&k?SNCjl8aHa88kh5ItSAm0h7e*@z)dnRGGPO6HT5sXi6dEaf z%~?iq0vz!@2TdKI2^HN5GyxW%jZj4&a`>YYjuUR}h;Ahwa{(`ypzJ;YB7em()=@{G zZx}1i2{oX_W92E6a$eLnczuD-|NpVVARKJNwWrz3(NVBI8A*1 zrPn~3TE(V7LD#}skx5Sok96WaD|prYH@r$Q^je5#Rhxw>uZ6jqzTr^m2+v1>JDlJ} z!+(~uNp=Ldt_T1C^UEV3-rCH*}FS1xT^lfg_0L zM$)<}%;>^s|+j4Z}il*{T&-Es|yzqIL;I`U@=Dz!G`f`h< zh)%1{$f&-+4Npdlp#K!|eojAfx@*$!mGQu5E@-Xn1`*{0@Lf2Iia$4P=;GSn;<`voH3tzgLOP=d!u!WzmT~v_I3u4WE z_e^j^k>}9wAsb$^L8a?zRU2XI{$ndQKXMU|tKP6|Vc`>DI`ajrLgk{`8y+RrQ%;ya zn70;{ZY`hzTp#0r(tk;I&HeIw=!VmYcYIf)(-A?PP#ra<2q|uk2m5=c8lgQ2_E7PE?4-S9gToM^|`0htkJZd1O=yYCOjo1Mc%g@lXd&fe0=9}vFm2|r8{RQ*c5vLzIV0nWsSmea2lS9v=DKiQs zkEM+*l~gQ~;K5Io*olY&&P0e;k?m;c-;5FLI4t8l8RjFs2S!cmO6`{WJg-Sm?0bF~ z?{}6$*PTO&Jv*0Z`aoed>LUwcv%{PKiIti+OyP zOnz=IbSBMsyEcln>syxMp1Ph z{i5-~MzcO6AaG%3)#8pt`PqfWx-ieoltuWA2lY1lJ$P>&j&&NeI&Pob6W!hAe4pI+ z7g)HhHuwJf)9LSQm6Rub*eAE0{=&kx*b&A=nkV`hT!T&b}LaP&idtz%c@y+=d?yww*|jl zzHDJyVbPGei0SmP^K2&$_0CPr3rsy0r!AY)H@CK@Ab%*|+?UTa5JY{TQR!y|PSQ0+ z{956-X2`;>b6m@iIc{`ZyNv4N3JZGL(JsgJOO9)I zpGk)FsSC0=d>>HixW;>bmgcx-_|B)maV;Y?tj2NeGOCX&zO8x8(JsgJA05~3M8m`v zCV=mS?^1qsw0n~svPq6>ACe;5pWBPCt2)~|1~t(wF`DGWq@-Alxwofzu%o$0Q_ z`y_o_QeqsZZLYO{ptH9}lN6trm?*l%Il7Ifd2w%#lW5Rb)6qE~(N*2sHn_aG->N}F zS7(d0X8;rr^|V_1HG>^iO?7dp#?oi)kvf-39bz?C@FvA~3=a0qN=O)J>F?|t9Ecx) z6hM1|rJ$7Ll3vnBR+4^HT-&kld5~!E{%kuDLG)?Hm4;Mc zL=WzIF_zy)1J3A{c=TO~HY@6|Rx%*q_aGj(lWsuhBwhH@qy?k9fs21hv>a_5x`tGV z{#L+UCPr&WfxymbE63Pw@mzydcnR+M0jU|+8vO48uCeVJQX@uieBr=&Wdz64PKLzj z{t*luQ$O0RfRl{=i8#-~ab=uD-<6Tl^CYab;~=X<{CCQ2E}--a&bjO~c*^1N-z(7K z1h-e9{U;ZVYw&9Pa-O+W4FbX}?1)VOz82u<#Qh+y<8er~Ajv%e zxC(%i&pG19ehBis+Rt7zQuN|=a97M33giOrm?J$AJ-iXad=b->cvl*LDx(T>pc*Up z$%xk>s6T{a4L=POhruSan8PDc!_vWmV-PoIz#8K~R|52u1l)S;<}je%Vl^MUa*mx-BJTuu}^>q!QY#h6T=nY-&jzzT})w>XBs z7eiu8;00Y|DWu3PYzVSk1|6>;tKf61F%PUE*Ws%}31x`qf58_L&yZ)yb5uqy zP#5Y-7LymBNMcJpfMTsHE=bD(pD^MUt(b(yti9^KN*^FQ*oDiq%#ZM`<#8tevlEFhb&MQB}(ei1E~NgkdT;CUg=ML3)7AL6^U zFG&rKI<(ERe+C$*Nj>g4oJO>{!8iPX@jYPt5YRpWq?ge1YX`P(;g6{T$4_{25x67l ze-#w)YfhaCEhkAFM&;S}0skT3e**Xqf$n3VVIQf$vq~IQ_TQ6goNMrGj{P|@*M2|f z;@F-8wv(XiP0;l&=sE^}kFcL1QNYY0CkyV*0Qwm~KLhAz0R1GOzXzyi0Pzbzya0%2 zAX7e4qUYa@ID-*qFybU=;4)2yltVD~C1AZkW(dqrqxB-bpSg&7;g{g=bx?2^6dVQx zhe5$%Q1A@+I}H8~gObDG?=Yx24A_SO`!LqjrvU#C;PFH7_#t>a1|Hu8kB4CoCi`AU z_mo4^#~^Ey{adtr0m)tvcdz4)TLE7sn}9zRnn{C}B-xI6}mE`o}$NEyy^@sz=u ziV>6iaAg7)X~4?A2|EV}#pqLpwg#N})6)VLzd9kVI7Kf2#~Dy`1}%q0uVc94nVboF zO0$0e_?5VegXB#1_ksIcP$O}|ZI;7)6PUP-eJgC_lz{Rk+TTNDj{uFFZj=28T0X@1 z%aB9_`p1DU6KpgM2d9bKqBP>ttGoqU|`Au{zTkTS{ANtyjh$*69yN(V}h9@rRN=&%4&UzP0wZuirWR z=|1`Py6m;rdY<>T*52R#b|e##MbeW|+4I`hZQ1tlkB>Yml3j_~*W7$)-(4ePYwi&l z{RHZ+x%u8B6R5|Q{|dX20|)QFb?h_mzgA>kF7nadZTt7#@|};|`VAcW3O>7TL&f|{ zvM=LY9GA7X9XfK~Bl18G<&WX?xd-pOdEf8f{n_V4=HT#1erVr)cV$n>cX50JDkkpO zcWD2*H~#HoB7gK=)ID+6op&EO`s90lD)Pr`an9H8I=ug`+efl7;CT`4=L@;ubN=gp z^sP6aaQ@F_bUrFX{^r2jaK6ZwK6>;!A}{qudmImpN0?y4Ir-ncv5kMhi&lZH0^t1E7YSW zJ?3jsll(TIqi|6h0SZb$5|B>Ujg*|GQe*3Zby|6a^iWlxMO8+mx- zSEI{DuN(dN==btv`L_J({HFYqb5_i`bX<^4{{J%b#8`w&H;m&z!j9#1EbL{gv0Q{KCo? zPTF!9Rv%gYvDGh}anl(OtyzS>p8kDo&1cszz8h_87x#!HsHypR&whe!N*5b1!&U*T+UvAvB@y3leZW`IN zanlW(p4{|bJzM^hj;y8_r1HHn>u&u==9k1k?E(--F)uj=gmFu zo#*}V{BzHL?1D2cc<6$kTzKt;&s?O|B^kIy#11=FZtP} zH(mOb%Qjy2$Yn2Fe%#DYvpzF26>abS#FjC@>aQ1?v}U7JK%xuk>8UK z$cIIi?%ck7vf?ub^{erDInt^zdv5zxuQ$@`&2aC!%6*r!o5(!I;t_;4M7dZOl0jng zNf2G_J}pDs3{RxpJ!c8WV!T?^+pHvRVM>wUu06pwC)(C!Q)^| zCHH!LqFUBn#2e*d=u*|oI_q1;fy{iJdW>}$=V{q-xh&6qdRVLUeyuzmQ5dHyg^X7? z8lh=ts*Y!`qg|^;O%uk~Qr26Zsd0q1oXIvVv&#(={j;?3W}cp5KKoi zST16X#RFwwF$O(z%Y}PxA`3G)HW)wp^F**~_CZG0mrqa4T%D#Pa2!Fmx?}%t%f)9Z zlXf_gu?jc>HualyK*N-$)g@?vLwax~1XKKrW3~BykOwttTDR!MvEzDb(v6}D^;$(0 zCalU$WI+vvpwHO4;_)dL)w7MvfvU#CMIu$ES5(GV);W!;rXy(1rErNU9hS&%P z=`;^0CSy%J#dr`~N1QLVvp!TF3>P{FxIHmjK-6dv#f%{$hREVpJcH#E8@UmGnHL&% zOM#l=_V(x`?hCEpV(r>a52eyKiy&hAu+Gp~8cAC50&*^UV6s@Jn9Vv$ zv3gNaB|5$ob>gi`I7S-4@0Q?{eb;fcW#Xw;be%z#zOJlJJ=M+g~fX&df3 zr!+blx`I{IYQPzV_rg$srE83DX)NwMTv&DB5Ny24mdkW9U_TfcW~1U}HjOVsuyFTV z>tki9?9DsNQYRh{Q?a(Q4_xWCix+n78)QnGEt8+wa@nx~*-Am8Y7sLRF{J@}AIes$ zcong;ooRwxS&rgja8|PrK!QpbfI3(_)*SA7I9g+=1~@XWe3@bdxA~Qe4{{=N1w(Sx zk;JTl^Nod~cRc}V+L^0{OnJ{6Jr?@3HE^&FlZa0>K0rd2F30Lu-Cq@s&i!a^m}HOf z@cjg?+|efCVPo?COsT)9Mj#)i#g8AtUrF@{r@yJ|grcskz!|Jd$G5SKo2BX<9M@#w zdn9FkYAJI)$KmpdF|&vh`=@o99$7Z~h%8d=&r_>3K^~WrA#=#PV(g~-VZjEByLk>% z)^ROFjJBq$DqDNsPmn9i{6yUBx{$ZF+!klFp`U*$ncInVDa7LD(6+J(vM?JkUB#*K z@jM6C!IT4ioVtN;gAF63?okU~uwDot>^o7Us#mJ5wdEAw|1{eV{uT2wy~q6OIGT*& z_NooiRibXsx+xzOkQM{TvpU*ojrA~rNC84TJ@3c%>D zvzjo*_o`dz$gozW)jA1g7n>mcQI*t|nTdmG_ch75j|eeJT9av{s-DN=W6V1wK3brl z+HsXFwPcOKMA~2D%!ETF=9b<7oI}PnN-XwylQ`|jBpV+$`?6z$KH-A33ug#+UEIS2 z4?4s8iQy}zhBr>jc*W-p1ZE$il3*QsO-pSVO|`E@yf=jJG|JZrx;DxRx-cEZDY+Oo z)j+Za(n2FTeU799mU#R)KY*oAxUDtV+P_XN{qOWNLdKelHEXLAlTLgrKF74};+{>< zx)$$G+BR`D%Cb)x>gDq})oa19{*7f=%o}=3`~CNGji3N!rfb8c-p(jFVliFEWlG#W zJZ^c@1lz`vkMpJ-jU2ifWQ2(qgN`q1pd$Q>Ggy(Mh<&3Z`a&Db&B}VpI8jEHC;zfM z>tfl&d6O~QFb}viPzecTpmE8i*z4ht`XZ8{g(6GTe%ttBSX-GMyQJhtZ98`>T_JL@ zqMD~)wkAZo?{qI=+)JB?VhxnBu{PGuJQn~p+WB|_tvH=oJ=4|7z7rAp(PHizZLsnA8S|22>ZFw}+FSZb=QS|BJhp*YhE4Uc zjBVvmbtToWA423En2l#KH9nRWkFy-x zV3;8LH=N?hv^5{BTbq1c{k#m1>4$0T<3)Q@OAFU3jnIbjamuauAtqugepp{@%W}{w zu*Uy#QH5$f4zbFTzIT>gNx1+;kppH{uzRB6L(#!>+C&gdrbXu`>b$C@_E70)2!`TaI>?LWVt zAT~*w6syu$`oM7=)T_dhd^L6k#;qbBx1kGVum8?yM- zlHRwLe2|A~Cd0^-wn;foF;-ad={UJSq-7(*HgNB>_L*HgJHWB(#^czrmT^6nj_(y( z38N1!#DEgs#ow9?Xph>6Bbu!N%qrt!Y-__pUNlKKiJ(dag`F#R(i_An$5rZ$_=8u) z`YOviPceip%_S|TC5-K#zpt6A`uFtR?{t#;2$Was>9IW9<{c(p>*~MwO0cS?qo0GP zkGTyz)jmx3F|VQ>6wAt?-j`coZjUqba&L>#IH`?P;Z$302a{{JPV>W1k~P%E(yYEo z+BmLU^os{)UM=_CdBvJAoU!E>ErsQnmvLh1Jh*wT8-kaA_Nl`DRXedS6QQw)5t`)b ztGfDOMUBbG@zN8lA}YppYy1%5OfHa7d?&T^DkaE@2pp6e9BjnPBsre3w(=RU2#>Kg zOiZaet4C@WRi6$INAae|EUo|>w@$IibkdZ@s4*|4ch6!2b6^`Kr?P8dLq%LRpIS=k zMR;^{ojrB-uYm!r;eI`J*Q>Rq{%=YL?t{hHEKgkaG0$Y#w9R%6_bHRxlQj&AhTxuo zto9A{$rz_uA5)X3;tSV;Dn#8uuuysp8j5nL7;cD~(%1scXH3F87Fj`Tk1pSLA<(r12+aK6`aL!y88djgCw(0^<%{pS;d z^f=^z~qF_ae$s)LRW;vOKD$|U9N!;O~U%q50U zp6__?B?G@$J4M@VgS&v&Lk`H>pf)ZLtIWZJ2M~WESG77~F>TVPFs|B=bER|`^wZ%v zY4&Vh$`MQ=OilaN#t^`cIk4^tKRA`U?8f@Aq&ABsX>>e^SLz|4;@Dv60GfU|#*`)1Rj&JvJJl^aN!FV|w;rqFbh=d(#RUN6 zHG}Wq$DvbNIVES-9!taQfN9flo>%P4%f!t;!9rB7&NAXUbCMPpHRZB?Ic&#Rn-`E} z{9(PdiBq#3Bc(p!Y$;e2Sqy1A?mY-N+xv*x4X~KKuxG(eH^^mF-=iV}?UjqhETGE8 zwa3+%zIUY%cQBV^U~66$r^;5Ts+IOTavkdL+J=0O3o#A$$N8q$=DOdklDdiWrmMJ) z`6!MOJM2?6SM)m`i#Ldvv3ltD1>pN!UE>vFUUE0oFk9*YsQMx>#FA4w$us5yx^p@c zoESMA&t1Z|`7}Q7rR$%ik@c6w5JO7IGKQGVSl**{u|Q{uC^jU(e9Mx=zN5>{7s}Qi z?z%mZ0d3jvF$KnWR?vKG9c*J>tyXS#sQe@#9-BK>0@SJ~W7x`I>>qas!pIz*C!t6D zE1DqYNo=j}SGeDRg)0WrmT86>v3x-)VKu-u){bqg4@b-?5fZYi4WDr#9`$Izt;jvp8MRM!NOH|zM)G)fh2X*$Gjrv$er+FZEDhN`BG>tk&2sXF|@I*Hlj zTujY_$blcl$)!p9P@lyuBFlyQdYFV)`yMa*<+6=yX(9M9l$4C*pJRpu{CrjIqv1K` z*!P$xb7NnYTAgW<=K!6eQE?!?P!Ot7uT~RNrwdHV%0Cy7L#a}~Mpdm66Y)@LF|T4h zj~jkVDdGOq8fS4J3f<&Zy#cd*7uQY)j2Fp0PQzmYup~ zb=wV#mki6F@Xo+~R26iQbJydWSh2OTmHzW5>H8zYOln*TvQXb(oymcz@sIPYi`!Y7 zxL@W8+`J>6V%3jOVX4ZLb8p|*TALz!DcktounZkm#yhi!plL&Io*#RY(>lkY>cxe$ zI*j%{2L#*FcpG%gQDS))%jzF$RJ!Y%8)Q|n@mWh4%m}X33u6yhfO)1yh<(eZp81DHS11f8_R|kjo43H4i=rGZeZg$_T5phU{C3@v^pj& ziFz`*Tgo~f%Sw(p8+Rk?eB>vksu?w&4)|R22y8ts#}?aL@N{A+V${*mvHOQoE?QNx zQ{V17Cgc#tH<@VPjxYzyxhvhMgAwtQYfjH(fxz(WbGfe0>;fmvUzx){p4{$gDF>^Q31R1c(}Z-(n5% zngthAj!8*C5J-G1tdEEafMW~1tisRKv)b4WJ5!RnQ=`#cwWomh3eN8(^GF(x``>@M zcZmnN7iC~&;x%2wb(9fh$m6CXt7AJ(lpzX4LiF66Tv3Q(0Zb<6;qDvgzuf$dW1ZcQ zx3#O|uYte^NKrAFfMy^8|L&}Tbws`X?OpQ04v0V2v-!2zt?8Jl)y3`Yc%5B{8b;r) zH6m(}WrI%b*886K0j;fzyaC8$CiLoK|{eG3@&-t#Is#C(vqYwf{xYq`Az`=X4iFt_34 z);2)!a**=B=WnSey|+}lr|HN@FuCjQwb>7Xo&%V z0S}AyU~z+WrbEUDwY6ww)@&>Halbiffos4+ns7NUumD9NaO;2!_d4~rhxIbs?Y^-m znxYLfA%x@c4g7e<|a$c?wDF# zF^$_0t4_!oCtwxf2ESWJW6!Bgn^oOq)`O)xIZ5DLo$tT6>+hhKqV*Ub>Z~l!Iv(SB z#e6I`=INgH0f5M$&mpC|GY$74yu*9>s`}mF(n5VwJ`K-lknFD*m%YQXIex0HXiGzLQO9qoAE7qd zsiyw_${Gh^qNXL8M&dk=!C`&u!iYL3Vi>Bb?uf%z{q=FH>!belVX${YV#t`rb(Uvp zZQ^`fXE6z(RU?nvqonfI)YVg_E@HVoirp@#Z~`~Rs_uRsVyILkmc#fUpt zqd+^v-{EFyvDoo}J|06_+>9gM;7uhp0}JZP1$@s?wOP^{H#- zQl^gephHnUm;-WQX2@-bXC6bG_bjwbsl=?Bq~v1-P=hkIpj;eqHM!QejS55X2yuNT zJe+5_&^1d;?6=6$+EznMpx^^O4PI&H`Oe~Vk5;IST zYt$Cp+OxCuQk%FKp6#C%PC_DNQ>iMq1Z+9Gnx1Osp#J+m!hK8nyXk7SED(?z97}n- zU0Z%D1Y65z*`js*xc4e@w1{odJ&t>pFUG&BwhlZL$Q8S|5^gM^#Hm34`Rb}`6?abQ zo>cMwsiWCcMd`O? zq=BxHRG_c=s@XwBK}QG*QvVyKs<=Izjs&e?#8b?#<1~0d z5L!;06#{J>PbFj49FJppcv{h&a^ZLb)mjO5{ymPpQjTYqTb+#-r#7;iI<%f}9@706jP|E)BnnZ00oJl}&mv4#qclY!!i6F|&_dZ79}38~Gdd=-O$v&=2t& zX(BFKQWq9UBx%E=BDfW7Xo$5#m0xsZ1D6nhNhha*L&R1^;B73c)4e0w)Qq&!jza4x z7HfkZ9#0y4HeVxd>;Y!otb^2iWJkg!a4aY0^*JB>9tBq~yhnU!e+m0vr)kXkoHW}bqKY@AW&GPr}jW8?9B8xG!Rp}rLHLJEfQr{?3 z1nQ)3OC(gkURTew7*d70Sf8*E3<+~-q|iQ!2%ml9^>`~?*!>4(LY-to>ciHb?86xP z?*v--3YDQ=lMAy+5Yvi=9oMn?F2QD<*}eBp-yPKHkc`PbK&;Ux+9*w@&TvMXOkc0< zIY#emn@zpi%C^yJ$t&X9A`~W)fG>h|h989cZLM7Ca~XbR`Jm5_;FrD!eSS2m&!hYt zScq+NwVoHU+{SRk=8 z;dFV2)8$9y40*e6<8ZoqhtuU9&TX<4e>-H0-%rZUo9>_3d-(RdkL;k|pWo4ES$od*uwf9b*f`|jAgciYyjJGS88=t-$m4EAbuN$@t%y zR>`UO<^Soxz8Z2~1AVN6HqVp|a+YkAO>#E$xmhJTDcfW_q`Omg$!?jFX*pNUlk?>Q zX!au6BNxjh;Cz`}F0X*Bu9R2GtK`*kmHdXh2JdaTT7DBUdmSY4dbw8K0BOBZeoNjY z*UN9q4f1BWQTAo4voo?a+1hMfwmv&E+mM}=ZOk@hXJ_YRo3kz1)@(A{mTk{=WIMB6 z+3svAo6gS7&dbivF32v-F3R>~7t53KXYyWopL|IklOM`M@*(+v{E7U9d`f;QkH~lB zJ@N@SiUUZlmC_{;oTfQmZlH26R@?Y|Pc?&G&t+0@Tu$WK45`IVS zf<@d7J2@iv;_V2}%YCrr`{f<-yYfzXTK-htB@bXd@NW5uydYm#e9s-X-+bpS``2u} zZ|l~rlWB2VTHKx%ccjIgX>nIt+?^Ju(&BVl+?N(_N{ctA#aq(i{kH7E`{H zDc{MI?_|n%GUYp&@|{fiPNsY(Q@)ca-^rBkWXg9kd^ckPbbkBo9XZv*f0u5Zu2J9dBL%^P1J8X6$F>&3mhw(tDU;k{4svFG`-WiM9@ z{+;_OU(3g7)!zL_j$YrrvdiU1`0~Mh2X}10$qa{ z!1n#S+`9*!CA#-pT=z$Z4&Hj?i6`&<9?|_r_?oXDI=t)9&3$e@Rrp+V|H!W&=H|CRT?!h0$59xd6e4>iuw zAzCWcecantn#K9sIVW2`xd$Lf-?M$6=8E6-srv^ScU_z?a2)o%+eQ11+{$gy=###o z0qGn_`rn5?hTYXZCGShT4t!?4#nhg@*uWGA0+T?m|J3wX2^Fm%J zViT7KXpB#q$$zlqPtdW^CyyPI%kGgJ3-n*#3|C3D87Gf&RI{*UNHOU>}O`bH|N?p4<6rl z{L$lIn!A4PLv!Cb;i?lpd%|n;#^*gW?>ocmhr7ei&+nUm)%?TrADaKf{I^E7jXXH= z)`AZ#cyPfF7GA#a=)x~8nz?A}qK6l~a^jj3KY8LSix(`uVeua>e)XiKC+$4x(Uaa; za`BS8mOQ=W&65}K-`)K8z{#(i{La#OOFz8y*`+U@viOucPkD6NEdJXme|If=XxX#N zzO$T`FI&EK`A3%j_2`_@vC&WQ-?vwc@!t(A9$WG5sn?(S#ZzBhdHKo@uY7scoK;t@ zx}E>tSUqd?y4AO@eq!}Yt6yJp!J6mSyu9Y^wd>YiyY|6#ed`Xad*ifKr|moK>C*>K zzv1-9PyfF&_MY*T^`q-Qx&HMtFF*5l&ivY0i_W_KtiRtdzTv(N-x?bqdtmI<&eG1& z&U537#}ADE?Z&wqZ`}CYrqNAzZhCq11)Cq<{LYrEwmh=s?X$O?{mjIoiOVMLns|ER zwaJSoADevZoXgI6>|8qc+H>zd_vQ1>I`6*oUO9jK{Lfv`cfrRH)5ECHPeU}DPM{Gw zkxr)Nw361+8MJ{m(%Ez_T}VGem(mqh@8$)n2aa_m@v+59b*~KyuywE=Qz{H*zfRQ0~*uWk;sNep}%BV_cRt zStJ%}03qJAIl|X(*Z)U&3bk8bzJ*hyA)QbakgJ)Bm&0s36* zFj`mYK)6?5fsU=7En0gF=Xbk~k&^T;WD8cwNj)EJz&1k^o*8E&o?$7=W!A+upH+YA=_SXSIYh!%ABJGOS$jsBB(WAMPtO^A+TRrmUvx27l-ggE6FO0SK}V`b zTOahq5JWjaL#(3#cZ$)kbZwT{zDR{b2p zqwo&Wm{fleHMdc)3tV7LnKL-0PMOwJk0XW|yY%MT8Zh5IRQpq5j8#9%r$Kk(E4r)p zm-jaoDmUO#`O;L60b>tYJr&icgPf8uebb6b7OP@Js@&o@%7wVOl6i)gH3Q6{6Dv#@ zNo5?BI34eGFr1++m;|?nF*BUUR^k`~&IBGAKe=PQAY6k5LB673-ja+5K_c-&mP}G^ z2|bIel}#0}eu>#)#AL_owZ-?eKy6u7Ce_Pj1m}*iiN*SCS5`?&WEl>a6+7BgEg_XA zAPGxUJjr67WOcP02k^LqITVx zIafVsTF?Mnx~|g`oqhM{Mk=DQGVw!`8K;y1B6T z=>)%Gf*i`M)+zf%^*AQ|d&59hsP>rZ3HRq=&-i7XrN$S}E{^L>a7$l3IGbQ(Z12lG z8W@B%D5GVTp{z#F6LSc2dT$|~{)@)RvJ~9&NtI8vs9ZhqT0QQ7up+yA)_4gsim5-tU0o2%u6z8qHhuWqF*d zOlV$06(nPmE)|eOco=f5R4L0+oR1I4jZrv;D;vNh5I2>g#l7LM zL0*PlQR;E^nF7>a4jgEP73S1(J~0)p6}gq90DZzd=^Ue(Bxnv+(^{V4DQKX`p3r^H zhI(sS`uw!l80?^{Xc4V}T2nBXM<^=9XzqveY8v4^t>(WL9Z)Ees=P&v z^8#W(WC~4^K^OdW(EYX8H@oMw*j3+(-(u8bNHcZ?9M6#aB#E*E^)T@qBX5;sxQy7g zXKS5mji^(v$p9ET6mWIE!+f>!9qnCHAOI5kL7g7gH0Z~3rp%$To-v#S%8qBgd7Wqg z3tHJT7wPi_wf6+dn8k<=#K@4zwyN**^eo`wHNEoh6NkN)B=&Njg{d|sX;rUN;K0h8 z&qHT9{TL|T?My{k797mLom$SO;dR zVj!|wtZSY?A*`EeXuO{)SyR?$sjM}{(bM)12Gvh(z2K4{VaHM|a@K5+JjCEiJJ*L~J$t!$+%6<=-d}rAABKKz7fNWgOuT&84dY-L3*?(^c{{nYbzsTzt zfF^juAmEiP#juk&!n)Kr-ut|(*jHH}c|Eae(mq5*#a(AGFz3Krtx_LiM^;9)8y)w8 z561bi)d6!MNMPrFV3Z}51`5FQY2dyPTeNM9E1%Eg47rM4DcWYOZ^iW{l^fEJhgjcIIy+w!S+>Nv%D>Lt>tRkF_q0C)J_ zztA3qVfcrlM5;(F8g$L^!c$k;y^hU=eZ}v(3)r!9gu>abh!lGFNgV||7i95s_XYNy zg(P-DZsj1zZ861hE6xdI=*Wo9=a~0~aX{HFOBET?f*CT$1aB7Ad^E9xJObDSykFC- zcj-~6;Blj@WA3so2k1$A%jXqIKmo#oJ!ELgpm^=H;XqMnuNno>yY$C``!Q2)Tgo~H z2QA}WUJLoMwFg)#kZE0}A*Lpd7T!Jr?lPpk1{~(u)xJDzdRG)cWItN3sdVM}Qx@wZ z8sb>_8ce+3*Og=v(twS88} zIZ_}OxYquW*X}Z5E4v)TGj9Dn+fCO!xF@kIYk$xnw~m2;&7Q=@v^S*uRv2$Bp84vz zPt)GiR*GL__b=rmf^>}4CP}h&dx?Qlvr+A z3S;m0a`W?;z^Yf`oUrk!823xpA>+6Y`SWsD$&YirPJK@a!Y0DYdR8s2xSmyq&+4lT zcMflW9FaFcZFyyDg=Y>x8(4RaaSnRmzQiD6qkjF1uPAsP*1xAIa~|~@w4uJGdPNz> zQDbg&c05)q4^GWF2e9>Vv!5qJ9BtgdnD`=WwM(Lf8zE>iUjTZep+C82+&#JfqD z9iYxu32w`Qm!0_X1i62fhht*m$M!x@ z*R(Gz$E5r!MlIX^k@wg`;7OBwWbmiv_WIn>K&GFv_v{m!QXLw6V$q>2`Mh7DYu2+^ zp595djFW5^c)vZj<_*oD$Ji@+7VY@%@=S0Ge(kw|jznrm1-6l*?G+}?*V%JD*)|qx z6!b^(zA@KvqpQtwRI+>H#-lOWh(530T05%4xEd$DyruLXUKea_0D@3>6pYqUE zm*pv@<`~r}=s1ptxWseM-10mFLusuY?Ykftq{A>>f-<=%`cZR;2+#*cB8LV@P6Gu@{oxcVm7_ z=2l|A%0N}h{Xuw7f$X_wuJL6*GpN&#aAkvW$Tt{4D*a}}_mRwOfkFF)DY2{~Gb;qeo~_C+ z^X+rHu`l$2#zYkCN}9)dCE{YZhlo01Q->Nn9)v~K0e;h~#CLU#Ml3sTrTMbTuT~D- zcn2nN<8%)Q?CXrC+_ODQ>}iR|Y3!`*o~Y=z$9g;ySgk!N=DZ9j>#-)OM;rn;i-*n6 zUZTb_-T9pL34cMGJ#@%FxalOyvm!;)Z25?3IL7z-c!q@|q~5d3+BM`-zY#xyBC@U0 z{+;1YBdX<6{hgbWM$1f;u&$BWs6Jm4Z8gugwku3#R%}t%jzz8tOE!Wj)7_0<3xu7t<_>L%jD! z7%UQp`J@;KG74*Qe*V~8zNkw@m`_y_E2%w4B`lMS@p>t(#O);`TGUc+{`0 zkrS|E9|_MyRQL$uwTyYV*HMc{sy*iIMVglmm8swbafB>JBZwN{0SoAJxFH_zcb~w-xgSnH#jh z1_sJeQ8bGSC}jSr5EEgtd?g+wku)C$mRLq)2u4gH-DjInKie zP=HawqsQfAyBbkb;8XcNRbr@P6pBhyAOmVGBQ2^!Jp}N;MGsycUlFEu5=eYa#lG$L z!N3hn)5Y)oAz+-Q2>yHAp6~V=%Z$^w)emCP6yCjl zKO_N+QYi>W8`@O(jgHb-8fOyLij-fCsHzj~HuNn?jfsQ9S`2E*n9XQkWf)Y)k%49? z{P!GH_Z@LAp4VR;5^??lN+Lq2E7>wmN@Hs>>eg|B#(Pl^ssk=$lMQ;A@-r9emn%X9 z(o}IG)zM6kX{zS{4P$0?hUiZoAI2^}RhA=d2d*er+Zd#Ht@af&>g;jNB0AD*mcD6?Qv z^FS6>CZr?dN@a`ch*zT1X5SyXphMfEA^;D_BP~0Qprg@;70O%O^C2Ij%An$Gvo*X2 zA2E?Auep5LXc9w%2b%5$Zi6rcUK>5n0Y;fGkF#z+wP$jzBsPkm-bPPY7>)}H!Ru#euy+oN9$fj?tr>X#?h*TG<#P;T z8F@TmG!h@p9|KpxF0X{f^E^Z-g$5#=yzgdN4CUVG+ZMOe=vnU~e#| z6#00ExX}u`#yu0QTVq$tm9Q~A^waP?NTODdw^pq$V_zi@yRA?`llUP@X!TooY(M#k z-C74QfO7PN!#=7YSH8i1__;&=_OEE%?3s(`d{9$v*!EItxK(}REmGUoRCN`FDDOqy zImUyg14YlN6|S9VFPds^A)-mAaaL_*^>8A8$#ZqOme4c4X)l_hk)$U=O+hy;$5hxo zBDO{z_(#qsVsy7r9_IjoK(Mnhgn4oI=8K?h=a2z!k7ooQ?!l|Lk+RkTIuAO!w2w}4 zA2nG-GUV0`dTn@5TsIn6oK_Fql_jCp4RZ?dM(wC9RpyW~S4>&XiH$4k?W!e|ugPuA<07;L+ecc4 zPwOpCA9EPR`v6tnD=M51=#Z9B+R!+l(L9A;cP zms5O5o5XxQ57#S#LcQ=oKO-PLtx4Ki79GPJ<59aQORcPV{Qz8{9PG~`hd-_p$rj3? zg^nMO58EpKf6M*mXffRr@_jrbx+UcMP5pq$&+t#n$ytL^kC&pc&F3RN@A%2rPRRGs z5UmOMexB8y8S(?>oEiLP)%l@*Q0n{14d7{A;PiQq)8{=-pYNwpx+9$9ar%0X)8{?T zaT?>lP5i&N`+bKt-*m_5w!=5ydSv^7(Mu2Cynp|$!`JTGbKAb{hqrCJe)O8d2lwo` zW82LK?%1|%d~9sf2L9LCOgC|NqqL0<)6H}%9ii=XfXkOkc|Yx^U7Wj?_j~9z+Q&x^ z^SRsTdOqhG&L8CZJ>0@JzWRWq+i=UJ8~#@nrv**S3&68_)rm(nS;jQ`L3QCdN#^8b9lidM5G z*U~yVjZUXCXg%xlEMc=lN=`s3q`e*tl`XZ};2R%SL>0epJ&(Xiozti*dZ}c_#Z`w`Ypcm*r=r35o z->2WBm*_?MCheu~(*MwJ(Z^Wfx3GEaW3_*t&EQw*5SzoTY$QkMcKSHIPDklZHi%!N zU#Gk18Tu3Y1l>(t_RTlwP5RQ@+Ya2knIt+?^CVV`(v!x0A}-N#*UN@^(^rJE^>#RNhW1Zzq+v zlgiskMc2apesl1)tgFAQa+jV5uz$LdGK9~qQkqSGJ3OkVsJCO=IkqSGJ3OkVs zJCO=IkqSGJ3OkVsJCO=IkqSGJ3OkW1cQRG(WGe4uD(_?}?_?_PWGe4uD(_?}?_?_P aWGe4uD(_?}?_?_PWGe4uD(~cOqW=eI(CQrk literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/ImGui/misc/fonts/Roboto-Medium.ttf b/libultraship/libultraship/Lib/ImGui/misc/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39c63d7461796094c0b8889ee8fe2706d344a99a GIT binary patch literal 162588 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 cASb?` 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

    2. 2a-ytx-(Y1%*Q`;e(V?9Smc22g?_xG~I&%zq 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≀A#j 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%0AHUW;|^l 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 + +// Build with, e.g: +// # cl.exe binary_to_compressed_c.cpp +// # g++ binary_to_compressed_c.cpp +// # clang++ binary_to_compressed_c.cpp +// You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui + +// Usage: +// binary_to_compressed_c.exe [-base85] [-nocompress] +// Usage example: +// # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp +// # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp + +#define _CRT_SECURE_NO_WARNINGS +#include +#include +#include +#include + +// stb_compress* from stb.h - declaration +typedef unsigned int stb_uint; +typedef unsigned char stb_uchar; +stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len); + +static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression); + +int main(int argc, char** argv) +{ + if (argc < 3) + { + printf("Syntax: %s [-base85] [-nocompress] \n", argv[0]); + return 0; + } + + int argn = 1; + bool use_base85_encoding = false; + bool use_compression = true; + if (argv[argn][0] == '-') + { + if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; } + else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; } + else + { + fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]); + return 1; + } + } + + bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression); + if (!ret) + fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]); + return ret ? 0 : 1; +} + +char Encode85Byte(unsigned int x) +{ + x = (x % 85) + 35; + return (x >= '\\') ? x + 1 : x; +} + +bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression) +{ + // Read file + FILE* f = fopen(filename, "rb"); + if (!f) return false; + int data_sz; + if (fseek(f, 0, SEEK_END) || (data_sz = (int)ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) { fclose(f); return false; } + char* data = new char[data_sz + 4]; + if (fread(data, 1, data_sz, f) != (size_t)data_sz) { fclose(f); delete[] data; return false; } + memset((void*)(((char*)data) + data_sz), 0, 4); + fclose(f); + + // Compress + int maxlen = data_sz + 512 + (data_sz >> 2) + sizeof(int); // total guess + char* compressed = use_compression ? new char[maxlen] : data; + int compressed_sz = use_compression ? stb_compress((stb_uchar*)compressed, (stb_uchar*)data, data_sz) : data_sz; + if (use_compression) + memset(compressed + compressed_sz, 0, maxlen - compressed_sz); + + // Output as Base85 encoded + FILE* out = stdout; + fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz); + fprintf(out, "// Exported using binary_to_compressed_c.cpp\n"); + const char* compressed_str = use_compression ? "compressed_" : ""; + if (use_base85_encoding) + { + fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5); + char prev_c = 0; + for (int src_i = 0; src_i < compressed_sz; src_i += 4) + { + // This is made a little more complicated by the fact that ??X sequences are interpreted as trigraphs by old C/C++ compilers. So we need to escape pairs of ??. + unsigned int d = *(unsigned int*)(compressed + src_i); + for (unsigned int n5 = 0; n5 < 5; n5++, d /= 85) + { + char c = Encode85Byte(d); + fprintf(out, (c == '?' && prev_c == '?') ? "\\%c" : "%c", c); + prev_c = c; + } + if ((src_i % 112) == 112 - 4) + fprintf(out, "\"\n \""); + } + fprintf(out, "\";\n\n"); + } + else + { + fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz); + fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4); + int column = 0; + for (int i = 0; i < compressed_sz; i += 4) + { + unsigned int d = *(unsigned int*)(compressed + i); + if ((column++ % 12) == 0) + fprintf(out, "\n 0x%08x, ", d); + else + fprintf(out, "0x%08x, ", d); + } + fprintf(out, "\n};\n\n"); + } + + // Cleanup + delete[] data; + if (use_compression) + delete[] compressed; + return true; +} + +// stb_compress* from stb.h - definition + +//////////////////// compressor /////////////////////// + +static stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint 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 (s2 << 16) + s1; +} + +static unsigned int stb_matchlen(stb_uchar *m1, stb_uchar *m2, stb_uint maxlen) +{ + stb_uint i; + for (i=0; i < maxlen; ++i) + if (m1[i] != m2[i]) return i; + return i; +} + +// simple implementation that just takes the source data in a big block + +static stb_uchar *stb__out; +static FILE *stb__outfile; +static stb_uint stb__outbytes; + +static void stb__write(unsigned char v) +{ + fputc(v, stb__outfile); + ++stb__outbytes; +} + +//#define stb_out(v) (stb__out ? *stb__out++ = (stb_uchar) (v) : stb__write((stb_uchar) (v))) +#define stb_out(v) do { if (stb__out) *stb__out++ = (stb_uchar) (v); else stb__write((stb_uchar) (v)); } while (0) + +static void stb_out2(stb_uint v) { stb_out(v >> 8); stb_out(v); } +static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v); } +static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16); stb_out(v >> 8 ); stb_out(v); } + +static void outliterals(stb_uchar *in, int numlit) +{ + while (numlit > 65536) { + outliterals(in,65536); + in += 65536; + numlit -= 65536; + } + + if (numlit == 0) ; + else if (numlit <= 32) stb_out (0x000020 + numlit-1); + else if (numlit <= 2048) stb_out2(0x000800 + numlit-1); + else /* numlit <= 65536) */ stb_out3(0x070000 + numlit-1); + + if (stb__out) { + memcpy(stb__out,in,numlit); + stb__out += numlit; + } else + fwrite(in, 1, numlit, stb__outfile); +} + +static int stb__window = 0x40000; // 256K + +static int stb_not_crap(int best, int dist) +{ + return ((best > 2 && dist <= 0x00100) + || (best > 5 && dist <= 0x04000) + || (best > 7 && dist <= 0x80000)); +} + +static stb_uint stb__hashsize = 32768; + +// note that you can play with the hashing functions all you +// want without needing to change the decompressor +#define stb__hc(q,h,c) (((h) << 7) + ((h) >> 25) + q[c]) +#define stb__hc2(q,h,c,d) (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d]) +#define stb__hc3(q,c,d,e) ((q[c] << 14) + (q[d] << 7) + q[e]) + +static unsigned int stb__running_adler; + +static int stb_compress_chunk(stb_uchar *history, + stb_uchar *start, + stb_uchar *end, + int length, + int *pending_literals, + stb_uchar **chash, + stb_uint mask) +{ + (void)history; + int window = stb__window; + stb_uint match_max; + stb_uchar *lit_start = start - *pending_literals; + stb_uchar *q = start; + +#define STB__SCRAMBLE(h) (((h) + ((h) >> 16)) & mask) + + // stop short of the end so we don't scan off the end doing + // the hashing; this means we won't compress the last few bytes + // unless they were part of something longer + while (q < start+length && q+12 < end) { + int m; + stb_uint h1,h2,h3,h4, h; + stb_uchar *t; + int best = 2, dist=0; + + if (q+65536 > end) + match_max = end-q; + else + match_max = 65536; + +#define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d))) + +#define STB__TRY(t,p) /* avoid retrying a match we already tried */ \ + if (p ? dist != q-t : 1) \ + if ((m = stb_matchlen(t, q, match_max)) > best) \ + if (stb__nc(m,q-(t))) \ + best = m, dist = q - (t) + + // rather than search for all matches, only try 4 candidate locations, + // chosen based on 4 different hash functions of different lengths. + // this strategy is inspired by LZO; hashing is unrolled here using the + // 'hc' macro + h = stb__hc3(q,0, 1, 2); h1 = STB__SCRAMBLE(h); + t = chash[h1]; if (t) STB__TRY(t,0); + h = stb__hc2(q,h, 3, 4); h2 = STB__SCRAMBLE(h); + h = stb__hc2(q,h, 5, 6); t = chash[h2]; if (t) STB__TRY(t,1); + h = stb__hc2(q,h, 7, 8); h3 = STB__SCRAMBLE(h); + h = stb__hc2(q,h, 9,10); t = chash[h3]; if (t) STB__TRY(t,1); + h = stb__hc2(q,h,11,12); h4 = STB__SCRAMBLE(h); + t = chash[h4]; if (t) STB__TRY(t,1); + + // because we use a shared hash table, can only update it + // _after_ we've probed all of them + chash[h1] = chash[h2] = chash[h3] = chash[h4] = q; + + if (best > 2) + assert(dist > 0); + + // see if our best match qualifies + if (best < 3) { // fast path literals + ++q; + } else if (best > 2 && best <= 0x80 && dist <= 0x100) { + outliterals(lit_start, q-lit_start); lit_start = (q += best); + stb_out(0x80 + best-1); + stb_out(dist-1); + } else if (best > 5 && best <= 0x100 && dist <= 0x4000) { + outliterals(lit_start, q-lit_start); lit_start = (q += best); + stb_out2(0x4000 + dist-1); + stb_out(best-1); + } else if (best > 7 && best <= 0x100 && dist <= 0x80000) { + outliterals(lit_start, q-lit_start); lit_start = (q += best); + stb_out3(0x180000 + dist-1); + stb_out(best-1); + } else if (best > 8 && best <= 0x10000 && dist <= 0x80000) { + outliterals(lit_start, q-lit_start); lit_start = (q += best); + stb_out3(0x100000 + dist-1); + stb_out2(best-1); + } else if (best > 9 && dist <= 0x1000000) { + if (best > 65536) best = 65536; + outliterals(lit_start, q-lit_start); lit_start = (q += best); + if (best <= 0x100) { + stb_out(0x06); + stb_out3(dist-1); + stb_out(best-1); + } else { + stb_out(0x04); + stb_out3(dist-1); + stb_out2(best-1); + } + } else { // fallback literals if no match was a balanced tradeoff + ++q; + } + } + + // if we didn't get all the way, add the rest to literals + if (q-start < length) + q = start+length; + + // the literals are everything from lit_start to q + *pending_literals = (q - lit_start); + + stb__running_adler = stb_adler32(stb__running_adler, start, q - start); + return q - start; +} + +static int stb_compress_inner(stb_uchar *input, stb_uint length) +{ + int literals = 0; + stb_uint len,i; + + stb_uchar **chash; + chash = (stb_uchar**) malloc(stb__hashsize * sizeof(stb_uchar*)); + if (chash == NULL) return 0; // failure + for (i=0; i < stb__hashsize; ++i) + chash[i] = NULL; + + // stream signature + stb_out(0x57); stb_out(0xbc); + stb_out2(0); + + stb_out4(0); // 64-bit length requires 32-bit leading 0 + stb_out4(length); + stb_out4(stb__window); + + stb__running_adler = 1; + + len = stb_compress_chunk(input, input, input+length, length, &literals, chash, stb__hashsize-1); + assert(len == length); + + outliterals(input+length - literals, literals); + + free(chash); + + stb_out2(0x05fa); // end opcode + + stb_out4(stb__running_adler); + + return 1; // success +} + +stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length) +{ + stb__out = out; + stb__outfile = NULL; + + stb_compress_inner(input, length); + + return stb__out - out; +} diff --git a/libultraship/libultraship/Lib/ImGui/misc/freetype/README.md b/libultraship/libultraship/Lib/ImGui/misc/freetype/README.md new file mode 100644 index 000000000..84f6dd064 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/freetype/README.md @@ -0,0 +1,37 @@ +# imgui_freetype + +Build font atlases using FreeType instead of stb_truetype (which is the default font rasterizer). +
      by @vuhdo, @mikesart, @ocornut. + +### Usage + +1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype --triplet=x64-windows`, `vcpkg integrate install`). +2. Add imgui_freetype.h/cpp alongside your project files. +3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file + +### About Gamma Correct Blending + +FreeType assumes blending in linear space rather than gamma space. +See FreeType note for [FT_Render_Glyph](https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph). +For correct results you need to be using sRGB and convert to linear space in the pixel shader output. +The default Dear ImGui styles will be impacted by this change (alpha values will need tweaking). + +### Testbed for toying with settings (for developers) + +See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad + +### Known issues + +- Oversampling settins are ignored but also not so much necessary with the higher quality rendering. + +### Comparaison + +Small, thin anti-aliased fonts typically benefit a lot from FreeType's hinting: +![comparing_font_rasterizers](https://user-images.githubusercontent.com/8225057/107550178-fef87f00-6bd0-11eb-8d09-e2edb2f0ccfc.gif) + +### Colorful glyphs/emojis + +You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain colorful glyphs. See the +["Using Colorful Glyphs/Emojis"](https://github.com/ocornut/imgui/edit/master/docs/FONTS.md#using-colorful-glyphsemojis) section of FONTS.md. + +![colored glyphs](https://user-images.githubusercontent.com/8225057/106171241-9dc4ba80-6191-11eb-8a69-ca1467b206d1.png) diff --git a/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.cpp b/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.cpp new file mode 100644 index 000000000..a72ec8c83 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.cpp @@ -0,0 +1,779 @@ +// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder) +// (code) + +// Get the latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype +// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut. + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL. +// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. +// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format. +// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+). +// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'. +// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas(). +// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. +// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!) +// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions(). +// 2019/01/10: re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding. +// 2018/06/08: added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX. +// 2018/02/04: moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club) +// 2018/01/22: fix for addition of ImFontAtlas::TexUvscale member. +// 2017/10/22: minor inconsequential change to match change in master (removed an unnecessary statement). +// 2017/09/26: fixes for imgui internal changes. +// 2017/08/26: cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply. +// 2017/08/16: imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks. + +// About Gamma Correct Blending: +// - FreeType assumes blending in linear space rather than gamma space. +// - See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Render_Glyph +// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output. +// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking). + +// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer). + +#include "imgui_freetype.h" +#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*, +#include +#include +#include FT_FREETYPE_H // +#include FT_MODULE_H // +#include FT_GLYPH_H // +#include FT_SYNTHESIS_H // + +#ifdef _MSC_VER +#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). +#endif + +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#endif + +//------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------- + +// Default memory allocators +static void* ImGuiFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return IM_ALLOC(size); } +static void ImGuiFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_FREE(ptr); } + +// Current memory allocators +static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFreeTypeDefaultAllocFunc; +static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc; +static void* GImGuiFreeTypeAllocatorUserData = NULL; + +//------------------------------------------------------------------------- +// Code +//------------------------------------------------------------------------- + +namespace +{ + // Glyph metrics: + // -------------- + // + // xmin xmax + // | | + // |<-------- width -------->| + // | | + // | +-------------------------+----------------- ymax + // | | ggggggggg ggggg | ^ ^ + // | | g:::::::::ggg::::g | | | + // | | g:::::::::::::::::g | | | + // | | g::::::ggggg::::::gg | | | + // | | g:::::g g:::::g | | | + // offsetX -|-------->| g:::::g g:::::g | offsetY | + // | | g:::::g g:::::g | | | + // | | g::::::g g:::::g | | | + // | | g:::::::ggggg:::::g | | | + // | | g::::::::::::::::g | | height + // | | gg::::::::::::::g | | | + // baseline ---*---------|---- gggggggg::::::g-----*-------- | + // / | | g:::::g | | + // origin | | gggggg g:::::g | | + // | | g:::::gg gg:::::g | | + // | | g::::::ggg:::::::g | | + // | | gg:::::::::::::g | | + // | | ggg::::::ggg | | + // | | gggggg | v + // | +-------------------------+----------------- ymin + // | | + // |------------- advanceX ----------->| + + // A structure that describe a glyph. + struct GlyphInfo + { + int Width; // Glyph's width in pixels. + int Height; // Glyph's height in pixels. + FT_Int OffsetX; // The distance from the origin ("pen position") to the left of the glyph. + FT_Int OffsetY; // The distance from the origin to the top of the glyph. This is usually a value < 0. + float AdvanceX; // The distance from the origin to the origin of the next glyph. This is usually a value > 0. + bool IsColored; // The glyph is colored + }; + + // Font parameters and metrics. + struct FontInfo + { + uint32_t PixelHeight; // Size this font was generated with. + float Ascender; // The pixel extents above the baseline in pixels (typically positive). + float Descender; // The extents below the baseline in pixels (typically negative). + float LineSpacing; // The baseline-to-baseline distance. Note that it usually is larger than the sum of the ascender and descender taken as absolute values. There is also no guarantee that no glyphs extend above or below subsequent baselines when using this distance. Think of it as a value the designer of the font finds appropriate. + float LineGap; // The spacing in pixels between one row's descent and the next row's ascent. + float MaxAdvanceWidth; // This field gives the maximum horizontal cursor advance for all glyphs in the font. + }; + + // FreeType glyph rasterizer. + // NB: No ctor/dtor, explicitly call Init()/Shutdown() + struct FreeTypeFont + { + bool InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags); // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime. + void CloseFont(); + void SetPixelHeight(int pixel_height); // Change font pixel size. All following calls to RasterizeGlyph() will use this size + const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint); + const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info); + void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = NULL); + ~FreeTypeFont() { CloseFont(); } + + // [Internals] + FontInfo Info; // Font descriptor of the current font. + FT_Face Face; + unsigned int UserFlags; // = ImFontConfig::RasterizerFlags + FT_Int32 LoadFlags; + FT_Render_Mode RenderMode; + }; + + // From SDL_ttf: Handy routines for converting from fixed point + #define FT_CEIL(X) (((X + 63) & -64) / 64) + + bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags) + { + FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face); + if (error != 0) + return false; + error = FT_Select_Charmap(Face, FT_ENCODING_UNICODE); + if (error != 0) + return false; + + // Convert to FreeType flags (NB: Bold and Oblique are processed separately) + UserFlags = cfg.FontBuilderFlags | extra_font_builder_flags; + + LoadFlags = 0; + if ((UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) == 0) + LoadFlags |= FT_LOAD_NO_BITMAP; + + if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting) + LoadFlags |= FT_LOAD_NO_HINTING; + if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint) + LoadFlags |= FT_LOAD_NO_AUTOHINT; + if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint) + LoadFlags |= FT_LOAD_FORCE_AUTOHINT; + if (UserFlags & ImGuiFreeTypeBuilderFlags_LightHinting) + LoadFlags |= FT_LOAD_TARGET_LIGHT; + else if (UserFlags & ImGuiFreeTypeBuilderFlags_MonoHinting) + LoadFlags |= FT_LOAD_TARGET_MONO; + else + LoadFlags |= FT_LOAD_TARGET_NORMAL; + + if (UserFlags & ImGuiFreeTypeBuilderFlags_Monochrome) + RenderMode = FT_RENDER_MODE_MONO; + else + RenderMode = FT_RENDER_MODE_NORMAL; + + if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor) + LoadFlags |= FT_LOAD_COLOR; + + memset(&Info, 0, sizeof(Info)); + SetPixelHeight((uint32_t)cfg.SizePixels); + + return true; + } + + void FreeTypeFont::CloseFont() + { + if (Face) + { + FT_Done_Face(Face); + Face = NULL; + } + } + + void FreeTypeFont::SetPixelHeight(int pixel_height) + { + // Vuhdo: I'm not sure how to deal with font sizes properly. As far as I understand, currently ImGui assumes that the 'pixel_height' + // is a maximum height of an any given glyph, i.e. it's the sum of font's ascender and descender. Seems strange to me. + // NB: FT_Set_Pixel_Sizes() doesn't seem to get us the same result. + FT_Size_RequestRec req; + req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM; + req.width = 0; + req.height = (uint32_t)pixel_height * 64; + req.horiResolution = 0; + req.vertResolution = 0; + FT_Request_Size(Face, &req); + + // Update font info + FT_Size_Metrics metrics = Face->size->metrics; + Info.PixelHeight = (uint32_t)pixel_height; + Info.Ascender = (float)FT_CEIL(metrics.ascender); + Info.Descender = (float)FT_CEIL(metrics.descender); + Info.LineSpacing = (float)FT_CEIL(metrics.height); + Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender); + Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance); + } + + const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint) + { + uint32_t glyph_index = FT_Get_Char_Index(Face, codepoint); + if (glyph_index == 0) + return NULL; + + // If this crash for you: FreeType 2.11.0 has a crash bug on some bitmap/colored fonts. + // - https://gitlab.freedesktop.org/freetype/freetype/-/issues/1076 + // - https://github.com/ocornut/imgui/issues/4567 + // - https://github.com/ocornut/imgui/issues/4566 + // You can use FreeType 2.10, or the patched version of 2.11.0 in VcPkg, or probably any upcoming FreeType version. + FT_Error error = FT_Load_Glyph(Face, glyph_index, LoadFlags); + if (error) + return NULL; + + // Need an outline for this to work + FT_GlyphSlot slot = Face->glyph; + IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP); + + // Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting) + if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold) + FT_GlyphSlot_Embolden(slot); + if (UserFlags & ImGuiFreeTypeBuilderFlags_Oblique) + { + FT_GlyphSlot_Oblique(slot); + //FT_BBox bbox; + //FT_Outline_Get_BBox(&slot->outline, &bbox); + //slot->metrics.width = bbox.xMax - bbox.xMin; + //slot->metrics.height = bbox.yMax - bbox.yMin; + } + + return &slot->metrics; + } + + const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info) + { + FT_GlyphSlot slot = Face->glyph; + FT_Error error = FT_Render_Glyph(slot, RenderMode); + if (error != 0) + return NULL; + + FT_Bitmap* ft_bitmap = &Face->glyph->bitmap; + out_glyph_info->Width = (int)ft_bitmap->width; + out_glyph_info->Height = (int)ft_bitmap->rows; + out_glyph_info->OffsetX = Face->glyph->bitmap_left; + out_glyph_info->OffsetY = -Face->glyph->bitmap_top; + out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x); + out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA); + + return ft_bitmap; + } + + void FreeTypeFont::BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table) + { + IM_ASSERT(ft_bitmap != NULL); + const uint32_t w = ft_bitmap->width; + const uint32_t h = ft_bitmap->rows; + const uint8_t* src = ft_bitmap->buffer; + const uint32_t src_pitch = ft_bitmap->pitch; + + switch (ft_bitmap->pixel_mode) + { + case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel. + { + if (multiply_table == NULL) + { + for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) + for (uint32_t x = 0; x < w; x++) + dst[x] = IM_COL32(255, 255, 255, src[x]); + } + else + { + for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) + for (uint32_t x = 0; x < w; x++) + dst[x] = IM_COL32(255, 255, 255, multiply_table[src[x]]); + } + break; + } + case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB. + { + uint8_t color0 = multiply_table ? multiply_table[0] : 0; + uint8_t color1 = multiply_table ? multiply_table[255] : 255; + for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) + { + uint8_t bits = 0; + const uint8_t* bits_ptr = src; + for (uint32_t x = 0; x < w; x++, bits <<= 1) + { + if ((x & 7) == 0) + bits = *bits_ptr++; + dst[x] = IM_COL32(255, 255, 255, (bits & 0x80) ? color1 : color0); + } + } + break; + } + case FT_PIXEL_MODE_BGRA: + { + // FIXME: Converting pre-multiplied alpha to straight. Doesn't smell good. + #define DE_MULTIPLY(color, alpha) (ImU32)(255.0f * (float)color / (float)alpha + 0.5f) + if (multiply_table == NULL) + { + for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) + for (uint32_t x = 0; x < w; x++) + { + uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3]; + dst[x] = IM_COL32(DE_MULTIPLY(r, a), DE_MULTIPLY(g, a), DE_MULTIPLY(b, a), a); + } + } + else + { + for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch) + { + for (uint32_t x = 0; x < w; x++) + { + uint8_t r = src[x * 4 + 2], g = src[x * 4 + 1], b = src[x * 4], a = src[x * 4 + 3]; + dst[x] = IM_COL32(multiply_table[DE_MULTIPLY(r, a)], multiply_table[DE_MULTIPLY(g, a)], multiply_table[DE_MULTIPLY(b, a)], multiply_table[a]); + } + } + } + #undef DE_MULTIPLY + break; + } + default: + IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!"); + } + } +} + +#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) +#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION +#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0) +#define STBRP_STATIC +#define STB_RECT_PACK_IMPLEMENTATION +#endif +#ifdef IMGUI_STB_RECT_PACK_FILENAME +#include IMGUI_STB_RECT_PACK_FILENAME +#else +#include "imstb_rectpack.h" +#endif +#endif + +struct ImFontBuildSrcGlyphFT +{ + GlyphInfo Info; + uint32_t Codepoint; + unsigned int* BitmapData; // Point within one of the dst_tmp_bitmap_buffers[] array + + ImFontBuildSrcGlyphFT() { memset(this, 0, sizeof(*this)); } +}; + +struct ImFontBuildSrcDataFT +{ + FreeTypeFont Font; + stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position. + const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF) + int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[] + int GlyphsHighest; // Highest requested codepoint + int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font) + ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB) + ImVector GlyphsList; +}; + +// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont) +struct ImFontBuildDstDataFT +{ + int SrcCount; // Number of source fonts targeting this destination font. + int GlyphsHighest; + int GlyphsCount; + ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font. +}; + +bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, unsigned int extra_flags) +{ + IM_ASSERT(atlas->ConfigData.Size > 0); + + ImFontAtlasBuildInit(atlas); + + // Clear atlas + atlas->TexID = (ImTextureID)NULL; + atlas->TexWidth = atlas->TexHeight = 0; + atlas->TexUvScale = ImVec2(0.0f, 0.0f); + atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); + atlas->ClearTexData(); + + // Temporary storage for building + bool src_load_color = false; + ImVector src_tmp_array; + ImVector dst_tmp_array; + src_tmp_array.resize(atlas->ConfigData.Size); + dst_tmp_array.resize(atlas->Fonts.Size); + memset((void*)src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes()); + memset((void*)dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes()); + + // 1. Initialize font loading structure, check font data validity + for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + ImFontConfig& cfg = atlas->ConfigData[src_i]; + FreeTypeFont& font_face = src_tmp.Font; + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + + // Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) + src_tmp.DstIndex = -1; + for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++) + if (cfg.DstFont == atlas->Fonts[output_i]) + src_tmp.DstIndex = output_i; + IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array? + if (src_tmp.DstIndex == -1) + return false; + + // Load font + if (!font_face.InitFont(ft_library, cfg, extra_flags)) + return false; + + // Measure highest codepoints + src_load_color |= (cfg.FontBuilderFlags & ImGuiFreeTypeBuilderFlags_LoadColor) != 0; + ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; + src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault(); + for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) + src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]); + dst_tmp.SrcCount++; + dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest); + } + + // 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs. + int total_glyphs_count = 0; + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; + src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1); + if (dst_tmp.GlyphsSet.Storage.empty()) + dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1); + + for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) + for (int codepoint = src_range[0]; codepoint <= (int)src_range[1]; codepoint++) + { + if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite) + continue; + uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..) + if (glyph_index == 0) + continue; + + // Add to avail set/counters + src_tmp.GlyphsCount++; + dst_tmp.GlyphsCount++; + src_tmp.GlyphsSet.SetBit(codepoint); + dst_tmp.GlyphsSet.SetBit(codepoint); + total_glyphs_count++; + } + } + + // 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another) + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount); + + IM_ASSERT(sizeof(src_tmp.GlyphsSet.Storage.Data[0]) == sizeof(ImU32)); + const ImU32* it_begin = src_tmp.GlyphsSet.Storage.begin(); + const ImU32* it_end = src_tmp.GlyphsSet.Storage.end(); + for (const ImU32* it = it_begin; it < it_end; it++) + if (ImU32 entries_32 = *it) + for (ImU32 bit_n = 0; bit_n < 32; bit_n++) + if (entries_32 & ((ImU32)1 << bit_n)) + { + ImFontBuildSrcGlyphFT src_glyph; + src_glyph.Codepoint = (ImWchar)(((it - it_begin) << 5) + bit_n); + //src_glyph.GlyphIndex = 0; // FIXME-OPT: We had this info in the previous step and lost it.. + src_tmp.GlyphsList.push_back(src_glyph); + } + src_tmp.GlyphsSet.Clear(); + IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount); + } + for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++) + dst_tmp_array[dst_i].GlyphsSet.Clear(); + dst_tmp_array.clear(); + + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) + // (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity) + ImVector buf_rects; + buf_rects.resize(total_glyphs_count); + memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes()); + + // Allocate temporary rasterization data buffers. + // We could not find a way to retrieve accurate glyph size without rendering them. + // (e.g. slot->metrics->width not always matching bitmap->width, especially considering the Oblique transform) + // We allocate in chunks of 256 KB to not waste too much extra memory ahead. Hopefully users of FreeType won't find the temporary allocations. + const int BITMAP_BUFFERS_CHUNK_SIZE = 256 * 1024; + int buf_bitmap_current_used_bytes = 0; + ImVector buf_bitmap_buffers; + buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE)); + + // 4. Gather glyphs sizes so we can pack them in our virtual canvas. + // 8. Render/rasterize font characters into the texture + int total_surface = 0; + int buf_rects_out_n = 0; + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + ImFontConfig& cfg = atlas->ConfigData[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + src_tmp.Rects = &buf_rects[buf_rects_out_n]; + buf_rects_out_n += src_tmp.GlyphsCount; + + // Compute multiply table if requested + const bool multiply_enabled = (cfg.RasterizerMultiply != 1.0f); + unsigned char multiply_table[256]; + if (multiply_enabled) + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + + // Gather the sizes of all rectangles we will need to pack + const int padding = atlas->TexGlyphPadding; + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++) + { + ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i]; + + const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint); + if (metrics == NULL) + continue; + + // Render glyph into a bitmap (currently held by FreeType) + const FT_Bitmap* ft_bitmap = src_tmp.Font.RenderGlyphAndGetInfo(&src_glyph.Info); + if (ft_bitmap == NULL) + continue; + + // Allocate new temporary chunk if needed + const int bitmap_size_in_bytes = src_glyph.Info.Width * src_glyph.Info.Height * 4; + if (buf_bitmap_current_used_bytes + bitmap_size_in_bytes > BITMAP_BUFFERS_CHUNK_SIZE) + { + buf_bitmap_current_used_bytes = 0; + buf_bitmap_buffers.push_back((unsigned char*)IM_ALLOC(BITMAP_BUFFERS_CHUNK_SIZE)); + } + + // Blit rasterized pixels to our temporary buffer and keep a pointer to it. + src_glyph.BitmapData = (unsigned int*)(buf_bitmap_buffers.back() + buf_bitmap_current_used_bytes); + buf_bitmap_current_used_bytes += bitmap_size_in_bytes; + src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : NULL); + + src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding); + src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding); + total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h; + } + } + + // We need a width for the skyline algorithm, any width! + // The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. + // User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface. + const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1; + atlas->TexHeight = 0; + if (atlas->TexDesiredWidth > 0) + atlas->TexWidth = atlas->TexDesiredWidth; + else + atlas->TexWidth = (surface_sqrt >= 4096 * 0.7f) ? 4096 : (surface_sqrt >= 2048 * 0.7f) ? 2048 : (surface_sqrt >= 1024 * 0.7f) ? 1024 : 512; + + // 5. Start packing + // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). + const int TEX_HEIGHT_MAX = 1024 * 32; + const int num_nodes_for_packing_algorithm = atlas->TexWidth - atlas->TexGlyphPadding; + ImVector pack_nodes; + pack_nodes.resize(num_nodes_for_packing_algorithm); + stbrp_context pack_context; + stbrp_init_target(&pack_context, atlas->TexWidth, TEX_HEIGHT_MAX, pack_nodes.Data, pack_nodes.Size); + ImFontAtlasBuildPackCustomRects(atlas, &pack_context); + + // 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point. + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount); + + // Extend texture height and mark missing glyphs as non-packed so we won't render them. + // FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?) + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) + if (src_tmp.Rects[glyph_i].was_packed) + atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h); + } + + // 7. Allocate texture + atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); + if (src_load_color) + { + size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 4; + atlas->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(tex_size); + memset(atlas->TexPixelsRGBA32, 0, tex_size); + } + else + { + size_t tex_size = (size_t)atlas->TexWidth * atlas->TexHeight * 1; + atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(tex_size); + memset(atlas->TexPixelsAlpha8, 0, tex_size); + } + + // 8. Copy rasterized font characters back into the main texture + // 9. Setup ImFont and glyphs for runtime + bool tex_use_colors = false; + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + // When merging fonts with MergeMode=true: + // - We can have multiple input fonts writing into a same destination font. + // - dst_font->ConfigData is != from cfg which is our source configuration. + ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFont* dst_font = cfg.DstFont; + + const float ascent = src_tmp.Font.Info.Ascender; + const float descent = src_tmp.Font.Info.Descender; + ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); + const float font_off_x = cfg.GlyphOffset.x; + const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); + + const int padding = atlas->TexGlyphPadding; + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) + { + ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i]; + stbrp_rect& pack_rect = src_tmp.Rects[glyph_i]; + IM_ASSERT(pack_rect.was_packed); + if (pack_rect.w == 0 && pack_rect.h == 0) + continue; + + GlyphInfo& info = src_glyph.Info; + IM_ASSERT(info.Width + padding <= pack_rect.w); + IM_ASSERT(info.Height + padding <= pack_rect.h); + const int tx = pack_rect.x + padding; + const int ty = pack_rect.y + padding; + + // Register glyph + float x0 = info.OffsetX + font_off_x; + float y0 = info.OffsetY + font_off_y; + float x1 = x0 + info.Width; + float y1 = y0 + info.Height; + float u0 = (tx) / (float)atlas->TexWidth; + float v0 = (ty) / (float)atlas->TexHeight; + float u1 = (tx + info.Width) / (float)atlas->TexWidth; + float v1 = (ty + info.Height) / (float)atlas->TexHeight; + dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX); + + ImFontGlyph* dst_glyph = &dst_font->Glyphs.back(); + IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint); + if (src_glyph.Info.IsColored) + dst_glyph->Colored = tex_use_colors = true; + + // Blit from temporary buffer to final texture + size_t blit_src_stride = (size_t)src_glyph.Info.Width; + size_t blit_dst_stride = (size_t)atlas->TexWidth; + unsigned int* blit_src = src_glyph.BitmapData; + if (atlas->TexPixelsAlpha8 != NULL) + { + unsigned char* blit_dst = atlas->TexPixelsAlpha8 + (ty * blit_dst_stride) + tx; + for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride) + for (int x = 0; x < info.Width; x++) + blit_dst[x] = (unsigned char)((blit_src[x] >> IM_COL32_A_SHIFT) & 0xFF); + } + else + { + unsigned int* blit_dst = atlas->TexPixelsRGBA32 + (ty * blit_dst_stride) + tx; + for (int y = 0; y < info.Height; y++, blit_dst += blit_dst_stride, blit_src += blit_src_stride) + for (int x = 0; x < info.Width; x++) + blit_dst[x] = blit_src[x]; + } + } + + src_tmp.Rects = NULL; + } + atlas->TexPixelsUseColors = tex_use_colors; + + // Cleanup + for (int buf_i = 0; buf_i < buf_bitmap_buffers.Size; buf_i++) + IM_FREE(buf_bitmap_buffers[buf_i]); + src_tmp_array.clear_destruct(); + + ImFontAtlasBuildFinish(atlas); + + return true; +} + +// FreeType memory allocation callbacks +static void* FreeType_Alloc(FT_Memory /*memory*/, long size) +{ + return GImGuiFreeTypeAllocFunc((size_t)size, GImGuiFreeTypeAllocatorUserData); +} + +static void FreeType_Free(FT_Memory /*memory*/, void* block) +{ + GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData); +} + +static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block) +{ + // Implement realloc() as we don't ask user to provide it. + if (block == NULL) + return GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData); + + if (new_size == 0) + { + GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData); + return NULL; + } + + if (new_size > cur_size) + { + void* new_block = GImGuiFreeTypeAllocFunc((size_t)new_size, GImGuiFreeTypeAllocatorUserData); + memcpy(new_block, block, (size_t)cur_size); + GImGuiFreeTypeFreeFunc(block, GImGuiFreeTypeAllocatorUserData); + return new_block; + } + + return block; +} + +static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas) +{ + // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html + FT_MemoryRec_ memory_rec = {}; + memory_rec.user = NULL; + memory_rec.alloc = &FreeType_Alloc; + memory_rec.free = &FreeType_Free; + memory_rec.realloc = &FreeType_Realloc; + + // https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library + FT_Library ft_library; + FT_Error error = FT_New_Library(&memory_rec, &ft_library); + if (error != 0) + return false; + + // If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator. + FT_Add_Default_Modules(ft_library); + + bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags); + FT_Done_Library(ft_library); + + return ret; +} + +const ImFontBuilderIO* ImGuiFreeType::GetBuilderForFreeType() +{ + static ImFontBuilderIO io; + io.FontBuilder_Build = ImFontAtlasBuildWithFreeType; + return &io; +} + +void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data) +{ + GImGuiFreeTypeAllocFunc = alloc_func; + GImGuiFreeTypeFreeFunc = free_func; + GImGuiFreeTypeAllocatorUserData = user_data; +} diff --git a/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.h b/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.h new file mode 100644 index 000000000..713e4639e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/freetype/imgui_freetype.h @@ -0,0 +1,50 @@ +// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder) +// (headers) + +#pragma once + +#include "imgui.h" // IMGUI_API + +// Forward declarations +struct ImFontAtlas; +struct ImFontBuilderIO; + +// Hinting greatly impacts visuals (and glyph sizes). +// - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter. +// - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h +// - The Default hinting mode usually looks good, but may distort glyphs in an unusual way. +// - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer. +// You can set those flags globaly in ImFontAtlas::FontBuilderFlags +// You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags +enum ImGuiFreeTypeBuilderFlags +{ + ImGuiFreeTypeBuilderFlags_NoHinting = 1 << 0, // Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes. + ImGuiFreeTypeBuilderFlags_NoAutoHint = 1 << 1, // Disable auto-hinter. + ImGuiFreeTypeBuilderFlags_ForceAutoHint = 1 << 2, // Indicates that the auto-hinter is preferred over the font's native hinter. + ImGuiFreeTypeBuilderFlags_LightHinting = 1 << 3, // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text. + ImGuiFreeTypeBuilderFlags_MonoHinting = 1 << 4, // Strong hinting algorithm that should only be used for monochrome output. + ImGuiFreeTypeBuilderFlags_Bold = 1 << 5, // Styling: Should we artificially embolden the font? + ImGuiFreeTypeBuilderFlags_Oblique = 1 << 6, // Styling: Should we slant the font, emulating italic style? + ImGuiFreeTypeBuilderFlags_Monochrome = 1 << 7, // Disable anti-aliasing. Combine this with MonoHinting for best results! + ImGuiFreeTypeBuilderFlags_LoadColor = 1 << 8, // Enable FreeType color-layered glyphs + ImGuiFreeTypeBuilderFlags_Bitmap = 1 << 9 // Enable FreeType bitmap glyphs +}; + +namespace ImGuiFreeType +{ + // This is automatically assigned when using '#define IMGUI_ENABLE_FREETYPE'. + // If you need to dynamically select between multiple builders: + // - you can manually assign this builder with 'atlas->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()' + // - prefer deep-copying this into your own ImFontBuilderIO instance if you use hot-reloading that messes up static data. + IMGUI_API const ImFontBuilderIO* GetBuilderForFreeType(); + + // Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE() + // However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired. + IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL); + + // Obsolete names (will be removed soon) + // Prefer using '#define IMGUI_ENABLE_FREETYPE' +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); } +#endif +} diff --git a/libultraship/libultraship/Lib/ImGui/misc/single_file/imgui_single_file.h b/libultraship/libultraship/Lib/ImGui/misc/single_file/imgui_single_file.h new file mode 100644 index 000000000..6c1fb369f --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/single_file/imgui_single_file.h @@ -0,0 +1,18 @@ +// dear imgui: single-file wrapper include +// We use this to validate compiling all *.cpp files in a same compilation unit. +// Users of that technique (also called "Unity builds") can generally provide this themselves, +// so we don't really recommend you use this in your projects. + +// Do this: +// #define IMGUI_IMPLEMENTATION +// Before you include this file in *one* C++ file to create the implementation. +// Using this in your project will leak the contents of imgui_internal.h and ImVec2 operators in this compilation unit. +#include "../../imgui.h" + +#ifdef IMGUI_IMPLEMENTATION +#include "../../imgui.cpp" +#include "../../imgui_demo.cpp" +#include "../../imgui_draw.cpp" +#include "../../imgui_tables.cpp" +#include "../../imgui_widgets.cpp" +#endif diff --git a/libultraship/libultraship/Lib/SDL/BUGS.txt b/libultraship/libultraship/Lib/SDL/BUGS.txt new file mode 100644 index 000000000..b1463e777 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/BUGS.txt @@ -0,0 +1,16 @@ + +Bugs are now managed in the SDL issue tracker, here: + + https://github.com/libsdl-org/SDL/issues + +You may report bugs there, and search to see if a given issue has already + been reported, discussed, and maybe even fixed. + + +You may also find help at the SDL forums/mailing list: + + https://discourse.libsdl.org/ + +Bug reports are welcome here, but we really appreciate if you use the issue + tracker, as bugs discussed on the mailing list may be forgotten or missed. + diff --git a/libultraship/libultraship/Lib/SDL/COPYING.txt b/libultraship/libultraship/Lib/SDL/COPYING.txt new file mode 100644 index 000000000..0e2bef3fc --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/COPYING.txt @@ -0,0 +1,20 @@ + +Simple DirectMedia Layer +Copyright (C) 1997-2020 Sam Lantinga + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as 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/libultraship/libultraship/Lib/SDL/README-SDL.txt b/libultraship/libultraship/Lib/SDL/README-SDL.txt new file mode 100644 index 000000000..8d92955a9 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/README-SDL.txt @@ -0,0 +1,13 @@ + +Please distribute this file with the SDL runtime environment: + +The Simple DirectMedia Layer (SDL for short) is a cross-platform library +designed to make it easy to write multi-media software, such as games +and emulators. + +The Simple DirectMedia Layer library source code is available from: +https://www.libsdl.org/ + +This library is distributed under the terms of the zlib license: +http://www.zlib.net/zlib_license.html + diff --git a/libultraship/libultraship/Lib/SDL/README.txt b/libultraship/libultraship/Lib/SDL/README.txt new file mode 100644 index 000000000..431ba0e74 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/README.txt @@ -0,0 +1,21 @@ + + Simple DirectMedia Layer + + (SDL) + + Version 2.0 + +--- +https://www.libsdl.org/ + +Simple DirectMedia Layer is a cross-platform development library designed +to provide low level access to audio, keyboard, mouse, joystick, and graphics +hardware via OpenGL and Direct3D. It is used by video playback software, +emulators, and popular games including Valve's award winning catalog +and many Humble Bundle games. + +More extensive documentation is available in the docs directory, starting +with README.md + +Enjoy! + Sam Lantinga (slouken@libsdl.org) diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL.h new file mode 100644 index 000000000..7cdd3243d --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL.h @@ -0,0 +1,232 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL.h + * + * Main include header for the SDL library + */ + + +#ifndef SDL_h_ +#define SDL_h_ + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_audio.h" +#include "SDL_clipboard.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_filesystem.h" +#include "SDL_gamecontroller.h" +#include "SDL_haptic.h" +#include "SDL_hidapi.h" +#include "SDL_hints.h" +#include "SDL_joystick.h" +#include "SDL_loadso.h" +#include "SDL_log.h" +#include "SDL_messagebox.h" +#include "SDL_metal.h" +#include "SDL_mutex.h" +#include "SDL_power.h" +#include "SDL_render.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_shape.h" +#include "SDL_system.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_locale.h" +#include "SDL_misc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/** + * \name SDL_INIT_* + * + * These are the flags which may be passed to SDL_Init(). You should + * specify the subsystems which you will be using in your application. + */ +/* @{ */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_SENSOR 0x00008000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ +#define SDL_INIT_EVERYTHING ( \ + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \ + ) +/* @} */ + +/** + * Initialize the SDL library. + * + * SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the + * two may be used interchangeably. Though for readability of your code + * SDL_InitSubSystem() might be preferred. + * + * The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread) + * subsystems are initialized by default. Message boxes + * (SDL_ShowSimpleMessageBox) also attempt to work without initializing the + * video subsystem, in hopes of being useful in showing an error dialog when + * SDL_Init fails. You must specifically initialize other subsystems if you + * use them in your application. + * + * Logging (such as SDL_Log) works without initialization, too. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_INIT_TIMER`: timer subsystem + * - `SDL_INIT_AUDIO`: audio subsystem + * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events + * subsystem + * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the + * events subsystem + * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem + * - `SDL_INIT_GAMECONTROLLER`: controller subsystem; automatically + * initializes the joystick subsystem + * - `SDL_INIT_EVENTS`: events subsystem + * - `SDL_INIT_EVERYTHING`: all of the above subsystems + * - `SDL_INIT_NOPARACHUTE`: compatibility; this flag is ignored + * + * Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem() + * for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or + * call SDL_Quit() to force shutdown). If a subsystem is already loaded then + * this call will increase the ref-count and return. + * + * \param flags subsystem initialization flags + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + * \sa SDL_SetMainReady + * \sa SDL_WasInit + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/** + * Compatibility function to initialize the SDL library. + * + * In SDL2, this function and SDL_Init() are interchangeable. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_Quit + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/** + * Shut down specific SDL subsystems. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * SDL_QuitSubSystem() and SDL_WasInit() will not work. You will need to use + * that subsystem's quit function (SDL_VideoQuit()) directly instead. But + * generally, you should not be using those functions directly anyhow; use + * SDL_Init() instead. + * + * You still need to call SDL_Quit() even if you close all open subsystems + * with SDL_QuitSubSystem(). + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/** + * Get a mask of the specified subsystems which are currently initialized. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns a mask of all initialized subsystems if `flags` is 0, otherwise it + * returns the initialization status of the specified subsystems. + * + * The return value does not include SDL_INIT_NOPARACHUTE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_InitSubSystem + */ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/** + * Clean up all initialized subsystems. + * + * You should call this function even if you have already shutdown each + * initialized subsystem with SDL_QuitSubSystem(). It is safe to call this + * function even in the case of errors in initialization. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * then you must use that subsystem's quit function (SDL_VideoQuit()) to shut + * it down before calling SDL_Quit(). But generally, you should not be using + * those functions directly anyhow; use SDL_Init() instead. + * + * You can use this function with atexit() to ensure that it is run when your + * application is shutdown, but it is not wise to do this from a library or + * other dynamically loaded code. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_assert.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_assert.h new file mode 100644 index 000000000..defadf137 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_assert.h @@ -0,0 +1,324 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_assert_h_ +#define SDL_assert_h_ + +#include "SDL_config.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SDL_ASSERT_LEVEL +#ifdef SDL_DEFAULT_ASSERT_LEVEL +#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL +#elif defined(_DEBUG) || defined(DEBUG) || \ + (defined(__GNUC__) && !defined(__OPTIMIZE__)) +#define SDL_ASSERT_LEVEL 2 +#else +#define SDL_ASSERT_LEVEL 1 +#endif +#endif /* SDL_ASSERT_LEVEL */ + +/* +These are macros and not first class functions so that the debugger breaks +on the assertion line and not in some random guts of SDL, and so each +assert can have unique static variables associated with it. +*/ + +#if defined(_MSC_VER) +/* Don't include intrin.h here because it contains C++ code */ + extern void __cdecl __debugbreak(void); + #define SDL_TriggerBreakpoint() __debugbreak() +#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) +#elif defined(__APPLE__) && defined(__arm__) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" ) +#elif defined(__386__) && defined(__WATCOMC__) + #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } +#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) + #include + #define SDL_TriggerBreakpoint() raise(SIGTRAP) +#else + /* How do we trigger breakpoints on this platform? */ + #define SDL_TriggerBreakpoint() +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ +# define SDL_FUNCTION __func__ +#elif ((__GNUC__ >= 2) || defined(_MSC_VER) || defined (__WATCOMC__)) +# define SDL_FUNCTION __FUNCTION__ +#else +# define SDL_FUNCTION "???" +#endif +#define SDL_FILE __FILE__ +#define SDL_LINE __LINE__ + +/* +sizeof (x) makes the compiler still parse the expression even without +assertions enabled, so the code is always checked at compile time, but +doesn't actually generate code for it, so there are no side effects or +expensive checks at run time, just the constant size of what x WOULD be, +which presumably gets optimized out as unused. +This also solves the problem of... + + int somevalue = blah(); + SDL_assert(somevalue == 1); + +...which would cause compiles to complain that somevalue is unused if we +disable assertions. +*/ + +/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking + this condition isn't constant. And looks like an owl's face! */ +#ifdef _MSC_VER /* stupid /W4 warnings. */ +#define SDL_NULL_WHILE_LOOP_CONDITION (0,0) +#else +#define SDL_NULL_WHILE_LOOP_CONDITION (0) +#endif + +#define SDL_disabled_assert(condition) \ + do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) + +typedef enum +{ + SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ + SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ + SDL_ASSERTION_ABORT, /**< Terminate the program. */ + SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ + SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ +} SDL_AssertState; + +typedef struct SDL_AssertData +{ + int always_ignore; + unsigned int trigger_count; + const char *condition; + const char *filename; + int linenum; + const char *function; + const struct SDL_AssertData *next; +} SDL_AssertData; + +#if (SDL_ASSERT_LEVEL > 0) + +/* Never call this directly. Use the SDL_assert* macros. */ +extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, + const char *, + const char *, int) +#if defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) +/* this tells Clang's static analysis that we're a custom assert function, + and that the analyzer should assume the condition was always true past this + SDL_assert test. */ + __attribute__((analyzer_noreturn)) +#endif +#endif +; + +/* the do {} while(0) avoids dangling else problems: + if (x) SDL_assert(y); else blah(); + ... without the do/while, the "else" could attach to this macro's "if". + We try to handle just the minimum we need here in a macro...the loop, + the static vars, and break points. The heavy lifting is handled in + SDL_ReportAssertion(), in SDL_assert.c. +*/ +#define SDL_enabled_assert(condition) \ + do { \ + while ( !(condition) ) { \ + static struct SDL_AssertData sdl_assert_data = { \ + 0, 0, #condition, 0, 0, 0, 0 \ + }; \ + const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ + if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ + continue; /* go again. */ \ + } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ + SDL_TriggerBreakpoint(); \ + } \ + break; /* not retrying. */ \ + } \ + } while (SDL_NULL_WHILE_LOOP_CONDITION) + +#endif /* enabled assertions support code */ + +/* Enable various levels of assertions. */ +#if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_disabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 1 /* release settings. */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) +#else +# error Unknown assertion level. +#endif + +/* this assertion is never disabled at any level. */ +#define SDL_assert_always(condition) SDL_enabled_assert(condition) + + +/** + * A callback that fires when an SDL assertion fails. + * + * \param data a pointer to the SDL_AssertData structure corresponding to the + * current assertion + * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler() + * \returns an SDL_AssertState value indicating how to handle the failure. + */ +typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( + const SDL_AssertData* data, void* userdata); + +/** + * Set an application-defined assertion handler. + * + * This function allows an application to show its own assertion UI and/or + * force the response to an assertion failure. If the application doesn't + * provide this, SDL will try to do the right thing, popping up a + * system-specific GUI dialog, and probably minimizing any fullscreen windows. + * + * This callback may fire from any thread, but it runs wrapped in a mutex, so + * it will only fire from one thread at a time. + * + * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! + * + * \param handler the SDL_AssertionHandler function to call when an assertion + * fails or NULL for the default handler + * \param userdata a pointer that is passed to `handler` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAssertionHandler + */ +extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( + SDL_AssertionHandler handler, + void *userdata); + +/** + * Get the default assertion handler. + * + * This returns the function pointer that is called by default when an + * assertion is triggered. This is an internal function provided by SDL, that + * is used for assertions when SDL_SetAssertionHandler() hasn't been used to + * provide a different function. + * + * \returns the default SDL_AssertionHandler that is called when an assert + * triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GetAssertionHandler + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); + +/** + * Get the current assertion handler. + * + * This returns the function pointer that is called when an assertion is + * triggered. This is either the value last passed to + * SDL_SetAssertionHandler(), or if no application-specified function is set, + * is equivalent to calling SDL_GetDefaultAssertionHandler(). + * + * The parameter `puserdata` is a pointer to a void*, which will store the + * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value + * will always be NULL for the default handler. If you don't care about this + * data, it is safe to pass a NULL pointer to this function to ignore it. + * + * \param puserdata pointer which is filled with the "userdata" pointer that + * was passed to SDL_SetAssertionHandler() + * \returns the SDL_AssertionHandler that is called when an assert triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_SetAssertionHandler + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); + +/** + * Get a list of all assertion failures. + * + * This function gets all assertions triggered since the last call to + * SDL_ResetAssertionReport(), or the start of the program. + * + * The proper way to examine this data looks something like this: + * + * ```c + * const SDL_AssertData *item = SDL_GetAssertionReport(); + * while (item) { + * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", + * item->condition, item->function, item->filename, + * item->linenum, item->trigger_count, + * item->always_ignore ? "yes" : "no"); + * item = item->next; + * } + * ``` + * + * \returns a list of all failed assertions or NULL if the list is empty. This + * memory should not be modified or freed by the application. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ResetAssertionReport + */ +extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); + +/** + * Clear the list of all assertion failures. + * + * This function will clear the list of all assertions triggered up to that + * point. Immediately following this call, SDL_GetAssertionReport will return + * no items. In addition, any previously-triggered assertions will be reset to + * a trigger_count of zero, and their always_ignore state will be false. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAssertionReport + */ +extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); + + +/* these had wrong naming conventions until 2.0.4. Please update your app! */ +#define SDL_assert_state SDL_AssertState +#define SDL_assert_data SDL_AssertData + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_assert_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_atomic.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_atomic.h new file mode 100644 index 000000000..b29ceeac2 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_atomic.h @@ -0,0 +1,395 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_atomic.h + * + * Atomic operations. + * + * IMPORTANT: + * If you are not an expert in concurrent lockless programming, you should + * only be using the atomic lock and reference counting functions in this + * file. In all other cases you should be protecting your data structures + * with full mutexes. + * + * The list of "safe" functions to use are: + * SDL_AtomicLock() + * SDL_AtomicUnlock() + * SDL_AtomicIncRef() + * SDL_AtomicDecRef() + * + * Seriously, here be dragons! + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * + * You can find out a little more about lockless programming and the + * subtle issues that can arise here: + * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx + * + * There's also lots of good information here: + * http://www.1024cores.net/home/lock-free-algorithms + * http://preshing.com/ + * + * These operations may or may not actually be implemented using + * processor specific atomic operations. When possible they are + * implemented as true processor specific atomic operations. When that + * is not possible the are implemented using locks that *do* use the + * available atomic operations. + * + * All of the atomic operations that modify memory are full memory barriers. + */ + +#ifndef SDL_atomic_h_ +#define SDL_atomic_h_ + +#include "SDL_stdinc.h" +#include "SDL_platform.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SDL AtomicLock + * + * The atomic locks are efficient spinlocks using CPU instructions, + * but are vulnerable to starvation and can spin forever if a thread + * holding a lock has been terminated. For this reason you should + * minimize the code executed inside an atomic lock and never do + * expensive things like API or system calls while holding them. + * + * The atomic locks are not safe to lock recursively. + * + * Porting Note: + * The spin lock functions and type are required and can not be + * emulated because they are used in the atomic emulation code. + */ +/* @{ */ + +typedef int SDL_SpinLock; + +/** + * Try to lock a spin lock by setting it to a non-zero value. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * \returns SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already + * held. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicUnlock + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); + +/** + * Lock a spin lock by setting it to a non-zero value. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicTryLock + * \sa SDL_AtomicUnlock + */ +extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); + +/** + * Unlock a spin lock by setting it to 0. + * + * Always returns immediately. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicTryLock + */ +extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); + +/* @} *//* SDL AtomicLock */ + + +/** + * The compiler barrier prevents the compiler from reordering + * reads and writes to globally visible variables across the call. + */ +#if defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__) +void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) +#define SDL_CompilerBarrier() _ReadWriteBarrier() +#elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ +#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") +#elif defined(__WATCOMC__) +extern __inline void SDL_CompilerBarrier(void); +#pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; +#else +#define SDL_CompilerBarrier() \ +{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); } +#endif + +/** + * Memory barriers are designed to prevent reads and writes from being + * reordered by the compiler and being seen out of order on multi-core CPUs. + * + * A typical pattern would be for thread A to write some data and a flag, and + * for thread B to read the flag and get the data. In this case you would + * insert a release barrier between writing the data and the flag, + * guaranteeing that the data write completes no later than the flag is + * written, and you would insert an acquire barrier between reading the flag + * and reading the data, to ensure that all the reads associated with the flag + * have completed. + * + * In this pattern you should always see a release barrier paired with an + * acquire barrier and you should gate the data reads/writes with a single + * flag variable. + * + * For more information on these semantics, take a look at the blog post: + * http://preshing.com/20120913/acquire-and-release-semantics + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void); +extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); + +#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") +#elif defined(__GNUC__) && defined(__aarch64__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__GNUC__) && defined(__arm__) +#if 0 /* defined(__LINUX__) || defined(__ANDROID__) */ +/* Information from: + https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19 + + The Linux kernel provides a helper function which provides the right code for a memory barrier, + hard-coded at address 0xffff0fa0 +*/ +typedef void (*SDL_KernelMemoryBarrierFunc)(); +#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#elif 0 /* defined(__QNXNTO__) */ +#include + +#define SDL_MemoryBarrierRelease() __cpu_membarrier() +#define SDL_MemoryBarrierAcquire() __cpu_membarrier() +#else +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_5TE__) +#ifdef __thumb__ +/* The mcr instruction isn't available in thumb mode, use real functions */ +#define SDL_MEMORY_BARRIER_USES_FUNCTION +#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction() +#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction() +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#endif /* __thumb__ */ +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") +#endif /* __LINUX__ || __ANDROID__ */ +#endif /* __GNUC__ && __arm__ */ +#else +#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */ +#include +#define SDL_MemoryBarrierRelease() __machine_rel_barrier() +#define SDL_MemoryBarrierAcquire() __machine_acq_barrier() +#else +/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */ +#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() +#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() +#endif +#endif + +/** + * \brief A type representing an atomic integer value. It is a struct + * so people don't accidentally use numeric operations on it. + */ +typedef struct { int value; } SDL_atomic_t; + +/** + * Set an atomic variable to a new value if it is currently an old value. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param oldval the old value + * \param newval the new value + * \returns SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGet + * \sa SDL_AtomicSet + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); + +/** + * Set an atomic variable to a value. + * + * This function also acts as a full memory barrier. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicGet + */ +extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); + +/** + * Get the value of an atomic variable. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable + * \returns the current value of an atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicSet + */ +extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); + +/** + * Add to an atomic variable. + * + * This function also acts as a full memory barrier. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value to add + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicDecRef + * \sa SDL_AtomicIncRef + */ +extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); + +/** + * \brief Increment an atomic variable used as a reference count. + */ +#ifndef SDL_AtomicIncRef +#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) +#endif + +/** + * \brief Decrement an atomic variable used as a reference count. + * + * \return SDL_TRUE if the variable reached zero after decrementing, + * SDL_FALSE otherwise + */ +#ifndef SDL_AtomicDecRef +#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) +#endif + +/** + * Set a pointer to a new value if it is currently an old value. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \param oldval the old pointer value + * \param newval the new pointer value + * \returns SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCAS + * \sa SDL_AtomicGetPtr + * \sa SDL_AtomicSetPtr + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); + +/** + * Set a pointer to a value atomically. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \param v the desired pointer value + * \returns the previous value of the pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGetPtr + */ +extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); + +/** + * Get the value of a pointer atomically. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \returns the current value of a pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicSetPtr + */ +extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#include "close_code.h" + +#endif /* SDL_atomic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_audio.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_audio.h new file mode 100644 index 000000000..181f66c57 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_audio.h @@ -0,0 +1,1464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* !!! FIXME: several functions in here need Doxygen comments. */ + +/** + * \file SDL_audio.h + * + * Access to the raw audio mixing buffer for the SDL library. + */ + +#ifndef SDL_audio_h_ +#define SDL_audio_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Audio format flags. + * + * These are what the 16 bits in SDL_AudioFormat currently mean... + * (Unspecified bits are always zero). + * + * \verbatim + ++-----------------------sample is signed if set + || + || ++-----------sample is bigendian if set + || || + || || ++---sample is float if set + || || || + || || || +---sample bit size---+ + || || || | | + 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + \endverbatim + * + * There are macros in SDL 2.0 and later to query these bits. + */ +typedef Uint16 SDL_AudioFormat; + +/** + * \name Audio flags + */ +/* @{ */ + +#define SDL_AUDIO_MASK_BITSIZE (0xFF) +#define SDL_AUDIO_MASK_DATATYPE (1<<8) +#define SDL_AUDIO_MASK_ENDIAN (1<<12) +#define SDL_AUDIO_MASK_SIGNED (1<<15) +#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) +#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) +#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) +#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) +#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) +#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) +#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) + +/** + * \name Audio format flags + * + * Defaults to LSB byte order. + */ +/* @{ */ +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB +/* @} */ + +/** + * \name int32 support + */ +/* @{ */ +#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ +#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ +#define AUDIO_S32 AUDIO_S32LSB +/* @} */ + +/** + * \name float32 support + */ +/* @{ */ +#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ +#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ +#define AUDIO_F32 AUDIO_F32LSB +/* @} */ + +/** + * \name Native audio byte ordering + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_S32SYS AUDIO_S32LSB +#define AUDIO_F32SYS AUDIO_F32LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_S32SYS AUDIO_S32MSB +#define AUDIO_F32SYS AUDIO_F32MSB +#endif +/* @} */ + +/** + * \name Allow change flags + * + * Which audio format changes are allowed when opening a device. + */ +/* @{ */ +#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 +#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 +#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 +#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008 +#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE) +/* @} */ + +/* @} *//* Audio flags */ + +/** + * This function is called when the audio device needs more data. + * + * \param userdata An application-specific parameter saved in + * the SDL_AudioSpec structure + * \param stream A pointer to the audio data buffer. + * \param len The length of that buffer in bytes. + * + * Once the callback returns, the buffer will no longer be valid. + * Stereo samples are stored in a LRLRLR ordering. + * + * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if + * you like. Just open your audio device with a NULL callback. + */ +typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, + int len); + +/** + * The calculated values in this structure are calculated by SDL_OpenAudio(). + * + * For multi-channel audio, the default SDL channel mapping is: + * 2: FL FR (stereo) + * 3: FL FR LFE (2.1 surround) + * 4: FL FR BL BR (quad) + * 5: FL FR FC BL BR (quad + center) + * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) + * 7: FL FR FC LFE BC SL SR (6.1 surround) + * 8: FL FR FC LFE BL BR SL SR (7.1 surround) + */ +typedef struct SDL_AudioSpec +{ + int freq; /**< DSP frequency -- samples per second */ + SDL_AudioFormat format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ + void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ +} SDL_AudioSpec; + + +struct SDL_AudioCVT; +typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, + SDL_AudioFormat format); + +/** + * \brief Upper limit of filters in SDL_AudioCVT + * + * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is + * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers, + * one of which is the terminating NULL pointer. + */ +#define SDL_AUDIOCVT_MAX_FILTERS 9 + +/** + * \struct SDL_AudioCVT + * \brief A structure to hold a set of audio conversion filters and buffers. + * + * Note that various parts of the conversion pipeline can take advantage + * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require + * you to pass it aligned data, but can possibly run much faster if you + * set both its (buf) field to a pointer that is aligned to 16 bytes, and its + * (len) field to something that's a multiple of 16, if possible. + */ +#if defined(__GNUC__) && !defined(__CHERI_PURE_CAPABILITY__) +/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't + pad it out to 88 bytes to guarantee ABI compatibility between compilers. + This is not a concern on CHERI architectures, where pointers must be stored + at aligned locations otherwise they will become invalid, and thus structs + containing pointers cannot be packed without giving a warning or error. + vvv + The next time we rev the ABI, make sure to size the ints and add padding. +*/ +#define SDL_AUDIOCVT_PACKED __attribute__((packed)) +#else +#define SDL_AUDIOCVT_PACKED +#endif +/* */ +typedef struct SDL_AudioCVT +{ + int needed; /**< Set to 1 if conversion possible */ + SDL_AudioFormat src_format; /**< Source audio format */ + SDL_AudioFormat dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */ + int filter_index; /**< Current audio conversion function */ +} SDL_AUDIOCVT_PACKED SDL_AudioCVT; + + +/* Function prototypes */ + +/** + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + */ +/* @{ */ + +/** + * Use this function to get the number of built-in audio drivers. + * + * This function returns a hardcoded number. This never returns a negative + * value; if there are no drivers compiled into this build of SDL, this + * function returns zero. The presence of a driver in this list does not mean + * it will function, it just means SDL is capable of interacting with that + * interface. For example, a build of SDL might have esound support, but if + * there's no esound server available, SDL's esound driver would fail if used. + * + * By default, SDL tries all drivers, in its preferred order, until one is + * found to be usable. + * + * \returns the number of built-in audio drivers. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); + +/** + * Use this function to get the name of a built in audio driver. + * + * The list of audio drivers is given in the order that they are normally + * initialized by default; the drivers that seem more reasonable to choose + * first (as far as the SDL developers believe) are earlier in the list. + * + * The names of drivers are all simple, low-ASCII identifiers, like "alsa", + * "coreaudio" or "xaudio2". These never have Unicode characters, and are not + * meant to be proper names. + * + * \param index the index of the audio driver; the value ranges from 0 to + * SDL_GetNumAudioDrivers() - 1 + * \returns the name of the audio driver at the requested index, or NULL if an + * invalid index was specified. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); +/* @} */ + +/** + * \name Initialization and cleanup + * + * \internal These functions are used internally, and should not be used unless + * you have a specific need to specify the audio driver you want to + * use. You should normally use SDL_Init() or SDL_InitSubSystem(). + */ +/* @{ */ + +/** + * Use this function to initialize a particular audio driver. + * + * This function is used internally, and should not be used unless you have a + * specific need to designate the audio driver you want to use. You should + * normally use SDL_Init() or SDL_InitSubSystem(). + * + * \param driver_name the name of the desired audio driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioQuit + */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); + +/** + * Use this function to shut down audio if you initialized it with + * SDL_AudioInit(). + * + * This function is used internally, and should not be used unless you have a + * specific need to specify the audio driver you want to use. You should + * normally use SDL_Quit() or SDL_QuitSubSystem(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); +/* @} */ + +/** + * Get the name of the current audio driver. + * + * The returned string points to internal static memory and thus never becomes + * invalid, even if you quit the audio subsystem and initialize a new driver + * (although such a case would return a different static string from another + * call to this function, of course). As such, you should not modify or free + * the returned string. + * + * \returns the name of the current audio driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); + +/** + * This function is a legacy means of opening the audio device. + * + * This function remains for compatibility with SDL 1.2, but also because it's + * slightly easier to use than the new functions in SDL 2.0. The new, more + * powerful, and preferred way to do this is SDL_OpenAudioDevice(). + * + * This function is roughly equivalent to: + * + * ```c + * SDL_OpenAudioDevice(NULL, 0, desired, obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + * ``` + * + * With two notable exceptions: + * + * - If `obtained` is NULL, we use `desired` (and allow no changes), which + * means desired will be modified to have the correct values for silence, + * etc, and SDL will convert any differences between your app's specific + * request and the hardware behind the scenes. + * - The return value is always success or failure, and not a device ID, which + * means you can only have one device open at a time with this function. + * + * \param desired an SDL_AudioSpec structure representing the desired output + * format. Please refer to the SDL_OpenAudioDevice + * documentation for details on how to prepare this structure. + * \param obtained an SDL_AudioSpec structure filled in with the actual + * parameters, or NULL. + * \returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by `obtained`. + * + * If `obtained` is NULL, the audio data passed to the callback + * function will be guaranteed to be in the requested format, and + * will be automatically converted to the actual hardware audio + * format if necessary. If `obtained` is NULL, `desired` will have + * fields modified. + * + * This function returns a negative error code on failure to open the + * audio device or failure to set up the audio thread; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudio + * \sa SDL_LockAudio + * \sa SDL_PauseAudio + * \sa SDL_UnlockAudio + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, + SDL_AudioSpec * obtained); + +/** + * SDL Audio Device IDs. + * + * A successful call to SDL_OpenAudio() is always device id 1, and legacy + * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls + * always returns devices >= 2 on success. The legacy calls are good both + * for backwards compatibility and when you don't care about multiple, + * specific, or capture devices. + */ +typedef Uint32 SDL_AudioDeviceID; + +/** + * Get the number of built-in audio devices. + * + * This function is only valid after successfully initializing the audio + * subsystem. + * + * Note that audio capture support is not implemented as of SDL 2.0.4, so the + * `iscapture` parameter is for future expansion and should always be zero for + * now. + * + * This function will return -1 if an explicit list of devices can't be + * determined. Returning -1 is not an error. For example, if SDL is set up to + * talk to a remote audio server, it can't list every one available on the + * Internet, but it will still allow a specific host to be specified in + * SDL_OpenAudioDevice(). + * + * In many common cases, when this function returns a value <= 0, it can still + * successfully open the default device (NULL for first argument of + * SDL_OpenAudioDevice()). + * + * This function may trigger a complete redetect of available hardware. It + * should not be called for each iteration of a loop, but rather once at the + * start of a loop: + * + * ```c + * // Don't do this: + * for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) + * + * // do this instead: + * const int count = SDL_GetNumAudioDevices(0); + * for (int i = 0; i < count; ++i) { do_something_here(); } + * ``` + * + * \param iscapture zero to request playback devices, non-zero to request + * recording devices + * \returns the number of available devices exposed by the current driver or + * -1 if an explicit list of devices can't be determined. A return + * value of -1 does not necessarily mean an error condition. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceName + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); + +/** + * Get the human-readable name of a specific audio device. + * + * This function is only valid after successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * The string returned by this function is UTF-8 encoded, read-only, and + * managed internally. You are not to free it. If you need to keep the string + * for any length of time, you should make your own copy of it, as it will be + * invalid next time any of several other SDL functions are called. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \returns the name of the audio device at the requested index, or NULL on + * error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDevices + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, + int iscapture); + +/** + * Get the preferred audio format of a specific audio device. + * + * This function is only valid after a successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * `spec` will be filled with the sample rate, sample format, and channel + * count. All other values in the structure are filled with 0. When the + * supported struct members are 0, SDL was unable to get the property from the + * backend. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \param spec The SDL_AudioSpec to be initialized by this function. + * \returns 0 on success, nonzero on error + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetNumAudioDevices + */ +extern DECLSPEC int SDLCALL SDL_GetAudioDeviceSpec(int index, + int iscapture, + SDL_AudioSpec *spec); + + +/** + * Open a specific audio device. + * + * SDL_OpenAudio(), unlike this function, always acts on device ID 1. As such, + * this function will never return a 1 so as not to conflict with the legacy + * function. + * + * Please note that SDL 2.0 before 2.0.5 did not support recording; as such, + * this function would fail if `iscapture` was not zero. Starting with SDL + * 2.0.5, recording is implemented and this value can be non-zero. + * + * Passing in a `device` name of NULL requests the most reasonable default + * (and is equivalent to what SDL_OpenAudio() does to choose a device). The + * `device` name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but + * some drivers allow arbitrary and driver-specific strings, such as a + * hostname/IP address for a remote audio server, or a filename in the + * diskaudio driver. + * + * An opened audio device starts out paused, and should be enabled for playing + * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio + * callback function to be called. Since the audio driver may modify the + * requested size of the audio buffer, you should allocate any local mixing + * buffers after you open the audio device. + * + * The audio callback runs in a separate thread in most cases; you can prevent + * race conditions between your callback and other threads without fully + * pausing playback with SDL_LockAudioDevice(). For more information about the + * callback, see SDL_AudioSpec. + * + * Managing the audio spec via 'desired' and 'obtained': + * + * When filling in the desired audio spec structure: + * + * - `desired->freq` should be the frequency in sample-frames-per-second (Hz). + * - `desired->format` should be the audio format (`AUDIO_S16SYS`, etc). + * - `desired->samples` is the desired size of the audio buffer, in _sample + * frames_ (with stereo output, two samples--left and right--would make a + * single sample frame). This number should be a power of two, and may be + * adjusted by the audio driver to a value more suitable for the hardware. + * Good values seem to range between 512 and 8096 inclusive, depending on + * the application and CPU speed. Smaller values reduce latency, but can + * lead to underflow if the application is doing heavy processing and cannot + * fill the audio buffer in time. Note that the number of sample frames is + * directly related to time by the following formula: `ms = + * (sampleframes*1000)/freq` + * - `desired->size` is the size in _bytes_ of the audio buffer, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->silence` is the value used to set the buffer to silence, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->callback` should be set to a function that will be called when + * the audio device is ready for more data. It is passed a pointer to the + * audio buffer, and the length in bytes of the audio buffer. This function + * usually runs in a separate thread, and so you should protect data + * structures that it accesses by calling SDL_LockAudioDevice() and + * SDL_UnlockAudioDevice() in your code. Alternately, you may pass a NULL + * pointer here, and call SDL_QueueAudio() with some frequency, to queue + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). + * - `desired->userdata` is passed as the first parameter to your callback + * function. If you passed a NULL callback, this value is ignored. + * + * `allowed_changes` can have the following flags OR'd together: + * + * - `SDL_AUDIO_ALLOW_FREQUENCY_CHANGE` + * - `SDL_AUDIO_ALLOW_FORMAT_CHANGE` + * - `SDL_AUDIO_ALLOW_CHANNELS_CHANGE` + * - `SDL_AUDIO_ALLOW_ANY_CHANGE` + * + * These flags specify how SDL should behave when a device cannot offer a + * specific feature. If the application requests a feature that the hardware + * doesn't offer, SDL will always try to get the closest equivalent. + * + * For example, if you ask for float32 audio format, but the sound card only + * supports int16, SDL will set the hardware to int16. If you had set + * SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL will change the format in the `obtained` + * structure. If that flag was *not* set, SDL will prepare to convert your + * callback's float32 audio to int16 before feeding it to the hardware and + * will keep the originally requested format in the `obtained` structure. + * + * The resulting audio specs, varying depending on hardware and on what + * changes were allowed, will then be written back to `obtained`. + * + * If your application can only handle one specific data format, pass a zero + * for `allowed_changes` and let SDL transparently handle any differences. + * + * \param device a UTF-8 string reported by SDL_GetAudioDeviceName() or a + * driver-specific name as appropriate. NULL requests the most + * reasonable default device. + * \param iscapture non-zero to specify a device should be opened for + * recording, not playback + * \param desired an SDL_AudioSpec structure representing the desired output + * format; see SDL_OpenAudio() for more information + * \param obtained an SDL_AudioSpec structure filled in with the actual output + * format; see SDL_OpenAudio() for more information + * \param allowed_changes 0, or one or more flags OR'd together + * \returns a valid device ID that is > 0 on success or 0 on failure; call + * SDL_GetError() for more information. + * + * For compatibility with SDL 1.2, this will never return 1, since + * SDL reserves that ID for the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudioDevice + * \sa SDL_GetAudioDeviceName + * \sa SDL_LockAudioDevice + * \sa SDL_OpenAudio + * \sa SDL_PauseAudioDevice + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice( + const char *device, + int iscapture, + const SDL_AudioSpec *desired, + SDL_AudioSpec *obtained, + int allowed_changes); + + + +/** + * \name Audio state + * + * Get the current audio state. + */ +/* @{ */ +typedef enum +{ + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_AudioStatus; + +/** + * This function is a legacy means of querying the audio device. + * + * New programs might want to use SDL_GetAudioDeviceStatus() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_GetAudioDeviceStatus(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \returns the SDL_AudioStatus of the audio device opened by SDL_OpenAudio(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceStatus + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); + +/** + * Use this function to get the current audio state of an audio device. + * + * \param dev the ID of an audio device previously opened with + * SDL_OpenAudioDevice() + * \returns the SDL_AudioStatus of the specified audio device. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); +/* @} *//* Audio State */ + +/** + * \name Pause audio functions + * + * These functions pause and unpause the audio callback processing. + * They should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +/* @{ */ + +/** + * This function is a legacy means of pausing the audio device. + * + * New programs might want to use SDL_PauseAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_PauseAudioDevice(1, pause_on); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioStatus + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); + +/** + * Use this function to pause and unpause audio playback on a specified + * device. + * + * This function pauses and unpauses the audio callback processing for a given + * device. Newly-opened audio devices start in the paused state, so you must + * call this function with **pause_on**=0 after opening the specified audio + * device to start playing sound. This allows you to safely initialize data + * for your callback function after opening the audio device. Silence will be + * written to the audio device while paused, and the audio callback is + * guaranteed to not be called. Pausing one device does not prevent other + * unpaused devices from running their callbacks. + * + * Pausing state does not stack; even if you pause a device several times, a + * single unpause will start the device playing again, and vice versa. This is + * different from how SDL_LockAudioDevice() works. + * + * If you just need to protect a few variables from race conditions vs your + * callback, you shouldn't pause the audio device, as it will lead to dropouts + * in the audio playback. Instead, you should use SDL_LockAudioDevice(). + * + * \param dev a device opened by SDL_OpenAudioDevice() + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, + int pause_on); +/* @} *//* Pause audio functions */ + +/** + * Load the audio data of a WAVE file into memory. + * + * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to + * be valid pointers. The entire data portion of the file is then loaded into + * memory and decoded if necessary. + * + * If `freesrc` is non-zero, the data source gets automatically closed and + * freed before the function returns. + * + * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and + * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and + * A-law and mu-law (8 bits). Other formats are currently unsupported and + * cause an error. + * + * If this function succeeds, the pointer returned by it is equal to `spec` + * and the pointer to the audio data allocated by the function is written to + * `audio_buf` and its length in bytes to `audio_len`. The SDL_AudioSpec + * members `freq`, `channels`, and `format` are set to the values of the audio + * data in the buffer. The `samples` member is set to a sane default and all + * others are set to zero. + * + * It's necessary to use SDL_FreeWAV() to free the audio data returned in + * `audio_buf` when it is no longer used. + * + * Because of the underspecification of the .WAV format, there are many + * problematic files in the wild that cause issues with strict decoders. To + * provide compatibility with these files, this decoder is lenient in regards + * to the truncation of the file, the fact chunk, and the size of the RIFF + * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`, + * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to + * tune the behavior of the loading process. + * + * Any file that is invalid (due to truncation, corruption, or wrong values in + * the headers), too big, or unsupported causes an error. Additionally, any + * critical I/O error from the data source will terminate the loading process + * with an error. The function returns NULL on error and in all cases (with + * the exception of `src` being NULL), an appropriate error message will be + * set. + * + * It is required that the data source supports seeking. + * + * Example: + * + * ```c + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, &spec, &buf, &len); + * ``` + * + * Note that the SDL_LoadWAV macro does this same thing for you, but in a less + * messy way: + * + * ```c + * SDL_LoadWAV("sample.wav", &spec, &buf, &len); + * ``` + * + * \param src The data source for the WAVE data + * \param freesrc If non-zero, SDL will _always_ free the data source + * \param spec An SDL_AudioSpec that will be filled in with the wave file's + * format details + * \param audio_buf A pointer filled with the audio data, allocated by the + * function. + * \param audio_len A pointer filled with the length of the audio data buffer + * in bytes + * \returns This function, if successfully called, returns `spec`, which will + * be filled with the audio data format of the wave source data. + * `audio_buf` will be filled with a pointer to an allocated buffer + * containing the audio data, and `audio_len` is filled with the + * length of that audio buffer in bytes. + * + * This function returns NULL if the .WAV file cannot be opened, uses + * an unknown data format, or is corrupt; call SDL_GetError() for + * more information. + * + * When the application is done with the data returned in + * `audio_buf`, it should call SDL_FreeWAV() to dispose of it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeWAV + * \sa SDL_LoadWAV + */ +extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, + int freesrc, + SDL_AudioSpec * spec, + Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file. + * Compatibility convenience function. + */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/** + * Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW(). + * + * After a WAVE file has been opened with SDL_LoadWAV() or SDL_LoadWAV_RW() + * its data can eventually be freed with SDL_FreeWAV(). It is safe to call + * this function with a NULL pointer. + * + * \param audio_buf a pointer to the buffer created by SDL_LoadWAV() or + * SDL_LoadWAV_RW() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadWAV + * \sa SDL_LoadWAV_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); + +/** + * Initialize an SDL_AudioCVT structure for conversion. + * + * Before an SDL_AudioCVT structure can be used to convert audio data it must + * be initialized with source and destination information. + * + * This function will zero out every field of the SDL_AudioCVT, so it must be + * called before the application fills in the final buffer information. + * + * Once this function has returned successfully, and reported that a + * conversion is necessary, the application fills in the rest of the fields in + * SDL_AudioCVT, now that it knows how large a buffer it needs to allocate, + * and then can call SDL_ConvertAudio() to complete the conversion. + * + * \param cvt an SDL_AudioCVT structure filled in with audio conversion + * information + * \param src_format the source format of the audio data; for more info see + * SDL_AudioFormat + * \param src_channels the number of channels in the source + * \param src_rate the frequency (sample-frames-per-second) of the source + * \param dst_format the destination format of the audio data; for more info + * see SDL_AudioFormat + * \param dst_channels the number of channels in the destination + * \param dst_rate the frequency (sample-frames-per-second) of the destination + * \returns 1 if the audio filter is prepared, 0 if no conversion is needed, + * or a negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ConvertAudio + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, + SDL_AudioFormat src_format, + Uint8 src_channels, + int src_rate, + SDL_AudioFormat dst_format, + Uint8 dst_channels, + int dst_rate); + +/** + * Convert audio data to a desired audio format. + * + * This function does the actual audio data conversion, after the application + * has called SDL_BuildAudioCVT() to prepare the conversion information and + * then filled in the buffer details. + * + * Once the application has initialized the `cvt` structure using + * SDL_BuildAudioCVT(), allocated an audio buffer and filled it with audio + * data in the source format, this function will convert the buffer, in-place, + * to the desired format. + * + * The data conversion may go through several passes; any given pass may + * possibly temporarily increase the size of the data. For example, SDL might + * expand 16-bit data to 32 bits before resampling to a lower frequency, + * shrinking the data size after having grown it briefly. Since the supplied + * buffer will be both the source and destination, converting as necessary + * in-place, the application must allocate a buffer that will fully contain + * the data during its largest conversion pass. After SDL_BuildAudioCVT() + * returns, the application should set the `cvt->len` field to the size, in + * bytes, of the source data, and allocate a buffer that is `cvt->len * + * cvt->len_mult` bytes long for the `buf` field. + * + * The source data should be copied into this buffer before the call to + * SDL_ConvertAudio(). Upon successful return, this buffer will contain the + * converted audio, and `cvt->len_cvt` will be the size of the converted data, + * in bytes. Any bytes in the buffer past `cvt->len_cvt` are undefined once + * this function returns. + * + * \param cvt an SDL_AudioCVT structure that was previously set up by + * SDL_BuildAudioCVT(). + * \returns 0 if the conversion was completed successfully or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BuildAudioCVT + */ +extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); + +/* SDL_AudioStream is a new audio conversion interface. + The benefits vs SDL_AudioCVT: + - it can handle resampling data in chunks without generating + artifacts, when it doesn't have the complete buffer available. + - it can handle incoming data in any variable size. + - You push data as you have it, and pull it when you need it + */ +/* this is opaque to the outside world. */ +struct _SDL_AudioStream; +typedef struct _SDL_AudioStream SDL_AudioStream; + +/** + * Create a new audio stream. + * + * \param src_format The format of the source audio + * \param src_channels The number of channels of the source audio + * \param src_rate The sampling rate of the source audio + * \param dst_format The format of the desired audio output + * \param dst_channels The number of channels of the desired audio output + * \param dst_rate The sampling rate of the desired audio output + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioFormat src_format, + const Uint8 src_channels, + const int src_rate, + const SDL_AudioFormat dst_format, + const Uint8 dst_channels, + const int dst_rate); + +/** + * Add data to be converted/resampled to the stream. + * + * \param stream The stream the audio data is being added to + * \param buf A pointer to the audio data to add + * \param len The number of bytes to write to the stream + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len); + +/** + * Get converted/resampled data from the stream + * + * \param stream The stream the audio is being requested from + * \param buf A buffer to fill with audio data + * \param len The maximum number of bytes to fill + * \returns the number of bytes read from the stream, or -1 on error + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); + +/** + * Get the number of converted/resampled bytes available. + * + * The stream may be buffering data behind the scenes until it has enough to + * resample correctly, so this number might be lower than what you expect, or + * even be zero. Add more data or flush the stream if you need the data now. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); + +/** + * Tell the stream that you're done sending data, and anything being buffered + * should be converted/resampled and made available immediately. + * + * It is legal to add more data to a stream after flushing, but there will be + * audio gaps in the output. Generally this is intended to signal the end of + * input, so the complete output becomes available. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); + +/** + * Clear any pending data in the stream without converting it + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); + +/** + * Free an audio stream + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + */ +extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); + +#define SDL_MIX_MAXVOLUME 128 + +/** + * This function is a legacy means of mixing audio. + * + * This function is equivalent to calling... + * + * ```c + * SDL_MixAudioFormat(dst, src, format, len, volume); + * ``` + * + * ...where `format` is the obtained format of the audio device from the + * legacy SDL_OpenAudio() function. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MixAudioFormat + */ +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, + Uint32 len, int volume); + +/** + * Mix audio data in a specified format. + * + * This takes an audio buffer `src` of `len` bytes of `format` data and mixes + * it into `dst`, performing addition, volume adjustment, and overflow + * clipping. The buffer pointed to by `dst` must also be `len` bytes of + * `format` data. + * + * This is provided for convenience -- you can mix your own audio data. + * + * Do not use this function for mixing together more than two streams of + * sample data. The output from repeated application of this function may be + * distorted by clipping, because there is no accumulator with greater range + * than the input (not to mention this being an inefficient way of doing it). + * + * It is a common misconception that this function is required to write audio + * data to an output stream in an audio callback. While you can do that, + * SDL_MixAudioFormat() is really only needed when you're mixing a single + * audio stream with a volume adjustment. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param format the SDL_AudioFormat structure representing the desired audio + * format + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, + const Uint8 * src, + SDL_AudioFormat format, + Uint32 len, int volume); + +/** + * Queue more audio on non-callback devices. + * + * If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. SDL_QueueAudio() will return + * -1 to signify an error if you use it with capture devices. + * + * SDL offers two ways to feed audio to the device: you can either supply a + * callback that SDL triggers with some frequency to obtain more audio (pull + * method), or you can supply no callback, and then SDL will expect you to + * supply data at regular intervals (push method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Queued data will drain to the device as + * necessary without further intervention from you. If the device needs audio + * but there is not enough queued, it will play silence to make up the + * difference. This means you will have skips in your audio playback if you + * aren't routinely queueing sufficient data. + * + * This function copies the supplied data, so you are safe to free it when the + * function returns. This function is thread-safe, but queueing to the same + * device from two threads at once does not promise which buffer will be + * queued first. + * + * You may not queue audio on a device that is using an application-supplied + * callback; doing so returns an error. You have to use the audio callback or + * queue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * Note that SDL2 does not support planar audio. You will need to resample + * from planar audio formats into a non-planar one (see SDL_AudioFormat) + * before queuing audio. + * + * \param dev the device ID to which we will queue audio + * \param data the data to queue to the device for later playback + * \param len the number of bytes (not samples!) to which `data` points + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); + +/** + * Dequeue more audio on non-callback devices. + * + * If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. SDL_DequeueAudio() will always + * return 0 if you use it with playback devices. + * + * SDL offers two ways to retrieve audio from a capture device: you can either + * supply a callback that SDL triggers with some frequency as the device + * records more audio data, (push method), or you can supply no callback, and + * then SDL will expect you to retrieve data at regular intervals (pull + * method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting to + * not need captured audio for some length of time, use SDL_PauseAudioDevice() + * to stop the capture device from queueing more data. This can be useful + * during, say, level loading times. When unpaused, capture devices will start + * queueing data from that point, having flushed any capturable data available + * while paused. + * + * This function is thread-safe, but dequeueing from the same device from two + * threads at once does not promise which thread will dequeue data first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before dequeueing; SDL + * handles locking internally for this function. + * + * \param dev the device ID from which we will dequeue audio + * \param data a pointer into where audio data should be copied + * \param len the number of bytes (not samples!) to which (data) points + * \returns the number of bytes dequeued, which could be less than requested; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + +/** + * Get the number of bytes of still-queued audio. + * + * For playback devices: this is the number of bytes that have been queued for + * playback with SDL_QueueAudio(), but have not yet been sent to the hardware. + * + * Once we've sent it to the hardware, this function can not decide the exact + * byte boundary of what has been played. It's possible that we just gave the + * hardware several kilobytes right before you called this function, but it + * hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices, this is the number of bytes that have been captured by + * the device and are waiting for you to dequeue. This number may grow at any + * time, so this only informs of the lower-bound of available data. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before querying; SDL + * handles locking internally for this function. + * + * \param dev the device ID of which we will query queued audio size + * \returns the number of bytes (not samples!) of queued audio. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); + +/** + * Drop any queued audio data waiting to be sent to the hardware. + * + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * output devices, the hardware will start playing silence if more audio isn't + * queued. For capture devices, the hardware will start filling the empty + * queue with new data if the capture device isn't paused. + * + * This will not prevent playback of queued audio that's already been sent to + * the hardware, as we can not undo that, so expect there to be some fraction + * of a second of audio that might still be heard. This can be useful if you + * want to, say, drop any pending music or any unprocessed microphone input + * during a level change in your game. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before clearing the + * queue; SDL handles locking internally for this function. + * + * This function always succeeds and thus returns void. + * + * \param dev the device ID of which to clear the audio queue + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); + + +/** + * \name Audio lock functions + * + * The lock manipulated by these functions protects the callback function. + * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that + * the callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +/* @{ */ + +/** + * This function is a legacy means of locking the audio device. + * + * New programs might want to use SDL_LockAudioDevice() instead. This function + * is equivalent to calling... + * + * ```c + * SDL_LockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + * \sa SDL_UnlockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); + +/** + * Use this function to lock out the audio callback function for a specified + * device. + * + * The lock manipulated by these functions protects the audio callback + * function specified in SDL_OpenAudioDevice(). During a + * SDL_LockAudioDevice()/SDL_UnlockAudioDevice() pair, you can be guaranteed + * that the callback function for that device is not running, even if the + * device is not paused. While a device is locked, any other unpaused, + * unlocked devices may still run their callbacks. + * + * Calling this function from inside your audio callback is unnecessary. SDL + * obtains this lock before calling your function, and releases it when the + * function returns. + * + * You should not hold the lock longer than absolutely necessary. If you hold + * it too long, you'll experience dropouts in your audio playback. Ideally, + * your application locks the device, sets a few variables and unlocks again. + * Do not do heavy work while holding the lock for a device. + * + * It is safe to lock the audio device multiple times, as long as you unlock + * it an equivalent number of times. The callback will not run until the + * device has been unlocked completely in this way. If your application fails + * to unlock the device appropriately, your callback will never run, you might + * hear repeating bursts of audio, and SDL_CloseAudioDevice() will probably + * deadlock. + * + * Internally, the audio device lock is a mutex; if you lock from two threads + * at once, not only will you block the audio callback, you'll block the other + * thread. + * + * \param dev the ID of the device to be locked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); + +/** + * This function is a legacy means of unlocking the audio device. + * + * New programs might want to use SDL_UnlockAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_UnlockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); + +/** + * Use this function to unlock the audio callback function for a specified + * device. + * + * This function should be paired with a previous SDL_LockAudioDevice() call. + * + * \param dev the ID of the device to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); +/* @} *//* Audio lock functions */ + +/** + * This function is a legacy means of closing the audio device. + * + * This function is equivalent to calling... + * + * ```c + * SDL_CloseAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudio + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); + +/** + * Use this function to shut down audio processing and close the audio device. + * + * The application should close open audio devices once they are no longer + * needed. Calling this function will wait until the device's audio callback + * is not running, release the audio hardware and then clean up internal + * state. No further audio will play from this device once this function + * returns. + * + * This function may block briefly while pending audio data is played by the + * hardware, so that applications don't drop the last buffer of data they + * supplied. + * + * The device ID is invalid as soon as the device is closed, and is eligible + * for reuse in a new SDL_OpenAudioDevice() call immediately. + * + * \param dev an audio device previously opened with SDL_OpenAudioDevice() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_audio_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_bits.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_bits.h new file mode 100644 index 000000000..22cb85314 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_bits.h @@ -0,0 +1,126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_bits.h + * + * Functions for fiddling with bits and bitmasks. + */ + +#ifndef SDL_bits_h_ +#define SDL_bits_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_bits.h + */ + +/** + * Get the index of the most significant bit. Result is undefined when called + * with 0. This operation can also be stated as "count leading zeroes" and + * "log base 2". + * + * \return the index of the most significant bit, or -1 if the value is 0. + */ +#if defined(__WATCOMC__) && defined(__386__) +extern __inline int _SDL_bsr_watcom(Uint32); +#pragma aux _SDL_bsr_watcom = \ + "bsr eax, eax" \ + parm [eax] nomemory \ + value [eax] \ + modify exact [eax] nomemory; +#endif + +SDL_FORCE_INLINE int +SDL_MostSignificantBitIndex32(Uint32 x) +{ +#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + /* Count Leading Zeroes builtin in GCC. + * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html + */ + if (x == 0) { + return -1; + } + return 31 - __builtin_clz(x); +#elif defined(__WATCOMC__) && defined(__386__) + if (x == 0) { + return -1; + } + return _SDL_bsr_watcom(x); +#elif defined(_MSC_VER) + unsigned long index; + if (_BitScanReverse(&index, x)) { + return index; + } + return -1; +#else + /* Based off of Bit Twiddling Hacks by Sean Eron Anderson + * , released in the public domain. + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + */ + const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; + const int S[] = {1, 2, 4, 8, 16}; + + int msbIndex = 0; + int i; + + if (x == 0) { + return -1; + } + + for (i = 4; i >= 0; i--) + { + if (x & b[i]) + { + x >>= S[i]; + msbIndex |= S[i]; + } + } + + return msbIndex; +#endif +} + +SDL_FORCE_INLINE SDL_bool +SDL_HasExactlyOneBitSet32(Uint32 x) +{ + if (x && !(x & (x - 1))) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_bits_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_blendmode.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_blendmode.h new file mode 100644 index 000000000..b6d140dbb --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_blendmode.h @@ -0,0 +1,200 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_blendmode.h + * + * Header file declaring the SDL_BlendMode enumeration + */ + +#ifndef SDL_blendmode_h_ +#define SDL_blendmode_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The blend mode used in SDL_RenderCopy() and drawing operations. + */ +typedef enum +{ + SDL_BLENDMODE_NONE = 0x00000000, /**< no blending + dstRGBA = srcRGBA */ + SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) */ + SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending + dstRGB = (srcRGB * srcA) + dstRGB + dstA = dstA */ + SDL_BLENDMODE_MOD = 0x00000004, /**< color modulate + dstRGB = srcRGB * dstRGB + dstA = dstA */ + SDL_BLENDMODE_MUL = 0x00000008, /**< color multiply + dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) + dstA = (srcA * dstA) + (dstA * (1-srcA)) */ + SDL_BLENDMODE_INVALID = 0x7FFFFFFF + + /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ + +} SDL_BlendMode; + +/** + * \brief The blend operation used when combining source and destination pixel components + */ +typedef enum +{ + SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ + SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D11 */ + SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D11 */ + +} SDL_BlendOperation; + +/** + * \brief The normalized factor used to multiply pixel components + */ +typedef enum +{ + SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */ + SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */ + SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */ + SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */ + SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ + SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ + +} SDL_BlendFactor; + +/** + * Compose a custom blend mode for renderers. + * + * The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept + * the SDL_BlendMode returned by this function if the renderer supports it. + * + * A blend mode controls how the pixels from a drawing operation (source) get + * combined with the pixels from the render target (destination). First, the + * components of the source and destination pixels get multiplied with their + * blend factors. Then, the blend operation takes the two products and + * calculates the result that will get stored in the render target. + * + * Expressed in pseudocode, it would look like this: + * + * ```c + * dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); + * dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); + * ``` + * + * Where the functions `colorOperation(src, dst)` and `alphaOperation(src, + * dst)` can return one of the following: + * + * - `src + dst` + * - `src - dst` + * - `dst - src` + * - `min(src, dst)` + * - `max(src, dst)` + * + * The red, green, and blue components are always multiplied with the first, + * second, and third components of the SDL_BlendFactor, respectively. The + * fourth component is not used. + * + * The alpha component is always multiplied with the fourth component of the + * SDL_BlendFactor. The other components are not used in the alpha + * calculation. + * + * Support for these blend modes varies for each renderer. To check if a + * specific SDL_BlendMode is supported, create a renderer and pass it to + * either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will + * return with an error if the blend mode is not supported. + * + * This list describes the support of custom blend modes for each renderer in + * SDL 2.0.6. All renderers support the four blend modes listed in the + * SDL_BlendMode enumeration. + * + * - **direct3d**: Supports `SDL_BLENDOPERATION_ADD` with all factors. + * - **direct3d11**: Supports all operations with all factors. However, some + * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and + * `SDL_BLENDOPERATION_MAXIMUM`. + * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL + * 2.0.6. + * - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. Color and alpha factors need to be the same. OpenGL ES 1 + * implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` + * and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha + * operations being different from each other. May support color and alpha + * factors being different from each other. + * - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, + * `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` + * operations with all factors. + * - **psp**: No custom blend mode support. + * - **software**: No custom blend mode support. + * + * Some renderers do not provide an alpha component for the default render + * target. The `SDL_BLENDFACTOR_DST_ALPHA` and + * `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this + * case. + * + * \param srcColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the source pixels + * \param dstColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the destination pixels + * \param colorOperation the SDL_BlendOperation used to combine the red, + * green, and blue components of the source and + * destination pixels + * \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the source pixels + * \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the destination pixels + * \param alphaOperation the SDL_BlendOperation used to combine the alpha + * component of the source and destination pixels + * \returns an SDL_BlendMode that represents the chosen factors and + * operations. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_SetTextureBlendMode + * \sa SDL_GetTextureBlendMode + */ +extern DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, + SDL_BlendFactor dstColorFactor, + SDL_BlendOperation colorOperation, + SDL_BlendFactor srcAlphaFactor, + SDL_BlendFactor dstAlphaFactor, + SDL_BlendOperation alphaOperation); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_blendmode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_clipboard.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_clipboard.h new file mode 100644 index 000000000..935136305 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_clipboard.h @@ -0,0 +1,94 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef SDL_clipboard_h_ +#define SDL_clipboard_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * Put UTF-8 text into the clipboard. + * + * \param text the text to store in the clipboard + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_HasClipboardText + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * Get UTF-8 text from the clipboard, which must be freed with SDL_free(). + * + * This functions returns empty string if there was not enough memory left for + * a copy of the clipboard's content. + * + * \returns the clipboard text on success or an empty string on failure; call + * SDL_GetError() for more information. Caller must call SDL_free() + * on the returned pointer when done with it (even if there was an + * error). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * Query whether the clipboard exists and contains a non-empty text string. + * + * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_clipboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h new file mode 100644 index 000000000..13014df8f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config.h + */ + +/* Add any platform that doesn't build using the configure system. */ +#if defined(__WIN32__) +#include "SDL_config_windows.h" +#elif defined(__WINRT__) +#include "SDL_config_winrt.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +#elif defined(__IPHONEOS__) +#include "SDL_config_iphoneos.h" +#elif defined(__ANDROID__) +#include "SDL_config_android.h" +#elif defined(__PSP__) +#include "SDL_config_psp.h" +#elif defined(__OS2__) +#include "SDL_config_os2.h" +#elif defined(__EMSCRIPTEN__) +#include "SDL_config_emscripten.h" +#else +/* This is a minimal configuration just to get SDL running on new platforms. */ +#include "SDL_config_minimal.h" +#endif /* platform config */ + +#ifdef USING_GENERATED_CONFIG_H +#error Wrong SDL_config.h, check your include path? +#endif + +#endif /* SDL_config_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.cmake b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.cmake new file mode 100644 index 000000000..7f96bbe2f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.cmake @@ -0,0 +1,575 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_h_ +#define SDL_config_h_ + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* C language features */ +#cmakedefine const @HAVE_CONST@ +#cmakedefine inline @HAVE_INLINE@ +#cmakedefine volatile @HAVE_VOLATILE@ + +/* C datatypes */ +/* Define SIZEOF_VOIDP for 64/32 architectures */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#cmakedefine HAVE_GCC_ATOMICS @HAVE_GCC_ATOMICS@ +#cmakedefine HAVE_GCC_SYNC_LOCK_TEST_AND_SET @HAVE_GCC_SYNC_LOCK_TEST_AND_SET@ + +/* Comment this if you want to build without any C library requirements */ +#cmakedefine HAVE_LIBC 1 +#if HAVE_LIBC + +/* Useful headers */ +#cmakedefine STDC_HEADERS 1 +#cmakedefine HAVE_ALLOCA_H 1 +#cmakedefine HAVE_CTYPE_H 1 +#cmakedefine HAVE_FLOAT_H 1 +#cmakedefine HAVE_ICONV_H 1 +#cmakedefine HAVE_INTTYPES_H 1 +#cmakedefine HAVE_LIMITS_H 1 +#cmakedefine HAVE_MALLOC_H 1 +#cmakedefine HAVE_MATH_H 1 +#cmakedefine HAVE_MEMORY_H 1 +#cmakedefine HAVE_SIGNAL_H 1 +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_STDIO_H 1 +#cmakedefine HAVE_STDLIB_H 1 +#cmakedefine HAVE_STRINGS_H 1 +#cmakedefine HAVE_STRING_H 1 +#cmakedefine HAVE_SYS_TYPES_H 1 +#cmakedefine HAVE_WCHAR_H 1 +#cmakedefine HAVE_PTHREAD_NP_H 1 +#cmakedefine HAVE_LIBUNWIND_H 1 + +/* C library functions */ +#cmakedefine HAVE_DLOPEN 1 +#cmakedefine HAVE_MALLOC 1 +#cmakedefine HAVE_CALLOC 1 +#cmakedefine HAVE_REALLOC 1 +#cmakedefine HAVE_FREE 1 +#cmakedefine HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#cmakedefine HAVE_GETENV 1 +#cmakedefine HAVE_SETENV 1 +#cmakedefine HAVE_PUTENV 1 +#cmakedefine HAVE_UNSETENV 1 +#endif +#cmakedefine HAVE_QSORT 1 +#cmakedefine HAVE_ABS 1 +#cmakedefine HAVE_BCOPY 1 +#cmakedefine HAVE_MEMSET 1 +#cmakedefine HAVE_MEMCPY 1 +#cmakedefine HAVE_MEMMOVE 1 +#cmakedefine HAVE_MEMCMP 1 +#cmakedefine HAVE_WCSLEN 1 +#cmakedefine HAVE_WCSLCPY 1 +#cmakedefine HAVE_WCSLCAT 1 +#cmakedefine HAVE__WCSDUP 1 +#cmakedefine HAVE_WCSDUP 1 +#cmakedefine HAVE_WCSSTR 1 +#cmakedefine HAVE_WCSCMP 1 +#cmakedefine HAVE_WCSNCMP 1 +#cmakedefine HAVE_WCSCASECMP 1 +#cmakedefine HAVE__WCSICMP 1 +#cmakedefine HAVE_WCSNCASECMP 1 +#cmakedefine HAVE__WCSNICMP 1 +#cmakedefine HAVE_STRLEN 1 +#cmakedefine HAVE_STRLCPY 1 +#cmakedefine HAVE_STRLCAT 1 +#cmakedefine HAVE__STRREV 1 +#cmakedefine HAVE__STRUPR 1 +#cmakedefine HAVE__STRLWR 1 +#cmakedefine HAVE_INDEX 1 +#cmakedefine HAVE_RINDEX 1 +#cmakedefine HAVE_STRCHR 1 +#cmakedefine HAVE_STRRCHR 1 +#cmakedefine HAVE_STRSTR 1 +#cmakedefine HAVE_STRTOK_R 1 +#cmakedefine HAVE_ITOA 1 +#cmakedefine HAVE__LTOA 1 +#cmakedefine HAVE__UITOA 1 +#cmakedefine HAVE__ULTOA 1 +#cmakedefine HAVE_STRTOL 1 +#cmakedefine HAVE_STRTOUL 1 +#cmakedefine HAVE__I64TOA 1 +#cmakedefine HAVE__UI64TOA 1 +#cmakedefine HAVE_STRTOLL 1 +#cmakedefine HAVE_STRTOULL 1 +#cmakedefine HAVE_STRTOD 1 +#cmakedefine HAVE_ATOI 1 +#cmakedefine HAVE_ATOF 1 +#cmakedefine HAVE_STRCMP 1 +#cmakedefine HAVE_STRNCMP 1 +#cmakedefine HAVE__STRICMP 1 +#cmakedefine HAVE_STRCASECMP 1 +#cmakedefine HAVE__STRNICMP 1 +#cmakedefine HAVE_STRNCASECMP 1 +#cmakedefine HAVE_SSCANF 1 +#cmakedefine HAVE_VSSCANF 1 +#cmakedefine HAVE_VSNPRINTF 1 +#cmakedefine HAVE_M_PI 1 +#cmakedefine HAVE_ACOS 1 +#cmakedefine HAVE_ACOSF 1 +#cmakedefine HAVE_ASIN 1 +#cmakedefine HAVE_ASINF 1 +#cmakedefine HAVE_ATAN 1 +#cmakedefine HAVE_ATANF 1 +#cmakedefine HAVE_ATAN2 1 +#cmakedefine HAVE_ATAN2F 1 +#cmakedefine HAVE_CEIL 1 +#cmakedefine HAVE_CEILF 1 +#cmakedefine HAVE_COPYSIGN 1 +#cmakedefine HAVE_COPYSIGNF 1 +#cmakedefine HAVE_COS 1 +#cmakedefine HAVE_COSF 1 +#cmakedefine HAVE_EXP 1 +#cmakedefine HAVE_EXPF 1 +#cmakedefine HAVE_FABS 1 +#cmakedefine HAVE_FABSF 1 +#cmakedefine HAVE_FLOOR 1 +#cmakedefine HAVE_FLOORF 1 +#cmakedefine HAVE_FMOD 1 +#cmakedefine HAVE_FMODF 1 +#cmakedefine HAVE_LOG 1 +#cmakedefine HAVE_LOGF 1 +#cmakedefine HAVE_LOG10 1 +#cmakedefine HAVE_LOG10F 1 +#cmakedefine HAVE_LROUND 1 +#cmakedefine HAVE_LROUNDF 1 +#cmakedefine HAVE_POW 1 +#cmakedefine HAVE_POWF 1 +#cmakedefine HAVE_ROUND 1 +#cmakedefine HAVE_ROUNDF 1 +#cmakedefine HAVE_SCALBN 1 +#cmakedefine HAVE_SCALBNF 1 +#cmakedefine HAVE_SIN 1 +#cmakedefine HAVE_SINF 1 +#cmakedefine HAVE_SQRT 1 +#cmakedefine HAVE_SQRTF 1 +#cmakedefine HAVE_TAN 1 +#cmakedefine HAVE_TANF 1 +#cmakedefine HAVE_TRUNC 1 +#cmakedefine HAVE_TRUNCF 1 +#cmakedefine HAVE_FOPEN64 1 +#cmakedefine HAVE_FSEEKO 1 +#cmakedefine HAVE_FSEEKO64 1 +#cmakedefine HAVE_SIGACTION 1 +#cmakedefine HAVE_SA_SIGACTION 1 +#cmakedefine HAVE_SETJMP 1 +#cmakedefine HAVE_NANOSLEEP 1 +#cmakedefine HAVE_SYSCONF 1 +#cmakedefine HAVE_SYSCTLBYNAME 1 +#cmakedefine HAVE_CLOCK_GETTIME 1 +#cmakedefine HAVE_GETPAGESIZE 1 +#cmakedefine HAVE_MPROTECT 1 +#cmakedefine HAVE_ICONV 1 +#cmakedefine HAVE_PTHREAD_SETNAME_NP 1 +#cmakedefine HAVE_PTHREAD_SET_NAME_NP 1 +#cmakedefine HAVE_SEM_TIMEDWAIT 1 +#cmakedefine HAVE_GETAUXVAL 1 +#cmakedefine HAVE_ELF_AUX_INFO 1 +#cmakedefine HAVE_POLL 1 +#cmakedefine HAVE__EXIT 1 + +#elif defined(__WIN32__) +#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDDEF_H 1 +#cmakedefine HAVE_FLOAT_H 1 + +#else +/* We may need some replacement for stdarg.h here */ +#include +#endif /* HAVE_LIBC */ + +#cmakedefine HAVE_ALTIVEC_H 1 +#cmakedefine HAVE_DBUS_DBUS_H 1 +#cmakedefine HAVE_FCITX 1 +#cmakedefine HAVE_IBUS_IBUS_H 1 +#cmakedefine HAVE_SYS_INOTIFY_H 1 +#cmakedefine HAVE_INOTIFY_INIT 1 +#cmakedefine HAVE_INOTIFY_INIT1 1 +#cmakedefine HAVE_INOTIFY 1 +#cmakedefine HAVE_O_CLOEXEC 1 + +/* Apple platforms might be building universal binaries, where Intel builds + can use immintrin.h but other architectures can't. */ +#ifdef __APPLE__ +# if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +# endif +#else /* non-Apple platforms can use the normal CMake check for this. */ +#cmakedefine HAVE_IMMINTRIN_H 1 +#endif + +#cmakedefine HAVE_LIBUDEV_H 1 +#cmakedefine HAVE_LIBSAMPLERATE_H 1 +#cmakedefine HAVE_LIBDECOR_H 1 + +#cmakedefine HAVE_D3D_H @HAVE_D3D_H@ +#cmakedefine HAVE_D3D11_H @HAVE_D3D11_H@ +#cmakedefine HAVE_DDRAW_H @HAVE_DDRAW_H@ +#cmakedefine HAVE_DSOUND_H @HAVE_DSOUND_H@ +#cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@ +#cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@ +#cmakedefine HAVE_WINDOWS_GAMING_INPUT_H @HAVE_WINDOWS_GAMING_INPUT_H@ +#cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@ + +#cmakedefine HAVE_MMDEVICEAPI_H @HAVE_MMDEVICEAPI_H@ +#cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@ +#cmakedefine HAVE_TPCSHRD_H @HAVE_TPCSHRD_H@ +#cmakedefine HAVE_SENSORSAPI_H @HAVE_SENSORSAPI_H@ + +#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@ +#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@ + +/* SDL internal assertion support */ +#cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@ + +/* Allow disabling of core subsystems */ +#cmakedefine SDL_ATOMIC_DISABLED @SDL_ATOMIC_DISABLED@ +#cmakedefine SDL_AUDIO_DISABLED @SDL_AUDIO_DISABLED@ +#cmakedefine SDL_CPUINFO_DISABLED @SDL_CPUINFO_DISABLED@ +#cmakedefine SDL_EVENTS_DISABLED @SDL_EVENTS_DISABLED@ +#cmakedefine SDL_FILE_DISABLED @SDL_FILE_DISABLED@ +#cmakedefine SDL_JOYSTICK_DISABLED @SDL_JOYSTICK_DISABLED@ +#cmakedefine SDL_HAPTIC_DISABLED @SDL_HAPTIC_DISABLED@ +#cmakedefine SDL_HIDAPI_DISABLED @SDL_HIDAPI_DISABLED@ +#cmakedefine SDL_SENSOR_DISABLED @SDL_SENSOR_DISABLED@ +#cmakedefine SDL_LOADSO_DISABLED @SDL_LOADSO_DISABLED@ +#cmakedefine SDL_RENDER_DISABLED @SDL_RENDER_DISABLED@ +#cmakedefine SDL_THREADS_DISABLED @SDL_THREADS_DISABLED@ +#cmakedefine SDL_TIMERS_DISABLED @SDL_TIMERS_DISABLED@ +#cmakedefine SDL_VIDEO_DISABLED @SDL_VIDEO_DISABLED@ +#cmakedefine SDL_POWER_DISABLED @SDL_POWER_DISABLED@ +#cmakedefine SDL_FILESYSTEM_DISABLED @SDL_FILESYSTEM_DISABLED@ + +/* Enable various audio drivers */ +#cmakedefine SDL_AUDIO_DRIVER_ALSA @SDL_AUDIO_DRIVER_ALSA@ +#cmakedefine SDL_AUDIO_DRIVER_ALSA_DYNAMIC @SDL_AUDIO_DRIVER_ALSA_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_ANDROID @SDL_AUDIO_DRIVER_ANDROID@ +#cmakedefine SDL_AUDIO_DRIVER_OPENSLES @SDL_AUDIO_DRIVER_OPENSLES@ +#cmakedefine SDL_AUDIO_DRIVER_AAUDIO @SDL_AUDIO_DRIVER_AAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS @SDL_AUDIO_DRIVER_ARTS@ +#cmakedefine SDL_AUDIO_DRIVER_ARTS_DYNAMIC @SDL_AUDIO_DRIVER_ARTS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_COREAUDIO @SDL_AUDIO_DRIVER_COREAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_DISK @SDL_AUDIO_DRIVER_DISK@ +#cmakedefine SDL_AUDIO_DRIVER_DSOUND @SDL_AUDIO_DRIVER_DSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_DUMMY @SDL_AUDIO_DRIVER_DUMMY@ +#cmakedefine SDL_AUDIO_DRIVER_EMSCRIPTEN @SDL_AUDIO_DRIVER_EMSCRIPTEN@ +#cmakedefine SDL_AUDIO_DRIVER_ESD @SDL_AUDIO_DRIVER_ESD@ +#cmakedefine SDL_AUDIO_DRIVER_ESD_DYNAMIC @SDL_AUDIO_DRIVER_ESD_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@ +#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_HAIKU @SDL_AUDIO_DRIVER_HAIKU@ +#cmakedefine SDL_AUDIO_DRIVER_JACK @SDL_AUDIO_DRIVER_JACK@ +#cmakedefine SDL_AUDIO_DRIVER_JACK_DYNAMIC @SDL_AUDIO_DRIVER_JACK_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NAS @SDL_AUDIO_DRIVER_NAS@ +#cmakedefine SDL_AUDIO_DRIVER_NAS_DYNAMIC @SDL_AUDIO_DRIVER_NAS_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_NETBSD @SDL_AUDIO_DRIVER_NETBSD@ +#cmakedefine SDL_AUDIO_DRIVER_OSS @SDL_AUDIO_DRIVER_OSS@ +#cmakedefine SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H @SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H@ +#cmakedefine SDL_AUDIO_DRIVER_PAUDIO @SDL_AUDIO_DRIVER_PAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_PIPEWIRE @SDL_AUDIO_DRIVER_PIPEWIRE@ +#cmakedefine SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC @SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO @SDL_AUDIO_DRIVER_PULSEAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC @SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_QSA @SDL_AUDIO_DRIVER_QSA@ +#cmakedefine SDL_AUDIO_DRIVER_SNDIO @SDL_AUDIO_DRIVER_SNDIO@ +#cmakedefine SDL_AUDIO_DRIVER_SNDIO_DYNAMIC @SDL_AUDIO_DRIVER_SNDIO_DYNAMIC@ +#cmakedefine SDL_AUDIO_DRIVER_SUNAUDIO @SDL_AUDIO_DRIVER_SUNAUDIO@ +#cmakedefine SDL_AUDIO_DRIVER_WASAPI @SDL_AUDIO_DRIVER_WASAPI@ +#cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@ +#cmakedefine SDL_AUDIO_DRIVER_OS2 @SDL_AUDIO_DRIVER_OS2@ +#cmakedefine SDL_AUDIO_DRIVER_VITA @SDL_AUDIO_DRIVER_VITA@ +#cmakedefine SDL_AUDIO_DRIVER_PSP @SDL_AUDIO_DRIVER_PSP@ + +/* Enable various input drivers */ +#cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@ +#cmakedefine SDL_INPUT_LINUXKD @SDL_INPUT_LINUXKD@ +#cmakedefine SDL_INPUT_FBSDKBIO @SDL_INPUT_FBSDKBIO@ +#cmakedefine SDL_JOYSTICK_ANDROID @SDL_JOYSTICK_ANDROID@ +#cmakedefine SDL_JOYSTICK_HAIKU @SDL_JOYSTICK_HAIKU@ +#cmakedefine SDL_JOYSTICK_WGI @SDL_JOYSTICK_WGI@ +#cmakedefine SDL_JOYSTICK_DINPUT @SDL_JOYSTICK_DINPUT@ +#cmakedefine SDL_JOYSTICK_XINPUT @SDL_JOYSTICK_XINPUT@ +#cmakedefine SDL_JOYSTICK_DUMMY @SDL_JOYSTICK_DUMMY@ +#cmakedefine SDL_JOYSTICK_IOKIT @SDL_JOYSTICK_IOKIT@ +#cmakedefine SDL_JOYSTICK_MFI @SDL_JOYSTICK_MFI@ +#cmakedefine SDL_JOYSTICK_LINUX @SDL_JOYSTICK_LINUX@ +#cmakedefine SDL_JOYSTICK_OS2 @SDL_JOYSTICK_OS2@ +#cmakedefine SDL_JOYSTICK_USBHID @SDL_JOYSTICK_USBHID@ +#cmakedefine SDL_HAVE_MACHINE_JOYSTICK_H @SDL_HAVE_MACHINE_JOYSTICK_H@ +#cmakedefine SDL_JOYSTICK_HIDAPI @SDL_JOYSTICK_HIDAPI@ +#cmakedefine SDL_JOYSTICK_RAWINPUT @SDL_JOYSTICK_RAWINPUT@ +#cmakedefine SDL_JOYSTICK_EMSCRIPTEN @SDL_JOYSTICK_EMSCRIPTEN@ +#cmakedefine SDL_JOYSTICK_VIRTUAL @SDL_JOYSTICK_VIRTUAL@ +#cmakedefine SDL_JOYSTICK_VITA @SDL_JOYSTICK_VITA@ +#cmakedefine SDL_JOYSTICK_PSP @SDL_JOYSTICK_PSP@ +#cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@ +#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@ +#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@ +#cmakedefine SDL_HAPTIC_DINPUT @SDL_HAPTIC_DINPUT@ +#cmakedefine SDL_HAPTIC_XINPUT @SDL_HAPTIC_XINPUT@ +#cmakedefine SDL_HAPTIC_ANDROID @SDL_HAPTIC_ANDROID@ +#cmakedefine SDL_LIBUSB_DYNAMIC @SDL_LIBUSB_DYNAMIC@ + +/* Enable various sensor drivers */ +#cmakedefine SDL_SENSOR_ANDROID @SDL_SENSOR_ANDROID@ +#cmakedefine SDL_SENSOR_COREMOTION @SDL_SENSOR_COREMOTION@ +#cmakedefine SDL_SENSOR_WINDOWS @SDL_SENSOR_WINDOWS@ +#cmakedefine SDL_SENSOR_DUMMY @SDL_SENSOR_DUMMY@ +#cmakedefine SDL_SENSOR_VITA @SDL_SENSOR_VITA@ + +/* Enable various shared object loading systems */ +#cmakedefine SDL_LOADSO_DLOPEN @SDL_LOADSO_DLOPEN@ +#cmakedefine SDL_LOADSO_DUMMY @SDL_LOADSO_DUMMY@ +#cmakedefine SDL_LOADSO_LDG @SDL_LOADSO_LDG@ +#cmakedefine SDL_LOADSO_WINDOWS @SDL_LOADSO_WINDOWS@ +#cmakedefine SDL_LOADSO_OS2 @SDL_LOADSO_OS2@ + +/* Enable various threading systems */ +#cmakedefine SDL_THREAD_GENERIC_COND_SUFFIX @SDL_THREAD_GENERIC_COND_SUFFIX@ +#cmakedefine SDL_THREAD_PTHREAD @SDL_THREAD_PTHREAD@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX@ +#cmakedefine SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP @SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP@ +#cmakedefine SDL_THREAD_WINDOWS @SDL_THREAD_WINDOWS@ +#cmakedefine SDL_THREAD_OS2 @SDL_THREAD_OS2@ +#cmakedefine SDL_THREAD_VITA @SDL_THREAD_VITA@ +#cmakedefine SDL_THREAD_PSP @SDL_THREAD_PSP@ + +/* Enable various timer systems */ +#cmakedefine SDL_TIMER_HAIKU @SDL_TIMER_HAIKU@ +#cmakedefine SDL_TIMER_DUMMY @SDL_TIMER_DUMMY@ +#cmakedefine SDL_TIMER_UNIX @SDL_TIMER_UNIX@ +#cmakedefine SDL_TIMER_WINDOWS @SDL_TIMER_WINDOWS@ +#cmakedefine SDL_TIMER_OS2 @SDL_TIMER_OS2@ +#cmakedefine SDL_TIMER_VITA @SDL_TIMER_VITA@ +#cmakedefine SDL_TIMER_PSP @SDL_TIMER_PSP@ + +/* Enable various video drivers */ +#cmakedefine SDL_VIDEO_DRIVER_ANDROID @SDL_VIDEO_DRIVER_ANDROID@ +#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@ +#cmakedefine SDL_VIDEO_DRIVER_HAIKU @SDL_VIDEO_DRIVER_HAIKU@ +#cmakedefine SDL_VIDEO_DRIVER_COCOA @SDL_VIDEO_DRIVER_COCOA@ +#cmakedefine SDL_VIDEO_DRIVER_UIKIT @SDL_VIDEO_DRIVER_UIKIT@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB @SDL_VIDEO_DRIVER_DIRECTFB@ +#cmakedefine SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC @SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ +#cmakedefine SDL_VIDEO_DRIVER_OFFSCREEN @SDL_VIDEO_DRIVER_OFFSCREEN@ +#cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ +#cmakedefine SDL_VIDEO_DRIVER_WINRT @SDL_VIDEO_DRIVER_WINRT@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@ +#cmakedefine SDL_VIDEO_DRIVER_RPI @SDL_VIDEO_DRIVER_RPI@ +#cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@ +#cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@ +#cmakedefine SDL_VIDEO_DRIVER_OS2 @SDL_VIDEO_DRIVER_OS2@ +#cmakedefine SDL_VIDEO_DRIVER_QNX @SDL_VIDEO_DRIVER_QNX@ +#cmakedefine SDL_VIDEO_DRIVER_RISCOS @SDL_VIDEO_DRIVER_RISCOS@ +#cmakedefine SDL_VIDEO_DRIVER_PSP @SDL_VIDEO_DRIVER_PSP@ + +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM @SDL_VIDEO_DRIVER_KMSDRM@ +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM @SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM@ + +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@ +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR@ + +#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES @SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS @SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE @SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XCURSOR @SDL_VIDEO_DRIVER_X11_XCURSOR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XDBE @SDL_VIDEO_DRIVER_X11_XDBE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINERAMA @SDL_VIDEO_DRIVER_X11_XINERAMA@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2 @SDL_VIDEO_DRIVER_X11_XINPUT2@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH @SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XFIXES @SDL_VIDEO_DRIVER_X11_XFIXES@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XRANDR @SDL_VIDEO_DRIVER_X11_XRANDR@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSCRNSAVER @SDL_VIDEO_DRIVER_X11_XSCRNSAVER@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XSHAPE @SDL_VIDEO_DRIVER_X11_XSHAPE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_XVIDMODE @SDL_VIDEO_DRIVER_X11_XVIDMODE@ +#cmakedefine SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS @SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS@ +#cmakedefine SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM @SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM@ +#cmakedefine SDL_VIDEO_DRIVER_VITA @SDL_VIDEO_DRIVER_VITA@ + +#cmakedefine SDL_VIDEO_RENDER_D3D @SDL_VIDEO_RENDER_D3D@ +#cmakedefine SDL_VIDEO_RENDER_D3D11 @SDL_VIDEO_RENDER_D3D11@ +#cmakedefine SDL_VIDEO_RENDER_OGL @SDL_VIDEO_RENDER_OGL@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES @SDL_VIDEO_RENDER_OGL_ES@ +#cmakedefine SDL_VIDEO_RENDER_OGL_ES2 @SDL_VIDEO_RENDER_OGL_ES2@ +#cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@ +#cmakedefine SDL_VIDEO_RENDER_METAL @SDL_VIDEO_RENDER_METAL@ +#cmakedefine SDL_VIDEO_RENDER_VITA_GXM @SDL_VIDEO_RENDER_VITA_GXM@ +#cmakedefine SDL_VIDEO_RENDER_PSP @SDL_VIDEO_RENDER_PSP@ + +/* Enable OpenGL support */ +#cmakedefine SDL_VIDEO_OPENGL @SDL_VIDEO_OPENGL@ +#cmakedefine SDL_VIDEO_OPENGL_ES @SDL_VIDEO_OPENGL_ES@ +#cmakedefine SDL_VIDEO_OPENGL_ES2 @SDL_VIDEO_OPENGL_ES2@ +#cmakedefine SDL_VIDEO_OPENGL_BGL @SDL_VIDEO_OPENGL_BGL@ +#cmakedefine SDL_VIDEO_OPENGL_CGL @SDL_VIDEO_OPENGL_CGL@ +#cmakedefine SDL_VIDEO_OPENGL_GLX @SDL_VIDEO_OPENGL_GLX@ +#cmakedefine SDL_VIDEO_OPENGL_WGL @SDL_VIDEO_OPENGL_WGL@ +#cmakedefine SDL_VIDEO_OPENGL_EGL @SDL_VIDEO_OPENGL_EGL@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA @SDL_VIDEO_OPENGL_OSMESA@ +#cmakedefine SDL_VIDEO_OPENGL_OSMESA_DYNAMIC @SDL_VIDEO_OPENGL_OSMESA_DYNAMIC@ + +/* Enable Vulkan support */ +#cmakedefine SDL_VIDEO_VULKAN @SDL_VIDEO_VULKAN@ + +/* Enable Metal support */ +#cmakedefine SDL_VIDEO_METAL @SDL_VIDEO_METAL@ + +/* Enable system power support */ +#cmakedefine SDL_POWER_ANDROID @SDL_POWER_ANDROID@ +#cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@ +#cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@ +#cmakedefine SDL_POWER_WINRT @SDL_POWER_WINRT@ +#cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@ +#cmakedefine SDL_POWER_UIKIT @SDL_POWER_UIKIT@ +#cmakedefine SDL_POWER_HAIKU @SDL_POWER_HAIKU@ +#cmakedefine SDL_POWER_EMSCRIPTEN @SDL_POWER_EMSCRIPTEN@ +#cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@ +#cmakedefine SDL_POWER_VITA @SDL_POWER_VITA@ +#cmakedefine SDL_POWER_PSP @SDL_POWER_PSP@ + +/* Enable system filesystem support */ +#cmakedefine SDL_FILESYSTEM_ANDROID @SDL_FILESYSTEM_ANDROID@ +#cmakedefine SDL_FILESYSTEM_HAIKU @SDL_FILESYSTEM_HAIKU@ +#cmakedefine SDL_FILESYSTEM_COCOA @SDL_FILESYSTEM_COCOA@ +#cmakedefine SDL_FILESYSTEM_DUMMY @SDL_FILESYSTEM_DUMMY@ +#cmakedefine SDL_FILESYSTEM_RISCOS @SDL_FILESYSTEM_RISCOS@ +#cmakedefine SDL_FILESYSTEM_UNIX @SDL_FILESYSTEM_UNIX@ +#cmakedefine SDL_FILESYSTEM_WINDOWS @SDL_FILESYSTEM_WINDOWS@ +#cmakedefine SDL_FILESYSTEM_EMSCRIPTEN @SDL_FILESYSTEM_EMSCRIPTEN@ +#cmakedefine SDL_FILESYSTEM_OS2 @SDL_FILESYSTEM_OS2@ +#cmakedefine SDL_FILESYSTEM_VITA @SDL_FILESYSTEM_VITA@ +#cmakedefine SDL_FILESYSTEM_PSP @SDL_FILESYSTEM_PSP@ + +/* Enable assembly routines */ +#cmakedefine SDL_ASSEMBLY_ROUTINES @SDL_ASSEMBLY_ROUTINES@ +#cmakedefine SDL_ALTIVEC_BLITTERS @SDL_ALTIVEC_BLITTERS@ +#cmakedefine SDL_ARM_SIMD_BLITTERS @SDL_ARM_SIMD_BLITTERS@ +#cmakedefine SDL_ARM_NEON_BLITTERS @SDL_ARM_NEON_BLITTERS@ + +/* Whether SDL_DYNAMIC_API needs dlopen */ +#cmakedefine DYNAPI_NEEDS_DLOPEN @DYNAPI_NEEDS_DLOPEN@ + +/* Enable dynamic libsamplerate support */ +#cmakedefine SDL_LIBSAMPLERATE_DYNAMIC @SDL_LIBSAMPLERATE_DYNAMIC@ + +/* Enable ime support */ +#cmakedefine SDL_USE_IME @SDL_USE_IME@ + +/* Platform specific definitions */ +#cmakedefine SDL_IPHONE_KEYBOARD @SDL_IPHONE_KEYBOARD@ +#cmakedefine SDL_IPHONE_LAUNCHSCREEN @SDL_IPHONE_LAUNCHSCREEN@ + +#cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@ +#cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@ + +#if !defined(__WIN32__) && !defined(__WINRT__) +# if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +# endif /* if (stdint.h isn't available) */ +#else /* __WIN32__ */ +# if !defined(_STDINT_H_) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) +# if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__CODEGEARC__) +#define HAVE_STDINT_H 1 +# elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +# ifndef _UINTPTR_T_DEFINED +# ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +# else +typedef unsigned int uintptr_t; +# endif +#define _UINTPTR_T_DEFINED +# endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +# if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +# endif +# if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +# endif +# else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +# ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +# endif +typedef unsigned int uintptr_t; +# endif /* __GNUC__ || _MSC_VER */ +# endif /* !_STDINT_H_ && !HAVE_STDINT_H */ +#endif /* __WIN32__ */ + +#endif /* SDL_config_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.in b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.in new file mode 100644 index 000000000..0d981b410 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config.h.in @@ -0,0 +1,480 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_h_ +#define SDL_config_h_ + +/** + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features + */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* Make sure that this isn't included by Visual C++ */ +#ifdef _MSC_VER +#error You should run git checkout -f include/SDL_config.h +#endif + +/* C language features */ +#undef const +#undef inline +#undef volatile + +/* C datatypes */ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#undef HAVE_GCC_ATOMICS +#undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET + +/* Comment this if you want to build without any C library requirements */ +#undef HAVE_LIBC +#if HAVE_LIBC + +/* Useful headers */ +#undef STDC_HEADERS +#undef HAVE_ALLOCA_H +#undef HAVE_CTYPE_H +#undef HAVE_FLOAT_H +#undef HAVE_ICONV_H +#undef HAVE_INTTYPES_H +#undef HAVE_LIMITS_H +#undef HAVE_MALLOC_H +#undef HAVE_MATH_H +#undef HAVE_MEMORY_H +#undef HAVE_SIGNAL_H +#undef HAVE_STDARG_H +#undef HAVE_STDINT_H +#undef HAVE_STDIO_H +#undef HAVE_STDLIB_H +#undef HAVE_STRINGS_H +#undef HAVE_STRING_H +#undef HAVE_SYS_TYPES_H +#undef HAVE_WCHAR_H +#undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUNWIND_H + +/* C library functions */ +#undef HAVE_DLOPEN +#undef HAVE_MALLOC +#undef HAVE_CALLOC +#undef HAVE_REALLOC +#undef HAVE_FREE +#undef HAVE_ALLOCA +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#undef HAVE_GETENV +#undef HAVE_SETENV +#undef HAVE_PUTENV +#undef HAVE_UNSETENV +#endif +#undef HAVE_QSORT +#undef HAVE_ABS +#undef HAVE_BCOPY +#undef HAVE_MEMSET +#undef HAVE_MEMCPY +#undef HAVE_MEMMOVE +#undef HAVE_MEMCMP +#undef HAVE_WCSLEN +#undef HAVE_WCSLCPY +#undef HAVE_WCSLCAT +#undef HAVE__WCSDUP +#undef HAVE_WCSDUP +#undef HAVE_WCSSTR +#undef HAVE_WCSCMP +#undef HAVE_WCSNCMP +#undef HAVE_WCSCASECMP +#undef HAVE__WCSICMP +#undef HAVE_WCSNCASECMP +#undef HAVE__WCSNICMP +#undef HAVE_STRLEN +#undef HAVE_STRLCPY +#undef HAVE_STRLCAT +#undef HAVE__STRREV +#undef HAVE__STRUPR +#undef HAVE__STRLWR +#undef HAVE_INDEX +#undef HAVE_RINDEX +#undef HAVE_STRCHR +#undef HAVE_STRRCHR +#undef HAVE_STRSTR +#undef HAVE_STRTOK_R +#undef HAVE_ITOA +#undef HAVE__LTOA +#undef HAVE__UITOA +#undef HAVE__ULTOA +#undef HAVE_STRTOL +#undef HAVE_STRTOUL +#undef HAVE__I64TOA +#undef HAVE__UI64TOA +#undef HAVE_STRTOLL +#undef HAVE_STRTOULL +#undef HAVE_STRTOD +#undef HAVE_ATOI +#undef HAVE_ATOF +#undef HAVE_STRCMP +#undef HAVE_STRNCMP +#undef HAVE__STRICMP +#undef HAVE_STRCASECMP +#undef HAVE__STRNICMP +#undef HAVE_STRNCASECMP +#undef HAVE_SSCANF +#undef HAVE_VSSCANF +#undef HAVE_SNPRINTF +#undef HAVE_VSNPRINTF +#undef HAVE_M_PI +#undef HAVE_ACOS +#undef HAVE_ACOSF +#undef HAVE_ASIN +#undef HAVE_ASINF +#undef HAVE_ATAN +#undef HAVE_ATANF +#undef HAVE_ATAN2 +#undef HAVE_ATAN2F +#undef HAVE_CEIL +#undef HAVE_CEILF +#undef HAVE_COPYSIGN +#undef HAVE_COPYSIGNF +#undef HAVE_COS +#undef HAVE_COSF +#undef HAVE_EXP +#undef HAVE_EXPF +#undef HAVE_FABS +#undef HAVE_FABSF +#undef HAVE_FLOOR +#undef HAVE_FLOORF +#undef HAVE_FMOD +#undef HAVE_FMODF +#undef HAVE_LOG +#undef HAVE_LOGF +#undef HAVE_LOG10 +#undef HAVE_LOG10F +#undef HAVE_LROUND +#undef HAVE_LROUNDF +#undef HAVE_POW +#undef HAVE_POWF +#undef HAVE_ROUND +#undef HAVE_ROUNDF +#undef HAVE_SCALBN +#undef HAVE_SCALBNF +#undef HAVE_SIN +#undef HAVE_SINF +#undef HAVE_SQRT +#undef HAVE_SQRTF +#undef HAVE_TAN +#undef HAVE_TANF +#undef HAVE_TRUNC +#undef HAVE_TRUNCF +#undef HAVE_FOPEN64 +#undef HAVE_FSEEKO +#undef HAVE_FSEEKO64 +#undef HAVE_SIGACTION +#undef HAVE_SA_SIGACTION +#undef HAVE_SETJMP +#undef HAVE_NANOSLEEP +#undef HAVE_SYSCONF +#undef HAVE_SYSCTLBYNAME +#undef HAVE_CLOCK_GETTIME +#undef HAVE_GETPAGESIZE +#undef HAVE_MPROTECT +#undef HAVE_ICONV +#undef HAVE_PTHREAD_SETNAME_NP +#undef HAVE_PTHREAD_SET_NAME_NP +#undef HAVE_SEM_TIMEDWAIT +#undef HAVE_GETAUXVAL +#undef HAVE_ELF_AUX_INFO +#undef HAVE_POLL +#undef HAVE__EXIT + +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#endif /* HAVE_LIBC */ + +#undef HAVE_O_CLOEXEC +#undef HAVE_ALTIVEC_H +#undef HAVE_DBUS_DBUS_H +#undef HAVE_FCITX +#undef HAVE_SYS_INOTIFY_H +#undef HAVE_INOTIFY_INIT +#undef HAVE_INOTIFY_INIT1 +#undef HAVE_INOTIFY +#undef HAVE_IBUS_IBUS_H +#undef HAVE_IMMINTRIN_H +#undef HAVE_LIBUDEV_H +#undef HAVE_LIBSAMPLERATE_H +#undef HAVE_LIBDECOR_H + +#undef HAVE_DDRAW_H +#undef HAVE_DINPUT_H +#undef HAVE_DSOUND_H +#undef HAVE_DXGI_H +#undef HAVE_WINDOWS_GAMING_INPUT_H +#undef HAVE_XINPUT_H +#undef HAVE_XINPUT_GAMEPAD_EX +#undef HAVE_XINPUT_STATE_EX + +#undef HAVE_MMDEVICEAPI_H +#undef HAVE_AUDIOCLIENT_H +#undef HAVE_TPCSHRD_H +#undef HAVE_SENSORSAPI_H + +/* SDL internal assertion support */ +#undef SDL_DEFAULT_ASSERT_LEVEL + +/* Allow disabling of core subsystems */ +#undef SDL_ATOMIC_DISABLED +#undef SDL_AUDIO_DISABLED +#undef SDL_CPUINFO_DISABLED +#undef SDL_EVENTS_DISABLED +#undef SDL_FILE_DISABLED +#undef SDL_JOYSTICK_DISABLED +#undef SDL_HAPTIC_DISABLED +#undef SDL_HIDAPI_DISABLED +#undef SDL_SENSOR_DISABLED +#undef SDL_LOADSO_DISABLED +#undef SDL_RENDER_DISABLED +#undef SDL_THREADS_DISABLED +#undef SDL_TIMERS_DISABLED +#undef SDL_VIDEO_DISABLED +#undef SDL_POWER_DISABLED +#undef SDL_FILESYSTEM_DISABLED + +/* Enable various audio drivers */ +#undef SDL_AUDIO_DRIVER_AAUDIO +#undef SDL_AUDIO_DRIVER_ALSA +#undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +#undef SDL_AUDIO_DRIVER_ANDROID +#undef SDL_AUDIO_DRIVER_ARTS +#undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC +#undef SDL_AUDIO_DRIVER_COREAUDIO +#undef SDL_AUDIO_DRIVER_DISK +#undef SDL_AUDIO_DRIVER_DSOUND +#undef SDL_AUDIO_DRIVER_DUMMY +#undef SDL_AUDIO_DRIVER_EMSCRIPTEN +#undef SDL_AUDIO_DRIVER_ESD +#undef SDL_AUDIO_DRIVER_ESD_DYNAMIC +#undef SDL_AUDIO_DRIVER_FUSIONSOUND +#undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC +#undef SDL_AUDIO_DRIVER_HAIKU +#undef SDL_AUDIO_DRIVER_JACK +#undef SDL_AUDIO_DRIVER_JACK_DYNAMIC +#undef SDL_AUDIO_DRIVER_NACL +#undef SDL_AUDIO_DRIVER_NAS +#undef SDL_AUDIO_DRIVER_NAS_DYNAMIC +#undef SDL_AUDIO_DRIVER_NETBSD +#undef SDL_AUDIO_DRIVER_OPENSLES +#undef SDL_AUDIO_DRIVER_OSS +#undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H +#undef SDL_AUDIO_DRIVER_PAUDIO +#undef SDL_AUDIO_DRIVER_PIPEWIRE +#undef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC +#undef SDL_AUDIO_DRIVER_PULSEAUDIO +#undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_QSA +#undef SDL_AUDIO_DRIVER_SNDIO +#undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC +#undef SDL_AUDIO_DRIVER_SUNAUDIO +#undef SDL_AUDIO_DRIVER_WASAPI +#undef SDL_AUDIO_DRIVER_WINMM +#undef SDL_AUDIO_DRIVER_OS2 + +/* Enable various input drivers */ +#undef SDL_INPUT_LINUXEV +#undef SDL_INPUT_FBSDKBIO +#undef SDL_INPUT_LINUXKD +#undef SDL_INPUT_WSCONS +#undef SDL_JOYSTICK_HAIKU +#undef SDL_JOYSTICK_DINPUT +#undef SDL_JOYSTICK_WGI +#undef SDL_JOYSTICK_XINPUT +#undef SDL_JOYSTICK_DUMMY +#undef SDL_JOYSTICK_IOKIT +#undef SDL_JOYSTICK_MFI +#undef SDL_JOYSTICK_LINUX +#undef SDL_JOYSTICK_ANDROID +#undef SDL_JOYSTICK_OS2 +#undef SDL_JOYSTICK_USBHID +#undef SDL_HAVE_MACHINE_JOYSTICK_H +#undef SDL_JOYSTICK_HIDAPI +#undef SDL_JOYSTICK_RAWINPUT +#undef SDL_JOYSTICK_EMSCRIPTEN +#undef SDL_JOYSTICK_VIRTUAL +#undef SDL_HAPTIC_DUMMY +#undef SDL_HAPTIC_ANDROID +#undef SDL_HAPTIC_LINUX +#undef SDL_HAPTIC_IOKIT +#undef SDL_HAPTIC_DINPUT +#undef SDL_HAPTIC_XINPUT + +/* Enable various sensor drivers */ +#undef SDL_SENSOR_ANDROID +#undef SDL_SENSOR_COREMOTION +#undef SDL_SENSOR_WINDOWS +#undef SDL_SENSOR_DUMMY + +/* Enable various shared object loading systems */ +#undef SDL_LOADSO_DLOPEN +#undef SDL_LOADSO_DUMMY +#undef SDL_LOADSO_LDG +#undef SDL_LOADSO_WINDOWS +#undef SDL_LOADSO_OS2 + +/* Enable various threading systems */ +#undef SDL_THREAD_GENERIC_COND_SUFFIX +#undef SDL_THREAD_PTHREAD +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX +#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP +#undef SDL_THREAD_WINDOWS +#undef SDL_THREAD_OS2 + +/* Enable various timer systems */ +#undef SDL_TIMER_HAIKU +#undef SDL_TIMER_DUMMY +#undef SDL_TIMER_UNIX +#undef SDL_TIMER_WINDOWS +#undef SDL_TIMER_OS2 + +/* Enable various video drivers */ +#undef SDL_VIDEO_DRIVER_HAIKU +#undef SDL_VIDEO_DRIVER_COCOA +#undef SDL_VIDEO_DRIVER_DIRECTFB +#undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC +#undef SDL_VIDEO_DRIVER_DUMMY +#undef SDL_VIDEO_DRIVER_WINDOWS +#undef SDL_VIDEO_DRIVER_WAYLAND +#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +#undef SDL_VIDEO_DRIVER_X11 +#undef SDL_VIDEO_DRIVER_RPI +#undef SDL_VIDEO_DRIVER_KMSDRM +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +#undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM +#undef SDL_VIDEO_DRIVER_ANDROID +#undef SDL_VIDEO_DRIVER_EMSCRIPTEN +#undef SDL_VIDEO_DRIVER_OFFSCREEN +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE +#undef SDL_VIDEO_DRIVER_X11_XCURSOR +#undef SDL_VIDEO_DRIVER_X11_XDBE +#undef SDL_VIDEO_DRIVER_X11_XINERAMA +#undef SDL_VIDEO_DRIVER_X11_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +#undef SDL_VIDEO_DRIVER_X11_XFIXES +#undef SDL_VIDEO_DRIVER_X11_XRANDR +#undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#undef SDL_VIDEO_DRIVER_X11_XSHAPE +#undef SDL_VIDEO_DRIVER_X11_XVIDMODE +#undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#undef SDL_VIDEO_DRIVER_NACL +#undef SDL_VIDEO_DRIVER_VIVANTE +#undef SDL_VIDEO_DRIVER_VIVANTE_VDK +#undef SDL_VIDEO_DRIVER_OS2 +#undef SDL_VIDEO_DRIVER_QNX +#undef SDL_VIDEO_DRIVER_RISCOS + +#undef SDL_VIDEO_RENDER_D3D +#undef SDL_VIDEO_RENDER_D3D11 +#undef SDL_VIDEO_RENDER_OGL +#undef SDL_VIDEO_RENDER_OGL_ES +#undef SDL_VIDEO_RENDER_OGL_ES2 +#undef SDL_VIDEO_RENDER_DIRECTFB +#undef SDL_VIDEO_RENDER_METAL + +/* Enable OpenGL support */ +#undef SDL_VIDEO_OPENGL +#undef SDL_VIDEO_OPENGL_ES +#undef SDL_VIDEO_OPENGL_ES2 +#undef SDL_VIDEO_OPENGL_BGL +#undef SDL_VIDEO_OPENGL_CGL +#undef SDL_VIDEO_OPENGL_EGL +#undef SDL_VIDEO_OPENGL_GLX +#undef SDL_VIDEO_OPENGL_WGL +#undef SDL_VIDEO_OPENGL_OSMESA +#undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC + +/* Enable Vulkan support */ +#undef SDL_VIDEO_VULKAN + +/* Enable Metal support */ +#undef SDL_VIDEO_METAL + +/* Enable system power support */ +#undef SDL_POWER_LINUX +#undef SDL_POWER_WINDOWS +#undef SDL_POWER_MACOSX +#undef SDL_POWER_HAIKU +#undef SDL_POWER_ANDROID +#undef SDL_POWER_EMSCRIPTEN +#undef SDL_POWER_HARDWIRED + +/* Enable system filesystem support */ +#undef SDL_FILESYSTEM_HAIKU +#undef SDL_FILESYSTEM_COCOA +#undef SDL_FILESYSTEM_DUMMY +#undef SDL_FILESYSTEM_UNIX +#undef SDL_FILESYSTEM_WINDOWS +#undef SDL_FILESYSTEM_NACL +#undef SDL_FILESYSTEM_ANDROID +#undef SDL_FILESYSTEM_EMSCRIPTEN +#undef SDL_FILESYSTEM_OS2 +#undef SDL_FILESYSTEM_RISCOS + +/* Enable assembly routines */ +#undef SDL_ASSEMBLY_ROUTINES +#undef SDL_ALTIVEC_BLITTERS +#undef SDL_ARM_SIMD_BLITTERS +#undef SDL_ARM_NEON_BLITTERS + +/* Whether SDL_DYNAMIC_API needs dlopen() */ +#undef DYNAPI_NEEDS_DLOPEN + +/* Enable ime support */ +#undef SDL_USE_IME + +/* Enable dynamic udev support */ +#undef SDL_UDEV_DYNAMIC + +/* Enable dynamic libusb support */ +#undef SDL_LIBUSB_DYNAMIC + +/* Enable dynamic libsamplerate support */ +#undef SDL_LIBSAMPLERATE_DYNAMIC + +#endif /* SDL_config_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_android.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_android.h new file mode 100644 index 000000000..4a13a3a53 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_android.h @@ -0,0 +1,192 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_android_h_ +#define SDL_config_android_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_android.h + * + * This is a configuration that can be used to build SDL for Android + */ + +#include + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_CLOCK_GETTIME 1 + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_ANDROID 1 +#define SDL_AUDIO_DRIVER_OPENSLES 1 +#define SDL_AUDIO_DRIVER_AAUDIO 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_ANDROID 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_ANDROID 1 + +/* Enable sensor driver */ +#define SDL_SENSOR_ANDROID 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_ANDROID 1 + +/* Enable OpenGL ES */ +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable Vulkan support */ +/* Android does not support Vulkan in native code using the "armeabi" ABI. */ +#if defined(__ARM_ARCH) && __ARM_ARCH < 7 +#define SDL_VIDEO_VULKAN 0 +#else +#define SDL_VIDEO_VULKAN 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_ANDROID 1 + +/* Enable the filesystem driver */ +#define SDL_FILESYSTEM_ANDROID 1 + +#endif /* SDL_config_android_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_emscripten.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_emscripten.h new file mode 100644 index 000000000..7efe32373 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_emscripten.h @@ -0,0 +1,216 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 _SDL_config_emscripten_h_ +#define _SDL_config_emscripten_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_emscripten.h + * + * This is a configuration that can be used to build SDL for Emscripten. + */ + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif +#define HAVE_GCC_ATOMICS 1 + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_WCHAR_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_WCSCASECMP 1 +#define HAVE_WCSNCASECMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_FSEEKO 1 +#define HAVE_FSEEKO64 1 +#define HAVE_SIGACTION 1 +#define HAVE_SA_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_CLOCK_GETTIME 1 +/* #undef HAVE_GETPAGESIZE */ +#define HAVE_MPROTECT 1 +#define HAVE_ICONV 1 + +/* SDL internal assertion support */ +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ + +#define SDL_CPUINFO_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#define SDL_HIDAPI_DISABLED 1 +#ifndef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREADS_DISABLED 1 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_EMSCRIPTEN 1 + +/* Enable various sensor drivers */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#ifdef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREAD_PTHREAD 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1 + +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ +/* #undef SDL_VIDEO_OPENGL_ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +/* #undef SDL_VIDEO_OPENGL_GLX */ +/* #undef SDL_VIDEO_OPENGL_WGL */ +#define SDL_VIDEO_OPENGL_EGL 1 +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable system power support */ +#define SDL_POWER_EMSCRIPTEN 1 + +/* Enable system filesystem support */ +#define SDL_FILESYSTEM_EMSCRIPTEN 1 + +#endif /* _SDL_config_emscripten_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_iphoneos.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_iphoneos.h new file mode 100644 index 000000000..0aa242563 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_iphoneos.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_iphoneos_h_ +#define SDL_config_iphoneos_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +/* The libunwind functions are only available on x86 */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 +#define HAVE_O_CLOEXEC 1 + +/* enable iPhone version of Core Audio driver */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DUMMY 1 + +/* Enable joystick support */ +/* Only enable HIDAPI support if you want to support Steam Controllers on iOS and tvOS */ +/*#define SDL_JOYSTICK_HIDAPI 1*/ +#define SDL_JOYSTICK_MFI 1 +#define SDL_JOYSTICK_VIRTUAL 1 + +#ifdef __TVOS__ +#define SDL_SENSOR_DUMMY 1 +#else +/* Enable the CoreMotion sensor driver */ +#define SDL_SENSOR_COREMOTION 1 +#endif + +/* Enable Unix style SO loading */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Supported video drivers */ +#define SDL_VIDEO_DRIVER_UIKIT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES */ +#if !TARGET_OS_MACCATALYST +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer + Also supported in simulator from iOS 13.0 and tvOS 13.0 + */ +#if (TARGET_OS_SIMULATOR && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (__TV_OS_VERSION_MIN_REQUIRED >= 130000))) || (!TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000))) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_UIKIT 1 + +/* enable iPhone keyboard support */ +#define SDL_IPHONE_KEYBOARD 1 + +/* enable iOS extended launch screen */ +#define SDL_IPHONE_LAUNCHSCREEN 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +#endif /* SDL_config_iphoneos_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_macosx.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_macosx.h new file mode 100644 index 000000000..ff42e3d5f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_macosx.h @@ -0,0 +1,280 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_macosx_h_ +#define SDL_config_macosx_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ +#include + +/* This is a set of defines to configure the SDL features */ + +#ifdef __LP64__ + #define SIZEOF_VOIDP 8 +#else + #define SIZEOF_VOIDP 4 +#endif + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 + +#if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070) +#define HAVE_O_CLOEXEC 1 +#endif + +#define HAVE_GCC_ATOMICS 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_IOKIT 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_IOKIT 1 + +/* The MFI controller support requires ARC Objective C runtime */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__) +#define SDL_JOYSTICK_MFI 1 +#endif + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_COCOA 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#undef SDL_VIDEO_DRIVER_X11 +#define SDL_VIDEO_DRIVER_X11_DYNAMIC "/opt/X11/lib/libX11.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/opt/X11/lib/libXext.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/opt/X11/lib/libXinerama.1.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/opt/X11/lib/libXi.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/opt/X11/lib/libXrandr.2.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/opt/X11/lib/libXss.1.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/opt/X11/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 +#define SDL_VIDEO_DRIVER_X11_XRANDR 1 +#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 +#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 +#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 + +#ifdef MAC_OS_X_VERSION_10_8 +/* + * No matter the versions targeted, this is the 10.8 or later SDK, so you have + * to use the external Xquartz, which is a more modern Xlib. Previous SDKs + * used an older Xlib. + */ +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal only supported on 64-bit architectures with 10.11+ */ +#if TARGET_RT_64_BIT && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#ifndef SDL_VIDEO_RENDER_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#else +#define SDL_VIDEO_RENDER_METAL 0 +#endif +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_CGL +#define SDL_VIDEO_OPENGL_CGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_GLX +#define SDL_VIDEO_OPENGL_GLX 1 +#endif + +/* Enable Vulkan and Metal support */ +#ifndef SDL_VIDEO_VULKAN +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#else +#define SDL_VIDEO_VULKAN 0 +#endif +#endif + +#ifndef SDL_VIDEO_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#else +#define SDL_VIDEO_METAL 0 +#endif +#endif + +/* Enable system power support */ +#define SDL_POWER_MACOSX 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 +#ifdef __ppc__ +#define SDL_ALTIVEC_BLITTERS 1 +#endif + +#endif /* SDL_config_macosx_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_minimal.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_minimal.h new file mode 100644 index 000000000..4df92f748 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_minimal.h @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_minimal_h_ +#define SDL_config_minimal_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_minimal.h + * + * This is the minimal configuration that can be used to build SDL. + */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* Here are some reasonable defaults */ +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +#else +#define HAVE_STDINT_H 1 +#endif /* Visual Studio 2008 */ + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable the stub timer support (src/timer/dummy/\*.c) */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable the dummy video driver (src/video/dummy/\*.c) */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_minimal_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_os2.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_os2.h new file mode 100644 index 000000000..1728bd772 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_os2.h @@ -0,0 +1,205 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_os2_h_ +#define SDL_config_os2_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#define SIZEOF_VOIDP 4 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_OS2 1 + +#define SDL_POWER_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 + +#define SDL_SENSOR_DUMMY 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_OS2 1 +#define SDL_JOYSTICK_OS2 1 +#ifndef HAVE_LIBUSB_H /* see Makefile */ +#define SDL_HIDAPI_DISABLED 1 +/*#undef SDL_JOYSTICK_HIDAPI */ +#else +#define SDL_JOYSTICK_HIDAPI 1 +/* dynamically loaded libusb-1.0 dll: */ +#define SDL_LIBUSB_DYNAMIC "usb100.dll" +#endif +/*#undef SDL_JOYSTICK_VIRTUAL */ + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ + +#define SDL_THREAD_OS2 1 +#define SDL_LOADSO_OS2 1 +#define SDL_TIMER_OS2 1 +#define SDL_FILESYSTEM_OS2 1 + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 + +/* use libsamplerate for audio rate conversion. */ +/*#define HAVE_LIBSAMPLERATE_H 1 */ + +/* Enable dynamic libsamplerate support */ +#define SDL_LIBSAMPLERATE_DYNAMIC "SAMPRATE.DLL" + +#define HAVE_LIBC 1 + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 + +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_WCHAR_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_SIGNAL_H 1 + +#if 0 /* see Makefile */ +#define HAVE_ICONV 1 +#define HAVE_ICONV_H 1 +#endif + +/* #undef HAVE_DLOPEN */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#if defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE__FTELLI64 1 +#endif +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +#define HAVE_WCSCMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +/* #undef HAVE_WCSDUP */ +#define HAVE__WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +/* #undef HAVE_INDEX */ +/* #undef HAVE_RINDEX */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE__I64TOA 1 +#define HAVE__UI64TOA 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 +#define HAVE_ACOS 1 +/* #undef HAVE_ACOSF */ +#define HAVE_ASIN 1 +/* #undef HAVE_ASINF */ +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +/* #undef HAVE_ATAN2F */ +#define HAVE_CEIL 1 +/* #undef HAVE_CEILF */ +/* #undef HAVE_COPYSIGN */ +/* #undef HAVE_COPYSIGNF */ +#define HAVE_COS 1 +/* #undef HAVE_COSF */ +#define HAVE_EXP 1 +/* #undef HAVE_EXPF */ +#define HAVE_FABS 1 +/* #undef HAVE_FABSF */ +#define HAVE_FLOOR 1 +/* #undef HAVE_FLOORF */ +#define HAVE_FMOD 1 +/* #undef HAVE_FMODF */ +#define HAVE_LOG 1 +/* #undef HAVE_LOGF */ +#define HAVE_LOG10 1 +/* #undef HAVE_LOG10F */ +#define HAVE_POW 1 +/* #undef HAVE_POWF */ +#define HAVE_SIN 1 +/* #undef HAVE_SINF */ +/* #undef HAVE_SCALBN */ +/* #undef HAVE_SCALBNF */ +#define HAVE_SQRT 1 +/* #undef HAVE_SQRTF */ +#define HAVE_TAN 1 +/* #undef HAVE_TANF */ +/* #undef HAVE_TRUNC */ +/* #undef HAVE_TRUNCF */ +/* #undef HAVE_LROUND */ +/* #undef HAVE_LROUNDF */ +/* #undef HAVE_ROUND */ +/* #undef HAVE_ROUNDF */ + +#endif /* SDL_config_os2_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_pandora.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_pandora.h new file mode 100644 index 000000000..e0be390bc --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_pandora.h @@ -0,0 +1,140 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_pandora_h_ +#define SDL_config_pandora_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define SDL_BYTEORDER 1234 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_OSS 1 + +#define SDL_INPUT_LINUXEV 1 +#define SDL_JOYSTICK_LINUX 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_LINUX 1 + +#define SDL_SENSOR_DUMMY 1 + +#define SDL_LOADSO_DLOPEN 1 + +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1 + +#define SDL_TIMER_UNIX 1 +#define SDL_FILESYSTEM_UNIX 1 + +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_X11 1 +#define SDL_VIDEO_DRIVER_PANDORA 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_OPENGL_ES 1 + +#endif /* SDL_config_pandora_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_psp.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_psp.h new file mode 100644 index 000000000..72c1eb668 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_psp.h @@ -0,0 +1,165 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_psp_h_ +#define SDL_config_psp_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +/* #define HAVE_SYSCONF 1 */ +/* #define HAVE_SIGACTION 1 */ + + +/* PSP isn't that sophisticated */ +#define LACKS_SYS_MMAN_H 1 + +/* Enable the PSP thread support (src/thread/psp/\*.c) */ +#define SDL_THREAD_PSP 1 + +/* Enable the PSP timer support (src/timer/psp/\*.c) */ +#define SDL_TIMER_PSP 1 + +/* Enable the PSP joystick driver (src/joystick/psp/\*.c) */ +#define SDL_JOYSTICK_PSP 1 +#define SDL_JOYSTICK_VIRTUAL 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable the PSP audio driver (src/audio/psp/\*.c) */ +#define SDL_AUDIO_DRIVER_PSP 1 + +/* PSP video driver */ +#define SDL_VIDEO_DRIVER_PSP 1 + +/* PSP render driver */ +#define SDL_VIDEO_RENDER_PSP 1 + +#define SDL_POWER_PSP 1 + +/* Enable the PSP filesystem support (src/filesystem/psp/\*.c) */ +#define SDL_FILESYSTEM_PSP 1 + +/* PSP doesn't have haptic device (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* PSP doesn't have HIDAPI available */ +#define SDL_HIDAPI_DISABLED 1 + +/* PSP can't load shared object (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +#endif /* SDL_config_psp_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_windows.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_windows.h new file mode 100644 index 000000000..c9ed1cfea --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_windows.h @@ -0,0 +1,305 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_windows_h_ +#define SDL_config_windows_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* winsdkver.h defines _WIN32_MAXVER for SDK version detection. It is present since at least the Windows 7 SDK, + * but out of caution we'll only use it if the compiler supports __has_include() to confirm its presence. + * If your compiler doesn't support __has_include() but you have winsdkver.h, define HAVE_WINSDKVER_H. */ +#if !defined(HAVE_WINSDKVER_H) && defined(__has_include) +#if __has_include() +#define HAVE_WINSDKVER_H 1 +#endif +#endif + +#ifdef HAVE_WINSDKVER_H +#include +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) || defined(__clang__) || defined(__BORLANDC__) || defined(__CODEGEARC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0A00 /* Windows 10 SDK */ +#define HAVE_WINDOWS_GAMING_INPUT_H 1 +#endif +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602 /* Windows 8 SDK */ +#define HAVE_D3D11_H 1 +#endif +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 +#define HAVE_SENSORSAPI_H 1 +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#if _MSC_VER >= 1800 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#endif +/* This function is available with at least the VC++ 2008 C runtime library */ +#if _MSC_VER >= 1400 +#define HAVE__FSEEKI64 1 +#endif +#endif +#if !defined(_MSC_VER) || defined(_USE_MATH_DEFINES) +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_WASAPI 1 +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#ifndef __WINRT__ +#define SDL_JOYSTICK_RAWINPUT 1 +#endif +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#define SDL_SENSOR_WINDOWS 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* SDL_config_windows_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_winrt.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_winrt.h new file mode 100644 index 000000000..690ffe159 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_winrt.h @@ -0,0 +1,258 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_winrt_h_ +#define SDL_config_winrt_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Make sure the Windows SDK's NTDDI_VERSION macro gets defined. This is used + by SDL to determine which version of the Windows SDK is being used. +*/ +#include + +/* Define possibly-undefined NTDDI values (used when compiling SDL against + older versions of the Windows SDK. +*/ +#ifndef NTDDI_WINBLUE +#define NTDDI_WINBLUE 0x06030000 +#endif +#ifndef NTDDI_WIN10 +#define NTDDI_WIN10 0x0A000000 +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +/* Useful headers */ +#define HAVE_DXGI_H 1 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#define HAVE_XINPUT_H 1 +#endif + +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 + +#define HAVE_LIBC 1 +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE_STRTOLL */ +/* #undef HAVE_STRTOULL */ +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_VSNPRINTF 1 +/* TODO, WinRT: consider using ??_s versions of the following */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +/* #undef HAVE_SSCANF */ +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE__SCALB 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_WASAPI 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_VIRTUAL 1 +#if (NTDDI_VERSION >= NTDDI_WIN10) +#define SDL_JOYSTICK_WGI 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_XINPUT 1 +#endif /* WIN10 */ +#endif + +/* WinRT doesn't have HIDAPI available */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 +#else +/* WinRT on Windows 8.0 and Windows Phone 8.0 don't support CreateThread() */ +#define SDL_THREAD_STDCPP 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_WINRT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 + +/* Enable appropriate renderer(s) */ +#define SDL_VIDEO_RENDER_D3D11 1 + +#if SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_WINRT 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* SDL_config_winrt_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_wiz.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_wiz.h new file mode 100644 index 000000000..29b8242ec --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_config_wiz.h @@ -0,0 +1,154 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_config_wiz_h_ +#define SDL_config_wiz_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +#define SDL_BYTEORDER 1234 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_POW 1 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_OSS 1 + +#define SDL_INPUT_LINUXEV 1 +#define SDL_JOYSTICK_LINUX 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_LINUX 1 + +#define SDL_SENSOR_DUMMY 1 + +#define SDL_LOADSO_DLOPEN 1 + +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1 + +#define SDL_TIMER_UNIX 1 + +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_PANDORA 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_OPENGL_ES 1 + +#endif /* SDL_config_wiz_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_copying.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_copying.h new file mode 100644 index 000000000..49e3f9da0 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_copying.h @@ -0,0 +1,20 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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/libultraship/libultraship/Lib/SDL/SDL2/SDL_cpuinfo.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_cpuinfo.h new file mode 100644 index 000000000..1fc40991d --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_cpuinfo.h @@ -0,0 +1,559 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef SDL_cpuinfo_h_ +#define SDL_cpuinfo_h_ + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#ifdef __clang__ +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ + +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} + +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ +#include +#ifndef _WIN64 +#ifndef __MMX__ +#define __MMX__ +#endif +#ifndef __3dNOW__ +#define __3dNOW__ +#endif +#endif +#ifndef __SSE__ +#define __SSE__ +#endif +#ifndef __SSE2__ +#define __SSE2__ +#endif +#ifndef __SSE3__ +#define __SSE3__ +#endif +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) +# include +#endif +#else +/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ +#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) +#include +#endif +#if !defined(SDL_DISABLE_ARM_NEON_H) +# if defined(__ARM_NEON) +# include +# elif defined(__WINDOWS__) || defined(__WINRT__) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined(_M_ARM) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# if defined (_M_ARM64) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# endif +#endif +#endif /* compiler version */ + +#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) +#include +#endif +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#include +#else +#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) +#include +#endif +#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) +#include +#endif +#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) +#include +#endif +#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) +#include +#endif +#endif /* HAVE_IMMINTRIN_H */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * Get the number of CPU cores available. + * + * \returns the total number of logical CPU cores. On CPUs that include + * technologies such as hyperthreading, the number of logical cores + * may be more than the number of physical cores. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * Determine the L1 cache line size of the CPU. + * + * This is useful for determining multi-threaded structure padding or SIMD + * prefetch sizes. + * + * \returns the L1 cache line size of the CPU, in bytes. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * Determine whether the CPU has the RDTSC instruction. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * Determine whether the CPU has AltiVec features. + * + * This always returns false on CPUs that aren't using PowerPC instruction + * sets. + * + * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * Determine whether the CPU has MMX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * Determine whether the CPU has 3DNow! features. + * + * This always returns false on CPUs that aren't using AMD instruction sets. + * + * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * Determine whether the CPU has SSE features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * Determine whether the CPU has SSE2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * Determine whether the CPU has SSE3 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * Determine whether the CPU has SSE4.1 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * Determine whether the CPU has SSE4.2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * Determine whether the CPU has AVX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * Determine whether the CPU has AVX2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * Determine whether the CPU has AVX-512F (foundation) features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_HasAVX + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); + +/** + * Determine whether the CPU has ARM SIMD (ARMv6) features. + * + * This is different from ARM NEON, which is a different instruction set. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_HasNEON + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); + +/** + * Determine whether the CPU has NEON (ARM SIMD) features. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); + +/** + * Get the amount of RAM configured in the system. + * + * \returns the amount of RAM configured in the system in MB. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + +/** + * Report the alignment this system needs for SIMD allocations. + * + * This will return the minimum number of bytes to which a pointer must be + * aligned to be compatible with SIMD instructions on the current machine. For + * example, if the machine supports SSE only, it will return 16, but if it + * supports AVX-512F, it'll return 64 (etc). This only reports values for + * instruction sets SDL knows about, so if your SDL build doesn't have + * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and + * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. + * Plan accordingly. + * + * \returns the alignment in bytes needed for available, known SIMD + * instructions. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); + +/** + * Allocate memory in a SIMD-friendly way. + * + * This will allocate a block of memory that is suitable for use with SIMD + * instructions. Specifically, it will be properly aligned and padded for the + * system's supported vector instructions. + * + * The memory returned will be padded such that it is safe to read or write an + * incomplete vector at the end of the memory block. This can be useful so you + * don't have to drop back to a scalar fallback at the end of your SIMD + * processing loop to deal with the final elements without overflowing the + * allocated buffer. + * + * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or + * delete[], etc. + * + * Note that SDL will only deal with SIMD instruction sets it is aware of; for + * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and + * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants + * 64. To be clear: if you can't decide to use an instruction set with an + * SDL_Has*() function, don't use that instruction set with memory allocated + * through here. + * + * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't + * out of memory, but you are not allowed to dereference it (because you only + * own zero bytes of that buffer). + * + * \param len The length, in bytes, of the block to allocate. The actual + * allocated block might be larger due to padding, etc. + * \returns a pointer to the newly-allocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDAlignment + * \sa SDL_SIMDRealloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); + +/** + * Reallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, + * SDL_malloc, memalign, new[], etc. + * + * \param mem The pointer obtained from SDL_SIMDAlloc. This function also + * accepts NULL, at which point this function is the same as + * calling SDL_SIMDAlloc with a NULL pointer. + * \param len The length, in bytes, of the block to allocated. The actual + * allocated block might be larger due to padding, etc. Passing 0 + * will return a non-NULL pointer, assuming the system isn't out of + * memory. + * \returns a pointer to the newly-reallocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SIMDAlignment + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); + +/** + * Deallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from + * malloc, realloc, SDL_malloc, memalign, new[], etc. + * + * However, SDL_SIMDFree(NULL) is a legal no-op. + * + * The memory pointed to by `ptr` is no longer valid for access upon return, + * and may be returned to the system or reused by a future allocation. The + * pointer passed to this function is no longer safe to dereference once this + * function returns, and should be discarded. + * + * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to + * deallocate. NULL is a legal no-op. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDRealloc + */ +extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_cpuinfo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_egl.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_egl.h new file mode 100644 index 000000000..f90e27b26 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_egl.h @@ -0,0 +1,2302 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_egl.h + * + * This is a simple file to encapsulate the EGL API headers. + */ +#if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) + +#if defined(__vita__) || defined(__psp2__) +#include +#endif + +#include +#include + +#else /* _MSC_VER */ + +/* EGL headers for Visual Studio */ + +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 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. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * 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 filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * 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; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#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_ */ + + +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* Platform-specific types and definitions for egl.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ + */ + +/*#include */ + +/* Macros used in EGL function prototype declarations. + * + * EGL functions should be prototyped as: + * + * EGLAPI return-type EGLAPIENTRY eglFunction(arguments); + * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); + * + * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h + */ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType + * are aliases of window-system-dependent types, such as X Display * or + * Windows Device Context. They must be defined in platform-specific + * code below. The EGL-prefixed versions of Native*Type are the same + * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. + */ + +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include + +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; + +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__ANDROID__) || defined(ANDROID) + +struct ANativeWindow; +struct egl_native_pixmap_t; + +typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; + +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; + +#elif defined(USE_X11) + +/* X11 (tentative) */ +#include +#include + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef khronos_int32_t EGLint; + + +/* C++ / C typecast macros for special EGL handle values */ +#if defined(__cplusplus) +#define EGL_CAST(type, value) (static_cast(value)) +#else +#define EGL_CAST(type, value) ((type) (value)) +#endif + +#endif /* __eglplatform_h */ + + +#ifndef __egl_h_ +#define __egl_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +** +** This header is generated from the Khronos EGL 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.khronos.org/registry/egl +** +** Khronos $Git commit SHA1: b35e89ca9a $ on $Git commit date: 2021-09-01 09:34:00 +0530 $ +*/ + +/*#include */ + +#ifndef EGL_EGL_PROTOTYPES +#define EGL_EGL_PROTOTYPES 1 +#endif + +/* Generated on date 20210901 */ + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_VERSION_1_0 +#define EGL_VERSION_1_0 1 +typedef unsigned int EGLBoolean; +typedef void *EGLDisplay; +/*#include */ +/*#include */ +typedef void *EGLConfig; +typedef void *EGLSurface; +typedef void *EGLContext; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BLUE_SIZE 0x3022 +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_CORE_NATIVE_ENGINE 0x305B +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_DONT_CARE EGL_CAST(EGLint,-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_HEIGHT 0x3056 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_NONE 0x3038 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_READ 0x305A +#define EGL_RED_SIZE 0x3024 +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SUCCESS 0x3000 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRUE 1 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_WIDTH 0x3057 +#define EGL_WINDOW_BIT 0x0004 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void); +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw); +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id); +EGLAPI EGLint EGLAPIENTRY eglGetError (void); +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif +#endif /* EGL_VERSION_1_0 */ + +#ifndef EGL_VERSION_1_1 +#define EGL_VERSION_1_1 1 +#define EGL_BACK_BUFFER 0x3084 +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_CONTEXT_LOST 0x300E +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_TARGET 0x3081 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif +#endif /* EGL_VERSION_1_1 */ + +#ifndef EGL_VERSION_1_2 +#define EGL_VERSION_1_2 1 +typedef unsigned int EGLenum; +typedef void *EGLClientBuffer; +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_CLIENT_APIS 0x308D +#define EGL_COLORSPACE 0x3087 +#define EGL_COLORSPACE_sRGB 0x3089 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_DISPLAY_SCALING 10000 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_RGB_BUFFER 0x308E +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_UNKNOWN EGL_CAST(EGLint,-1) +#define EGL_VERTICAL_RESOLUTION 0x3091 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif +#endif /* EGL_VERSION_1_2 */ + +#ifndef EGL_VERSION_1_3 +#define EGL_VERSION_1_3 1 +#define EGL_CONFORMANT 0x3042 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_COLORSPACE_sRGB 0x3089 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#endif /* EGL_VERSION_1_3 */ + +#ifndef EGL_VERSION_1_4 +#define EGL_VERSION_1_4 1 +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_OPENGL_API 0x30A2 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif +#endif /* EGL_VERSION_1_4 */ + +#ifndef EGL_VERSION_1_5 +#define EGL_VERSION_1_5 1 +typedef void *EGLSync; +typedef intptr_t EGLAttrib; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef void *EGLImage; +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SIGNALED 0x30F2 +#define EGL_UNSIGNALED 0x30F3 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_NO_SYNC EGL_CAST(EGLSync,0) +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); +#if EGL_EGL_PROTOTYPES +EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image); +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif +#endif /* EGL_VERSION_1_5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __egl_h_ */ + + +#ifndef __eglext_h_ +#define __eglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +** +** This header is generated from the Khronos EGL 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.khronos.org/registry/egl +** +** Khronos $Git commit SHA1: b35e89ca9a $ on $Git commit date: 2021-09-01 09:34:00 +0530 $ +*/ + +/*#include */ + +#define EGL_EGLEXT_VERSION 20210901 + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: egl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#endif /* EGL_KHR_cl_event */ + +#ifndef EGL_KHR_cl_event2 +#define EGL_KHR_cl_event2 1 +typedef void *EGLSyncKHR; +typedef intptr_t EGLAttribKHR; +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#endif +#endif /* EGL_KHR_cl_event2 */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#endif /* EGL_KHR_config_attribs */ + +#ifndef EGL_KHR_context_flush_control +#define EGL_KHR_context_flush_control 1 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#endif /* EGL_KHR_context_flush_control */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#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 /* EGL_KHR_create_context */ + +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 +#endif /* EGL_KHR_create_context_no_error */ + +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value); +typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value); +EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#endif +#endif /* EGL_KHR_debug */ + +#ifndef EGL_KHR_display_reference +#define EGL_KHR_display_reference 1 +#define EGL_TRACK_REFERENCES_KHR 0x3352 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#endif +#endif /* EGL_KHR_display_reference */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +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 PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#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 eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_fence_sync */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 +#endif /* EGL_KHR_get_all_proc_addresses */ + +#ifndef EGL_KHR_gl_colorspace +#define EGL_KHR_gl_colorspace 1 +#define EGL_GL_COLORSPACE_KHR 0x309D +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#endif /* EGL_KHR_gl_colorspace */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 +#endif /* EGL_KHR_gl_renderbuffer_image */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC +#endif /* EGL_KHR_gl_texture_2D_image */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD +#endif /* EGL_KHR_gl_texture_3D_image */ + +#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 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +typedef void *EGLImageKHR; +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0) +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#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 +#endif /* EGL_KHR_image */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif /* EGL_KHR_image_base */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +#endif /* EGL_KHR_image_pixmap */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface); +#endif +#endif /* EGL_KHR_lock_surface */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif /* EGL_KHR_lock_surface2 */ + +#ifndef EGL_KHR_lock_surface3 +#define EGL_KHR_lock_surface3 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#endif +#endif /* EGL_KHR_lock_surface3 */ + +#ifndef EGL_KHR_mutable_render_buffer +#define EGL_KHR_mutable_render_buffer 1 +#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 +#endif /* EGL_KHR_mutable_render_buffer */ + +#ifndef EGL_KHR_no_config_context +#define EGL_KHR_no_config_context 1 +#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) +#endif /* EGL_KHR_no_config_context */ + +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 +#define EGL_BUFFER_AGE_KHR 0x313D +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_partial_update */ + +#ifndef EGL_KHR_platform_android +#define EGL_KHR_platform_android 1 +#define EGL_PLATFORM_ANDROID_KHR 0x3141 +#endif /* EGL_KHR_platform_android */ + +#ifndef EGL_KHR_platform_gbm +#define EGL_KHR_platform_gbm 1 +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif /* EGL_KHR_platform_gbm */ + +#ifndef EGL_KHR_platform_wayland +#define EGL_KHR_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#endif /* EGL_KHR_platform_wayland */ + +#ifndef EGL_KHR_platform_x11 +#define EGL_KHR_platform_x11 1 +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 +#endif /* EGL_KHR_platform_x11 */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 +#ifdef KHRONOS_SUPPORT_INT64 +#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 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0) +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_reusable_sync */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_NO_STREAM_KHR EGL_CAST(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 +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); +#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 +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream */ + +#ifndef EGL_KHR_stream_attrib +#define EGL_KHR_stream_attrib 1 +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream_attrib */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#ifdef EGL_KHR_stream +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#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 +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_consumer_gltexture */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#ifdef EGL_KHR_stream +#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1) +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_cross_process_fd */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +#ifdef EGL_KHR_stream +#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 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_fifo */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#ifdef EGL_KHR_stream +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_BIT_KHR 0x0800 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_eglsurface */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +#endif /* EGL_KHR_surfaceless_context */ + +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_swap_buffers_with_damage */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA +#endif /* EGL_KHR_vg_parent_image */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif +#endif /* EGL_KHR_wait_sync */ + +#ifndef EGL_ANDROID_GLES_layers +#define EGL_ANDROID_GLES_layers 1 +#endif /* EGL_ANDROID_GLES_layers */ + +#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); +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif +#endif /* EGL_ANDROID_blob_cache */ + +#ifndef EGL_ANDROID_create_native_client_buffer +#define EGL_ANDROID_create_native_client_buffer 1 +#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 +#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 +#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 +#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list); +#endif +#endif /* EGL_ANDROID_create_native_client_buffer */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif /* EGL_ANDROID_framebuffer_target */ + +#ifndef EGL_ANDROID_front_buffer_auto_refresh +#define EGL_ANDROID_front_buffer_auto_refresh 1 +#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C +#endif /* EGL_ANDROID_front_buffer_auto_refresh */ + +#ifndef EGL_ANDROID_get_frame_timestamps +#define EGL_ANDROID_get_frame_timestamps 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2) +#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1) +#define EGL_TIMESTAMPS_ANDROID 0x3430 +#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 +#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 +#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 +#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 +#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 +#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 +#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 +#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 +#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A +#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B +#define EGL_READS_DONE_TIME_ANDROID 0x343C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#endif +#endif /* EGL_ANDROID_get_frame_timestamps */ + +#ifndef EGL_ANDROID_get_native_client_buffer +#define EGL_ANDROID_get_native_client_buffer 1 +struct AHardwareBuffer; +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#endif +#endif /* EGL_ANDROID_get_native_client_buffer */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif /* EGL_ANDROID_image_native_buffer */ + +#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 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_ANDROID_native_fence_sync */ + +#ifndef EGL_ANDROID_presentation_time +#define EGL_ANDROID_presentation_time 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#endif +#endif /* EGL_ANDROID_presentation_time */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif /* EGL_ANDROID_recordable */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 +#endif /* EGL_ANGLE_device_d3d */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +#endif /* EGL_ANGLE_query_surface_pointer */ + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +#ifndef EGL_ANGLE_sync_control_rate +#define EGL_ANGLE_sync_control_rate 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#endif +#endif /* EGL_ANGLE_sync_control_rate */ + +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 +#define EGL_FIXED_SIZE_ANGLE 0x3201 +#endif /* EGL_ANGLE_window_fixed_size */ + +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A +#endif /* EGL_ARM_implicit_external_sync */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 +#define EGL_DISCARD_SAMPLES_ARM 0x3286 +#endif /* EGL_ARM_pixmap_multisample_discard */ + +#ifndef EGL_EXT_bind_to_front +#define EGL_EXT_bind_to_front 1 +#define EGL_FRONT_BUFFER_EXT 0x3464 +#endif /* EGL_EXT_bind_to_front */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif /* EGL_EXT_buffer_age */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 +#endif /* EGL_EXT_client_extensions */ + +#ifndef EGL_EXT_client_sync +#define EGL_EXT_client_sync 1 +#define EGL_SYNC_CLIENT_EXT 0x3364 +#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_client_sync */ + +#ifndef EGL_EXT_compositor +#define EGL_EXT_compositor 1 +#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 +#define EGL_EXTERNAL_REF_ID_EXT 0x3461 +#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462 +#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy); +#endif +#endif /* EGL_EXT_compositor */ + +#ifndef EGL_EXT_config_select_group +#define EGL_EXT_config_select_group 1 +#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0 +#endif /* EGL_EXT_config_select_group */ + +#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 /* EGL_EXT_create_context_robustness */ + +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 +typedef void *EGLDeviceEXT; +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#endif +#endif /* EGL_EXT_device_base */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C +#endif /* EGL_EXT_device_drm */ + +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 +#endif /* EGL_EXT_device_enumeration */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#define EGL_OPENWF_DEVICE_EXT 0x333D +#endif /* EGL_EXT_device_openwf */ + +#ifndef EGL_EXT_device_persistent_id +#define EGL_EXT_device_persistent_id 1 +#define EGL_DEVICE_UUID_EXT 0x335C +#define EGL_DRIVER_UUID_EXT 0x335D +#define EGL_DRIVER_NAME_EXT 0x335E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#endif +#endif /* EGL_EXT_device_persistent_id */ + +#ifndef EGL_EXT_device_query +#define EGL_EXT_device_query 1 +#endif /* EGL_EXT_device_query */ + +#ifndef EGL_EXT_device_query_name +#define EGL_EXT_device_query_name 1 +#define EGL_RENDERER_EXT 0x335F +#endif /* EGL_EXT_device_query_name */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_linear +#define EGL_EXT_gl_colorspace_bt2020_linear 1 +#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F +#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_pq +#define EGL_EXT_gl_colorspace_bt2020_pq 1 +#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 +#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ + +#ifndef EGL_EXT_gl_colorspace_display_p3 +#define EGL_EXT_gl_colorspace_display_p3 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363 +#endif /* EGL_EXT_gl_colorspace_display_p3 */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_linear +#define EGL_EXT_gl_colorspace_display_p3_linear 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 +#endif /* EGL_EXT_gl_colorspace_display_p3_linear */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough +#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 +#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ + +#ifndef EGL_EXT_gl_colorspace_scrgb +#define EGL_EXT_gl_colorspace_scrgb 1 +#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 +#endif /* EGL_EXT_gl_colorspace_scrgb */ + +#ifndef EGL_EXT_gl_colorspace_scrgb_linear +#define EGL_EXT_gl_colorspace_scrgb_linear 1 +#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 +#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ + +#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 /* EGL_EXT_image_dma_buf_import */ + +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#endif +#endif /* EGL_EXT_image_dma_buf_import_modifiers */ + +#ifndef EGL_EXT_image_gl_colorspace +#define EGL_EXT_image_gl_colorspace 1 +#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D +#endif /* EGL_EXT_image_gl_colorspace */ + +#ifndef EGL_EXT_image_implicit_sync_control +#define EGL_EXT_image_implicit_sync_control 1 +#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 +#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471 +#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472 +#endif /* EGL_EXT_image_implicit_sync_control */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif /* EGL_EXT_multiview_window */ + +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0) +#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0) +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#endif +#endif /* EGL_EXT_output_base */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 +#endif /* EGL_EXT_output_drm */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 +#endif /* EGL_EXT_output_openwf */ + +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float 1 +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B +#endif /* EGL_EXT_pixel_format_float */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#endif +#endif /* EGL_EXT_platform_base */ + +#ifndef EGL_EXT_platform_device +#define EGL_EXT_platform_device 1 +#define EGL_PLATFORM_DEVICE_EXT 0x313F +#endif /* EGL_EXT_platform_device */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#endif /* EGL_EXT_platform_wayland */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 +#endif /* EGL_EXT_platform_x11 */ + +#ifndef EGL_EXT_platform_xcb +#define EGL_EXT_platform_xcb 1 +#define EGL_PLATFORM_XCB_EXT 0x31DC +#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE +#endif /* EGL_EXT_platform_xcb */ + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + +#ifndef EGL_EXT_protected_content +#define EGL_EXT_protected_content 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_content */ + +#ifndef EGL_EXT_protected_surface +#define EGL_EXT_protected_surface 1 +#endif /* EGL_EXT_protected_surface */ + +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#endif +#endif /* EGL_EXT_stream_consumer_egloutput */ + +#ifndef EGL_EXT_surface_CTA861_3_metadata +#define EGL_EXT_surface_CTA861_3_metadata 1 +#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360 +#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361 +#endif /* EGL_EXT_surface_CTA861_3_metadata */ + +#ifndef EGL_EXT_surface_SMPTE2086_metadata +#define EGL_EXT_surface_SMPTE2086_metadata 1 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 +#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 +#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 +#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 +#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A +#define EGL_METADATA_SCALING_EXT 50000 +#endif /* EGL_EXT_surface_SMPTE2086_metadata */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_EXT_swap_buffers_with_damage */ + +#ifndef EGL_EXT_sync_reuse +#define EGL_EXT_sync_reuse 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_sync_reuse */ + +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D +#endif /* EGL_EXT_yuv_surface */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#endif +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#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 /* EGL_IMG_context_priority */ + +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 +#endif /* EGL_IMG_image_plane_attribs */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#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 +#endif /* EGL_MESA_drm_image */ + +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#endif +#endif /* EGL_MESA_image_dma_buf_export */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif /* EGL_MESA_platform_gbm */ + +#ifndef EGL_MESA_platform_surfaceless +#define EGL_MESA_platform_surfaceless 1 +#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD +#endif /* EGL_MESA_platform_surfaceless */ + +#ifndef EGL_MESA_query_driver +#define EGL_MESA_query_driver 1 +typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); +typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy); +EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy); +#endif +#endif /* EGL_MESA_query_driver */ + +#ifndef EGL_NOK_swap_region +#define EGL_NOK_swap_region 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region */ + +#ifndef EGL_NOK_swap_region2 +#define EGL_NOK_swap_region2 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region2 */ + +#ifndef EGL_NOK_texture_from_pixmap +#define EGL_NOK_texture_from_pixmap 1 +#define EGL_Y_INVERTED_NOK 0x307F +#endif /* EGL_NOK_texture_from_pixmap */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif /* EGL_NV_3dvision_surface */ + +#ifndef EGL_NV_context_priority_realtime +#define EGL_NV_context_priority_realtime 1 +#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 +#endif /* EGL_NV_context_priority_realtime */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif /* EGL_NV_coverage_sample */ + +#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 /* EGL_NV_coverage_sample_resolve */ + +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D +#endif /* EGL_NV_cuda_event */ + +#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 /* EGL_NV_depth_nonlinear */ + +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 +#define EGL_CUDA_DEVICE_NV 0x323A +#endif /* EGL_NV_device_cuda */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +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); +#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 +#endif /* EGL_NV_native_query */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +#endif /* EGL_NV_post_convert_rounding */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif +#endif /* EGL_NV_post_sub_buffer */ + +#ifndef EGL_NV_quadruple_buffer +#define EGL_NV_quadruple_buffer 1 +#define EGL_QUADRUPLE_BUFFER_NV 0x3231 +#endif /* EGL_NV_quadruple_buffer */ + +#ifndef EGL_NV_robustness_video_memory_purge +#define EGL_NV_robustness_video_memory_purge 1 +#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#endif /* EGL_NV_robustness_video_memory_purge */ + +#ifndef EGL_NV_stream_consumer_eglimage +#define EGL_NV_stream_consumer_eglimage 1 +#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373 +#define EGL_STREAM_IMAGE_ADD_NV 0x3374 +#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375 +#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list); +EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#endif +#endif /* EGL_NV_stream_consumer_eglimage */ + +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +#ifndef EGL_NV_stream_cross_display +#define EGL_NV_stream_cross_display 1 +#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E +#endif /* EGL_NV_stream_cross_display */ + +#ifndef EGL_NV_stream_cross_object +#define EGL_NV_stream_cross_object 1 +#define EGL_STREAM_CROSS_OBJECT_NV 0x334D +#endif /* EGL_NV_stream_cross_object */ + +#ifndef EGL_NV_stream_cross_partition +#define EGL_NV_stream_cross_partition 1 +#define EGL_STREAM_CROSS_PARTITION_NV 0x323F +#endif /* EGL_NV_stream_cross_partition */ + +#ifndef EGL_NV_stream_cross_process +#define EGL_NV_stream_cross_process 1 +#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 +#endif /* EGL_NV_stream_cross_process */ + +#ifndef EGL_NV_stream_cross_system +#define EGL_NV_stream_cross_system 1 +#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F +#endif /* EGL_NV_stream_cross_system */ + +#ifndef EGL_NV_stream_dma +#define EGL_NV_stream_dma 1 +#define EGL_STREAM_DMA_NV 0x3371 +#define EGL_STREAM_DMA_SERVER_NV 0x3372 +#endif /* EGL_NV_stream_dma */ + +#ifndef EGL_NV_stream_fifo_next +#define EGL_NV_stream_fifo_next 1 +#define EGL_PENDING_FRAME_NV 0x3329 +#define EGL_STREAM_TIME_PENDING_NV 0x332A +#endif /* EGL_NV_stream_fifo_next */ + +#ifndef EGL_NV_stream_fifo_synchronous +#define EGL_NV_stream_fifo_synchronous 1 +#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 +#endif /* EGL_NV_stream_fifo_synchronous */ + +#ifndef EGL_NV_stream_flush +#define EGL_NV_stream_flush 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_flush */ + +#ifndef EGL_NV_stream_frame_limits +#define EGL_NV_stream_frame_limits 1 +#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 +#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 +#endif /* EGL_NV_stream_frame_limits */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_PENDING_METADATA_NV 0x3328 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#endif +#endif /* EGL_NV_stream_metadata */ + +#ifndef EGL_NV_stream_origin +#define EGL_NV_stream_origin 1 +#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 +#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 +#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 +#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 +#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A +#define EGL_LEFT_NV 0x336B +#define EGL_RIGHT_NV 0x336C +#define EGL_TOP_NV 0x336D +#define EGL_BOTTOM_NV 0x336E +#define EGL_X_AXIS_NV 0x336F +#define EGL_Y_AXIS_NV 0x3370 +#endif /* EGL_NV_stream_origin */ + +#ifndef EGL_NV_stream_remote +#define EGL_NV_stream_remote 1 +#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 +#define EGL_STREAM_TYPE_NV 0x3241 +#define EGL_STREAM_PROTOCOL_NV 0x3242 +#define EGL_STREAM_ENDPOINT_NV 0x3243 +#define EGL_STREAM_LOCAL_NV 0x3244 +#define EGL_STREAM_PRODUCER_NV 0x3247 +#define EGL_STREAM_CONSUMER_NV 0x3248 +#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 +#endif /* EGL_NV_stream_remote */ + +#ifndef EGL_NV_stream_reset +#define EGL_NV_stream_reset 1 +#define EGL_SUPPORT_RESET_NV 0x3334 +#define EGL_SUPPORT_REUSE_NV 0x3335 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_reset */ + +#ifndef EGL_NV_stream_socket +#define EGL_NV_stream_socket 1 +#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B +#define EGL_SOCKET_HANDLE_NV 0x324C +#define EGL_SOCKET_TYPE_NV 0x324D +#endif /* EGL_NV_stream_socket */ + +#ifndef EGL_NV_stream_socket_inet +#define EGL_NV_stream_socket_inet 1 +#define EGL_SOCKET_TYPE_INET_NV 0x324F +#endif /* EGL_NV_stream_socket_inet */ + +#ifndef EGL_NV_stream_socket_unix +#define EGL_NV_stream_socket_unix 1 +#define EGL_SOCKET_TYPE_UNIX_NV 0x324E +#endif /* EGL_NV_stream_socket_unix */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 +#define EGL_SYNC_NEW_FRAME_NV 0x321F +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#endif +#endif /* EGL_NV_stream_sync */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef KHRONOS_SUPPORT_INT64 +#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 EGL_CAST(EGLSyncNV,0) +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); +#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 +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_sync */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_system_time */ + +#ifndef EGL_NV_triple_buffer +#define EGL_NV_triple_buffer 1 +#define EGL_TRIPLE_BUFFER_NV 0x3230 +#endif /* EGL_NV_triple_buffer */ + +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 +#endif /* EGL_TIZEN_image_native_buffer */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif /* EGL_TIZEN_image_native_surface */ + +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + +#ifdef __cplusplus +} +#endif + +#endif /* __eglext_h_ */ + +#endif /* _MSC_VER */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_endian.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_endian.h new file mode 100644 index 000000000..46c296253 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_endian.h @@ -0,0 +1,317 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_endian.h + * + * Functions for reading and writing endian-specific values + */ + +#ifndef SDL_endian_h_ +#define SDL_endian_h_ + +#include "SDL_stdinc.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ +#ifdef __clang__ +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ + +#include +#endif + +/** + * \name The two types of endianness + */ +/* @{ */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 +/* @} */ + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifdef __linux__ +#include +#define SDL_BYTEORDER __BYTE_ORDER +#elif defined(__OpenBSD__) +#include +#define SDL_BYTEORDER BYTE_ORDER +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#include +#define SDL_BYTEORDER BYTE_ORDER +#else +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MIPSEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_endian.h + */ + +/* various modern compilers may have builtin swap */ +#if defined(__GNUC__) || defined(__clang__) +# define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +# define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAS_BUILTIN_BSWAP64 (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + + /* this one is broken */ +# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95) +#else +# define HAS_BUILTIN_BSWAP16 0 +# define HAS_BUILTIN_BSWAP32 0 +# define HAS_BUILTIN_BSWAP64 0 +# define HAS_BROKEN_BSWAP 0 +#endif + +#if HAS_BUILTIN_BSWAP16 +#define SDL_Swap16(x) __builtin_bswap16(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ushort) +#define SDL_Swap16(x) _byteswap_ushort(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); + return (Uint16)result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint16 SDL_Swap16(Uint16); +#pragma aux SDL_Swap16 = \ + "xchg al, ah" \ + parm [ax] \ + modify [ax]; +#else +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); +} +#endif + +#if HAS_BUILTIN_BSWAP32 +#define SDL_Swap32(x) __builtin_bswap32(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ulong) +#define SDL_Swap32(x) _byteswap_ulong(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0": "=r"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); + return result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint32 SDL_Swap32(Uint32); +#pragma aux SDL_Swap32 = \ + "bswap eax" \ + parm [eax] \ + modify [eax]; +#else +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | (x >> 24))); +} +#endif + +#if HAS_BUILTIN_BSWAP64 +#define SDL_Swap64(x) __builtin_bswap64(x) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_uint64) +#define SDL_Swap64(x) _byteswap_uint64(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + union { + struct { + Uint32 a, b; + } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r"(v.s.a), "=r"(v.s.b) + : "0" (v.s.a), "1"(v.s.b)); + return v.u; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint64 SDL_Swap64(Uint64); +#pragma aux SDL_Swap64 = \ + "bswap eax" \ + "bswap edx" \ + "xchg eax,edx" \ + parm [eax edx] \ + modify [eax edx]; +#else +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif + + +SDL_FORCE_INLINE float +SDL_SwapFloat(float x) +{ + union { + float f; + Uint32 ui32; + } swapper; + swapper.f = x; + swapper.ui32 = SDL_Swap32(swapper.ui32); + return swapper.f; +} + +/* remove extra macros */ +#undef HAS_BROKEN_BSWAP +#undef HAS_BUILTIN_BSWAP16 +#undef HAS_BUILTIN_BSWAP32 +#undef HAS_BUILTIN_BSWAP64 + +/** + * \name Swap to native + * Byteswap item from the specified endianness to the native endianness. + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapFloatLE(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#define SDL_SwapFloatBE(X) (X) +#endif +/* @} *//* Swap to native */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_endian_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_error.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_error.h new file mode 100644 index 000000000..5c961e428 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_error.h @@ -0,0 +1,163 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_error.h + * + * Simple error message routines for SDL. + */ + +#ifndef SDL_error_h_ +#define SDL_error_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ + + +/** + * Set the SDL error message for the current thread. + * + * Calling this function will replace any previous error message that was set. + * + * This function always returns -1, since SDL frequently uses -1 to signify an + * failing result, leading to this idiom: + * + * ```c + * if (error_code) { + * return SDL_SetError("This operation has failed: %d", error_code); + * } + * ``` + * + * \param fmt a printf()-style message format string + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * \returns always -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_GetError + */ +extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Retrieve a message about the last error that occurred on the current + * thread. + * + * It is possible for multiple errors to occur before calling SDL_GetError(). + * Only the last error is returned. + * + * The message is only applicable when an SDL function has signaled an error. + * You must check the return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). You should *not* use the results of + * SDL_GetError() to decide if an error has occurred! Sometimes SDL will set + * an error string even when reporting success. + * + * SDL will *not* clear the error string for successful API calls. You *must* + * check return values for failure cases before you can assume the error + * string applies. + * + * Error strings are set per-thread, so an error set in a different thread + * will not interfere with the current thread's operation. + * + * The returned string is internally allocated and must not be freed by the + * application. + * + * \returns a message with information about the specific error that occurred, + * or an empty string if there hasn't been an error message set since + * the last call to SDL_ClearError(). The message is only applicable + * when an SDL function has signaled an error. You must check the + * return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_SetError + */ +extern DECLSPEC const char *SDLCALL SDL_GetError(void); + +/** + * Get the last error message that was set for the current thread. + * + * This allows the caller to copy the error string into a provided buffer, but + * otherwise operates exactly the same as SDL_GetError(). + * + * \param errstr A buffer to fill with the last error message that was set for + * the current thread + * \param maxlen The size of the buffer pointed to by the errstr parameter + * \returns the pointer passed in as the `errstr` parameter. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetError + */ +extern DECLSPEC char * SDLCALL SDL_GetErrorMsg(char *errstr, int maxlen); + +/** + * Clear any previous error message for this thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetError + * \sa SDL_SetError + */ +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/** + * \name Internal error functions + * + * \internal + * Private error reporting function - used internally. + */ +/* @{ */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) +typedef enum +{ + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +/* SDL_Error() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); +/* @} *//* Internal error functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_error_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_events.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_events.h new file mode 100644 index 000000000..3722a6311 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_events.h @@ -0,0 +1,1135 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_events.h + * + * Include file for SDL event handling. + */ + +#ifndef SDL_events_h_ +#define SDL_events_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_quit.h" +#include "SDL_gesture.h" +#include "SDL_touch.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/** + * The types of events that can be delivered. + */ +typedef enum +{ + SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ + + /* Application events */ + SDL_QUIT = 0x100, /**< User-requested quit */ + + /* These application events have special meaning on iOS, see README-ios.md for details */ + SDL_APP_TERMINATING, /**< The application is being terminated by the OS + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + */ + SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onLowMemory() + */ + SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + */ + SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + */ + SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + */ + SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + */ + + SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ + + /* Display events */ + SDL_DISPLAYEVENT = 0x150, /**< Display state change */ + + /* Window events */ + SDL_WINDOWEVENT = 0x200, /**< Window state change */ + SDL_SYSWMEVENT, /**< System specific event */ + + /* Keyboard events */ + SDL_KEYDOWN = 0x300, /**< Key pressed */ + SDL_KEYUP, /**< Key released */ + SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ + SDL_TEXTINPUT, /**< Keyboard text input */ + SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an + input language or keyboard layout change. + */ + + /* Mouse events */ + SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ + + /* Joystick events */ + SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ + SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */ + SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */ + SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */ + SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */ + + /* Touch events */ + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + + /* Gesture events */ + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + + /* Clipboard events */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + + /* Drag and drop events */ + SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ + + /* Audio hotplug events */ + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ + + /* Sensor events */ + SDL_SENSORUPDATE = 0x1200, /**< A sensor was updated */ + + /* Render events */ + SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ + SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + + /* Internal events */ + SDL_POLLSENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */ + + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, + * and should be allocated with SDL_RegisterEvents() + */ + SDL_USEREVENT = 0x8000, + + /** + * This last event is only for bounding internal arrays + */ + SDL_LASTEVENT = 0xFFFF +} SDL_EventType; + +/** + * \brief Fields shared by every event + */ +typedef struct SDL_CommonEvent +{ + Uint32 type; + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_CommonEvent; + +/** + * \brief Display state change event data (event.display.*) + */ +typedef struct SDL_DisplayEvent +{ + Uint32 type; /**< ::SDL_DISPLAYEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 display; /**< The associated display index */ + Uint8 event; /**< ::SDL_DisplayEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ +} SDL_DisplayEvent; + +/** + * \brief Window state change event data (event.window.*) + */ +typedef struct SDL_WindowEvent +{ + Uint32 type; /**< ::SDL_WINDOWEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window */ + Uint8 event; /**< ::SDL_WindowEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ + Sint32 data2; /**< event dependent data */ +} SDL_WindowEvent; + +/** + * \brief Keyboard button event structure (event.key.*) + */ +typedef struct SDL_KeyboardEvent +{ + Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 repeat; /**< Non-zero if this is a key repeat */ + Uint8 padding2; + Uint8 padding3; + SDL_Keysym keysym; /**< The key that was pressed or released */ +} SDL_KeyboardEvent; + +#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text editing event structure (event.edit.*) + */ +typedef struct SDL_TextEditingEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingEvent; + + +#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text input event structure (event.text.*) + */ +typedef struct SDL_TextInputEvent +{ + Uint32 type; /**< ::SDL_TEXTINPUT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ +} SDL_TextInputEvent; + +/** + * \brief Mouse motion event structure (event.motion.*) + */ +typedef struct SDL_MouseMotionEvent +{ + Uint32 type; /**< ::SDL_MOUSEMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint32 state; /**< The current button state */ + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ + Sint32 xrel; /**< The relative motion in the X direction */ + Sint32 yrel; /**< The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/** + * \brief Mouse button event structure (event.button.*) + */ +typedef struct SDL_MouseButtonEvent +{ + Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ + Uint8 padding1; + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ +} SDL_MouseButtonEvent; + +/** + * \brief Mouse wheel event structure (event.wheel.*) + */ +typedef struct SDL_MouseWheelEvent +{ + Uint32 type; /**< ::SDL_MOUSEWHEEL */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ + Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ + Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ + float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */ + float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */ +} SDL_MouseWheelEvent; + +/** + * \brief Joystick axis motion event structure (event.jaxis.*) + */ +typedef struct SDL_JoyAxisEvent +{ + Uint32 type; /**< ::SDL_JOYAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The joystick axis index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_JoyAxisEvent; + +/** + * \brief Joystick trackball motion event structure (event.jball.*) + */ +typedef struct SDL_JoyBallEvent +{ + Uint32 type; /**< ::SDL_JOYBALLMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 ball; /**< The joystick trackball index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/** + * \brief Joystick hat position change event structure (event.jhat.*) + */ +typedef struct SDL_JoyHatEvent +{ + Uint32 type; /**< ::SDL_JOYHATMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value. + * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP + * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT + * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyHatEvent; + +/** + * \brief Joystick button event structure (event.jbutton.*) + */ +typedef struct SDL_JoyButtonEvent +{ + Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyButtonEvent; + +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ +} SDL_JoyDeviceEvent; + + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The controller button (SDL_GameControllerButton) */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ +} SDL_ControllerDeviceEvent; + +/** + * \brief Game controller touchpad event structure (event.ctouchpad.*) + */ +typedef struct SDL_ControllerTouchpadEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 touchpad; /**< The index of the touchpad */ + Sint32 finger; /**< The index of the finger on the touchpad */ + float x; /**< Normalized in the range 0...1 with 0 being on the left */ + float y; /**< Normalized in the range 0...1 with 0 being at the top */ + float pressure; /**< Normalized in the range 0...1 */ +} SDL_ControllerTouchpadEvent; + +/** + * \brief Game controller sensor event structure (event.csensor.*) + */ +typedef struct SDL_ControllerSensorEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ + float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ +} SDL_ControllerSensorEvent; + +/** + * \brief Audio device event structure (event.adevice.*) + */ +typedef struct SDL_AudioDeviceEvent +{ + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; +} SDL_AudioDeviceEvent; + + +/** + * \brief Touch finger event structure (event.tfinger.*) + */ +typedef struct SDL_TouchFingerEvent +{ + Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_FingerID fingerId; + float x; /**< Normalized in the range 0...1 */ + float y; /**< Normalized in the range 0...1 */ + float dx; /**< Normalized in the range -1...1 */ + float dy; /**< Normalized in the range -1...1 */ + float pressure; /**< Normalized in the range 0...1 */ + Uint32 windowID; /**< The window underneath the finger, if any */ +} SDL_TouchFingerEvent; + + +/** + * \brief Multiple Finger Gesture Event (event.mgesture.*) + */ +typedef struct SDL_MultiGestureEvent +{ + Uint32 type; /**< ::SDL_MULTIGESTURE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + float dTheta; + float dDist; + float x; + float y; + Uint16 numFingers; + Uint16 padding; +} SDL_MultiGestureEvent; + + +/** + * \brief Dollar Gesture Event (event.dgesture.*) + */ +typedef struct SDL_DollarGestureEvent +{ + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_GestureID gestureId; + Uint32 numFingers; + float error; + float x; /**< Normalized center of gesture */ + float y; /**< Normalized center of gesture */ +} SDL_DollarGestureEvent; + + +/** + * \brief An event used to request a file open by the system (event.drop.*) + * This event is enabled by default, you can disable it with SDL_EventState(). + * \note If this event is enabled, you must free the filename in the event. + */ +typedef struct SDL_DropEvent +{ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ +} SDL_DropEvent; + + +/** + * \brief Sensor event structure (event.sensor.*) + */ +typedef struct SDL_SensorEvent +{ + Uint32 type; /**< ::SDL_SENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The instance ID of the sensor */ + float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ +} SDL_SensorEvent; + +/** + * \brief The "quit requested" event + */ +typedef struct SDL_QuitEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_QuitEvent; + +/** + * \brief OS Specific event + */ +typedef struct SDL_OSEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_OSEvent; + +/** + * \brief A user-defined event type (event.user.*) + */ +typedef struct SDL_UserEvent +{ + Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window if any */ + Sint32 code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ +} SDL_UserEvent; + + +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; + +/** + * \brief A video driver dependent system event (event.syswm.*) + * This event is disabled by default, you can enable it with SDL_EventState() + * + * \note If you want to use this event, you should include SDL_syswm.h. + */ +typedef struct SDL_SysWMEvent +{ + Uint32 type; /**< ::SDL_SYSWMEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ +} SDL_SysWMEvent; + +/** + * \brief General event structure + */ +typedef union SDL_Event +{ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_DisplayEvent display; /**< Display event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */ + SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_SensorEvent sensor; /**< Sensor event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC. + Visual C++ will respect the push pack pragma and use 52 bytes (size of + SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit + architectures) for this union, and GCC will use the alignment of the + largest datatype within the union, which is 8 bytes on 64-bit + architectures. + + So... we'll add padding to force the size to be 56 bytes for both. + + On architectures where pointers are 16 bytes, this needs rounding up to + the next multiple of 16, 64, and on architectures where pointers are + even larger the size of SDL_UserEvent will dominate as being 3 pointers. + */ + Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; +} SDL_Event; + +/* Make sure we haven't broken binary compatibility */ +SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); + + +/* Function prototypes */ + +/** + * Pump the event loop, gathering events from the input devices. + * + * This function updates the event queue and internal input device state. + * + * **WARNING**: This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider only doing those + * things on the main thread in any case. + * + * SDL_PumpEvents() gathers all the pending input information from devices and + * places it in the event queue. Without calls to SDL_PumpEvents() no events + * would ever be placed on the queue. Often the need for calls to + * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and + * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not + * polling or waiting for events (e.g. you are filtering them), then you must + * call SDL_PumpEvents() to force an event queue update. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent + */ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* @{ */ +typedef enum +{ + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; + +/** + * Check the event queue for messages and optionally return them. + * + * `action` may be any of the following: + * + * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the + * event queue. + * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will _not_ be removed from the queue. + * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will be removed from the queue. + * + * You may have to call SDL_PumpEvents() before calling this function. + * Otherwise, the events may not be ready to be filtered when you call + * SDL_PeepEvents(). + * + * This function is thread-safe. + * + * \param events destination buffer for the retrieved events + * \param numevents if action is SDL_ADDEVENT, the number of events to add + * back to the event queue; if action is SDL_PEEKEVENT or + * SDL_GETEVENT, the maximum number of events to retrieve + * \param action action to take; see [[#action|Remarks]] for details + * \param minType minimum value of the event type to be considered; + * SDL_FIRSTEVENT is a safe choice + * \param maxType maximum value of the event type to be considered; + * SDL_LASTEVENT is a safe choice + * \returns the number of events actually stored or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, + SDL_eventaction action, + Uint32 minType, Uint32 maxType); +/* @} */ + +/** + * Check for the existence of a certain event type in the event queue. + * + * If you need to check for a range of event types, use SDL_HasEvents() + * instead. + * + * \param type the type of event to be queried; see SDL_EventType for details + * \returns SDL_TRUE if events matching `type` are present, or SDL_FALSE if + * events matching `type` are not present. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); + + +/** + * Check for the existence of certain event types in the event queue. + * + * If you need to check for a single event type, use SDL_HasEvent() instead. + * + * \param minType the low end of event type to be queried, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be queried, inclusive; see + * SDL_EventType for details + * \returns SDL_TRUE if events with type >= `minType` and <= `maxType` are + * present, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); + +/** + * Clear events of a specific type from the event queue. + * + * This will unconditionally remove any events from the queue that match + * `type`. If you need to remove a range of event types, use SDL_FlushEvents() + * instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param type the type of event to be cleared; see SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvents + */ +extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); + +/** + * Clear events of a range of types from the event queue. + * + * This will unconditionally remove any events from the queue that are in the + * range of `minType` to `maxType`, inclusive. If you need to remove a single + * event type, use SDL_FlushEvent() instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param minType the low end of event type to be cleared, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be cleared, inclusive; see + * SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvent + */ +extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); + +/** + * Poll for currently pending events. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. The 1 returned refers to + * this event, immediately stored in the SDL Event structure -- not an event + * to follow. + * + * If `event` is NULL, it simply returns 1 if there is an event in the queue, + * but will not remove it from the queue. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that set the video mode. + * + * SDL_PollEvent() is the favored way of receiving system events since it can + * be done from the main loop and does not suspend the main loop while waiting + * on an event to be posted. + * + * The common practice is to fully process the event queue once every frame, + * usually as a first step before updating the game's state: + * + * ```c + * while (game_is_still_running) { + * SDL_Event event; + * while (SDL_PollEvent(&event)) { // poll until all events are handled! + * // decide what to do with this event. + * } + * + * // update game state, draw the current frame + * } + * ``` + * + * \param event the SDL_Event structure to be filled with the next event from + * the queue, or NULL + * \returns 1 if there is a pending event or 0 if there are none available. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + * \sa SDL_SetEventFilter + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); + +/** + * Wait indefinitely for the next available event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEventTimeout + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); + +/** + * Wait until the specified timeout (in milliseconds) for the next available + * event. + * + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \param timeout the maximum number of milliseconds to wait for the next + * available event + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. This also returns 0 if + * the timeout elapsed without an event arriving. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEvent + */ +extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, + int timeout); + +/** + * Add an event to the event queue. + * + * The event queue can actually be used as a two way communication channel. + * Not only can events be read from the queue, but the user can also push + * their own events onto it. `event` is a pointer to the event structure you + * wish to push onto the queue. The event is copied into the queue, and the + * caller may dispose of the memory pointed to after SDL_PushEvent() returns. + * + * Note: Pushing device input events onto the queue doesn't modify the state + * of the device within SDL. + * + * This function is thread-safe, and can be called from other threads safely. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter but events added with SDL_PeepEvents() do not. + * + * For pushing application-specific events, please use SDL_RegisterEvents() to + * get an event type that does not conflict with other code that also wants + * its own custom event types. + * + * \param event the SDL_Event to be added to the queue + * \returns 1 on success, 0 if the event was filtered, or a negative error + * code on failure; call SDL_GetError() for more information. A + * common reason for error is the event queue being full. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PeepEvents + * \sa SDL_PollEvent + * \sa SDL_RegisterEvents + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); + +/** + * A function pointer used for callbacks that watch the event queue. + * + * \param userdata what was passed as `userdata` to SDL_SetEventFilter() + * or SDL_AddEventWatch, etc + * \param event the event that triggered the callback + * \returns 1 to permit event to be added to the queue, and 0 to disallow + * it. When used with SDL_AddEventWatch, the return value is ignored. + * + * \sa SDL_SetEventFilter + * \sa SDL_AddEventWatch + */ +typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); + +/** + * Set up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * If the filter function returns 1 when called, then the event will be added + * to the internal queue. If it returns 0, then the event will be dropped from + * the queue, but the internal state will still be updated. This allows + * selective filtering of dynamically arriving events. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * On platforms that support it, if the quit event is generated by an + * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the + * application at the next event poll. + * + * There is one caveat when dealing with the ::SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will be + * closed, otherwise the window will remain open if possible. + * + * Note: Disabled events never make it to the event filter function; see + * SDL_EventState(). + * + * Note: If you just want to inspect events without filtering, you should use + * SDL_AddEventWatch() instead. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter, but events pushed onto the queue with SDL_PeepEvents() do + * not. + * + * \param filter An SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + * \sa SDL_EventState + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + */ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, + void *userdata); + +/** + * Query the current event filter. + * + * This function can be used to "chain" filters, by saving the existing filter + * before replacing it with a function that will call that saved filter. + * + * \param filter the current callback function will be stored here + * \param userdata the pointer that is passed to the current event filter will + * be stored here + * \returns SDL_TRUE on success or SDL_FALSE if there is no event filter set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetEventFilter + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, + void **userdata); + +/** + * Add a callback to be triggered when an event is added to the event queue. + * + * `filter` will be called when an event happens, and its return value is + * ignored. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * If the quit event is generated by a signal (e.g. SIGINT), it will bypass + * the internal queue and be delivered to the watch callback immediately, and + * arrive at the next event poll. + * + * Note: the callback is called for events posted by the user through + * SDL_PushEvent(), but not for disabled events, nor for events by a filter + * callback set with SDL_SetEventFilter(), nor for events posted by the user + * through SDL_PeepEvents(). + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelEventWatch + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch callback added with SDL_AddEventWatch(). + * + * This function takes the same input as SDL_AddEventWatch() to identify and + * delete the corresponding callback. + * + * \param filter the function originally passed to SDL_AddEventWatch() + * \param userdata the pointer originally passed to SDL_AddEventWatch() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Run a specific filter function on the current event queue, removing any + * events for which the filter returns 0. + * + * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), + * this function does not change the filter permanently, it only uses the + * supplied filter until this function returns. + * + * \param filter the SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_SetEventFilter + */ +extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, + void *userdata); + +/* @{ */ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 + +/** + * Set the state of processing events by type. + * + * `state` may be any of the following: + * + * - `SDL_QUERY`: returns the current processing state of the specified event + * - `SDL_IGNORE` (aka `SDL_DISABLE`): the event will automatically be dropped + * from the event queue and will not be filtered + * - `SDL_ENABLE`: the event will be processed normally + * + * \param type the type of event; see SDL_EventType for details + * \param state how to process the event + * \returns `SDL_DISABLE` or `SDL_ENABLE`, representing the processing state + * of the event before this function makes any changes to it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventState + */ +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); +/* @} */ +#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) + +/** + * Allocate a set of user-defined events, and return the beginning event + * number for that set of events. + * + * Calling this function with `numevents` <= 0 is an error and will return + * (Uint32)-1. + * + * Note, (Uint32)-1 means the maximum unsigned 32-bit integer value (or + * 0xFFFFFFFF), but is clearer to write. + * + * \param numevents the number of events to be allocated + * \returns the beginning event number, or (Uint32)-1 if there are not enough + * user-defined events left. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PushEvent + */ +extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_events_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_filesystem.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_filesystem.h new file mode 100644 index 000000000..16f02e287 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_filesystem.h @@ -0,0 +1,145 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_filesystem.h + * + * \brief Include file for filesystem SDL API functions + */ + +#ifndef SDL_filesystem_h_ +#define SDL_filesystem_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the directory where the application was run from. + * + * This is not necessarily a fast call, so you should call this once near + * startup and save the string if you need it. + * + * **Mac OS X and iOS Specific Functionality**: If the application is in a + * ".app" bundle, this function returns the Resource directory (e.g. + * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding + * a property to the Info.plist file. Adding a string key with the name + * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the + * behaviour. + * + * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an + * application in /Applications/SDLApp/MyApp.app): + * + * - `resource`: bundle resource directory (the default). For example: + * `/Applications/SDLApp/MyApp.app/Contents/Resources` + * - `bundle`: the Bundle directory. For example: + * `/Applications/SDLApp/MyApp.app/` + * - `parent`: the containing directory of the bundle. For example: + * `/Applications/SDLApp/` + * + * The returned path is guaranteed to end with a path separator ('\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \returns an absolute path in UTF-8 encoding to the application data + * directory. NULL will be returned on error or when the platform + * doesn't implement this functionality, call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetPrefPath + */ +extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); + +/** + * Get the user-and-app-specific path where files can be written. + * + * Get the "pref dir". This is meant to be where users can write personal + * files (preferences and save games, etc) that are specific to your + * application. This directory is unique per user, per application. + * + * This function will decide the appropriate location in the native + * filesystem, create the directory if necessary, and return a string of the + * absolute path to the directory in UTF-8 encoding. + * + * On Windows, the string might look like: + * + * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\` + * + * On Linux, the string might look like" + * + * `/home/bob/.local/share/My Program Name/` + * + * On Mac OS X, the string might look like: + * + * `/Users/bob/Library/Application Support/My Program Name/` + * + * You should assume the path returned by this function is the only safe place + * to write files (and that SDL_GetBasePath(), while it might be writable, or + * even the parent of the returned path, isn't where you should be writing + * things). + * + * Both the org and app strings may become part of a directory name, so please + * follow these rules: + * + * - Try to use the same org string (_including case-sensitivity_) for all + * your applications that use this function. + * - Always use a unique app string for each one, and make sure it never + * changes for an app once you've decided on it. + * - Unicode characters are legal, as long as it's UTF-8 encoded, but... + * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game + * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. + * + * The returned path is guaranteed to end with a path separator ('\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \param org the name of your organization + * \param app the name of your application + * \returns a UTF-8 string of the user directory in platform-dependent + * notation. NULL if there's a problem (creating directory failed, + * etc.). + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetBasePath + */ +extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_filesystem_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_gamecontroller.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_gamecontroller.h new file mode 100644 index 000000000..bdd9b8993 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_gamecontroller.h @@ -0,0 +1,1001 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef SDL_gamecontroller_h_ +#define SDL_gamecontroller_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + * + * If you would like to receive controller updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The gamecontroller structure used to identify an SDL game controller + */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + +typedef enum +{ + SDL_CONTROLLER_TYPE_UNKNOWN = 0, + SDL_CONTROLLER_TYPE_XBOX360, + SDL_CONTROLLER_TYPE_XBOXONE, + SDL_CONTROLLER_TYPE_PS3, + SDL_CONTROLLER_TYPE_PS4, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO, + SDL_CONTROLLER_TYPE_VIRTUAL, + SDL_CONTROLLER_TYPE_PS5, + SDL_CONTROLLER_TYPE_AMAZON_LUNA, + SDL_CONTROLLER_TYPE_GOOGLE_STADIA +} SDL_GameControllerType; + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +/** + * Get the SDL joystick layer binding for this controller button/axis mapping + */ +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * + * ```c + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for (int i = 0; i < nJoysticks; i++) { + * if (SDL_IsGameController(i)) { + * nGameControllers++; + * } + * } + * ``` + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * + * ```c + * "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * ``` + */ + +/** + * Load a set of Game Controller mappings from a seekable SDL data stream. + * + * You can call this function several times, if needed, to load different + * database files. + * + * If a new mapping is loaded for an already known controller GUID, the later + * version will overwrite the one currently loaded. + * + * Mappings not belonging to the current platform or with no platform field + * specified will be ignored (i.e. mappings for Linux will be ignored in + * Windows, etc). + * + * This function will load the text database entirely in memory before + * processing it, so take this into consideration if you are in a memory + * constrained environment. + * + * \param rw the data stream for the mappings to be added + * \param freerw non-zero to close the stream after being read + * \returns the number of mappings added or -1 on error; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerAddMappingsFromFile + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw); + +/** + * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() + * + * Convenience macro. + */ +#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Add support for controllers that SDL is unaware of or to cause an existing + * controller to have a different binding. + * + * The mapping string has the format "GUID,name,mapping", where GUID is the + * string value from SDL_JoystickGetGUIDString(), name is the human readable + * string for the device and mappings are controller mappings to joystick + * ones. Under Windows there is a reserved GUID of "xinput" that covers all + * XInput devices. The mapping format for joystick is: {| |bX |a joystick + * button, index X |- |hX.Y |hat X with value Y |- |aX |axis X of the joystick + * |} Buttons can be used as a controller axes and vice versa. + * + * This string shows an example of a valid mapping for a controller: + * + * ```c + * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" + * ``` + * + * \param mappingString the mapping string + * \returns 1 if a new mapping is added, 0 if an existing mapping is updated, + * -1 on error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString); + +/** + * Get the number of mappings installed. + * + * \returns the number of mappings. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void); + +/** + * Get the mapping at a particular index. + * + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * the index is out of range. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index); + +/** + * Get the game controller mapping string for a given GUID. + * + * The returned string must be freed with SDL_free(). + * + * \param guid a structure containing the GUID for which a mapping is desired + * \returns a mapping string or NULL on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid); + +/** + * Get the current mapping of a Game Controller. + * + * The returned string must be freed with SDL_free(). + * + * Details about mappings are discussed with SDL_GameControllerAddMapping(). + * + * \param gamecontroller the game controller you want to get the current + * mapping for + * \returns a string that has the controller's mapping or NULL if no mapping + * is available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller); + +/** + * Check if the given joystick is supported by the game controller interface. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns SDL_TRUE if the given joystick is supported by the game controller + * interface, SDL_FALSE if it isn't or it's an invalid index. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); + +/** + * Get the implementation dependent name for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent name for the game controller, or NULL + * if there is no name or the index is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerName + * \sa SDL_GameControllerOpen + * \sa SDL_IsGameController + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Get the type of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index); + +/** + * Get the mapping of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * no mapping is available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); + +/** + * Open a game controller for use. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * The index passed as an argument refers to the N'th game controller on the + * system. This index is not the value which will identify this controller in + * future controller events. The joystick's instance id (SDL_JoystickID) will + * be used there instead. + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns a gamecontroller identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerNameForIndex + * \sa SDL_IsGameController + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Get the SDL_GameController associated with an instance id. + * + * \param joyid the instance id to get the SDL_GameController for + * \returns an SDL_GameController on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); + +/** + * Get the SDL_GameController associated with a player index. + * + * Please note that the player index is _not_ the device index, nor is it the + * instance id! + * + * \param player_index the player index, which is not the device index or the + * instance id! + * \returns the SDL_GameController associated with a player index. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GameControllerGetPlayerIndex + * \sa SDL_GameControllerSetPlayerIndex + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(int player_index); + +/** + * Get the implementation-dependent name for an opened game controller. + * + * This is the same name as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent name for the game controller, or NULL + * if there is no name or the identifier passed is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); + +/** + * Get the type of this currently opened controller + * + * This is the same name as returned by SDL_GameControllerTypeForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller the game controller object to query. + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller); + +/** + * Get the player index of an opened game controller. + * + * For XInput controllers this returns the XInput user index. + * + * \param gamecontroller the game controller object to query. + * \returns the player index for controller, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller); + +/** + * Set the player index of an opened game controller. + * + * \param gamecontroller the game controller object to adjust. + * \param player_index Player index to assign to this controller. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index); + +/** + * Get the USB vendor ID of an opened controller, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB vendor ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController *gamecontroller); + +/** + * Get the USB product ID of an opened controller, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *gamecontroller); + +/** + * Get the product version of an opened controller, if available. + * + * If the product version isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product version, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller); + +/** + * Get the serial number of an opened controller, if available. + * + * Returns the serial number of the controller, or NULL if it is not + * available. + * + * \param gamecontroller the game controller object to query. + * \return the serial number, or NULL if unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller); + +/** + * Check if a controller has been opened and is currently connected. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns SDL_TRUE if the controller has been opened and is currently + * connected, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); + +/** + * Get the Joystick ID from a Game Controller. + * + * This function will give you a SDL_Joystick object, which allows you to use + * the SDL_Joystick functions with a SDL_GameController object. This would be + * useful for getting a joystick's position at any given time, even if it + * hasn't moved (moving it would produce an event, which would have the axis' + * value). + * + * The pointer returned is owned by the SDL_GameController. You should not + * call SDL_JoystickClose() on it, for example, since doing so will likely + * cause SDL to crash. + * + * \param gamecontroller the game controller object that you want to get a + * joystick from + * \returns a SDL_Joystick object; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); + +/** + * Query or change current state of Game Controller events. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * Any number can be passed to SDL_GameControllerEventState(), but only -1, 0, + * and 1 will have any effect. Other numbers will just be returned. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns the same value passed to the function, with exception to -1 + * (SDL_QUERY), which will return the current state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * Manually pump game controller updates if not using the loop. + * + * This function is called automatically by the event loop if events are + * enabled. Under such circumstances, it will not be necessary to call this + * function. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); + + +/** + * The list of axes available from a controller + * + * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to SDL_JOYSTICK_AXIS_MAX, + * and are centered within ~8000 of zero, though advanced UI will allow users to set + * or autodetect the dead zone, which varies between controllers. + * + * Trigger axis values range from 0 to SDL_JOYSTICK_AXIS_MAX. + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_GameControllerAxis; + +/** + * Convert a string into SDL_GameControllerAxis enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * Note specially that "righttrigger" and "lefttrigger" map to + * `SDL_CONTROLLER_AXIS_TRIGGERRIGHT` and `SDL_CONTROLLER_AXIS_TRIGGERLEFT`, + * respectively. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerAxis enum corresponding to the input string, + * or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetStringForAxis + */ +extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *str); + +/** + * Convert from an SDL_GameControllerAxis enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param axis an enum value for a given SDL_GameControllerAxis + * \returns a string for the given axis, or NULL if an invalid axis is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxisFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); + +/** + * Get the SDL joystick layer binding for a controller axis mapping. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (one of the SDL_GameControllerAxis values) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller axis doesn't exist on the device), its + * `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForButton + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * Query whether a game controller has a given axis. + * + * This merely reports whether the controller's mapping defined this axis, as + * that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (an SDL_GameControllerAxis value) + * \returns SDL_TRUE if the controller has this axis, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL +SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * Get the current state of an axis control on a game controller. + * + * The axis indices start at index 0. + * + * The state is a value ranging from -32768 to 32767. Triggers, however, range + * from 0 to 32767 (they never return a negative value). + * + * \param gamecontroller a game controller + * \param axis an axis index (one of the SDL_GameControllerAxis values) + * \returns axis state (including 0) on success or 0 (also) on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButton + */ +extern DECLSPEC Sint16 SDLCALL +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ + SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 */ + SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 */ + SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 */ + SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 */ + SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ + SDL_CONTROLLER_BUTTON_MAX +} SDL_GameControllerButton; + +/** + * Convert a string into an SDL_GameControllerButton enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerButton enum corresponding to the input + * string, or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *str); + +/** + * Convert from an SDL_GameControllerButton enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param button an enum value for a given SDL_GameControllerButton + * \returns a string for the given button, or NULL if an invalid axis is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButtonFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); + +/** + * Get the SDL joystick layer binding for a controller button mapping. + * + * \param gamecontroller a game controller + * \param button an button enum value (an SDL_GameControllerButton value) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller button doesn't exist on the device), + * its `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForAxis + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Query whether a game controller has a given button. + * + * This merely reports whether the controller's mapping defined this button, + * as that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param button a button enum value (an SDL_GameControllerButton value) + * \returns SDL_TRUE if the controller has this button, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the current state of a button on a game controller. + * + * \param gamecontroller a game controller + * \param button a button index (one of the SDL_GameControllerButton values) + * \returns 1 for pressed state or 0 for not pressed state or error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxis + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the number of touchpads on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller); + +/** + * Get the number of supported simultaneous fingers on a touchpad on a game + * controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad); + +/** + * Get the current state of a finger on a touchpad on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure); + +/** + * Return whether a game controller has a particular sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor exists, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Set whether data reporting for a game controller sensor is enabled. + * + * \param gamecontroller The controller to update + * \param type The type of sensor to enable/disable + * \param enabled Whether data reporting should be enabled + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled); + +/** + * Query whether sensor data reporting is enabled for a game controller. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor is enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the data rate (number of events per second) of a game controller + * sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \return the data rate, or 0.0f if the data rate is not available. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC float SDLCALL SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the current state of a game controller sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * See SDL_sensor.h for the details for each type of sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \return 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values); + +/** + * Start a rumble effect on a game controller. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param gamecontroller The controller to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GameControllerHasRumble + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the game controller's triggers. + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. The first controller to offer this feature was the PlayStation 5's + * DualShock 5. + * + * \param gamecontroller The controller to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GameControllerHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a game controller has an LED. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have a + * modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have rumble + * support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumble(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support on triggers. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have trigger + * rumble support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller); + +/** + * Update a game controller's LED color. + * + * \param gamecontroller The controller to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0, or -1 if this controller does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a controller specific effect packet + * + * \param gamecontroller The controller to affect + * \param data The data to send to the controller + * \param size The size of the data to send to the controller + * \returns 0, or -1 if this controller or driver doesn't support effect + * packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size); + +/** + * Close a game controller previously opened with SDL_GameControllerOpen(). + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); + +/** + * Return the sfSymbolsName for a given button on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param button a button on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForAxis + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button); + +/** + * Return the sfSymbolsName for a given axis on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param axis an axis on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForButton + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gamecontroller_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_gesture.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_gesture.h new file mode 100644 index 000000000..e2caea2a9 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_gesture.h @@ -0,0 +1,117 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gesture.h + * + * Include file for SDL gesture event handling. + */ + +#ifndef SDL_gesture_h_ +#define SDL_gesture_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "SDL_touch.h" + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_GestureID; + +/* Function prototypes */ + +/** + * Begin recording a gesture on a specified touch device or all touch devices. + * + * If the parameter `touchId` is -1 (i.e., all devices), this function will + * always return 1, regardless of whether there actually are any devices. + * + * \param touchId the touch device id, or -1 for all touch devices + * \returns 1 on success or 0 if the specified device could not be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice + */ +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); + + +/** + * Save all currently loaded Dollar Gesture templates. + * + * \param dst a SDL_RWops to save to + * \returns the number of saved templates on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); + +/** + * Save a currently loaded Dollar Gesture template. + * + * \param gestureId a gesture id + * \param dst a SDL_RWops to save to + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveAllDollarTemplates + */ +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); + + +/** + * Load Dollar Gesture templates from a file. + * + * \param touchId a touch id + * \param src a SDL_RWops to load from + * \returns the number of loaded templates on success or a negative error code + * (or 0) on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SaveAllDollarTemplates + * \sa SDL_SaveDollarTemplate + */ +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gesture_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_haptic.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_haptic.h new file mode 100644 index 000000000..f240ae927 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_haptic.h @@ -0,0 +1,1341 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_haptic.h + * + * \brief The SDL haptic subsystem allows you to control haptic (force feedback) + * devices. + * + * The basic usage is as follows: + * - Initialize the subsystem (::SDL_INIT_HAPTIC). + * - Open a haptic device. + * - SDL_HapticOpen() to open from index. + * - SDL_HapticOpenFromJoystick() to open from an existing joystick. + * - Create an effect (::SDL_HapticEffect). + * - Upload the effect with SDL_HapticNewEffect(). + * - Run the effect with SDL_HapticRunEffect(). + * - (optional) Free the effect with SDL_HapticDestroyEffect(). + * - Close the haptic device with SDL_HapticClose(). + * + * \par Simple rumble example: + * \code + * SDL_Haptic *haptic; + * + * // Open the device + * haptic = SDL_HapticOpen( 0 ); + * if (haptic == NULL) + * return -1; + * + * // Initialize simple rumble + * if (SDL_HapticRumbleInit( haptic ) != 0) + * return -1; + * + * // Play effect at 50% strength for 2 seconds + * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) + * return -1; + * SDL_Delay( 2000 ); + * + * // Clean up + * SDL_HapticClose( haptic ); + * \endcode + * + * \par Complete example: + * \code + * int test_haptic( SDL_Joystick * joystick ) { + * SDL_Haptic *haptic; + * SDL_HapticEffect effect; + * int effect_id; + * + * // Open the device + * haptic = SDL_HapticOpenFromJoystick( joystick ); + * if (haptic == NULL) return -1; // Most likely joystick isn't haptic + * + * // See if it can do sine waves + * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { + * SDL_HapticClose(haptic); // No sine effect + * return -1; + * } + * + * // Create the effect + * SDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + * effect.type = SDL_HAPTIC_SINE; + * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates + * effect.periodic.direction.dir[0] = 18000; // Force comes from south + * effect.periodic.period = 1000; // 1000 ms + * effect.periodic.magnitude = 20000; // 20000/32767 strength + * effect.periodic.length = 5000; // 5 seconds long + * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength + * effect.periodic.fade_length = 1000; // Takes 1 second to fade away + * + * // Upload the effect + * effect_id = SDL_HapticNewEffect( haptic, &effect ); + * + * // Test the effect + * SDL_HapticRunEffect( haptic, effect_id, 1 ); + * SDL_Delay( 5000); // Wait for the effect to finish + * + * // We destroy the effect, although closing the device also does this + * SDL_HapticDestroyEffect( haptic, effect_id ); + * + * // Close the device + * SDL_HapticClose(haptic); + * + * return 0; // Success + * } + * \endcode + */ + +#ifndef SDL_haptic_h_ +#define SDL_haptic_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF). + * + * At the moment the magnitude variables are mixed between signed/unsigned, and + * it is also not made clear that ALL of those variables expect a max of 0x7FFF. + * + * Some platforms may have higher precision than that (Linux FF, Windows XInput) + * so we should fix the inconsistency in favor of higher possible precision, + * adjusting for platforms that use different scales. + * -flibit + */ + +/** + * \typedef SDL_Haptic + * + * \brief The haptic structure used to identify an SDL haptic. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + */ +struct _SDL_Haptic; +typedef struct _SDL_Haptic SDL_Haptic; + + +/** + * \name Haptic features + * + * Different haptic features a device can have. + */ +/* @{ */ + +/** + * \name Haptic effects + */ +/* @{ */ + +/** + * \brief Constant effect supported. + * + * Constant haptic effect. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_CONSTANT (1u<<0) + +/** + * \brief Sine wave effect supported. + * + * Periodic haptic effect that simulates sine waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SINE (1u<<1) + +/** + * \brief Left/Right effect supported. + * + * Haptic effect for direct control over high/low frequency motors. + * + * \sa SDL_HapticLeftRight + * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, + * we ran out of bits, and this is important for XInput devices. + */ +#define SDL_HAPTIC_LEFTRIGHT (1u<<2) + +/* !!! FIXME: put this back when we have more bits in 2.1 */ +/* #define SDL_HAPTIC_SQUARE (1<<2) */ + +/** + * \brief Triangle wave effect supported. + * + * Periodic haptic effect that simulates triangular waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_TRIANGLE (1u<<3) + +/** + * \brief Sawtoothup wave effect supported. + * + * Periodic haptic effect that simulates saw tooth up waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) + +/** + * \brief Sawtoothdown wave effect supported. + * + * Periodic haptic effect that simulates saw tooth down waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) + +/** + * \brief Ramp effect supported. + * + * Ramp haptic effect. + * + * \sa SDL_HapticRamp + */ +#define SDL_HAPTIC_RAMP (1u<<6) + +/** + * \brief Spring effect supported - uses axes position. + * + * Condition haptic effect that simulates a spring. Effect is based on the + * axes position. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_SPRING (1u<<7) + +/** + * \brief Damper effect supported - uses axes velocity. + * + * Condition haptic effect that simulates dampening. Effect is based on the + * axes velocity. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_DAMPER (1u<<8) + +/** + * \brief Inertia effect supported - uses axes acceleration. + * + * Condition haptic effect that simulates inertia. Effect is based on the axes + * acceleration. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_INERTIA (1u<<9) + +/** + * \brief Friction effect supported - uses axes movement. + * + * Condition haptic effect that simulates friction. Effect is based on the + * axes movement. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_FRICTION (1u<<10) + +/** + * \brief Custom effect is supported. + * + * User defined custom haptic effect. + */ +#define SDL_HAPTIC_CUSTOM (1u<<11) + +/* @} *//* Haptic effects */ + +/* These last few are features the device has, not effects */ + +/** + * \brief Device can set global gain. + * + * Device supports setting the global gain. + * + * \sa SDL_HapticSetGain + */ +#define SDL_HAPTIC_GAIN (1u<<12) + +/** + * \brief Device can set autocenter. + * + * Device supports setting autocenter. + * + * \sa SDL_HapticSetAutocenter + */ +#define SDL_HAPTIC_AUTOCENTER (1u<<13) + +/** + * \brief Device can be queried for effect status. + * + * Device supports querying effect status. + * + * \sa SDL_HapticGetEffectStatus + */ +#define SDL_HAPTIC_STATUS (1u<<14) + +/** + * \brief Device can be paused. + * + * Devices supports being paused. + * + * \sa SDL_HapticPause + * \sa SDL_HapticUnpause + */ +#define SDL_HAPTIC_PAUSE (1u<<15) + + +/** + * \name Direction encodings + */ +/* @{ */ + +/** + * \brief Uses polar coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_POLAR 0 + +/** + * \brief Uses cartesian coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_CARTESIAN 1 + +/** + * \brief Uses spherical coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_SPHERICAL 2 + +/** + * \brief Use this value to play an effect on the steering wheel axis. This + * provides better compatibility across platforms and devices as SDL will guess + * the correct axis. + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_STEERING_AXIS 3 + +/* @} *//* Direction encodings */ + +/* @} *//* Haptic features */ + +/* + * Misc defines. + */ + +/** + * \brief Used to play a device an infinite number of times. + * + * \sa SDL_HapticRunEffect + */ +#define SDL_HAPTIC_INFINITY 4294967295U + + +/** + * \brief Structure that represents a haptic direction. + * + * This is the direction where the force comes from, + * instead of the direction in which the force is exerted. + * + * Directions can be specified by: + * - ::SDL_HAPTIC_POLAR : Specified by polar coordinates. + * - ::SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates. + * - ::SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates. + * + * Cardinal directions of the haptic device are relative to the positioning + * of the device. North is considered to be away from the user. + * + * The following diagram represents the cardinal directions: + * \verbatim + .--. + |__| .-------. + |=.| |.-----.| + |--| || || + | | |'-----'| + |__|~')_____(' + [ COMPUTER ] + + + North (0,-1) + ^ + | + | + (-1,0) West <----[ HAPTIC ]----> East (1,0) + | + | + v + South (0,1) + + + [ USER ] + \|||/ + (o o) + ---ooO-(_)-Ooo--- + \endverbatim + * + * If type is ::SDL_HAPTIC_POLAR, direction is encoded by hundredths of a + * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses + * the first \c dir parameter. The cardinal directions would be: + * - North: 0 (0 degrees) + * - East: 9000 (90 degrees) + * - South: 18000 (180 degrees) + * - West: 27000 (270 degrees) + * + * If type is ::SDL_HAPTIC_CARTESIAN, direction is encoded by three positions + * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses + * the first three \c dir parameters. The cardinal directions would be: + * - North: 0,-1, 0 + * - East: 1, 0, 0 + * - South: 0, 1, 0 + * - West: -1, 0, 0 + * + * The Z axis represents the height of the effect if supported, otherwise + * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you + * can use any multiple you want, only the direction matters. + * + * If type is ::SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. + * The first two \c dir parameters are used. The \c dir parameters are as + * follows (all values are in hundredths of degrees): + * - Degrees from (1, 0) rotated towards (0, 1). + * - Degrees towards (0, 0, 1) (device needs at least 3 axes). + * + * + * Example of force coming from the south with all encodings (force coming + * from the south means the user will have to pull the stick to counteract): + * \code + * SDL_HapticDirection direction; + * + * // Cartesian directions + * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding. + * direction.dir[0] = 0; // X position + * direction.dir[1] = 1; // Y position + * // Assuming the device has 2 axes, we don't need to specify third parameter. + * + * // Polar directions + * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding. + * direction.dir[0] = 18000; // Polar only uses first parameter + * + * // Spherical coordinates + * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding + * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters. + * \endcode + * + * \sa SDL_HAPTIC_POLAR + * \sa SDL_HAPTIC_CARTESIAN + * \sa SDL_HAPTIC_SPHERICAL + * \sa SDL_HAPTIC_STEERING_AXIS + * \sa SDL_HapticEffect + * \sa SDL_HapticNumAxes + */ +typedef struct SDL_HapticDirection +{ + Uint8 type; /**< The type of encoding. */ + Sint32 dir[3]; /**< The encoded direction. */ +} SDL_HapticDirection; + + +/** + * \brief A structure containing a template for a Constant effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CONSTANT effect. + * + * A constant effect applies a constant force in the specified direction + * to the joystick. + * + * \sa SDL_HAPTIC_CONSTANT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticConstant +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CONSTANT */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Constant */ + Sint16 level; /**< Strength of the constant effect. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticConstant; + +/** + * \brief A structure containing a template for a Periodic effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SINE + * - ::SDL_HAPTIC_LEFTRIGHT + * - ::SDL_HAPTIC_TRIANGLE + * - ::SDL_HAPTIC_SAWTOOTHUP + * - ::SDL_HAPTIC_SAWTOOTHDOWN + * + * A periodic effect consists in a wave-shaped effect that repeats itself + * over time. The type determines the shape of the wave and the parameters + * determine the dimensions of the wave. + * + * Phase is given by hundredth of a degree meaning that giving the phase a value + * of 9000 will displace it 25% of its period. Here are sample values: + * - 0: No phase displacement. + * - 9000: Displaced 25% of its period. + * - 18000: Displaced 50% of its period. + * - 27000: Displaced 75% of its period. + * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred. + * + * Examples: + * \verbatim + SDL_HAPTIC_SINE + __ __ __ __ + / \ / \ / \ / + / \__/ \__/ \__/ + + SDL_HAPTIC_SQUARE + __ __ __ __ __ + | | | | | | | | | | + | |__| |__| |__| |__| | + + SDL_HAPTIC_TRIANGLE + /\ /\ /\ /\ /\ + / \ / \ / \ / \ / + / \/ \/ \/ \/ + + SDL_HAPTIC_SAWTOOTHUP + /| /| /| /| /| /| /| + / | / | / | / | / | / | / | + / |/ |/ |/ |/ |/ |/ | + + SDL_HAPTIC_SAWTOOTHDOWN + \ |\ |\ |\ |\ |\ |\ | + \ | \ | \ | \ | \ | \ | \ | + \| \| \| \| \| \| \| + \endverbatim + * + * \sa SDL_HAPTIC_SINE + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HAPTIC_TRIANGLE + * \sa SDL_HAPTIC_SAWTOOTHUP + * \sa SDL_HAPTIC_SAWTOOTHDOWN + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticPeriodic +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT, + ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or + ::SDL_HAPTIC_SAWTOOTHDOWN */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Periodic */ + Uint16 period; /**< Period of the wave. */ + Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ + Sint16 offset; /**< Mean value of the wave. */ + Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticPeriodic; + +/** + * \brief A structure containing a template for a Condition effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SPRING: Effect based on axes position. + * - ::SDL_HAPTIC_DAMPER: Effect based on axes velocity. + * - ::SDL_HAPTIC_INERTIA: Effect based on axes acceleration. + * - ::SDL_HAPTIC_FRICTION: Effect based on axes movement. + * + * Direction is handled by condition internals instead of a direction member. + * The condition effect specific members have three parameters. The first + * refers to the X axis, the second refers to the Y axis and the third + * refers to the Z axis. The right terms refer to the positive side of the + * axis and the left terms refer to the negative side of the axis. Please + * refer to the ::SDL_HapticDirection diagram for which side is positive and + * which is negative. + * + * \sa SDL_HapticDirection + * \sa SDL_HAPTIC_SPRING + * \sa SDL_HAPTIC_DAMPER + * \sa SDL_HAPTIC_INERTIA + * \sa SDL_HAPTIC_FRICTION + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCondition +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SPRING, ::SDL_HAPTIC_DAMPER, + ::SDL_HAPTIC_INERTIA or ::SDL_HAPTIC_FRICTION */ + SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Condition */ + Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */ + Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */ + Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */ + Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */ + Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */ + Sint16 center[3]; /**< Position of the dead zone. */ +} SDL_HapticCondition; + +/** + * \brief A structure containing a template for a Ramp effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect. + * + * The ramp effect starts at start strength and ends at end strength. + * It augments in linear fashion. If you use attack and fade with a ramp + * the effects get added to the ramp effect making the effect become + * quadratic instead of linear. + * + * \sa SDL_HAPTIC_RAMP + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticRamp +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_RAMP */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Ramp */ + Sint16 start; /**< Beginning strength level. */ + Sint16 end; /**< Ending strength level. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticRamp; + +/** + * \brief A structure containing a template for a Left/Right effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect. + * + * The Left/Right effect is used to explicitly control the large and small + * motors, commonly found in modern game controllers. The small (right) motor + * is high frequency, and the large (left) motor is low frequency. + * + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticLeftRight +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_LEFTRIGHT */ + + /* Replay */ + Uint32 length; /**< Duration of the effect in milliseconds. */ + + /* Rumble */ + Uint16 large_magnitude; /**< Control of the large controller motor. */ + Uint16 small_magnitude; /**< Control of the small controller motor. */ +} SDL_HapticLeftRight; + +/** + * \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CUSTOM effect. + * + * A custom force feedback effect is much like a periodic effect, where the + * application can define its exact shape. You will have to allocate the + * data yourself. Data should consist of channels * samples Uint16 samples. + * + * If channels is one, the effect is rotated using the defined direction. + * Otherwise it uses the samples in data for the different axes. + * + * \sa SDL_HAPTIC_CUSTOM + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCustom +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CUSTOM */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Custom */ + Uint8 channels; /**< Axes to use, minimum of one. */ + Uint16 period; /**< Sample periods. */ + Uint16 samples; /**< Amount of samples. */ + Uint16 *data; /**< Should contain channels*samples items. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticCustom; + +/** + * \brief The generic template for any haptic effect. + * + * All values max at 32767 (0x7FFF). Signed values also can be negative. + * Time values unless specified otherwise are in milliseconds. + * + * You can also pass ::SDL_HAPTIC_INFINITY to length instead of a 0-32767 + * value. Neither delay, interval, attack_length nor fade_length support + * ::SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends. + * + * Additionally, the ::SDL_HAPTIC_RAMP effect does not support a duration of + * ::SDL_HAPTIC_INFINITY. + * + * Button triggers may not be supported on all devices, it is advised to not + * use them if possible. Buttons start at index 1 instead of index 0 like + * the joystick. + * + * If both attack_length and fade_level are 0, the envelope is not used, + * otherwise both values are used. + * + * Common parts: + * \code + * // Replay - All effects have this + * Uint32 length; // Duration of effect (ms). + * Uint16 delay; // Delay before starting effect. + * + * // Trigger - All effects have this + * Uint16 button; // Button that triggers effect. + * Uint16 interval; // How soon before effect can be triggered again. + * + * // Envelope - All effects except condition effects have this + * Uint16 attack_length; // Duration of the attack (ms). + * Uint16 attack_level; // Level at the start of the attack. + * Uint16 fade_length; // Duration of the fade out (ms). + * Uint16 fade_level; // Level at the end of the fade. + * \endcode + * + * + * Here we have an example of a constant effect evolution in time: + * \verbatim + Strength + ^ + | + | effect level --> _________________ + | / \ + | / \ + | / \ + | / \ + | attack_level --> | \ + | | | <--- fade_level + | + +--------------------------------------------------> Time + [--] [---] + attack_length fade_length + + [------------------][-----------------------] + delay length + \endverbatim + * + * Note either the attack_level or the fade_level may be above the actual + * effect level. + * + * \sa SDL_HapticConstant + * \sa SDL_HapticPeriodic + * \sa SDL_HapticCondition + * \sa SDL_HapticRamp + * \sa SDL_HapticLeftRight + * \sa SDL_HapticCustom + */ +typedef union SDL_HapticEffect +{ + /* Common for all force feedback effects */ + Uint16 type; /**< Effect type. */ + SDL_HapticConstant constant; /**< Constant effect. */ + SDL_HapticPeriodic periodic; /**< Periodic effect. */ + SDL_HapticCondition condition; /**< Condition effect. */ + SDL_HapticRamp ramp; /**< Ramp effect. */ + SDL_HapticLeftRight leftright; /**< Left/Right effect. */ + SDL_HapticCustom custom; /**< Custom effect. */ +} SDL_HapticEffect; + + +/* Function prototypes */ + +/** + * Count the number of haptic devices attached to the system. + * + * \returns the number of haptic devices detected on the system or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticName + */ +extern DECLSPEC int SDLCALL SDL_NumHaptics(void); + +/** + * Get the implementation dependent name of a haptic device. + * + * This can be called before any joysticks are opened. If no name can be + * found, this function returns NULL. + * + * \param device_index index of the device to query. + * \returns the name of the device or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_NumHaptics + */ +extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); + +/** + * Open a haptic device for use. + * + * The index passed as an argument refers to the N'th haptic device on this + * system. + * + * When opening a haptic device, its gain will be set to maximum and + * autocenter will be disabled. To modify these values use SDL_HapticSetGain() + * and SDL_HapticSetAutocenter(). + * + * \param device_index index of the device to open + * \returns the device identifier or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticOpenFromMouse + * \sa SDL_HapticPause + * \sa SDL_HapticSetAutocenter + * \sa SDL_HapticSetGain + * \sa SDL_HapticStopAll + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); + +/** + * Check if the haptic device at the designated index has been opened. + * + * \param device_index the index of the device to query + * \returns 1 if it has been opened, 0 if it hasn't or on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticIndex + * \sa SDL_HapticOpen + */ +extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); + +/** + * Get the index of a haptic device. + * + * \param haptic the SDL_Haptic device to query + * \returns the index of the specified haptic device or a negative error code + * on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpened + */ +extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); + +/** + * Query whether or not the current mouse has haptic capabilities. + * + * \returns SDL_TRUE if the mouse is haptic or SDL_FALSE if it isn't. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromMouse + */ +extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); + +/** + * Try to open a haptic device from the current mouse. + * + * \returns the haptic device identifier or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_MouseIsHaptic + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); + +/** + * Query if a joystick has haptic features. + * + * \param joystick the SDL_Joystick to test for haptic capabilities + * \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromJoystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); + +/** + * Open a haptic device for use from a joystick device. + * + * You must still close the haptic device separately. It will not be closed + * with the joystick. + * + * When opened from a joystick you should first close the haptic device before + * closing the joystick device. If not, on some implementations the haptic + * device will also get unallocated and you'll be unable to use force feedback + * on that device. + * + * \param joystick the SDL_Joystick to create a haptic device from + * \returns a valid haptic device identifier on success or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticOpen + * \sa SDL_JoystickIsHaptic + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * + joystick); + +/** + * Close a haptic device previously opened with SDL_HapticOpen(). + * + * \param haptic the SDL_Haptic device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + */ +extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); + +/** + * Get the number of effects a haptic device can store. + * + * On some platforms this isn't fully supported, and therefore is an + * approximation. Always check to see if your created effect was actually + * created and do not rely solely on SDL_HapticNumEffects(). + * + * \param haptic the SDL_Haptic device to query + * \returns the number of effects the haptic device can store or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffectsPlaying + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); + +/** + * Get the number of effects a haptic device can play at the same time. + * + * This is not supported on all platforms, but will always return a value. + * + * \param haptic the SDL_Haptic device to query maximum playing effects + * \returns the number of effects the haptic device can play at the same time + * or a negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); + +/** + * Get the haptic device's supported features in bitwise manner. + * + * \param haptic the SDL_Haptic device to query + * \returns a list of supported haptic features in bitwise manner (OR'd), or 0 + * on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticEffectSupported + * \sa SDL_HapticNumEffects + */ +extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); + + +/** + * Get the number of haptic axes the device has. + * + * The number of haptic axes might be useful if working with the + * SDL_HapticDirection effect. + * + * \param haptic the SDL_Haptic device to query + * \returns the number of axes on success or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); + +/** + * Check to see if an effect is supported by a haptic device. + * + * \param haptic the SDL_Haptic device to query + * \param effect the desired effect to query + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, + SDL_HapticEffect * + effect); + +/** + * Create a new haptic effect on a specified device. + * + * \param haptic an SDL_Haptic device to create the effect on + * \param effect an SDL_HapticEffect structure containing the properties of + * the effect to create + * \returns the ID of the effect on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticUpdateEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, + SDL_HapticEffect * effect); + +/** + * Update the properties of an effect. + * + * Can be used dynamically, although behavior when dynamically changing + * direction may be strange. Specifically the effect may re-upload itself and + * start playing from the start. You also cannot change the type either when + * running SDL_HapticUpdateEffect(). + * + * \param haptic the SDL_Haptic device that has the effect + * \param effect the identifier of the effect to update + * \param data an SDL_HapticEffect structure containing the new effect + * properties to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticNewEffect + * \sa SDL_HapticRunEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, + int effect, + SDL_HapticEffect * data); + +/** + * Run the haptic effect on its associated haptic device. + * + * To repeat the effect over and over indefinitely, set `iterations` to + * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make + * one instance of the effect last indefinitely (so the effect does not fade), + * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY` + * instead. + * + * \param haptic the SDL_Haptic device to run the effect on + * \param effect the ID of the haptic effect to run + * \param iterations the number of iterations to run the effect; use + * `SDL_HAPTIC_INFINITY` to repeat forever + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticGetEffectStatus + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, + int effect, + Uint32 iterations); + +/** + * Stop the haptic effect on its associated haptic device. + * + * * + * + * \param haptic the SDL_Haptic device to stop the effect on + * \param effect the ID of the haptic effect to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, + int effect); + +/** + * Destroy a haptic effect on the device. + * + * This will stop the effect if it's running. Effects are automatically + * destroyed when the device is closed. + * + * \param haptic the SDL_Haptic device to destroy the effect on + * \param effect the ID of the haptic effect to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, + int effect); + +/** + * Get the status of the current effect on the specified haptic device. + * + * Device must support the SDL_HAPTIC_STATUS feature. + * + * \param haptic the SDL_Haptic device to query for the effect status on + * \param effect the ID of the haptic effect to query its status + * \returns 0 if it isn't playing, 1 if it is playing, or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, + int effect); + +/** + * Set the global gain of the specified haptic device. + * + * Device must support the SDL_HAPTIC_GAIN feature. + * + * The user may specify the maximum gain by setting the environment variable + * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to + * SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the + * maximum. + * + * \param haptic the SDL_Haptic device to set the gain on + * \param gain value to set the gain to, should be between 0 and 100 (0 - 100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); + +/** + * Set the global autocenter of the device. + * + * Autocenter should be between 0 and 100. Setting it to 0 will disable + * autocentering. + * + * Device must support the SDL_HAPTIC_AUTOCENTER feature. + * + * \param haptic the SDL_Haptic device to set autocentering on + * \param autocenter value to set autocenter to (0-100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, + int autocenter); + +/** + * Pause a haptic device. + * + * Device must support the `SDL_HAPTIC_PAUSE` feature. Call + * SDL_HapticUnpause() to resume playback. + * + * Do not modify the effects nor add new ones while the device is paused. That + * can cause all sorts of weird errors. + * + * \param haptic the SDL_Haptic device to pause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticUnpause + */ +extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); + +/** + * Unpause a haptic device. + * + * Call to unpause after SDL_HapticPause(). + * + * \param haptic the SDL_Haptic device to unpause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticPause + */ +extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); + +/** + * Stop all the currently playing effects on a haptic device. + * + * \param haptic the SDL_Haptic device to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); + +/** + * Check whether rumble is supported on a haptic device. + * + * \param haptic haptic device to check for rumble support + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); + +/** + * Initialize a haptic device for simple rumble playback. + * + * \param haptic the haptic device to initialize for simple rumble playback + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); + +/** + * Run a simple rumble effect on a haptic device. + * + * \param haptic the haptic device to play the rumble effect on + * \param strength strength of the rumble to play as a 0-1 float value + * \param length length of the rumble to play in milliseconds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); + +/** + * Stop the simple rumble on a haptic device. + * + * \param haptic the haptic device to stop the rumble effect on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleSupported + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_haptic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_hidapi.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_hidapi.h new file mode 100644 index 000000000..354af5c52 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_hidapi.h @@ -0,0 +1,451 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hidapi.h + * + * Header file for SDL HIDAPI functions. + * + * This is an adaptation of the original HIDAPI interface by Alan Ott, + * and includes source code licensed under the following BSD license: + * + Copyright (c) 2010, Alan Ott, Signal 11 Software + 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 Signal 11 Software nor the names of its + 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * If you would like a version of SDL without this code, you can build SDL + * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for example + * on iOS or tvOS to avoid a dependency on the CoreBluetooth framework. + */ + +#ifndef SDL_hidapi_h_ +#define SDL_hidapi_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle representing an open HID device + */ +struct SDL_hid_device_; +typedef struct SDL_hid_device_ SDL_hid_device; /**< opaque hidapi structure */ + +/** hidapi info structure */ +/** + * \brief Information about a connected HID device + */ +typedef struct SDL_hid_device_info +{ + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. */ + int interface_number; + + /** Additional information about the USB interface. + Valid on libusb and Android implementations. */ + int interface_class; + int interface_subclass; + int interface_protocol; + + /** Pointer to the next device */ + struct SDL_hid_device_info *next; +} SDL_hid_device_info; + + +/** + * Initialize the HIDAPI library. + * + * This function initializes the HIDAPI library. Calling it is not strictly + * necessary, as it will be called automatically by SDL_hid_enumerate() and + * any of the SDL_hid_open_*() functions if it is needed. This function should + * be called at the beginning of execution however, if there is a chance of + * HIDAPI handles being opened by different threads simultaneously. + * + * Each call to this function should have a matching call to SDL_hid_exit() + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_exit + */ +extern DECLSPEC int SDLCALL SDL_hid_init(void); + +/** + * Finalize the HIDAPI library. + * + * This function frees all of the static data associated with HIDAPI. It + * should be called at the end of execution to avoid memory leaks. + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_init + */ +extern DECLSPEC int SDLCALL SDL_hid_exit(void); + +/** + * Check to see if devices may have been added or removed. + * + * Enumerating the HID devices is an expensive operation, so you can call this + * to see if there have been any system device changes since the last call to + * this function. A change in the counter returned doesn't necessarily mean + * that anything has changed, but you can call SDL_hid_enumerate() to get an + * updated device list. + * + * Calling this function for the first time may cause a thread or other system + * resource to be allocated to track device change notifications. + * + * \returns a change counter that is incremented with each potential device + * change, or 0 if device change detection isn't available. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_enumerate + */ +extern DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void); + +/** + * Enumerate the HID Devices. + * + * This function returns a linked list of all the HID devices attached to the + * system which match vendor_id and product_id. If `vendor_id` is set to 0 + * then any vendor matches. If `product_id` is set to 0 then any product + * matches. If `vendor_id` and `product_id` are both set to 0, then all HID + * devices will be returned. + * + * \param vendor_id The Vendor ID (VID) of the types of device to open. + * \param product_id The Product ID (PID) of the types of device to open. + * \returns a pointer to a linked list of type SDL_hid_device_info, containing + * information about the HID devices attached to the system, or NULL + * in the case of failure. Free this linked list by calling + * SDL_hid_free_enumeration(). + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_device_change_count + */ +extern DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id); + +/** + * Free an enumeration Linked List + * + * This function frees a linked list created by SDL_hid_enumerate(). + * + * \param devs Pointer to a list of struct_device returned from + * SDL_hid_enumerate(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs); + +/** + * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally + * a serial number. + * + * If `serial_number` is NULL, the first device with the specified VID and PID + * is opened. + * + * \param vendor_id The Vendor ID (VID) of the device to open. + * \param product_id The Product ID (PID) of the device to open. + * \param serial_number The Serial Number of the device to open (Optionally + * NULL). + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + +/** + * Open a HID device by its path name. + * + * The path name be determined by calling SDL_hid_enumerate(), or a + * platform-specific path name can be used (eg: /dev/hidraw0 on Linux). + * + * \param path The path name of the device to open + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */); + +/** + * Write an Output report to a HID device. + * + * The first byte of `data` must contain the Report ID. For devices which only + * support a single report, this must be set to 0x0. The remaining bytes + * contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_write() will always contain one more byte than the report contains. + * For example, if a hid report is 16 bytes long, 17 bytes must be passed to + * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report), + * followed by the report data (16 bytes). In this example, the length passed + * in would be 17. + * + * SDL_hid_write() will send the data on the first OUT endpoint, if one + * exists. If it does not, it will send the data through the Control Endpoint + * (Endpoint 0). + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Read an Input report from a HID device with timeout. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \param milliseconds timeout in milliseconds or -1 for blocking wait. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read within the timeout period, this function + * returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds); + +/** + * Read an Input report from a HID device. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read and the handle is in non-blocking mode, this + * function returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Set the device handle to be non-blocking. + * + * In non-blocking mode calls to SDL_hid_read() will return immediately with a + * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read() + * will wait (block) until there is data to read before returning. + * + * Nonblocking can be turned on and off at any time. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param nonblock enable or not the nonblocking reads - 1 to enable + * nonblocking - 0 to disable nonblocking. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock); + +/** + * Send a Feature report to the device. + * + * Feature reports are sent over the Control endpoint as a Set_Report + * transfer. The first byte of `data` must contain the Report ID. For devices + * which only support a single report, this must be set to 0x0. The remaining + * bytes contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_send_feature_report() will always contain one more byte than the + * report contains. For example, if a hid report is 16 bytes long, 17 bytes + * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for + * devices which do not use numbered reports), followed by the report data (16 + * bytes). In this example, the length passed in would be 17. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send, including the report + * number. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Get a feature report from a HID device. + * + * Set the first byte of `data` to the Report ID of the report to be read. + * Make sure to allow space for this extra byte in `data`. Upon return, the + * first byte will still contain the Report ID, and the report data will start + * in data[1]. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into, including the Report ID. + * Set the first byte of `data` to the Report ID of the report to + * be read, or set it to zero if your device does not use numbered + * reports. + * \param length The number of bytes to read, including an extra byte for the + * report ID. The buffer can be longer than the actual report. + * \returns the number of bytes read plus one for the report ID (which is + * still in the first byte), or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Close a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_close(SDL_hid_device *dev); + +/** + * Get The Manufacturer String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Product String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Serial Number String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get a string from a HID device, based on its string index. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string_index The index of the string to get. + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen); + +/** + * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers + * + * \param active SDL_TRUE to start the scan, SDL_FALSE to stop the scan + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_ble_scan(SDL_bool active); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hidapi_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_hints.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_hints.h new file mode 100644 index 000000000..1185f4222 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_hints.h @@ -0,0 +1,1967 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hints.h + * + * Official documentation for SDL configuration variables + * + * This file contains functions to set and get configuration hints, + * as well as listing each of them alphabetically. + * + * The convention for naming hints is SDL_HINT_X, where "SDL_X" is + * the environment variable that can be used to override the default. + * + * In general these hints are just that - they may or may not be + * supported or applicable on any given platform, but they provide + * a way for an application or user to give the library a hint as + * to how they would like the library to work. + */ + +#ifndef SDL_hints_h_ +#define SDL_hints_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A variable controlling whether the Android / iOS built-in + * accelerometer should be listed as a joystick device. + * + * This variable can be set to the following values: + * "0" - The accelerometer is not listed as a joystick + * "1" - The accelerometer is available as a 3 axis joystick (the default). + */ +#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" + +/** + * \brief Specify the behavior of Alt+Tab while the keyboard is grabbed. + * + * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed + * and your window is full-screen. This prevents the user from getting stuck in + * your application if you've enabled keyboard grab. + * + * The variable can be set to the following values: + * "0" - SDL will not handle Alt+Tab. Your application is responsible + for handling Alt+Tab while the keyboard is grabbed. + * "1" - SDL will minimize your window when Alt+Tab is pressed (default) +*/ +#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" + +/** + * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. + * This is a debugging aid for developers and not expected to be used by end users. The default is "1" + * + * This variable can be set to the following values: + * "0" - don't allow topmost + * "1" - allow topmost + */ +#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" + +/** + * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" + +/** + * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" + +/** + * \brief A variable to control whether the event loop will block itself when the app is paused. + * + * The variable can be set to the following values: + * "0" - Non blocking. + * "1" - Blocking. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE" + +/** + * \brief A variable to control whether SDL will pause audio in background + * (Requires SDL_ANDROID_BLOCK_ON_PAUSE as "Non blocking") + * + * The variable can be set to the following values: + * "0" - Non paused. + * "1" - Paused. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO "SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO" + +/** + * \brief A variable to control whether we trap the Android back button to handle it manually. + * This is necessary for the right mouse button to work on some Android devices, or + * to be able to trap the back button for use in your code reliably. If set to true, + * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of + * SDL_SCANCODE_AC_BACK. + * + * The variable can be set to the following values: + * "0" - Back button will be handled as usual for system. (default) + * "1" - Back button will be trapped, allowing you to handle the key press + * manually. (This will also let right mouse click work on systems + * where the right mouse button functions as back.) + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" + +/** + * \brief Specify an application name. + * + * This hint lets you specify the application name sent to the OS when + * required. For example, this will often appear in volume control applets for + * audio streams, and in lists of applications which are inhibiting the + * screensaver. You should use a string that describes your program ("My Game + * 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: probably the application's name or "SDL Application" if SDL + * doesn't have any better information. + * + * Note that, for audio streams, this can be overridden with + * SDL_HINT_AUDIO_DEVICE_APP_NAME. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_APP_NAME "SDL_APP_NAME" + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + +/** + * \brief A variable controlling the audio category on iOS and Mac OS X + * + * This variable can be set to the following values: + * + * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default) + * "playback" - Use the AVAudioSessionCategoryPlayback category + * + * For more information, see Apple's documentation: + * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html + */ +#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your program ("My Game 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: this will be the name set with SDL_HINT_APP_NAME, if that hint is + * set. Otherwise, it'll probably the application's name or "SDL Application" + * if SDL doesn't have any better information. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing ("audio stream" is + * probably sufficient in many cases, but this could be useful for something + * like "team chat" if you have a headset playing VoIP audio separately). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "audio stream" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME" + +/** + * \brief Specify an application role for an audio device. + * + * Some audio backends (such as Pipewire) allow you to describe the role of + * your audio stream. Among other things, this description might show up in + * a system control panel or software for displaying and manipulating media + * playback/capture graphs. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing (Game, Music, Movie, + * etc...). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE" + +/** + * \brief A variable controlling speed/quality tradeoff of audio resampling. + * + * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ ) + * to handle audio resampling. There are different resampling modes available + * that produce different levels of quality, using more CPU. + * + * If this hint isn't specified to a valid setting, or libsamplerate isn't + * available, SDL will use the default, internal resampling algorithm. + * + * Note that this is currently only applicable to resampling audio that is + * being written to a device for playback or audio being read from a device + * for capture. SDL_AudioCVT always uses the default resampler (although this + * might change for SDL 2.1). + * + * This hint is currently only checked at audio subsystem initialization. + * + * This variable can be set to the following values: + * + * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast) + * "1" or "fast" - Use fast, slightly higher quality resampling, if available + * "2" or "medium" - Use medium quality resampling, if available + * "3" or "best" - Use high quality resampling, if available + */ +#define SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" + +/** + * \brief A variable controlling whether SDL updates joystick state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_JoystickUpdate() manually + * "1" - SDL will automatically call SDL_JoystickUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_JOYSTICKS "SDL_AUTO_UPDATE_JOYSTICKS" + +/** + * \brief A variable controlling whether SDL updates sensor state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_SensorUpdate() manually + * "1" - SDL will automatically call SDL_SensorUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_SENSORS "SDL_AUTO_UPDATE_SENSORS" + +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Override for SDL_GetDisplayUsableBounds() + * + * If set, this hint will override the expected results for + * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want + * to do this, but this allows an embedded system to request that some of the + * screen be reserved for other uses when paired with a well-behaved + * application. + * + * The contents of this hint must be 4 comma-separated integers, the first + * is the bounds x, then y, width and height, in that order. + */ +#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" + +/** + * \brief Disable giving back control to the browser automatically + * when running with asyncify + * + * With -s ASYNCIFY, SDL2 calls emscripten_sleep during operations + * such as refreshing the screen or polling events. + * + * This hint only applies to the emscripten platform + * + * The variable can be set to the following values: + * "0" - Disable emscripten_sleep calls (if you give back browser control manually or use asyncify for other purposes) + * "1" - Enable emscripten_sleep calls (the default) + */ +#define SDL_HINT_EMSCRIPTEN_ASYNCIFY "SDL_EMSCRIPTEN_ASYNCIFY" + +/** + * \brief override the binding element for keyboard inputs for Emscripten builds + * + * This hint only applies to the emscripten platform + * + * The variable can be one of + * "#window" - The javascript window object (this is the default) + * "#document" - The javascript document object + * "#screen" - the javascript window.screen object + * "#canvas" - the WebGL canvas element + * any other string without a leading # sign applies to the element on the page with that ID. + */ +#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" + +/** + * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs + * + * The variable can be set to the following values: + * "0" - Do not scan for Steam Controllers + * "1" - Scan for Steam Controllers (the default) + * + * The default value is "1". This hint must be set before initializing the joystick subsystem. + */ +#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" + +/** + * \brief A variable controlling whether SDL logs all events pushed onto its internal queue. + * + * This variable can be set to the following values: + * + * "0" - Don't log any events (default) + * "1" - Log all events except mouse and finger motion, which are pretty spammy. + * "2" - Log all events. + * + * This is generally meant to be used to debug SDL itself, but can be useful + * for application developers that need better visibility into what is going + * on in the event queue. Logged events are sent through SDL_Log(), which + * means by default they appear on stdout on most platforms or maybe + * OutputDebugString() on Windows, and can be funneled by the app with + * SDL_LogSetOutputFunction(), etc. + * + * This hint can be toggled on and off at runtime, if you only need to log + * events for a small subset of program execution. + */ +#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" + +/** + * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. + * + * SDL can try to accelerate the SDL screen surface by using streaming + * textures with a 3D rendering engine. This variable controls whether and + * how this is done. + * + * This variable can be set to the following values: + * "0" - Disable 3D acceleration + * "1" - Enable 3D acceleration, using the default renderer. + * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) + * + * By default SDL tries to make a best guess for each platform whether + * to use acceleration or not. + */ +#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" + +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries. + * + * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + +/** + * \brief A variable that lets you provide a file with extra gamecontroller db entries. + * + * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE" + +/** + * \brief A variable that overrides the automatic controller type detection + * + * The variable should be comma separated entries, in the form: VID/PID=type + * + * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd + * + * The type should be one of: + * Xbox360 + * XboxOne + * PS3 + * PS4 + * PS5 + * SwitchPro + * + * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + */ +#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE" + +/** + * \brief A variable containing a list of devices to skip when scanning for game controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES" + +/** + * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT" + +/** + * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. + * + * For example, on Nintendo Switch controllers, normally you'd get: + * + * (Y) + * (X) (B) + * (A) + * + * but if this hint is set, you'll get: + * + * (X) + * (Y) (A) + * (B) + * + * The variable can be set to the following values: + * "0" - Report the face buttons by position, as though they were on an Xbox controller. + * "1" - Report the face buttons by label instead of position + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + +/** + * \brief A variable controlling whether the idle timer is disabled on iOS. + * + * When an iOS app does not receive touches for some time, the screen is + * dimmed automatically. For games where the accelerometer is the only input + * this is problematic. This functionality can be disabled by setting this + * hint. + * + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. + * + * This variable can be set to the following values: + * "0" - Enable idle timer + * "1" - Disable idle timer + */ +#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" + +/** + * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. + * + * The variable can be set to the following values: + * "0" - SDL_TEXTEDITING events are sent, and it is the application's + * responsibility to render the text from these events and + * differentiate it somehow from committed text. (default) + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * and text that is being composed will be rendered in its own UI. + */ +#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" + +/** + * \brief A variable to control whether certain IMEs should show native UI components (such as the Candidate List) instead of suppressing them. + * + * The variable can be set to the following values: + * "0" - Native UI components are not display. (default) + * "1" - Native UI components are displayed. + */ +#define SDL_HINT_IME_SHOW_UI "SDL_IME_SHOW_UI" + +/** + * \brief A variable controlling whether the home indicator bar on iPhone X + * should be hidden. + * + * This variable can be set to the following values: + * "0" - The indicator bar is not hidden (default for windowed applications) + * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) + * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) + */ +#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" + +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the background. + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + +/** + * \brief A variable controlling whether the HIDAPI joystick drivers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI drivers are not used + * "1" - HIDAPI drivers are used (the default) + * + * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below. + */ +#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE" + + /** + * \brief A variable controlling whether Switch Joy-Cons should be treated the same as Switch Pro Controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - basic Joy-Con support with no analog input (the default) + * "1" - Joy-Cons treated as half full Pro Controllers with analog inputs and sensors + * + * This does not combine Joy-Cons into a single controller. That's up to the user. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS" + + /** + * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4" + +/** + * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS4 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value will also + * control the state of extended reports on PS5 controllers when the + * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE hint is not explicitly set. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS5 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5 "SDL_JOYSTICK_HIDAPI_PS5" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a PS5 controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED "SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED" + +/** + * \brief A variable controlling whether extended input reports should be used for PS5 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS5 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value defaults to + * the value of SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE "SDL_JOYSTICK_HIDAPI_PS5_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Google Stadia controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STADIA "SDL_JOYSTICK_HIDAPI_STADIA" + +/** + * \brief A variable controlling whether the HIDAPI driver for Steam Controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used for Steam Controllers, which requires Bluetooth access + * and may prompt the user for permission on iOS and Android. + * + * The default is "0" + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" + + /** + * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices. + * + * This variable can be set to the following values: + * "0" - RAWINPUT drivers are not used + * "1" - RAWINPUT drivers are used (the default) + * + */ +#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT" + + /** + * \brief A variable controlling whether the RAWINPUT driver should pull correlated data from XInput. + * + * This variable can be set to the following values: + * "0" - RAWINPUT driver will only use data from raw input APIs + * "1" - RAWINPUT driver will also pull data from XInput, providing + * better trigger axes, guide button presses, and rumble support + * for Xbox controllers + * + * The default is "1". This hint applies to any joysticks opened after setting the hint. + */ +#define SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT "SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT" + + /** + * \brief A variable controlling whether a separate thread should be used + * for handling joystick detection and raw input messages on Windows + * + * This variable can be set to the following values: + * "0" - A separate thread is not used (the default) + * "1" - A separate thread is used for handling raw input messages + * + */ +#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD" + +/** + * \brief Determines whether SDL enforces that DRM master is required in order + * to initialize the KMSDRM video backend. + * + * The DRM subsystem has a concept of a "DRM master" which is a DRM client that + * has the ability to set planes, set cursor, etc. When SDL is DRM master, it + * can draw to the screen using the SDL rendering APIs. Without DRM master, SDL + * is still able to process input and query attributes of attached displays, + * but it cannot change display state or draw to the screen directly. + * + * In some cases, it can be useful to have the KMSDRM backend even if it cannot + * be used for rendering. An app may want to use SDL for input processing while + * using another rendering API (such as an MMAL overlay on Raspberry Pi) or + * using its own code to render to DRM overlays that SDL doesn't support. + * + * This hint must be set before initializing the video subsystem. + * + * This variable can be set to the following values: + * "0" - SDL will allow usage of the KMSDRM backend without DRM master + * "1" - SDL Will require DRM master to use the KMSDRM backend (default) + */ +#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER" + + /** + * \brief A comma separated list of devices to open as joysticks + * + * This variable is currently only used by the Linux joystick driver. + */ +#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE" + + /** + * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux + * + * This variable can be set to the following values: + * "0" - Use /dev/input/event* + * "1" - Use /dev/input/js* + * + * By default the /dev/input/event* interfaces are used + */ +#define SDL_HINT_LINUX_JOYSTICK_CLASSIC "SDL_LINUX_JOYSTICK_CLASSIC" + + /** + * \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return unfiltered joystick axis values (the default) + * "1" - Return axis values with deadzones taken into account + */ +#define SDL_HINT_LINUX_JOYSTICK_DEADZONES "SDL_LINUX_JOYSTICK_DEADZONES" + +/** +* \brief When set don't force the SDL app to become a foreground process +* +* This hint only applies to Mac OS X. +* +*/ +#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" + +/** + * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac + * + * If present, holding ctrl while left clicking will generate a right click + * event when on Mac. + */ +#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" + +/** + * \brief A variable setting the double click radius, in pixels. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS" + +/** + * \brief A variable setting the double click time, in milliseconds. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME" + +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + +/** + * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode + */ +#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE" + +/** + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" + +/** + * \brief A variable controlling whether relative mouse motion is affected by renderer scaling + * + * This variable can be set to the following values: + * "0" - Relative motion is unaffected by DPI or renderer's logical size + * "1" - Relative motion is scaled according to DPI scaling and logical size + * + * By default relative mouse deltas are affected by DPI and renderer scaling + */ +#define SDL_HINT_MOUSE_RELATIVE_SCALING "SDL_MOUSE_RELATIVE_SCALING" + +/** + * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode + */ +#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE" + +/** + * \brief A variable controlling whether mouse events should generate synthetic touch events + * + * This variable can be set to the following values: + * "0" - Mouse events will not generate touch events (default for desktop platforms) + * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS) + */ +#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS" + +/** + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. + * + * This hint only applies to Unix-like platforms, and should set before + * any calls to SDL_Init() + * + * The variable can be set to the following values: + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it + * catches a signal, convert it into an SDL_QUIT event. + * "1" - SDL will not install a signal handler at all. + */ +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" + +/** + * \brief A variable controlling what driver to use for OpenGL ES contexts. + * + * On some platforms, currently Windows and X11, OpenGL drivers may support + * creating contexts with an OpenGL ES profile. By default SDL uses these + * profiles, when available, otherwise it attempts to load an OpenGL ES + * library, e.g. that provided by the ANGLE project. This variable controls + * whether SDL follows this default behaviour or will always load an + * OpenGL ES library. + * + * Circumstances where this is useful include + * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE, + * or emulator, e.g. those from ARM, Imagination or Qualcomm. + * - Resolving OpenGL ES function addresses at link time by linking with + * the OpenGL ES library instead of querying them at run time with + * SDL_GL_GetProcAddress(). + * + * Caution: for an application to work with the default behaviour across + * different OpenGL drivers it must query the OpenGL ES function + * addresses at run time using SDL_GL_GetProcAddress(). + * + * This variable is ignored on most platforms because OpenGL ES is native + * or not supported. + * + * This variable can be set to the following values: + * "0" - Use ES profile of OpenGL, if available. (Default when not set.) + * "1" - Load OpenGL ES library using the default library names. + * + */ +#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER" + +/** + * \brief A variable controlling which orientations are allowed on iOS/Android. + * + * In some circumstances it is necessary to be able to explicitly control + * which UI orientations are allowed. + * + * This variable is a space delimited list of the following values: + * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" + */ +#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" + +/** + * \brief A variable controlling the use of a sentinel event when polling the event queue + * + * This variable can be set to the following values: + * "0" - Disable poll sentinels + * "1" - Enable poll sentinels + * + * When polling for events, SDL_PumpEvents is used to gather new events from devices. + * If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will + * become stuck until the new events stop. + * This is most noticable when moving a high frequency mouse. + * + * By default, poll sentinels are enabled. + */ +#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL" + +/** + * \brief Override for SDL_GetPreferredLocales() + * + * If set, this will be favored over anything the OS might report for the + * user's preferred locales. Changing this hint at runtime will not generate + * a SDL_LOCALECHANGED event (but if you can change the hint, you can push + * your own event, if you want). + * + * The format of this hint is a comma-separated list of language and locale, + * combined with an underscore, as is a common format: "en_GB". Locale is + * optional: "en". So you might have a list like this: "en_GB,jp,es_PT" + */ +#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES" + +/** + * \brief A variable describing the content orientation on QtWayland-based platforms. + * + * On QtWayland platforms, windows are rotated client-side to allow for custom + * transitions. In order to correctly position overlays (e.g. volume bar) and + * gestures (e.g. events view, close/minimize gestures), the system needs to + * know in which orientation the application is currently drawing its contents. + * + * This does not cause the window to be rotated or resized, the application + * needs to take care of drawing the content in the right orientation (the + * framebuffer is always in portrait mode). + * + * This variable can be one of the following values: + * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" + */ +#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" + +/** + * \brief Flags to set on QtWayland windows to integrate with the native window manager. + * + * On QtWayland platforms, this hint controls the flags to set on the windows. + * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures. + * + * This variable is a space-separated list of the following values (empty = no flags): + * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager" + */ +#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS "SDL_QTWAYLAND_WINDOW_FLAGS" + +/** + * \brief A variable controlling whether the 2D render API is compatible or efficient. + * + * This variable can be set to the following values: + * + * "0" - Don't use batching to make rendering more efficient. + * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls. + * + * Up to SDL 2.0.9, the render API would draw immediately when requested. Now + * it batches up draw requests and sends them all to the GPU only when forced + * to (during SDL_RenderPresent, when changing render targets, by updating a + * texture that the batch needs, etc). This is significantly more efficient, + * but it can cause problems for apps that expect to render on top of the + * render API's output. As such, SDL will disable batching if a specific + * render backend is requested (since this might indicate that the app is + * planning to use the underlying graphics API directly). This hint can + * be used to explicitly request batching in this instance. It is a contract + * that you will either never use the underlying graphics API directly, or + * if you do, you will call SDL_RenderFlush() before you do so any current + * batch goes to the GPU before your work begins. Not following this contract + * will result in undefined behavior. + */ +#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" + +/** + * \brief A variable controlling how the 2D render API renders lines + * + * This variable can be set to the following values: + * "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20) + * "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points) + * "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20) + * "3" - Use the driver geometry API (correct, draws thicker diagonal lines) + * + * This variable should be set when the renderer is created. + */ +#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD" + +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Layer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" + +/** + * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. + * + * This variable can be set to the following values: + * "0" - Thread-safety is not enabled (faster) + * "1" - Thread-safety is enabled + * + * By default the Direct3D device is created with thread-safety disabled. + */ +#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" + +/** + * \brief A variable specifying which render driver to use. + * + * If the application doesn't pick a specific renderer to use, this variable + * specifies the name of the preferred renderer. If the preferred renderer + * can't be initialized, the normal default renderer is used. + * + * This variable is case insensitive and can be set to the following values: + * "direct3d" + * "opengl" + * "opengles2" + * "opengles" + * "metal" + * "software" + * + * The default varies by platform, but it's the first one in the list that + * is available on the current platform. + */ +#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" + +/** + * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize. + * + * This variable can be set to the following values: + * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen + * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen + * + * By default letterbox is used + */ +#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_RENDER_LOGICAL_SIZE_MODE" + +/** + * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. + * + * This variable can be set to the following values: + * "0" - Disable shaders + * "1" - Enable shaders + * + * By default shaders are used if OpenGL supports them. + */ +#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" + +/** + * \brief A variable controlling the scaling quality + * + * This variable can be set to the following values: + * "0" or "nearest" - Nearest pixel sampling + * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) + * "2" or "best" - Currently this is the same as "linear" + * + * By default nearest pixel sampling is used + */ +#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" + +/** + * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. + * + * This variable can be set to the following values: + * "0" - Disable vsync + * "1" - Enable vsync + * + * By default SDL does not sync screen surface updates with vertical refresh. + */ +#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" + + /** + * \brief A variable to control whether the return key on the soft keyboard + * should hide the soft keyboard on Android and iOS. + * + * The variable can be set to the following values: + * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default) + * "1" - The return key will hide the keyboard. + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + +/** + * \brief Specify an "activity name" for screensaver inhibition. + * + * Some platforms, notably Linux desktops, list the applications which are + * inhibiting the screensaver or other power-saving features. + * + * This hint lets you specify the "activity name" sent to the OS when + * SDL_DisableScreenSaver() is used (or the screensaver is automatically + * disabled). The contents of this hint are used when the screensaver is + * disabled. You should use a string that describes what your program is doing + * (and, therefore, why the screensaver is disabled). For example, "Playing a + * game" or "Watching a video". + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Playing a game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME "SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME" + +/** + * \brief Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime. + * + * On some platforms, like Linux, a realtime priority thread may be subject to restrictions + * that require special handling by the application. This hint exists to let SDL know that + * the app is prepared to handle said restrictions. + * + * On Linux, SDL will apply the following configuration to any thread that becomes realtime: + * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy, + * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit. + * * Exceeding this limit will result in the kernel sending SIGKILL to the app, + * * Refer to the man pages for more information. + * + * This variable can be set to the following values: + * "0" - default platform specific behaviour + * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy + */ +#define SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL "SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL" + +/** +* \brief A string specifying additional information to use with SDL_SetThreadPriority. +* +* By default SDL_SetThreadPriority will make appropriate system changes in order to +* apply a thread priority. For example on systems using pthreads the scheduler policy +* is changed automatically to a policy that works well with a given priority. +* Code which has specific requirements can override SDL's default behavior with this hint. +* +* pthread hint values are "current", "other", "fifo" and "rr". +* Currently no other platform hint values are defined but may be in the future. +* +* \note On Linux, the kernel may send SIGKILL to realtime tasks which exceed the distro +* configured execution budget for rtkit. This budget can be queried through RLIMIT_RTTIME +* after calling SDL_SetThreadPriority(). +*/ +#define SDL_HINT_THREAD_PRIORITY_POLICY "SDL_THREAD_PRIORITY_POLICY" + +/** +* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size +* +* Use this hint in case you need to set SDL's threads stack size to other than the default. +* This is specially useful if you build SDL against a non glibc libc library (such as musl) which +* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. +* +* Instead of this hint, in 2.0.9 and later, you can use +* SDL_CreateThreadWithStackSize(). This hint only works with the classic +* SDL_CreateThread(). +*/ +#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" + +/** + * \brief A variable that controls the timer resolution, in milliseconds. + * + * The higher resolution the timer, the more frequently the CPU services + * timer interrupts, and the more precise delays are, but this takes up + * power and CPU time. This hint is only used on Windows. + * + * See this blog post for more information: + * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ + * + * If this variable is set to "0", the system timer resolution is not set. + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" + +/** + * \brief A variable controlling whether touch events should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Touch events will not generate mouse events + * "1" - Touch events will generate mouse events + * + * By default SDL will generate mouse events for touch events + */ +#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" + +/** + * \brief A variable controlling whether the Android / tvOS remotes + * should be listed as joystick devices, instead of sending keyboard events. + * + * This variable can be set to the following values: + * "0" - Remotes send enter/escape/arrow key events + * "1" - Remotes are available as 2 axis, 2 button joysticks (the default). + */ +#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" + +/** + * \brief A variable controlling whether the screensaver is enabled. + * + * This variable can be set to the following values: + * "0" - Disable screensaver + * "1" - Enable screensaver + * + * By default SDL will disable the screensaver. + */ +#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" + +/** + * \brief Tell the video driver that we only want a double buffer. + * + * By default, most lowlevel 2D APIs will use a triple buffer scheme that + * wastes no CPU time on waiting for vsync after issuing a flip, but + * introduces a frame of latency. On the other hand, using a double buffer + * scheme instead is recommended for cases where low latency is an important + * factor because we save a whole frame of latency. + * We do so by waiting for vsync immediately after issuing a flip, usually just + * after eglSwapBuffers call in the backend's *_SwapWindow function. + * + * Since it's driver-specific, it's only supported where possible and + * implemented. Currently supported the following drivers: + * + * - KMSDRM (kmsdrm) + * - Raspberry Pi (raspberrypi) + */ +#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER" + +/** + * \brief A variable controlling whether the EGL window is allowed to be + * composited as transparent, rather than opaque. + * + * Most window systems will always render windows opaque, even if the surface + * format has an alpha channel. This is not always true, however, so by default + * SDL will try to enforce opaque composition. To override this behavior, you + * can set this hint to "1". + */ +#define SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY "SDL_VIDEO_EGL_ALLOW_TRANSPARENCY" + +/** + * \brief A variable controlling whether the graphics context is externally managed. + * + * This variable can be set to the following values: + * "0" - SDL will manage graphics contexts that are attached to windows. + * "1" - Disable graphics context management on windows. + * + * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the + * context will be automatically saved and restored when pausing the application. Additionally, some + * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this + * behavior, which is desireable when the application manages the graphics context, such as + * an externally managed OpenGL context or attaching a Vulkan surface to the window. + */ +#define SDL_HINT_VIDEO_EXTERNAL_CONTEXT "SDL_VIDEO_EXTERNAL_CONTEXT" + +/** + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) + */ +#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" + +/** + * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. + * + * This hint only applies to Mac OS X. + * + * The variable can be set to the following values: + * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and + * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" + * button on their titlebars). + * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and + * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" + * button on their titlebars). + * + * The default value is "1". Spaces are disabled regardless of this hint if + * the OS isn't at least Mac OS X Lion (10.7). This hint must be set before + * any windows are created. + */ +#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" + +/** + * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to false. + * \warning Before SDL 2.0.14, this defaulted to true! In 2.0.14, we're + * seeing if "true" causes more problems than it solves in modern times. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + +/** + * \brief A variable controlling whether the libdecor Wayland backend is allowed to be used. + * + * This variable can be set to the following values: + * "0" - libdecor use is disabled. + * "1" - libdecor use is enabled (default). + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" + +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: +* +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + +/** +* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries +* +* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It +* can use two different sets of binaries, those compiled by the user from source +* or those provided by the Chrome browser. In the later case, these binaries require +* that SDL loads a DLL providing the shader compiler. +* +* This variable can be set to the following values: +* "d3dcompiler_46.dll" - default, best for Vista or later. +* "d3dcompiler_43.dll" - for XP support. +* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. +* +*/ +#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" + +/** + * \brief A variable controlling whether X11 should use GLX or EGL by default + * + * This variable can be set to the following values: + * "0" - Use GLX + * "1" - Use EGL + * + * By default SDL will use GLX when both are present. + */ +#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" + +/** + * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_BYPASS_COMPOSITOR + * "1" - Enable _NET_WM_BYPASS_COMPOSITOR + * + * By default SDL will use _NET_WM_BYPASS_COMPOSITOR + * + */ +#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" + +/** + * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_PING + * "1" - Enable _NET_WM_PING + * + * By default SDL will use _NET_WM_PING, but for applications that know they + * will not always be able to respond to ping requests in a timely manner they can + * turn it off to avoid the window manager thinking the app is hung. + * The hint is checked in CreateWindow. + */ +#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" + +/** + * \brief A variable forcing the visual ID chosen for new X11 windows + * + */ +#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" + +/** + * \brief A variable controlling whether the X11 Xinerama extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable Xinerama + * "1" - Enable Xinerama + * + * By default SDL will use Xinerama if it is available. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will not use XRandR because of window manager issues. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A variable controlling whether the X11 VidMode extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XVidMode + * "1" - Enable XVidMode + * + * By default SDL will use XVidMode if it is available. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief Controls how the fact chunk affects the loading of a WAVE file. + * + * The fact chunk stores information about the number of samples of a WAVE + * file. The Standards Update from Microsoft notes that this value can be used + * to 'determine the length of the data in seconds'. This is especially useful + * for compressed formats (for which this is a mandatory chunk) if they produce + * multiple sample frames per block and truncating the block is not allowed. + * The fact chunk can exactly specify how many sample frames there should be + * in this case. + * + * Unfortunately, most application seem to ignore the fact chunk and so SDL + * ignores it by default as well. + * + * This variable can be set to the following values: + * + * "truncate" - Use the number of samples to truncate the wave data if + * the fact chunk is present and valid + * "strict" - Like "truncate", but raise an error if the fact chunk + * is invalid, not present for non-PCM formats, or if the + * data chunk doesn't have that many samples + * "ignorezero" - Like "truncate", but ignore fact chunk if the number of + * samples is zero + * "ignore" - Ignore fact chunk entirely (default) + */ +#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK" + +/** + * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file. + * + * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE + * file) is not always reliable. In case the size is wrong, it's possible to + * just ignore it and step through the chunks until a fixed limit is reached. + * + * Note that files that have trailing data unrelated to the WAVE file or + * corrupt files may slow down the loading process without a reliable boundary. + * By default, SDL stops after 10000 chunks to prevent wasting time. Use the + * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value. + * + * This variable can be set to the following values: + * + * "force" - Always use the RIFF chunk size as a boundary for the chunk search + * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default) + * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB + * "maximum" - Search for chunks until the end of file (not recommended) + */ +#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE" + +/** + * \brief Controls how a truncated WAVE file is handled. + * + * A WAVE file is considered truncated if any of the chunks are incomplete or + * the data chunk size is not a multiple of the block size. By default, SDL + * decodes until the first incomplete block, as most applications seem to do. + * + * This variable can be set to the following values: + * + * "verystrict" - Raise an error if the file is truncated + * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored + * "dropframe" - Decode until the first incomplete sample frame + * "dropblock" - Decode until the first incomplete block (default) + */ +#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION" + +/** + * \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception. + * The 0x406D1388 Exception is a trick used to inform Visual Studio of a + * thread's name, but it tends to cause problems with other debuggers, + * and the .NET runtime. Note that SDL 2.0.6 and later will still use + * the (safer) SetThreadDescription API, introduced in the Windows 10 + * Creators Update, if available. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. + * "1" - SDL will not raise this exception, and threads will be unnamed. (default) + * This is necessary with .NET languages or debuggers that aren't Visual Studio. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL + * + * This variable can be set to the following values: + * "0" - The window message loop is not run + * "1" - The window message loop is processed in SDL_PumpEvents() + * + * By default SDL will process the windows message loop + */ +#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" + +/** + * \brief Force SDL to use Critical Sections for mutexes on Windows. + * On Windows 7 and newer, Slim Reader/Writer Locks are available. + * They offer better performance, allocate no kernel ressources and + * use less memory. SDL will fall back to Critical Sections on older + * OS versions or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use SRW Locks when available. If not, fall back to Critical Sections. (default) + * "1" - Force the use of Critical Sections in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS "SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS" + +/** + * \brief Force SDL to use Kernel Semaphores on Windows. + * Kernel Semaphores are inter-process and require a context + * switch on every interaction. On Windows 8 and newer, the + * WaitOnAddress API is available. Using that and atomics to + * implement semaphores increases performance. + * SDL will fall back to Kernel Objects on older OS versions + * or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use Atomics and WaitOnAddress API when available. If not, fall back to Kernel Objects. (default) + * "1" - Force the use of Kernel Objects in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL" + +/** + * \brief A variable to specify custom icon resource id from RC file on Windows platform + */ +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" + +/** + * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will generate a window-close event when it sees Alt+F4. + * "1" - SDL will only do normal key handling for Alt+F4. + */ +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" + +/** + * \brief Use the D3D9Ex API introduced in Windows Vista, instead of normal D3D9. + * Direct3D 9Ex contains changes to state management that can eliminate device + * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may require + * some changes to your application to cope with the new behavior, so this + * is disabled by default. + * + * This hint must be set before initializing the video subsystem. + * + * For more information on Direct3D 9Ex, see: + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements + * + * This variable can be set to the following values: + * "0" - Use the original Direct3D 9 API (default) + * "1" - Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex is unavailable) + * + */ +#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX" + +/** + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * + * This variable can be set to the following values: + * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) + * "1" - The window frame is interactive when the cursor is hidden + * + * By default SDL will allow interaction with the window frame when the cursor is hidden + */ +#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" + +/** +* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called +* +* This variable can be set to the following values: +* "0" - The window is activated when the SDL_ShowWindow function is called +* "1" - The window is not activated when the SDL_ShowWindow function is called +* +* By default SDL will activate the window when the SDL_ShowWindow function is called +*/ +#define SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN "SDL_WINDOW_NO_ACTIVATION_WHEN_SHOWN" + +/** \brief Allows back-button-press events on Windows Phone to be marked as handled + * + * Windows Phone devices typically feature a Back button. When pressed, + * the OS will emit back-button-press events, which apps are expected to + * handle in an appropriate manner. If apps do not explicitly mark these + * events as 'Handled', then the OS will invoke its default behavior for + * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to + * terminate the app (and attempt to switch to the previous app, or to the + * device's home screen). + * + * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL + * to mark back-button-press events as Handled, if and when one is sent to + * the app. + * + * Internally, Windows Phone sends back button events as parameters to + * special back-button-press callback functions. Apps that need to respond + * to back-button-press events are expected to register one or more + * callback functions for such, shortly after being launched (during the + * app's initialization phase). After the back button is pressed, the OS + * will invoke these callbacks. If the app's callback(s) do not explicitly + * mark the event as handled by the time they return, or if the app never + * registers one of these callback, the OS will consider the event + * un-handled, and it will apply its default back button behavior (terminate + * the app). + * + * SDL registers its own back-button-press callback with the Windows Phone + * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN + * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which + * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. + * If the hint's value is set to "1", the back button event's Handled + * property will get set to 'true'. If the hint's value is set to something + * else, or if it is unset, SDL will leave the event's Handled property + * alone. (By default, the OS sets this property to 'false', to note.) + * + * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a + * back button is pressed, or can set it in direct-response to a back button + * being pressed. + * + * In order to get notified when a back button is pressed, SDL apps should + * register a callback function with SDL_AddEventWatch(), and have it listen + * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. + * (Alternatively, SDL_KEYUP events can be listened-for. Listening for + * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON + * set by such a callback, will be applied to the OS' current + * back-button-press event. + * + * More details on back button behavior in Windows Phone apps can be found + * at the following page, on Microsoft's developer site: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with its label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init(). + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" + +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init() functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" + +/** + * \brief Mark X11 windows as override-redirect. + * + * If set, this _might_ increase framerate at the expense of the desktop + * not working as expected. Override-redirect windows aren't noticed by the + * window manager at all. + * + * You should probably only use this for fullscreen windows, and you probably + * shouldn't even use it for that. But it's here if you want to try! + */ +#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT" + +/** + * \brief A variable that lets you disable the detection and use of Xinput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable XInput detection (only uses direct input) + * "1" - Enable XInput detection (the default) + */ +#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" + +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + +/** + * \brief A variable that causes SDL to not ignore audio "monitors" + * + * This is currently only used for PulseAudio and ignored elsewhere. + * + * By default, SDL ignores audio devices that aren't associated with physical + * hardware. Changing this hint to "1" will expose anything SDL sees that + * appears to be an audio source or sink. This will add "devices" to the list + * that the user probably doesn't want or need, but it can be useful in + * scenarios where you want to hook up SDL to some sort of virtual device, + * etc. + * + * The default value is "0". This hint must be set before SDL_Init(). + * + * This hint is available since SDL 2.0.16. Before then, virtual devices are + * always ignored. + */ +#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS" + + +/** + * \brief An enumeration of hint priorities + */ +typedef enum +{ + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE +} SDL_HintPriority; + + +/** + * Set a hint with a specific priority. + * + * The priority controls the behavior when setting a hint that already has a + * value. Hints will replace existing hints of their priority and lower. + * Environment variables are considered to have override priority. + * + * \param name the hint to set + * \param value the value of the hint variable + * \param priority the SDL_HintPriority level for the hint + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, + const char *value, + SDL_HintPriority priority); + +/** + * Set a hint with normal priority. + * + * Hints will not be set if there is an existing override hint or environment + * variable that takes precedence. You can use SDL_SetHintWithPriority() to + * set the hint with override priority instead. + * + * \param name the hint to set + * \param value the value of the hint variable + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, + const char *value); + +/** + * Get the value of a hint. + * + * \param name the hint to query + * \returns the string value of a hint or NULL if the hint isn't set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); + +/** + * Get the boolean value of a hint variable. + * + * \param name the name of the hint to get the boolean value from + * \param default_value the value to return if the hint does not exist + * \returns the boolean value of a hint or the provided default value if the + * hint does not exist. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + +/** + * Type definition of the hint callback function. + * + * \param userdata what was passed as `userdata` to SDL_AddHintCallback() + * \param name what was passed as `name` to SDL_AddHintCallback() + * \param oldValue the previous hint value + * \param newValue the new value hint is to be set to + */ +typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); + +/** + * Add a function to watch a particular hint. + * + * \param name the hint to watch + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer to pass to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelHintCallback + */ +extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Remove a function watching a particular hint. + * + * \param name the hint being watched + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer being passed to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddHintCallback + */ +extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Clear all hints. + * + * This function is automatically called during SDL_Quit(). + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_ClearHints(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hints_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_joystick.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_joystick.h new file mode 100644 index 000000000..e80c0057f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_joystick.h @@ -0,0 +1,946 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_joystick.h + * + * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term "player_index" is the number assigned to a player on a specific + * controller. For XInput controllers this returns the XInput user index. + * Many joysticks will not be able to supply this information. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + */ + +#ifndef SDL_joystick_h_ +#define SDL_joystick_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_joystick.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for joysticks, and load appropriate drivers. + * + * If you would like to receive joystick updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The joystick structure used to identify an SDL joystick + */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + +/* A structure that encodes the stable unique id for a joystick device */ +typedef struct { + Uint8 data[16]; +} SDL_JoystickGUID; + +/** + * This is a unique ID for a joystick for the time it is connected to the system, + * and is never reused for the lifetime of the application. If the joystick is + * disconnected and reconnected, it will get a new ID. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_JoystickID; + +typedef enum +{ + SDL_JOYSTICK_TYPE_UNKNOWN, + SDL_JOYSTICK_TYPE_GAMECONTROLLER, + SDL_JOYSTICK_TYPE_WHEEL, + SDL_JOYSTICK_TYPE_ARCADE_STICK, + SDL_JOYSTICK_TYPE_FLIGHT_STICK, + SDL_JOYSTICK_TYPE_DANCE_PAD, + SDL_JOYSTICK_TYPE_GUITAR, + SDL_JOYSTICK_TYPE_DRUM_KIT, + SDL_JOYSTICK_TYPE_ARCADE_PAD, + SDL_JOYSTICK_TYPE_THROTTLE +} SDL_JoystickType; + +typedef enum +{ + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, /* <= 5% */ + SDL_JOYSTICK_POWER_LOW, /* <= 20% */ + SDL_JOYSTICK_POWER_MEDIUM, /* <= 70% */ + SDL_JOYSTICK_POWER_FULL, /* <= 100% */ + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX +} SDL_JoystickPowerLevel; + +/* Set max recognized G-force from accelerometer + See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed + */ +#define SDL_IPHONE_MAX_GFORCE 5.0 + + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); + + +/** + * Unlocking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); + +/** + * Count the number of joysticks attached to the system. + * + * \returns the number of attached joysticks on success or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/** + * Get the implementation dependent name of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); + +/** + * Get the player index of a joystick, or -1 if it's not available This can be + * called before any joysticks are opened. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index); + +/** + * Get the implementation-dependent GUID for the joystick at a given device + * index. + * + * This function can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the GUID of the selected joystick. If called on an invalid index, + * this function returns a zero GUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); + +/** + * Get the USB vendor ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the vendor ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB vendor ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceVendor(int device_index); + +/** + * Get the USB product ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB product ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProduct(int device_index); + +/** + * Get the product version of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product version + * isn't available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the product version of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProductVersion(int device_index); + +/** + * Get the type of a joystick, if available. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the SDL_JoystickType of the selected joystick. If called on an + * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN` + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_index); + +/** + * Get the instance ID of a joystick. + * + * This can be called before any joysticks are opened. If the index is out of + * range, this function will return -1. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the instance id of the selected joystick. If called on an invalid + * index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickGetDeviceInstanceID(int device_index); + +/** + * Open a joystick for use. + * + * The `device_index` argument refers to the N'th joystick presently + * recognized by SDL on the system. It is **NOT** the same as the instance ID + * used to identify the joystick in future events. See + * SDL_JoystickInstanceID() for more details about instance IDs. + * + * The joystick subsystem must be initialized before a joystick can be opened + * for use. + * + * \param device_index the index of the joystick to query + * \returns a joystick identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickInstanceID + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); + +/** + * Get the SDL_Joystick associated with an instance id. + * + * \param instance_id the instance id to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID instance_id); + +/** + * Get the SDL_Joystick associated with a player index. + * + * \param player_index the player index to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_index); + +/** + * Attach a new virtual joystick. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, + int naxes, + int nbuttons, + int nhats); + +/** + * Detach a virtual joystick. + * + * \param device_index a value previously returned from + * SDL_JoystickAttachVirtual() + * \returns 0 on success, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickDetachVirtual(int device_index); + +/** + * Query whether or not the joystick at a given device index is virtual. + * + * \param device_index a joystick device index. + * \returns SDL_TRUE if the joystick is virtual, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index); + +/** + * Set values on an opened, virtual-joystick's axis. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param axis the specific axis on the virtual joystick to set. + * \param value the new value for the specified axis. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value); + +/** + * Set values on an opened, virtual-joystick's button. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param button the specific button on the virtual joystick to set. + * \param value the new value for the specified button. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value); + +/** + * Set values on an opened, virtual-joystick's hat. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param hat the specific hat on the virtual joystick to set. + * \param value the new value for the specified hat. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value); + +/** + * Get the implementation dependent name of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNameForIndex + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); + +/** + * Get the player index of an opened joystick. + * + * For XInput controllers this returns the XInput user index. Many joysticks + * will not be able to supply this information. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the player index, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick); + +/** + * Set the player index of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \param player_index the player index to set. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index); + +/** + * Get the implementation-dependent GUID for the joystick. + * + * This function requires an open joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the GUID of the given joystick. If called on an invalid index, + * this function returns a zero GUID; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick); + +/** + * Get the USB vendor ID of an opened joystick, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB vendor ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick *joystick); + +/** + * Get the USB product ID of an opened joystick, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB product ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick *joystick); + +/** + * Get the product version of an opened joystick, if available. + * + * If the product version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the product version of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick); + +/** + * Get the serial number of an opened joystick, if available. + * + * Returns the serial number of the joystick, or NULL if it is not available. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the serial number of the selected joystick, or NULL if + * unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick); + +/** + * Get the type of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the SDL_JoystickType of the selected joystick. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick *joystick); + +/** + * Get an ASCII string representation for a given SDL_JoystickGUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the SDL_JoystickGUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a SDL_JoystickGUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a SDL_JoystickGUID structure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Get the status of a specified joystick. + * + * \param joystick the joystick to query + * \returns SDL_TRUE if the joystick has been opened, SDL_FALSE if it has not; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick); + +/** + * Get the instance ID of an opened joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the instance ID of the specified joystick on success or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick); + +/** + * Get the number of general axis controls on a joystick. + * + * Often, the directional pad on a game controller will either look like 4 + * separate buttons or a POV hat, and not axes, but all of this is up to the + * device and platform. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of axis controls/number of axes on success or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetAxis + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); + +/** + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated with them + * and their state cannot be polled. + * + * Most joysticks do not have trackballs. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of trackballs on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetBall + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); + +/** + * Get the number of POV hats on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of POV hats on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetHat + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); + +/** + * Get the number of buttons on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of buttons on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetButton + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); + +/** + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick events are + * enabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/** + * Enable/disable joystick event polling. + * + * If joystick events are disabled, you must call SDL_JoystickUpdate() + * yourself and manually check the state of the joystick when you want + * joystick information. + * + * It is recommended that you leave joystick event handling enabled. + * + * **WARNING**: Calling this function may delete all events currently in SDL's + * event queue. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns 1 if enabled, 0 if disabled, or a negative error code on failure; + * call SDL_GetError() for more information. + * + * If `state` is `SDL_QUERY` then the current state is returned, + * otherwise the new processing state is returned. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerEventState + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +#define SDL_JOYSTICK_AXIS_MAX 32767 +#define SDL_JOYSTICK_AXIS_MIN -32768 + +/** + * Get the current state of an axis control on a joystick. + * + * SDL makes no promises about what part of the joystick any given axis refers + * to. Your game should have some sort of configuration UI to let users + * specify what each axis should be bound to. Alternately, SDL's higher-level + * Game Controller API makes a great effort to apply order to this lower-level + * interface, so you know that a specific axis is the "left thumb stick," etc. + * + * The value returned by SDL_JoystickGetAxis() is a signed integer (-32768 to + * 32767) representing the current position of the axis. It may be necessary + * to impose certain tolerances on these values to account for jitter. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \returns a 16-bit signed integer representing the current position of the + * axis or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumAxes + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, + int axis); + +/** + * Get the initial state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \param state Upon return, the initial value is supplied here. + * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, + int axis, Sint16 *state); + +/** + * \name Hat positions + */ +/* @{ */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* @} */ + +/** + * Get the current state of a POV hat on a joystick. + * + * The returned value will be one of the following positions: + * + * - `SDL_HAT_CENTERED` + * - `SDL_HAT_UP` + * - `SDL_HAT_RIGHT` + * - `SDL_HAT_DOWN` + * - `SDL_HAT_LEFT` + * - `SDL_HAT_RIGHTUP` + * - `SDL_HAT_RIGHTDOWN` + * - `SDL_HAT_LEFTUP` + * - `SDL_HAT_LEFTDOWN` + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param hat the hat index to get the state from; indices start at index 0 + * \returns the current hat position. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumHats + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, + int hat); + +/** + * Get the ball axis change since the last poll. + * + * Trackballs can only return relative motion since the last call to + * SDL_JoystickGetBall(), these motion deltas are placed into `dx` and `dy`. + * + * Most joysticks do not have trackballs. + * + * \param joystick the SDL_Joystick to query + * \param ball the ball index to query; ball indices start at index 0 + * \param dx stores the difference in the x axis position since the last poll + * \param dy stores the difference in the y axis position since the last poll + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumBalls + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, + int ball, int *dx, int *dy); + +/** + * Get the current state of a button on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param button the button index to get the state from; indices start at + * index 0 + * \returns 1 if the specified button is pressed, 0 otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumButtons + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, + int button); + +/** + * Start a rumble effect. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param joystick The joystick to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_JoystickHasRumble + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the joystick's triggers + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this function is for _trigger_ rumble; the first joystick to + * support this was the PlayStation 5's DualShock 5 controller. If you want + * the (more common) whole-controller rumble, use SDL_JoystickRumble() + * instead. + * + * \param joystick The joystick to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_JoystickHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a joystick has an LED. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has a modifiable LED, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumble(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support on triggers. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick); + +/** + * Update a joystick's LED color. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0 on success, -1 if this joystick does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a joystick specific effect packet + * + * \param joystick The joystick to affect + * \param data The data to send to the joystick + * \param size The size of the data to send to the joystick + * \returns 0, or -1 if this joystick or driver doesn't support effect packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size); + +/** + * Close a joystick previously opened with SDL_JoystickOpen(). + * + * \param joystick The joystick device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); + +/** + * Get the battery level of a joystick as SDL_JoystickPowerLevel. + * + * \param joystick the SDL_Joystick to query + * \returns the current battery level as SDL_JoystickPowerLevel on success or + * `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_joystick_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_keyboard.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_keyboard.h new file mode 100644 index 000000000..a53dde68e --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_keyboard.h @@ -0,0 +1,316 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keyboard.h + * + * Include file for SDL keyboard event handling + */ + +#ifndef SDL_keyboard_h_ +#define SDL_keyboard_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keycode.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The SDL keysym structure, used in key events. + * + * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. + */ +typedef struct SDL_Keysym +{ + SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ + SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ + Uint16 mod; /**< current key modifiers */ + Uint32 unused; +} SDL_Keysym; + +/* Function prototypes */ + +/** + * Query the window which currently has keyboard focus. + * + * \returns the window with keyboard focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); + +/** + * Get a snapshot of the current state of the keyboard. + * + * The pointer returned is a pointer to an internal SDL array. It will be + * valid for the whole lifetime of the application and should not be freed by + * the caller. + * + * A array element with a value of 1 means that the key is pressed and a value + * of 0 means that it is not. Indexes into this array are obtained by using + * SDL_Scancode values. + * + * Use SDL_PumpEvents() to update the state array. + * + * This function gives you the current state after all events have been + * processed, so if a key or button has been pressed and released before you + * process events, then the pressed state will never show up in the + * SDL_GetKeyboardState() calls. + * + * Note: This function doesn't take into account whether shift has been + * pressed or not. + * + * \param numkeys if non-NULL, receives the length of the returned array + * \returns a pointer to an array of key states. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PumpEvents + */ +extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); + +/** + * Get the current key modifier state for the keyboard. + * + * \returns an OR'd combination of the modifier keys for the keyboard. See + * SDL_Keymod for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyboardState + * \sa SDL_SetModState + */ +extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); + +/** + * Set the current key modifier state for the keyboard. + * + * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose + * modifier key states on your application. Simply pass your desired modifier + * states into `modstate`. This value may be a bitwise, OR'd combination of + * SDL_Keymod values. + * + * This does not change the keyboard state, only the key modifier flags that + * SDL reports. + * + * \param modstate the desired SDL_Keymod for the keyboard + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetModState + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); + +/** + * Get the key code corresponding to the given scancode according to the + * current keyboard layout. + * + * See SDL_Keycode for details. + * + * \param scancode the desired SDL_Scancode to query + * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); + +/** + * Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * See SDL_Scancode for details. + * + * \param key the desired SDL_Keycode to query + * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); + +/** + * Get a human-readable name for a scancode. + * + * See SDL_Scancode for details. + * + * **Warning**: The returned name is by design not stable across platforms, + * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left + * Windows" under Microsoft Windows, and some scancodes like + * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even + * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and + * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore + * unsuitable for creating a stable cross-platform two-way mapping between + * strings and scancodes. + * + * \param scancode the desired SDL_Scancode to query + * \returns a pointer to the name for the scancode. If the scancode doesn't + * have a name this function returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); + +/** + * Get a scancode from a human-readable name. + * + * \param name the human-readable scancode name + * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't + * recognized; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); + +/** + * Get a human-readable name for a key. + * + * See SDL_Scancode and SDL_Keycode for details. + * + * \param key the desired SDL_Keycode to query + * \returns a pointer to a UTF-8 string that stays valid at least until the + * next call to this function. If you need it around any longer, you + * must copy it. If the key doesn't have a name, this function + * returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); + +/** + * Get a key code from a human-readable name. + * + * \param name the human-readable key name + * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); + +/** + * Start accepting Unicode text input events. + * + * This function will start accepting Unicode text input events in the focused + * SDL window, and start emitting SDL_TextInputEvent (SDL_TEXTINPUT) and + * SDL_TextEditingEvent (SDL_TEXTEDITING) events. Please use this function in + * pair with SDL_StopTextInput(). + * + * On some platforms using this function activates the screen keyboard. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextInputRect + * \sa SDL_StopTextInput + */ +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); + +/** + * Check whether or not Unicode text input events are enabled. + * + * \returns SDL_TRUE if text input events are enabled else SDL_FALSE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + +/** + * Stop receiving any text input events. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); + +/** + * Set the rectangle used to type Unicode text inputs. + * + * \param rect the SDL_Rect structure representing the rectangle to receive + * text (ignored if NULL) + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_SetTextInputRect(SDL_Rect *rect); + +/** + * Check whether the platform has screen keyboard support. + * + * \returns SDL_TRUE if the platform has some screen keyboard support or + * SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + * \sa SDL_IsScreenKeyboardShown + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); + +/** + * Check whether the screen keyboard is shown for given window. + * + * \param window the window for which screen keyboard should be queried + * \returns SDL_TRUE if screen keyboard is shown or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasScreenKeyboardSupport + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_keyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_keycode.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_keycode.h new file mode 100644 index 000000000..35602541a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_keycode.h @@ -0,0 +1,353 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keycode.h + * + * Defines constants which identify keyboard keys and modifiers. + */ + +#ifndef SDL_keycode_h_ +#define SDL_keycode_h_ + +#include "SDL_stdinc.h" +#include "SDL_scancode.h" + +/** + * \brief The SDL virtual key representation. + * + * Values of this type are used to represent keyboard keys using the current + * layout of the keyboard. These values include Unicode values representing + * the unmodified character that would be generated by pressing the key, or + * an SDLK_* constant for those keys that do not generate characters. + * + * A special exception is the number keys at the top of the keyboard which + * always map to SDLK_0...SDLK_9, regardless of layout. + */ +typedef Sint32 SDL_Keycode; + +#define SDLK_SCANCODE_MASK (1<<30) +#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK) + +typedef enum +{ + SDLK_UNKNOWN = 0, + + SDLK_RETURN = '\r', + SDLK_ESCAPE = '\x1B', + SDLK_BACKSPACE = '\b', + SDLK_TAB = '\t', + SDLK_SPACE = ' ', + SDLK_EXCLAIM = '!', + SDLK_QUOTEDBL = '"', + SDLK_HASH = '#', + SDLK_PERCENT = '%', + SDLK_DOLLAR = '$', + SDLK_AMPERSAND = '&', + SDLK_QUOTE = '\'', + SDLK_LEFTPAREN = '(', + SDLK_RIGHTPAREN = ')', + SDLK_ASTERISK = '*', + SDLK_PLUS = '+', + SDLK_COMMA = ',', + SDLK_MINUS = '-', + SDLK_PERIOD = '.', + SDLK_SLASH = '/', + SDLK_0 = '0', + SDLK_1 = '1', + SDLK_2 = '2', + SDLK_3 = '3', + SDLK_4 = '4', + SDLK_5 = '5', + SDLK_6 = '6', + SDLK_7 = '7', + SDLK_8 = '8', + SDLK_9 = '9', + SDLK_COLON = ':', + SDLK_SEMICOLON = ';', + SDLK_LESS = '<', + SDLK_EQUALS = '=', + SDLK_GREATER = '>', + SDLK_QUESTION = '?', + SDLK_AT = '@', + + /* + Skip uppercase letters + */ + + SDLK_LEFTBRACKET = '[', + SDLK_BACKSLASH = '\\', + SDLK_RIGHTBRACKET = ']', + SDLK_CARET = '^', + SDLK_UNDERSCORE = '_', + SDLK_BACKQUOTE = '`', + SDLK_a = 'a', + SDLK_b = 'b', + SDLK_c = 'c', + SDLK_d = 'd', + SDLK_e = 'e', + SDLK_f = 'f', + SDLK_g = 'g', + SDLK_h = 'h', + SDLK_i = 'i', + SDLK_j = 'j', + SDLK_k = 'k', + SDLK_l = 'l', + SDLK_m = 'm', + SDLK_n = 'n', + SDLK_o = 'o', + SDLK_p = 'p', + SDLK_q = 'q', + SDLK_r = 'r', + SDLK_s = 's', + SDLK_t = 't', + SDLK_u = 'u', + SDLK_v = 'v', + SDLK_w = 'w', + SDLK_x = 'x', + SDLK_y = 'y', + SDLK_z = 'z', + + SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK), + + SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1), + SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2), + SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3), + SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4), + SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5), + SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6), + SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7), + SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8), + SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9), + SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10), + SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11), + SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12), + + SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN), + SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK), + SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE), + SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), + SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), + SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), + SDLK_DELETE = '\x7F', + SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), + SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), + SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), + SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT), + SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN), + SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP), + + SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR), + SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE), + SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY), + SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS), + SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS), + SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER), + SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1), + SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2), + SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3), + SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4), + SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5), + SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6), + SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7), + SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8), + SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9), + SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0), + SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD), + + SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION), + SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER), + SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS), + SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13), + SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14), + SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15), + SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16), + SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17), + SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18), + SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19), + SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20), + SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21), + SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22), + SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23), + SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24), + SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE), + SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP), + SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU), + SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT), + SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP), + SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN), + SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO), + SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT), + SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY), + SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE), + SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND), + SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE), + SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP), + SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN), + SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA), + SDLK_KP_EQUALSAS400 = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400), + + SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE), + SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ), + SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL), + SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR), + SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR), + SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2), + SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR), + SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT), + SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER), + SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN), + SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL), + SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL), + + SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00), + SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000), + SDLK_THOUSANDSSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR), + SDLK_DECIMALSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR), + SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT), + SDLK_CURRENCYSUBUNIT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT), + SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN), + SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN), + SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE), + SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE), + SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB), + SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE), + SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A), + SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B), + SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C), + SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D), + SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E), + SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F), + SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR), + SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER), + SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT), + SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS), + SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER), + SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND), + SDLK_KP_DBLAMPERSAND = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND), + SDLK_KP_VERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR), + SDLK_KP_DBLVERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR), + SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON), + SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH), + SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE), + SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT), + SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM), + SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE), + SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL), + SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR), + SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD), + SDLK_KP_MEMSUBTRACT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT), + SDLK_KP_MEMMULTIPLY = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY), + SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE), + SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS), + SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR), + SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY), + SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY), + SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL), + SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL), + SDLK_KP_HEXADECIMAL = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL), + + SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL), + SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT), + SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT), + SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI), + SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL), + SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT), + SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT), + SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI), + + SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE), + + SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT), + SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV), + SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP), + SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY), + SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE), + SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT), + SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW), + SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL), + SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR), + SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER), + SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH), + SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME), + SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK), + SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD), + SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP), + SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH), + SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS), + + SDLK_BRIGHTNESSDOWN = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN), + SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP), + SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH), + SDLK_KBDILLUMTOGGLE = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE), + SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN), + SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP), + SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT), + SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP), + SDLK_APP1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP1), + SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), + + SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), + SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD) +} SDL_KeyCode; + +/** + * \brief Enumeration of valid key mods (possibly OR'd together). + */ +typedef enum +{ + KMOD_NONE = 0x0000, + KMOD_LSHIFT = 0x0001, + KMOD_RSHIFT = 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LGUI = 0x0400, + KMOD_RGUI = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_SCROLL = 0x8000, + + KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL, + KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT, + KMOD_ALT = KMOD_LALT | KMOD_RALT, + KMOD_GUI = KMOD_LGUI | KMOD_RGUI, + + KMOD_RESERVED = KMOD_SCROLL /* This is for source-level compatibility with SDL 2.0.0. */ +} SDL_Keymod; + +#endif /* SDL_keycode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_loadso.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_loadso.h new file mode 100644 index 000000000..61857c813 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_loadso.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_loadso.h + * + * System dependent library loading routines + * + * Some things to keep in mind: + * \li These functions only work on C function names. Other languages may + * have name mangling and intrinsic language support that varies from + * compiler to compiler. + * \li Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * \li Avoid namespace collisions. If you load a symbol from the library, + * it is not defined whether or not it goes into the global symbol + * namespace for the application. If it does and it conflicts with + * symbols in your code or other shared libraries, you will not get + * the results you expect. :) + */ + +#ifndef SDL_loadso_h_ +#define SDL_loadso_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Dynamically load a shared object. + * + * \param sofile a system-dependent name of the object file + * \returns an opaque pointer to the object handle or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_UnloadObject + */ +extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); + +/** + * Look up the address of the named function in a shared object. + * + * This function pointer is no longer valid after calling SDL_UnloadObject(). + * + * This function can only look up C function names. Other languages may have + * name mangling and intrinsic language support that varies from compiler to + * compiler. + * + * Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * + * If the requested function doesn't exist, NULL is returned. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * \param name the name of the function to look up + * \returns a pointer to the function or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadObject + * \sa SDL_UnloadObject + */ +extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, + const char *name); + +/** + * Unload a shared object from memory. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_LoadObject + */ +extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_loadso_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_locale.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_locale.h new file mode 100644 index 000000000..751577994 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_locale.h @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_locale.h + * + * Include file for SDL locale services + */ + +#ifndef _SDL_locale_h +#define _SDL_locale_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +typedef struct SDL_Locale +{ + const char *language; /**< A language name, like "en" for English. */ + const char *country; /**< A country, like "US" for America. Can be NULL. */ +} SDL_Locale; + +/** + * Report the user's preferred locale. + * + * This returns an array of SDL_Locale structs, the final item zeroed out. + * When the caller is done with this array, it should call SDL_free() on the + * returned value; all the memory involved is allocated in a single block, so + * a single SDL_free() will suffice. + * + * Returned language strings are in the format xx, where 'xx' is an ISO-639 + * language specifier (such as "en" for English, "de" for German, etc). + * Country strings are in the format YY, where "YY" is an ISO-3166 country + * code (such as "US" for the United States, "CA" for Canada, etc). Country + * might be NULL if there's no specific guidance on them (so you might get { + * "en", "US" } for American English, but { "en", NULL } means "English + * language, generically"). Language strings are never NULL, except to + * terminate the array. + * + * Please note that not all of these strings are 2 characters; some are three + * or more. + * + * The returned list of locales are in the order of the user's preference. For + * example, a German citizen that is fluent in US English and knows enough + * Japanese to navigate around Tokyo might have a list like: { "de", "en_US", + * "jp", NULL }. Someone from England might prefer British English (where + * "color" is spelled "colour", etc), but will settle for anything like it: { + * "en_GB", "en", NULL }. + * + * This function returns NULL on error, including when the platform does not + * supply this information at all. + * + * This might be a "slow" call that has to query the operating system. It's + * best to ask for this once and save the results. However, this list can + * change, usually because the user has changed a system preference outside of + * your program; SDL will send an SDL_LOCALECHANGED event in this case, if + * possible, and you can call this function again to get an updated copy of + * preferred locales. + * + * \return array of locales, terminated with a locale with a NULL language + * field. Will return NULL on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_locale_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_log.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_log.h new file mode 100644 index 000000000..dbbcb1e6f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_log.h @@ -0,0 +1,404 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_log.h + * + * Simple log messages with categories and priorities. + * + * By default logs are quiet, but if you're debugging SDL you might want: + * + * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); + * + * Here's where the messages go on different platforms: + * Windows: debug output stream + * Android: log output + * Others: standard error output (stderr) + */ + +#ifndef SDL_log_h_ +#define SDL_log_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief The maximum size of a log message + * + * Messages longer than the maximum size will be truncated + */ +#define SDL_MAX_LOG_MESSAGE 4096 + +/** + * \brief The predefined log categories + * + * By default the application category is enabled at the INFO level, + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * CRITICAL level. + */ +typedef enum +{ + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + /* Reserved for future SDL library use */ + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + /* Beyond this point is reserved for application use, e.g. + enum { + MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, + MYAPP_CATEGORY_AWESOME2, + MYAPP_CATEGORY_AWESOME3, + ... + }; + */ + SDL_LOG_CATEGORY_CUSTOM +} SDL_LogCategory; + +/** + * \brief The predefined log priorities + */ +typedef enum +{ + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} SDL_LogPriority; + + +/** + * Set the priority of all log categories. + * + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); + +/** + * Set the priority of a particular log category. + * + * \param category the category to assign a priority to + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetPriority + * \sa SDL_LogSetAllPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, + SDL_LogPriority priority); + +/** + * Get the priority of a particular log category. + * + * \param category the category to query + * \returns the SDL_LogPriority for the requested category + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); + +/** + * Reset all priorities to default. + * + * This is called by SDL_Quit(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetAllPriority + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); + +/** + * Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO. + * + * = * \param fmt a printf() style message format string + * + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Log a message with SDL_LOG_PRIORITY_VERBOSE. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_DEBUG. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_INFO. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_WARN. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + */ +extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_ERROR. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_CRITICAL. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessage(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ap a variable argument list + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, + SDL_LogPriority priority, + const char *fmt, va_list ap); + +/** + * The prototype for the log output callback function. + * + * This function is called by SDL when there is new text to be logged. + * + * \param userdata what was passed as `userdata` to SDL_LogSetOutputFunction() + * \param category the category of the message + * \param priority the priority of the message + * \param message the message being output + */ +typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); + +/** + * Get the current log output function. + * + * \param callback an SDL_LogOutputFunction filled in with the current log + * callback + * \param userdata a pointer filled in with the pointer that is passed to + * `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); + +/** + * Replace the default log output function with one of your own. + * + * \param callback an SDL_LogOutputFunction to call instead of the default + * \param userdata a pointer that is passed to `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_main.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_main.h new file mode 100644 index 000000000..b3fec15fe --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_main.h @@ -0,0 +1,235 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_main_h_ +#define SDL_main_h_ + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + If you link with SDL dynamically on iOS, the main function can't be in a + shared library, so you need to link with libSDLmain.a, which includes a + stub main function that calls into the shared library to start execution. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See docs/README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +/* We need to export SDL_main so it can be launched from Java */ +#define SDLMAIN_DECLSPEC DECLSPEC + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__PSP__) +/* On PSP SDL provides a main function that sets the module info, + activates the GPU and starts the thread required to be able to exit + the software. + + If you provide this yourself, you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifndef SDLMAIN_DECLSPEC +#define SDLMAIN_DECLSPEC +#endif + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The prototype for the application's main() function + */ +typedef int (*SDL_main_func)(int argc, char *argv[]); +extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); + + +/** + * Circumvent failure of SDL_Init() when not using SDL_main() as an entry + * point. + * + * This function is defined in SDL_main.h, along with the preprocessor rule to + * redefine main() as SDL_main(). Thus to ensure that your main() function + * will not be changed it is necessary to define SDL_MAIN_HANDLED before + * including SDL.h. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#ifdef __WIN32__ + +/** + * Register a win32 window class for SDL's use. + * + * This can be called to set the application window class at startup. It is + * safe to call this multiple times, as long as every call is eventually + * paired with a call to SDL_UnregisterApp, but a second registration attempt + * while a previous registration is still active will be ignored, other than + * to increment a counter. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when initializing the video subsystem. + * + * \param name the window class name, in UTF-8 encoding. If NULL, SDL + * currently uses "SDL_app" but this isn't guaranteed. + * \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL + * currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of + * what is specified here. + * \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL + * will use `GetModuleHandle(NULL)` instead. + * \returns 0 on success, -1 on error. SDL_GetError() may have details. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst); + +/** + * Deregister the win32 window class from an SDL_RegisterApp call. + * + * This can be called to undo the effects of SDL_RegisterApp. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when deinitializing the video subsystem. + * + * It is safe to call this multiple times, as long as every call is eventually + * paired with a prior call to SDL_RegisterApp. The window class will only be + * deregistered when the registration counter in SDL_RegisterApp decrements to + * zero through calls to this function. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* __WIN32__ */ + + +#ifdef __WINRT__ + +/** + * Initialize and launch an SDL/WinRT application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.0.3. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); + +#endif /* __WINRT__ */ + +#if defined(__IPHONEOS__) + +/** + * Initializes and launches an SDL application. + * + * \param argc The argc parameter from the application's main() function + * \param argv The argv parameter from the application's main() function + * \param mainFunction The SDL app's C-style main(), an SDL_main_func + * \return the return value from mainFunction + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); + +#endif /* __IPHONEOS__ */ + + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_main_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_messagebox.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_messagebox.h new file mode 100644 index 000000000..d763534d2 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_messagebox.h @@ -0,0 +1,193 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_messagebox_h_ +#define SDL_messagebox_h_ + +#include "SDL_stdinc.h" +#include "SDL_video.h" /* For SDL_Window */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SDL_MessageBox flags. If supported will display warning icon, etc. + */ +typedef enum +{ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040, /**< informational dialog */ + SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = 0x00000080, /**< buttons placed left to right */ + SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = 0x00000100 /**< buttons placed right to left */ +} SDL_MessageBoxFlags; + +/** + * Flags for SDL_MessageBoxButtonData. + */ +typedef enum +{ + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ +} SDL_MessageBoxButtonFlags; + +/** + * Individual button data. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ + int buttonid; /**< User defined button id (value returned via SDL_ShowMessageBox) */ + const char * text; /**< The UTF-8 button text */ +} SDL_MessageBoxButtonData; + +/** + * RGB value used in a message box color scheme + */ +typedef struct +{ + Uint8 r, g, b; +} SDL_MessageBoxColor; + +typedef enum +{ + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX +} SDL_MessageBoxColorType; + +/** + * A set of colors to use for message box dialogs + */ +typedef struct +{ + SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; +} SDL_MessageBoxColorScheme; + +/** + * MessageBox structure containing title, text, window, etc. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxFlags */ + SDL_Window *window; /**< Parent window, can be NULL */ + const char *title; /**< UTF-8 title */ + const char *message; /**< UTF-8 message text */ + + int numbuttons; + const SDL_MessageBoxButtonData *buttons; + + const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ +} SDL_MessageBoxData; + +/** + * Create a modal message box. + * + * If your needs aren't complex, it might be easier to use + * SDL_ShowSimpleMessageBox. + * + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. + * + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param messageboxdata the SDL_MessageBoxData structure with title, text and + * other options + * \param buttonid the pointer to which user id of hit button should be copied + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowSimpleMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +/** + * Display a simple modal message box. + * + * If your needs aren't complex, this function is preferred over + * SDL_ShowMessageBox. + * + * `flags` may be any of the following: + * + * - `SDL_MESSAGEBOX_ERROR`: error dialog + * - `SDL_MESSAGEBOX_WARNING`: warning dialog + * - `SDL_MESSAGEBOX_INFORMATION`: informational dialog + * + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. + * + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param flags an SDL_MessageBoxFlags value + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window the parent window, or NULL for no parent + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_messagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_metal.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_metal.h new file mode 100644 index 000000000..9ecaa8151 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_metal.h @@ -0,0 +1,112 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_metal.h + * + * Header file for functions to creating Metal layers and views on SDL windows. + */ + +#ifndef SDL_metal_h_ +#define SDL_metal_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS). + * + * \note This can be cast directly to an NSView or UIView. + */ +typedef void *SDL_MetalView; + +/** + * \name Metal support functions + */ +/* @{ */ + +/** + * Create a CAMetalLayer-backed NSView/UIView and attach it to the specified + * window. + * + * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on + * its own. It is up to user code to do that. + * + * The returned handle can be casted directly to a NSView or UIView. To access + * the backing CAMetalLayer, call SDL_Metal_GetLayer(). + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_Metal_DestroyView + * \sa SDL_Metal_GetLayer + */ +extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window); + +/** + * Destroy an existing SDL_MetalView object. + * + * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was + * called after SDL_CreateWindow. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_Metal_CreateView + */ +extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view); + +/** + * Get a pointer to the backing CAMetalLayer for the given view. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_MetalCreateView + */ +extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view); + +/** + * Get the size of a window's underlying drawable in pixels (for use with + * setting viewport, scissor & etc). + * + * \param window SDL_Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, may be NULL + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + */ +extern DECLSPEC void SDLCALL SDL_Metal_GetDrawableSize(SDL_Window* window, int *w, + int *h); + +/* @} *//* Metal support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_metal_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_misc.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_misc.h new file mode 100644 index 000000000..261b6b871 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_misc.h @@ -0,0 +1,79 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_misc.h + * + * \brief Include file for SDL API functions that don't fit elsewhere. + */ + +#ifndef SDL_misc_h_ +#define SDL_misc_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Open a URL/URI in the browser or other appropriate external application. + * + * Open a URL in a separate, system-provided application. How this works will + * vary wildly depending on the platform. This will likely launch what makes + * sense to handle a specific URL's protocol (a web browser for `http://`, + * etc), but it might also be able to launch file managers for directories and + * other things. + * + * What happens when you open a URL varies wildly as well: your game window + * may lose focus (and may or may not lose focus if your game was fullscreen + * or grabbing input at the time). On mobile devices, your app will likely + * move to the background or your process might be paused. Any given platform + * may or may not handle a given URL. + * + * If this is unimplemented (or simply unavailable) for a platform, this will + * fail with an error. A successful result does not mean the URL loaded, just + * that we launched _something_ to handle it (or at least believe we did). + * + * All this to say: this function can be useful, but you should definitely + * test it on every platform you target. + * + * \param url A valid URL/URI to open. Use `file:///full/path/to/file` for + * local files, if supported. + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_OpenURL(const char *url); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_misc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_mouse.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_mouse.h new file mode 100644 index 000000000..1d4a2db0d --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_mouse.h @@ -0,0 +1,454 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_mouse.h + * + * Include file for SDL mouse event handling. + */ + +#ifndef SDL_mouse_h_ +#define SDL_mouse_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDL_Cursor SDL_Cursor; /**< Implementation dependent */ + +/** + * \brief Cursor types for SDL_CreateSystemCursor(). + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ + SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ + SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ + SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ + SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ + SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ + SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ + SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ + SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ + SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ + SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ + SDL_SYSTEM_CURSOR_HAND, /**< Hand */ + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; + +/** + * \brief Scroll direction types for the Scroll event + */ +typedef enum +{ + SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ + SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ +} SDL_MouseWheelDirection; + +/* Function prototypes */ + +/** + * Get the window which currently has mouse focus. + * + * \returns the window with mouse focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); + +/** + * Retrieve the current state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse cursor position relative to the focus window. You can pass NULL for + * either `x` or `y`. + * + * \param x the x coordinate of the mouse cursor position relative to the + * focus window + * \param y the y coordinate of the mouse cursor position relative to the + * focus window + * \returns a 32-bit button bitmask of the current button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGlobalMouseState + * \sa SDL_GetRelativeMouseState + * \sa SDL_PumpEvents + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); + +/** + * Get the current state of the mouse in relation to the desktop. + * + * This works similarly to SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if you + * need to track the mouse outside of a specific window and SDL_CaptureMouse() + * doesn't fit your needs. For example, it could be useful if you need to + * track the mouse while dragging a window, where coordinates relative to a + * window might not be in sync at all times. + * + * Note: SDL_GetMouseState() returns the mouse position as SDL understands it + * from the last pump of the event queue. This function, however, queries the + * OS for the current mouse position, and as such, might be a slightly less + * efficient function. Unless you know what you're doing and have a good + * reason to use this function, you probably want SDL_GetMouseState() instead. + * + * \param x filled in with the current X coord relative to the desktop; can be + * NULL + * \param y filled in with the current Y coord relative to the desktop; can be + * NULL + * \returns the current button state as a bitmask which can be tested using + * the SDL_BUTTON(X) macros. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_CaptureMouse + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); + +/** + * Retrieve the relative state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState() or since + * event initialization. You can pass NULL for either `x` or `y`. + * + * \param x a pointer filled with the last recorded x coordinate of the mouse + * \param y a pointer filled with the last recorded y coordinate of the mouse + * \returns a 32-bit button bitmask of the relative button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetMouseState + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/** + * Move the mouse cursor to the given position within the window. + * + * This function generates a mouse motion event. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param window the window to move the mouse into, or NULL for the current + * mouse focus + * \param x the x coordinate within the window + * \param y the y coordinate within the window + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WarpMouseGlobal + */ +extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, + int x, int y); + +/** + * Move the mouse to the given position in global screen space. + * + * This function generates a mouse motion event. + * + * A failure of this function usually means that it is unsupported by a + * platform. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param x the x coordinate + * \param y the y coordinate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_WarpMouseInWindow + */ +extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); + +/** + * Set relative mouse mode. + * + * While the mouse is in relative mode, the cursor is hidden, and the driver + * will try to report continuous motion in the current window. Only relative + * motion events will be delivered, the mouse position will not change. + * + * Note that this function will not be able to provide continuous relative + * motion when used over Microsoft Remote Desktop, instead motion is limited + * to the bounds of the screen. + * + * This function will flush any pending mouse motion. + * + * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * If relative mode is not supported, this returns -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRelativeMouseMode + */ +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); + +/** + * Capture the mouse and to track input outside an SDL window. + * + * Capturing enables your app to obtain mouse events globally, instead of just + * within your window. Not all video targets support this function. When + * capturing is enabled, the current window will get all mouse events, but + * unlike relative mode, no change is made to the cursor and it is not + * restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this function + * sparingly, and in small bursts. For example, you might want to track the + * mouse while the user is dragging something, until the user releases a mouse + * button. It is not recommended that you capture the mouse for long periods + * of time, such as the entire time your app is running. For that, you should + * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowGrab(), depending + * on your goals. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only allowed + * for the foreground window. If the window loses focus while capturing, the + * capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * `SDL_WINDOW_MOUSE_CAPTURE` flag set. + * + * \param enabled SDL_TRUE to enable capturing, SDL_FALSE to disable. + * \returns 0 on success or -1 if not supported; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetGlobalMouseState + */ +extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); + +/** + * Query whether relative mouse mode is enabled. + * + * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRelativeMouseMode + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); + +/** + * Create a cursor using the specified bitmap data and mask (in MSB format). + * + * `mask` has to be in MSB (Most Significant Bit) format. + * + * The cursor width (`w`) must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * + * - data=0, mask=1: white + * - data=1, mask=1: black + * - data=0, mask=0: transparent + * - data=1, mask=0: inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_FreeCursor(). + * + * If you want to have a color cursor, or create your cursor from an + * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can + * hide the cursor and draw your own as part of your game's rendering, but it + * will be bound to the framerate. + * + * Also, since SDL 2.0.0, SDL_CreateSystemCursor() is available, which + * provides twelve readily available system cursors to pick from. + * + * \param data the color value for each pixel of the cursor + * \param mask the mask value for each pixel of the cursor + * \param w the width of the cursor + * \param h the height of the cursor + * \param hot_x the X-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \param hot_y the Y-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \returns a new cursor with the specified parameters on success or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + * \sa SDL_SetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, + const Uint8 * mask, + int w, int h, int hot_x, + int hot_y); + +/** + * Create a color cursor. + * + * \param surface an SDL_Surface structure representing the cursor image + * \param hot_x the x position of the cursor hot spot + * \param hot_y the y position of the cursor hot spot + * \returns the new cursor on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, + int hot_x, + int hot_y); + +/** + * Create a system cursor. + * + * \param id an SDL_SystemCursor enum value + * \returns a cursor on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + +/** + * Set the active cursor. + * + * This function sets the currently active cursor to the specified one. If the + * cursor is currently visible, the change will be immediately represented on + * the display. SDL_SetCursor(NULL) can be used to force cursor redraw, if + * this is desired for any reason. + * + * \param cursor a cursor to make active + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_GetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); + +/** + * Get the active cursor. + * + * This function returns a pointer to the current cursor which is owned by the + * library. It is not necessary to free the cursor with SDL_FreeCursor(). + * + * \returns the active cursor or NULL if there is no mouse. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); + +/** + * Get the default cursor. + * + * \returns the default cursor on success or NULL on failure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); + +/** + * Free a previously-created cursor. + * + * Use this function to free cursor resources created with SDL_CreateCursor(), + * SDL_CreateColorCursor() or SDL_CreateSystemCursor(). + * + * \param cursor the cursor to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateColorCursor + * \sa SDL_CreateCursor + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); + +/** + * Toggle whether or not the cursor is shown. + * + * The cursor starts off displayed but can be turned off. Passing `SDL_ENABLE` + * displays the cursor and passing `SDL_DISABLE` hides it. + * + * The current state of the mouse cursor can be queried by passing + * `SDL_QUERY`; either `SDL_DISABLE` or `SDL_ENABLE` will be returned. + * + * \param toggle `SDL_ENABLE` to show the cursor, `SDL_DISABLE` to hide it, + * `SDL_QUERY` to query the current state without changing it. + * \returns `SDL_ENABLE` if the cursor is shown, or `SDL_DISABLE` if the + * cursor is hidden, or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_SetCursor + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/** + * Used as a mask when testing buttons in buttonstate. + * + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_X1 4 +#define SDL_BUTTON_X2 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_mutex.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_mutex.h new file mode 100644 index 000000000..173468f6a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_mutex.h @@ -0,0 +1,471 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_mutex_h_ +#define SDL_mutex_h_ + +/** + * \file SDL_mutex.h + * + * Functions to provide thread synchronization primitives. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Synchronization functions which can time out return this value + * if they time out. + */ +#define SDL_MUTEX_TIMEDOUT 1 + +/** + * This is the timeout value which corresponds to never time out. + */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/** + * \name Mutex functions + */ +/* @{ */ + +/* The SDL mutex structure, defined in SDL_sysmutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/** + * Create a new mutex. + * + * All newly-created mutexes begin in the _unlocked_ state. + * + * Calls to SDL_LockMutex() will not return while the mutex is locked by + * another thread. See SDL_TryLockMutex() to attempt to lock without blocking. + * + * SDL mutexes are reentrant. + * + * \returns the initialized and unlocked mutex or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); + +/** + * Lock the mutex. + * + * This will block until the mutex is available, which is to say it is in the + * unlocked state and the OS has chosen the caller as the next thread to lock + * it. Of all threads waiting to lock the mutex, only one may do so at a time. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * \param mutex the mutex to lock + * \return 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); +#define SDL_mutexP(m) SDL_LockMutex(m) + +/** + * Try to lock a mutex without blocking. + * + * This works just like SDL_LockMutex(), but if the mutex is not available, + * this function returns `SDL_MUTEX_TIMEOUT` immediately. + * + * This technique is useful if you need exclusive access to a resource but + * don't want to wait for it, and will return to it to try again later. + * + * \param mutex the mutex to try to lock + * \returns 0, `SDL_MUTEX_TIMEDOUT`, or -1 on error; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); + +/** + * Unlock the mutex. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * It is an error to unlock a mutex that has not been locked by the current + * thread, and doing so results in undefined behavior. + * + * It is also an error to unlock a mutex that isn't locked at all. + * + * \param mutex the mutex to unlock. + * \returns 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex); +#define SDL_mutexV(m) SDL_UnlockMutex(m) + +/** + * Destroy a mutex created with SDL_CreateMutex(). + * + * This function must be called on any mutex that is no longer needed. Failure + * to destroy a mutex will result in a system memory or resource leak. While + * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt + * to destroy a locked mutex, and may result in undefined behavior depending + * on the platform. + * + * \param mutex the mutex to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); + +/* @} *//* Mutex functions */ + + +/** + * \name Semaphore functions + */ +/* @{ */ + +/* The SDL semaphore structure, defined in SDL_syssem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/** + * Create a semaphore. + * + * This function creates a new semaphore and initializes it with the value + * `initial_value`. Each wait operation on the semaphore will atomically + * decrement the semaphore value and potentially block if the semaphore value + * is 0. Each post operation will atomically increment the semaphore value and + * wake waiting threads and allow them to retry the wait operation. + * + * \param initial_value the starting value of the semaphore + * \returns a new semaphore or NULL on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/** + * Destroy a semaphore. + * + * It is not safe to destroy a semaphore if there are threads currently + * waiting on it. + * + * \param sem the semaphore to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value or the call is interrupted by a + * signal or error. If the call is successful it will atomically decrement the + * semaphore value. + * + * This function is the equivalent of calling SDL_SemWaitTimeout() with a time + * length of `SDL_MUTEX_MAXWAIT`. + * + * \param sem the semaphore wait on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); + +/** + * See if a semaphore has a positive value and decrement it if it does. + * + * This function checks to see if the semaphore pointed to by `sem` has a + * positive value and atomically decrements the semaphore value if it does. If + * the semaphore doesn't have a positive value, the function immediately + * returns SDL_MUTEX_TIMEDOUT. + * + * \param sem the semaphore to wait on + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait would + * block, or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value, the call is interrupted by a + * signal or error, or the specified time has elapsed. If the call is + * successful it will atomically decrement the semaphore value. + * + * \param sem the semaphore to wait on + * \param ms the length of the timeout, in milliseconds + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not + * succeed in the allotted time, or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + */ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms); + +/** + * Atomically increment a semaphore's value and wake waiting threads. + * + * \param sem the semaphore to increment + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); + +/** + * Get the current value of a semaphore. + * + * \param sem the semaphore to query + * \returns the current value of the semaphore. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); + +/* @} *//* Semaphore functions */ + + +/** + * \name Condition variable functions + */ +/* @{ */ + +/* The SDL condition variable structure, defined in SDL_syscond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/** + * Create a condition variable. + * + * \returns a new condition variable or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_DestroyCond + */ +extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); + +/** + * Destroy a condition variable. + * + * \param cond the condition variable to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); + +/** + * Restart one of the threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); + +/** + * Restart all threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); + +/** + * Wait until a condition variable is signaled. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`. Once the condition variable is signaled, the mutex is re-locked and + * the function returns. + * + * The mutex must be locked before calling this function. + * + * This function is the equivalent of calling SDL_CondWaitTimeout() with a + * time length of `SDL_MUTEX_MAXWAIT`. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \returns 0 when it is signaled or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); + +/** + * Wait until a condition variable is signaled or a certain time has passed. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`, or for the specified time to elapse. Once the condition variable is + * signaled or the time elapsed, the mutex is re-locked and the function + * returns. + * + * The mutex must be locked before calling this function. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT` + * to wait indefinitely + * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if + * the condition is not signaled in the allotted time, or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +/* @} *//* Condition variable functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mutex_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_name.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_name.h new file mode 100644 index 000000000..6ff35b46e --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_name.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDLname_h_ +#define SDLname_h_ + +#if defined(__STDC__) || defined(__cplusplus) +#define NeedFunctionPrototypes 1 +#endif + +#define SDL_NAME(X) SDL_##X + +#endif /* SDLname_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl.h new file mode 100644 index 000000000..9aed5035a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl.h @@ -0,0 +1,2183 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengl.h + * + * This is a simple file to encapsulate the OpenGL API headers. + */ + +/** + * \def NO_SDL_GLEXT + * + * Define this if you have your own version of glext.h and want to disable the + * version included in SDL_opengl.h. + */ + +#ifndef SDL_opengl_h_ +#define SDL_opengl_h_ + +#include "SDL_config.h" + +#ifndef __IPHONEOS__ /* No OpenGL on iOS. */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * 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. + */ + + +#ifndef __gl_h_ +#define __gl_h_ + +#if defined(USE_MGL_NAMESPACE) +#include "gl_mangle.h" +#endif + + +/********************************************************************** + * Begin system-specific stuff. + */ + +#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) +#define __WIN32__ +#endif + +#if defined(__WIN32__) && !defined(__CYGWIN__) +# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ +# define GLAPI __declspec(dllexport) +# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ +# define GLAPI __declspec(dllimport) +# else /* for use with static link lib build of Win32 edition only */ +# define GLAPI extern +# endif /* _STATIC_MESA support */ +# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ +# define GLAPIENTRY +# else +# define GLAPIENTRY __stdcall +# endif +#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ +# define GLAPI extern +# define GLAPIENTRY __stdcall +#elif defined(__OS2__) || defined(__EMX__) /* native os/2 opengl */ +# define GLAPI extern +# define GLAPIENTRY _System +# define APIENTRY _System +# if defined(__GNUC__) && !defined(_System) +# define _System +# endif +#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define GLAPI __attribute__((visibility("default"))) +# define GLAPIENTRY +#endif /* WIN32 && !CYGWIN */ + +/* + * WINDOWS: Include windows.h here to define APIENTRY. + * It is also useful when applications include this file by + * including only glut.h, since glut.h depends on windows.h. + * Applications needing to include windows.h with parms other + * than "WIN32_LEAN_AND_MEAN" may include windows.h before + * glut.h or gl.h. + */ +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef GLAPI +#define GLAPI extern +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef APIENTRY +#define APIENTRY GLAPIENTRY +#endif + +/* "P" suffix to be used for a pointer to a function */ +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GLAPIENTRYP +#define GLAPIENTRYP GLAPIENTRY * +#endif + +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export on +#endif + +/* + * End system-specific stuff. + **********************************************************************/ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 +#define GL_VERSION_1_3 1 +#define GL_ARB_imaging 1 + + +/* + * Datatypes + */ +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; /* 1-byte signed */ +typedef short GLshort; /* 2-byte signed */ +typedef int GLint; /* 4-byte signed */ +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef unsigned short GLushort; /* 2-byte unsigned */ +typedef unsigned int GLuint; /* 4-byte unsigned */ +typedef int GLsizei; /* 4-byte signed */ +typedef float GLfloat; /* single precision float */ +typedef float GLclampf; /* single precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ +typedef double GLclampd; /* double precision float in [0,1] */ + + + +/* + * Constants + */ + +/* Boolean values */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* Data types */ +#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_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + +/* Primitives */ +#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_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* Vertex Arrays */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* Matrix Mode */ +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* Points */ +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 + +/* Lines */ +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 + +/* Polygons */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* Display Lists */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 + +/* Depth buffer */ +#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_DEPTH_TEST 0x0B71 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_COMPONENT 0x1902 + +/* Lighting */ +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_SHININESS 0x1601 +#define GL_EMISSION 0x1600 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_SHADE_MODEL 0x0B54 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_NORMALIZE 0x0BA1 + +/* User clipping planes */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* Accumulation buffer */ +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM 0x0100 +#define GL_ADD 0x0104 +#define GL_LOAD 0x0101 +#define GL_MULT 0x0103 +#define GL_RETURN 0x0102 + +/* Alpha testing */ +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +/* Blending */ +#define GL_BLEND 0x0BE2 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_DST 0x0BE0 +#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 + +/* Render Mode */ +#define GL_FEEDBACK 0x1C01 +#define GL_RENDER 0x1C00 +#define GL_SELECT 0x1C02 + +/* Feedback */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + +/* Selection */ +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 + +/* Fog */ +#define GL_FOG 0x0B60 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_LINEAR 0x2601 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* Logic Ops */ +#define GL_LOGIC_OP 0x0BF1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_CLEAR 0x1500 +#define GL_SET 0x150F +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_NOOP 0x1505 +#define GL_INVERT 0x150A +#define GL_AND 0x1501 +#define GL_NAND 0x150E +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_XOR 0x1506 +#define GL_EQUIV 0x1509 +#define GL_AND_REVERSE 0x1502 +#define GL_AND_INVERTED 0x1504 +#define GL_OR_REVERSE 0x150B +#define GL_OR_INVERTED 0x150D + +/* Stencil */ +#define GL_STENCIL_BITS 0x0D57 +#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_STENCIL_INDEX 0x1901 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 + +/* Buffers, Pixel Drawing/Reading */ +#define GL_NONE 0 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +/*GL_FRONT 0x0404 */ +/*GL_BACK 0x0405 */ +/*GL_FRONT_AND_BACK 0x0408 */ +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_COLOR_INDEX 0x1900 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_ALPHA_BITS 0x0D55 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_INDEX_BITS 0x0D51 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_READ_BUFFER 0x0C02 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_BITMAP 0x1A00 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_DITHER 0x0BD0 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 + +/* Implementation limits */ +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + +/* Gets */ +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_RENDER_MODE 0x0C40 +#define GL_RGBA_MODE 0x0C31 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_VIEWPORT 0x0BA2 + +/* Evaluators */ +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 + +/* Hints */ +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* Scissor box */ +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 + +/* Pixel Mode / Transfer */ +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + +/* Texture mapping */ +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_COMPONENTS 0x1003 +#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_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_SPHERE_MAP 0x2402 +#define GL_DECAL 0x2101 +#define GL_MODULATE 0x2100 +#define GL_NEAREST 0x2600 +#define GL_REPEAT 0x2901 +#define GL_CLAMP 0x2900 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 + +/* Utility */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* Errors */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 + +/* glPush/PopAttrib bits */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000FFFFF + + +/* OpenGL 1.1 */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#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_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF + + + +/* + * Miscellaneous + */ + +GLAPI void GLAPIENTRY glClearIndex( GLfloat c ); + +GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glClear( GLbitfield mask ); + +GLAPI void GLAPIENTRY glIndexMask( GLuint mask ); + +GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); + +GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref ); + +GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); + +GLAPI void GLAPIENTRY glLogicOp( GLenum opcode ); + +GLAPI void GLAPIENTRY glCullFace( GLenum mode ); + +GLAPI void GLAPIENTRY glFrontFace( GLenum mode ); + +GLAPI void GLAPIENTRY glPointSize( GLfloat size ); + +GLAPI void GLAPIENTRY glLineWidth( GLfloat width ); + +GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern ); + +GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode ); + +GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units ); + +GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask ); + +GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask ); + +GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag ); + +GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag ); + +GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height); + +GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation ); + +GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation ); + +GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glReadBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glEnable( GLenum cap ); + +GLAPI void GLAPIENTRY glDisable( GLenum cap ); + +GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap ); + + +GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */ + +GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */ + + +GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params ); + +GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params ); + +GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params ); + +GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask ); + +GLAPI void GLAPIENTRY glPopAttrib( void ); + + +GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */ + +GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */ + + +GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode ); + +GLAPI GLenum GLAPIENTRY glGetError( void ); + +GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name ); + +GLAPI void GLAPIENTRY glFinish( void ); + +GLAPI void GLAPIENTRY glFlush( void ); + +GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode ); + + +/* + * Depth Buffer + */ + +GLAPI void GLAPIENTRY glClearDepth( GLclampd depth ); + +GLAPI void GLAPIENTRY glDepthFunc( GLenum func ); + +GLAPI void GLAPIENTRY glDepthMask( GLboolean flag ); + +GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val ); + + +/* + * Accumulation Buffer + */ + +GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); + +GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value ); + + +/* + * Transformation + */ + +GLAPI void GLAPIENTRY glMatrixMode( GLenum mode ); + +GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, + GLsizei width, GLsizei height ); + +GLAPI void GLAPIENTRY glPushMatrix( void ); + +GLAPI void GLAPIENTRY glPopMatrix( void ); + +GLAPI void GLAPIENTRY glLoadIdentity( void ); + +GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glRotated( GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z ); + + +/* + * Display Lists + */ + +GLAPI GLboolean GLAPIENTRY glIsList( GLuint list ); + +GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ); + +GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ); + +GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ); + +GLAPI void GLAPIENTRY glEndList( void ); + +GLAPI void GLAPIENTRY glCallList( GLuint list ); + +GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type, + const GLvoid *lists ); + +GLAPI void GLAPIENTRY glListBase( GLuint base ); + + +/* + * Drawing Functions + */ + +GLAPI void GLAPIENTRY glBegin( GLenum mode ); + +GLAPI void GLAPIENTRY glEnd( void ); + + +GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex2iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex3iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex4iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ); +GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ); +GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ); +GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz ); +GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz ); + +GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glNormal3iv( const GLint *v ); +GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glIndexd( GLdouble c ); +GLAPI void GLAPIENTRY glIndexf( GLfloat c ); +GLAPI void GLAPIENTRY glIndexi( GLint c ); +GLAPI void GLAPIENTRY glIndexs( GLshort c ); +GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c ); +GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c ); +GLAPI void GLAPIENTRY glIndexiv( const GLint *c ); +GLAPI void GLAPIENTRY glIndexsv( const GLshort *c ); +GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue ); +GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue ); +GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue ); +GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue ); +GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue ); +GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue ); +GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue ); +GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue ); + +GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green, + GLbyte blue, GLbyte alpha ); +GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green, + GLdouble blue, GLdouble alpha ); +GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ); +GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green, + GLint blue, GLint alpha ); +GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green, + GLshort blue, GLshort alpha ); +GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ); +GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green, + GLuint blue, GLuint alpha ); +GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green, + GLushort blue, GLushort alpha ); + + +GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor3iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor3sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor3usv( const GLushort *v ); + +GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor4iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor4sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor4usv( const GLushort *v ); + + +GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s ); +GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s ); +GLAPI void GLAPIENTRY glTexCoord1i( GLint s ); +GLAPI void GLAPIENTRY glTexCoord1s( GLshort s ); + +GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t ); +GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t ); +GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t ); +GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ); +GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r ); +GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r ); +GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); +GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); +GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q ); +GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); +GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); +GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 ); +GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); + + +GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ); +GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ); +GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 ); +GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ); + + +/* + * Vertex Arrays (1.1) + */ + +GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params ); + +GLAPI void GLAPIENTRY glArrayElement( GLint i ); + +GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); + +GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride, + const GLvoid *pointer ); + +/* + * Lighting + */ + +GLAPI void GLAPIENTRY glShadeModel( GLenum mode ); + +GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname, + GLfloat *params ); +GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode ); + + +/* + * Raster functions + */ + +GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor ); + +GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize, + const GLfloat *values ); +GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize, + const GLuint *values ); +GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize, + const GLushort *values ); + +GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ); +GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ); +GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values ); + +GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + +GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels ); + +GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type ); + +/* + * Stenciling + */ + +GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask ); + +GLAPI void GLAPIENTRY glStencilMask( GLuint mask ); + +GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ); + +GLAPI void GLAPIENTRY glClearStencil( GLint s ); + + + +/* + * Texture mapping + */ + +GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param ); +GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params ); +GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); +GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target, + GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target, + GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level, + GLenum format, GLenum type, + GLvoid *pixels ); + + +/* 1.1 functions */ + +GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures ); + +GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures); + +GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture ); + +GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n, + const GLuint *textures, + const GLclampf *priorities ); + +GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, + const GLuint *textures, + GLboolean *residences ); + +GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture ); + + +GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level, + GLint xoffset, + GLsizei width, GLenum format, + GLenum type, const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + + +/* + * Evaluators + */ + +GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2, + GLint stride, + GLint order, const GLdouble *points ); +GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2, + GLint stride, + GLint order, const GLfloat *points ); + +GLAPI void GLAPIENTRY glMap2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ); +GLAPI void GLAPIENTRY glMap2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ); + +GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ); +GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ); +GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ); + +GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u ); +GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u ); + +GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v ); +GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v ); + +GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); +GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); + +GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ); +GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +GLAPI void GLAPIENTRY glEvalPoint1( GLint i ); + +GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j ); + +GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 ); + +GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); + + +/* + * Fog + */ + +GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param ); + +GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params ); + +GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params ); + + +/* + * Selection and Feedback + */ + +GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); + +GLAPI void GLAPIENTRY glPassThrough( GLfloat token ); + +GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ); + +GLAPI void GLAPIENTRY glInitNames( void ); + +GLAPI void GLAPIENTRY glLoadName( GLuint name ); + +GLAPI void GLAPIENTRY glPushName( GLuint name ); + +GLAPI void GLAPIENTRY glPopName( void ); + + + +/* + * OpenGL 1.2 + */ + +#define GL_RESCALE_NORMAL 0x803A +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#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 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#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_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#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_TEXTURE_BINDING_3D 0x806A + +GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, + GLenum type, const GLvoid *pixels); + +GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, + GLint y, GLsizei width, + GLsizei height ); + +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *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 GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + +/* + * GL_ARB_imaging + */ + +#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_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_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_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#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_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_BLEND_EQUATION 0x8009 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_COLOR 0x8005 + + +GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat, + GLsizei width, GLenum format, + GLenum type, const GLvoid *table ); + +GLAPI void GLAPIENTRY glColorSubTable( GLenum target, + GLsizei start, GLsizei count, + GLenum format, GLenum type, + const GLvoid *data ); + +GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname, + const GLint *params); + +GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + +GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *table ); + +GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glBlendEquation( GLenum mode ); + +GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width, + GLenum internalformat, GLboolean sink ); + +GLAPI void GLAPIENTRY glResetHistogram( GLenum target ); + +GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset, + GLenum format, GLenum type, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat, + GLboolean sink ); + +GLAPI void GLAPIENTRY glResetMinmax( GLenum target ); + +GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset, + GLenum format, GLenum types, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target, + GLenum internalformat, GLsizei width, GLenum format, GLenum type, + const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname, + GLfloat params ); + +GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); + +GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname, + GLint params ); + +GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height); + +GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format, + GLenum type, GLvoid *image ); + +GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *row, const GLvoid *column ); + +GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, + GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); + + + + +/* + * OpenGL 1.3 + */ + +/* multitexture */ +#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_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +/* texture_cube_map */ +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#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 +/* texture_compression */ +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#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 +/* multisample */ +#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_MULTISAMPLE_BIT 0x20000000 +/* transpose_matrix */ +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +/* texture_env_combine */ +#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 +/* texture_env_dot3 */ +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +/* texture_border_clamp */ +#define GL_CLAMP_TO_BORDER 0x812D + +GLAPI void GLAPIENTRY glActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ); + +GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v ); + + +GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); + + +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *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 GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); + + + +/* + * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) + */ +#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 + +GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s); +GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s); +GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s); +GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s); +GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t); +GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t); +GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v); + +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); + +#endif /* GL_ARB_multitexture */ + + + +/* + * Define this token if you want "old-style" header file behaviour (extensions + * defined in gl.h). Otherwise, extensions will be included from glext.h. + */ +#if !defined(NO_SDL_GLEXT) && !defined(GL_GLEXT_LEGACY) +#include "SDL_opengl_glext.h" +#endif /* GL_GLEXT_LEGACY */ + + + +/* + * ???. GL_MESA_packed_depth_stencil + * XXX obsolete + */ +#ifndef GL_MESA_packed_depth_stencil +#define GL_MESA_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_MESA 0x8750 +#define GL_UNSIGNED_INT_24_8_MESA 0x8751 +#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 +#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 +#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 + +#endif /* GL_MESA_packed_depth_stencil */ + + +#ifndef GL_ATI_blend_equation_separate +#define GL_ATI_blend_equation_separate 1 + +#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D + +GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); + +#endif /* GL_ATI_blend_equation_separate */ + + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + + +/** + ** NOTE!!!!! If you add new functions to this file, or update + ** glext.h be sure to regenerate the gl_mangle.h file. See comments + ** in that file for details. + **/ + + + +/********************************************************************** + * Begin system-specific stuff + */ +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export off +#endif + +/* + * End system-specific stuff + **********************************************************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* __gl_h_ */ + +#endif /* !__IPHONEOS__ */ + +#endif /* SDL_opengl_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl_glext.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl_glext.h new file mode 100644 index 000000000..6a402b15a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengl_glext.h @@ -0,0 +1,11180 @@ +#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: 26745 $ on $Date: 2014-05-21 03:12:26 -0700 (Wed, 21 May 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +#define GL_GLEXT_VERSION 20140521 + +/* 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 +#ifdef __MACOSX__ +typedef long GLsizeiptr; +typedef long GLintptr; +#else +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; +#endif +#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_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 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_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_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 +#endif /* GL_ARB_ES2_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_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 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#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_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_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_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_KHR_context_flush_control +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#endif /* GL_KHR_context_flush_control */ + +#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_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_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_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_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_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_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 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#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 +#ifdef __MACOSX__ /* The OS X headers haven't caught up with Khronos yet */ +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_debug +#define GL_KHR_debug 1 +#endif /* GL_KHR_debug */ + +#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); +typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +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); +GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z); +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 +#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_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 PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +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 glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +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 +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); +#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); +#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_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) (GLuint 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 (GLuint 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/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles.h new file mode 100644 index 000000000..8511b9607 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles.h + * + * This is a simple file to encapsulate the OpenGL ES 1.X API headers. + */ +#include "SDL_config.h" + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2.h new file mode 100644 index 000000000..172fcb3f4 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2.h @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles2.h + * + * This is a simple file to encapsulate the OpenGL ES 2.0 API headers. + */ +#include "SDL_config.h" + +#if !defined(_MSC_VER) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#include +#endif + +#else /* _MSC_VER */ + +/* OpenGL ES2 headers for Visual Studio */ +#include "SDL_opengles2_khrplatform.h" +#include "SDL_opengles2_gl2platform.h" +#include "SDL_opengles2_gl2.h" +#include "SDL_opengles2_gl2ext.h" + +#endif /* _MSC_VER */ + +#ifndef APIENTRY +#define APIENTRY GL_APIENTRY +#endif diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2.h new file mode 100644 index 000000000..c62fb0a54 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */ + +/*#include */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#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 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#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 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#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_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#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_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#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 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#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_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#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_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#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_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#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 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#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_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#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 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#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_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#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_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#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 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#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_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_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ + diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2ext.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2ext.h new file mode 100644 index 000000000..e8ca8b13f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2ext.h @@ -0,0 +1,2050 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ + +/* $Revision: 22801 $ on $Date:: 2013-08-21 03:20:48 -0700 #$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#ifndef GL_APIENTRYP +# define GL_APIENTRYP GL_APIENTRY* +#endif + +/* New types shared by several extensions */ + +#ifndef __gl3_h_ +/* These are defined with respect to in the + * Apple extension spec, but they are also used by non-APPLE + * extensions, and in the Khronos header we use the Khronos + * portable types in khrplatform.h, which must be defined. + */ +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + + +/*------------------------------------------------------------------------* + * OES extension tokens + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#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_depth24 */ +#ifndef GL_OES_depth24 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif + +/* GL_OES_depth_texture */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +/* GLeglImageOES defined in GL_OES_EGL_image already. */ +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_UNSIGNED_INT 0x1405 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +/* reuse GL_DEPTH_COMPONENT24_OES */ +/* reuse GL_DEPTH24_STENCIL8_OES */ +/* reuse GL_DEPTH_COMPONENT32_OES */ +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +/* reuse GL_RGB8_OES */ +/* reuse GL_RGBA8_OES */ +/* reuse GL_RGB10_EXT */ +/* reuse GL_RGB10_A2_EXT */ +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#endif + +/* GL_OES_texture_float */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_HALF_FLOAT_OES 0x8D61 +#endif + +/* GL_OES_texture_half_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_npot */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#endif + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif + +/*------------------------------------------------------------------------* + * KHR extension tokens + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_QUERY_KHR 0x82E3 +/* PROGRAM_PIPELINE only in GL */ +#define GL_SAMPLER_KHR 0x82E6 +/* DISPLAY_LIST only in GL */ +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#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 + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif + +/* GL_AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#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 +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_Z400_BINARY_AMD 0x8740 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#endif + +/*------------------------------------------------------------------------* + * APPLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +/* No new tokens introduced by this extension. */ + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync + +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif + +/*------------------------------------------------------------------------* + * ARM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif + +/* GL_ARM_rgba8 */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#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 +#endif + +/* GL_EXT_debug_marker */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#endif + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#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 +#endif + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */ +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#endif + +/* GL_EXT_multi_draw_arrays */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +/* reuse GL_NO_ERROR */ +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif + +/* GL_EXT_shader_texture_lod */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif + +/* GL_EXT_sRGB_write_control */ +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif + +/* GL_EXT_texture_sRGB_decode */ +#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_storage */ +#ifndef GL_EXT_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +/* reuse GL_RGBA16F_EXT */ +/* reuse GL_RGB16F_EXT */ +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_BGRA8_EXT 0x93A1 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif + +/*------------------------------------------------------------------------* + * DMP extension tokens + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_SHADER_BINARY_DMP 0x9250 +#endif + +/*------------------------------------------------------------------------* + * FJ extension tokens + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_SGX_BINARY_IMG 0x8C0A +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#endif + +/* GL_NV_draw_instanced */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +#endif + +/* GL_NV_generate_mipmap_sRGB */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_READ_BUFFER_NV 0x0C02 +#endif + +/* GL_NV_read_buffer_front */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif + +/* GL_NV_texture_compression_s3tc_update */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_npot_2D_mipmap */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +#endif + +/* GL_QCOM_extended_get2 */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------* + * OES extension functions + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#endif + +/* GL_OES_depth_texture */ +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif + +/* GL_OES_fbo_render_mipmap */ +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif + +/* GL_OES_fragment_precision_high */ +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid **params); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid **params); +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif + +/* GL_OES_texture_float */ +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif + +/* GL_OES_texture_float_linear */ +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#endif + +/* GL_OES_texture_half_float_linear */ +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif + +/* GL_OES_texture_npot */ +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#endif + +/* GL_OES_vertex_half_float */ +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#endif + +/*------------------------------------------------------------------------* + * KHR extension functions + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, GLvoid **params); +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif + + +/*------------------------------------------------------------------------* + * AMD extension functions + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#endif + +/* AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#endif + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif + +/*------------------------------------------------------------------------* + * APPLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#endif + +/*------------------------------------------------------------------------* + * ARM extension functions + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#endif + +/* GL_ARM_rgba8 */ +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif + +/*------------------------------------------------------------------------* + * EXT extension functions + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +/* GL_EXT_debug_marker */ +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#endif + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#endif /* GL_EXT_draw_buffers */ + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +/* All entry points also exist in GL_EXT_disjoint_timer_query */ +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#endif + +/* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#endif + +/*------------------------------------------------------------------------* + * DMP extension functions + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#endif + +/*------------------------------------------------------------------------* + * FJ extension functions + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension functions + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/*------------------------------------------------------------------------* + * NV extension functions + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#endif + +/* GL_NV_draw_instanced */ +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +/* GL_NV_generate_mipmap_sRGB */ +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#endif + +/* GL_NV_read_buffer_front */ +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif + +/* GL_NV_read_depth */ +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif + +/* GL_NV_read_depth_stencil */ +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif + +/* GL_NV_read_stencil */ +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#endif + +/* GL_NV_texture_compression_s3tc_update */ +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif + +/* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif + +/*------------------------------------------------------------------------* + * QCOM extension functions + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#endif + +/* GL_QCOM_driver_control */ +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#endif + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); +#endif + +/* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2ext_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2platform.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2platform.h new file mode 100644 index 000000000..c325686f0 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all 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 "OpenGL-ES" component "Registry". + */ + +/*#include */ + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_khrplatform.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_khrplatform.h new file mode 100644 index 000000000..c9e6f17d3 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_opengles2_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/libultraship/libultraship/Lib/SDL/SDL2/SDL_pixels.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_pixels.h new file mode 100644 index 000000000..5d2c0c898 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_pixels.h @@ -0,0 +1,644 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_pixels.h + * + * Header for the enumerated pixel format definitions. + */ + +#ifndef SDL_pixels_h_ +#define SDL_pixels_h_ + +#include "SDL_stdinc.h" +#include "SDL_endian.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Transparency definitions + * + * These define alpha as the opacity of a surface. + */ +/* @{ */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 +/* @} */ + +/** Pixel type. */ +typedef enum +{ + SDL_PIXELTYPE_UNKNOWN, + SDL_PIXELTYPE_INDEX1, + SDL_PIXELTYPE_INDEX4, + SDL_PIXELTYPE_INDEX8, + SDL_PIXELTYPE_PACKED8, + SDL_PIXELTYPE_PACKED16, + SDL_PIXELTYPE_PACKED32, + SDL_PIXELTYPE_ARRAYU8, + SDL_PIXELTYPE_ARRAYU16, + SDL_PIXELTYPE_ARRAYU32, + SDL_PIXELTYPE_ARRAYF16, + SDL_PIXELTYPE_ARRAYF32 +} SDL_PixelType; + +/** Bitmap pixel order, high bit -> low bit. */ +typedef enum +{ + SDL_BITMAPORDER_NONE, + SDL_BITMAPORDER_4321, + SDL_BITMAPORDER_1234 +} SDL_BitmapOrder; + +/** Packed component order, high bit -> low bit. */ +typedef enum +{ + SDL_PACKEDORDER_NONE, + SDL_PACKEDORDER_XRGB, + SDL_PACKEDORDER_RGBX, + SDL_PACKEDORDER_ARGB, + SDL_PACKEDORDER_RGBA, + SDL_PACKEDORDER_XBGR, + SDL_PACKEDORDER_BGRX, + SDL_PACKEDORDER_ABGR, + SDL_PACKEDORDER_BGRA +} SDL_PackedOrder; + +/** Array component order, low byte -> high byte. */ +/* !!! FIXME: in 2.1, make these not overlap differently with + !!! FIXME: SDL_PACKEDORDER_*, so we can simplify SDL_ISPIXELFORMAT_ALPHA */ +typedef enum +{ + SDL_ARRAYORDER_NONE, + SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_RGBA, + SDL_ARRAYORDER_ARGB, + SDL_ARRAYORDER_BGR, + SDL_ARRAYORDER_BGRA, + SDL_ARRAYORDER_ABGR +} SDL_ArrayOrder; + +/** Packed component layout. */ +typedef enum +{ + SDL_PACKEDLAYOUT_NONE, + SDL_PACKEDLAYOUT_332, + SDL_PACKEDLAYOUT_4444, + SDL_PACKEDLAYOUT_1555, + SDL_PACKEDLAYOUT_5551, + SDL_PACKEDLAYOUT_565, + SDL_PACKEDLAYOUT_8888, + SDL_PACKEDLAYOUT_2101010, + SDL_PACKEDLAYOUT_1010102 +} SDL_PackedLayout; + +#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) + +#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ + ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ + ((bits) << 8) | ((bytes) << 0)) + +#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) +#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) +#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) +#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) +#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF) +#define SDL_BYTESPERPIXEL(X) \ + (SDL_ISPIXELFORMAT_FOURCC(X) ? \ + ((((X) == SDL_PIXELFORMAT_YUY2) || \ + ((X) == SDL_PIXELFORMAT_UYVY) || \ + ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF)) + +#define SDL_ISPIXELFORMAT_INDEXED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) + +#define SDL_ISPIXELFORMAT_PACKED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32))) + +#define SDL_ISPIXELFORMAT_ARRAY(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32))) + +#define SDL_ISPIXELFORMAT_ALPHA(format) \ + ((SDL_ISPIXELFORMAT_PACKED(format) && \ + ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \ + (SDL_ISPIXELFORMAT_ARRAY(format) && \ + ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA)))) + +/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ +#define SDL_ISPIXELFORMAT_FOURCC(format) \ + ((format) && (SDL_PIXELFLAG(format) != 1)) + +/* Note: If you modify this list, update SDL_GetPixelFormatName() */ +typedef enum +{ + SDL_PIXELFORMAT_UNKNOWN, + SDL_PIXELFORMAT_INDEX1LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX1MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX4LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX4MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX8 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), + SDL_PIXELFORMAT_RGB332 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_332, 8, 1), + SDL_PIXELFORMAT_XRGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_RGB444 = SDL_PIXELFORMAT_XRGB4444, + SDL_PIXELFORMAT_XBGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_BGR444 = SDL_PIXELFORMAT_XBGR4444, + SDL_PIXELFORMAT_XRGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_RGB555 = SDL_PIXELFORMAT_XRGB1555, + SDL_PIXELFORMAT_XBGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_BGR555 = SDL_PIXELFORMAT_XBGR1555, + SDL_PIXELFORMAT_ARGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_RGBA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ABGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_BGRA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ARGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_RGBA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_ABGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_BGRA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_RGB565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_BGR565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_RGB24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, + 24, 3), + SDL_PIXELFORMAT_BGR24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, + 24, 3), + SDL_PIXELFORMAT_XRGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888, + SDL_PIXELFORMAT_RGBX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_XBGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGR888 = SDL_PIXELFORMAT_XBGR8888, + SDL_PIXELFORMAT_BGRX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_ARGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_RGBA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ABGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_BGRA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ARGB2101010 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_2101010, 32, 4), + + /* Aliases for RGBA byte arrays of color data, for the current platform */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, +#else + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, +#endif + + SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), + SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ + SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), + SDL_PIXELFORMAT_YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), + SDL_PIXELFORMAT_UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), + SDL_PIXELFORMAT_YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), + SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), + SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'), + SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */ + SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') +} SDL_PixelFormatEnum; + +/** + * The bits of this structure can be directly reinterpreted as an integer-packed + * color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 + * on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). + */ +typedef struct SDL_Color +{ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} SDL_Color; +#define SDL_Colour SDL_Color + +typedef struct SDL_Palette +{ + int ncolors; + SDL_Color *colors; + Uint32 version; + int refcount; +} SDL_Palette; + +/** + * \note Everything in the pixel format structure is read-only. + */ +typedef struct SDL_PixelFormat +{ + Uint32 format; + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 padding[2]; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + int refcount; + struct SDL_PixelFormat *next; +} SDL_PixelFormat; + +/** + * Get the human readable name of a pixel format. + * + * \param format the pixel format to query + * \returns the human readable name of the specified pixel format or + * `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); + +/** + * Convert one of the enumerated pixel formats to a bpp value and RGBA masks. + * + * \param format one of the SDL_PixelFormatEnum values + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask a pointer filled in with the red mask for the format + * \param Gmask a pointer filled in with the green mask for the format + * \param Bmask a pointer filled in with the blue mask for the format + * \param Amask a pointer filled in with the alpha mask for the format + * \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't + * possible; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MasksToPixelFormatEnum + */ +extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, + int *bpp, + Uint32 * Rmask, + Uint32 * Gmask, + Uint32 * Bmask, + Uint32 * Amask); + +/** + * Convert a bpp value and RGBA masks to an enumerated pixel format. + * + * This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't + * possible. + * + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask the red mask for the format + * \param Gmask the green mask for the format + * \param Bmask the blue mask for the format + * \param Amask the alpha mask for the format + * \returns one of the SDL_PixelFormatEnum values + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PixelFormatEnumToMasks + */ +extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/** + * Create an SDL_PixelFormat structure corresponding to a pixel format. + * + * Returned structure may come from a shared global cache (i.e. not newly + * allocated), and hence should not be modified, especially the palette. Weird + * errors such as `Blit combination not supported` may occur. + * + * \param pixel_format one of the SDL_PixelFormatEnum values + * \returns the new SDL_PixelFormat structure or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeFormat + */ +extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); + +/** + * Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). + * + * \param format the SDL_PixelFormat structure to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + */ +extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); + +/** + * Create a palette structure with the specified number of color entries. + * + * The palette entries are initialized to white. + * + * \param ncolors represents the number of color entries in the color palette + * \returns a new SDL_Palette structure on success or NULL on failure (e.g. if + * there wasn't enough memory); call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreePalette + */ +extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); + +/** + * Set the palette for a pixel format structure. + * + * \param format the SDL_PixelFormat structure that will use the palette + * \param palette the SDL_Palette structure that will be used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_FreePalette + */ +extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, + SDL_Palette *palette); + +/** + * Set a range of colors in a palette. + * + * \param palette the SDL_Palette structure to modify + * \param colors an array of SDL_Color structures to copy into the palette + * \param firstcolor the index of the first palette entry to modify + * \param ncolors the number of entries to modify + * \returns 0 on success or a negative error code if not all of the colors + * could be set; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, + const SDL_Color * colors, + int firstcolor, int ncolors); + +/** + * Free a palette created with SDL_AllocPalette(). + * + * \param palette the SDL_Palette structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + */ +extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); + +/** + * Map an RGB triple to an opaque pixel value for a given pixel format. + * + * This function maps the RGB color value to the specified pixel format and + * returns the pixel value best approximating the given RGB color value for + * the given pixel format. + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the specified pixel format has an alpha component it will be returned as + * all 1 bits (fully opaque). + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the pixel format + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGBA + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b); + +/** + * Map an RGBA quadruple to a pixel value for a given pixel format. + * + * This function maps the RGBA color value to the specified pixel format and + * returns the pixel value best approximating the given RGBA color value for + * the given pixel format. + * + * If the specified pixel format has no alpha component the alpha value will + * be ignored (as it will be in formats with a palette). + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \param a the alpha component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGB + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * Get RGB values from a pixel in the specified format. + * + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGBA + * \sa SDL_MapRGB + * \sa SDL_MapRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b); + +/** + * Get RGBA values from a pixel in the specified format. + * + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * If the surface has no alpha component, the alpha will be returned as 0xff + * (100% opaque). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * \param a a pointer filled in with the alpha component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_MapRGB + * \sa SDL_MapRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * Calculate a 256 entry gamma ramp for a gamma value. + * + * \param gamma a gamma value where 0.0 is black and 1.0 is identity + * \param ramp an array of 256 values filled in with the gamma ramp + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_pixels_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_platform.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_platform.h new file mode 100644 index 000000000..79b8b6f45 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_platform.h @@ -0,0 +1,235 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_platform.h + * + * Try to get a standard set of platform defines. + */ + +#ifndef SDL_platform_h_ +#define SDL_platform_h_ + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__HAIKU__) +#undef __HAIKU__ +#define __HAIKU__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if (defined(linux) || defined(__linux) || defined(__linux__)) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(ANDROID) || defined(__ANDROID__) +#undef __ANDROID__ +#undef __LINUX__ /* do we need to do this? */ +#define __ANDROID__ 1 +#endif + +#if defined(__APPLE__) +/* lets us know what version of Mac OS X we're compiling on */ +#include "AvailabilityMacros.h" +#include "TargetConditionals.h" + +/* Fix building with older SDKs that don't define these + See this for more information: + https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets +*/ +#ifndef TARGET_OS_MACCATALYST +#define TARGET_OS_MACCATALYST 0 +#endif +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS 0 +#endif +#ifndef TARGET_OS_IPHONE +#define TARGET_OS_IPHONE 0 +#endif +#ifndef TARGET_OS_TV +#define TARGET_OS_TV 0 +#endif +#ifndef TARGET_OS_SIMULATOR +#define TARGET_OS_SIMULATOR 0 +#endif + +#if TARGET_OS_TV +#undef __TVOS__ +#define __TVOS__ 1 +#endif +#if TARGET_OS_IPHONE +/* if compiling for iOS */ +#undef __IPHONEOS__ +#define __IPHONEOS__ 1 +#undef __MACOSX__ +#else +/* if not compiling for iOS */ +#undef __MACOSX__ +#define __MACOSX__ 1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# error SDL for Mac OS X only supports deploying on 10.6 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +#endif /* TARGET_OS_IPHONE */ +#endif /* defined(__APPLE__) */ + +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) || defined(__EMX__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__sun) && defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +/* Try to find out if we're compiling for WinRT or non-WinRT */ +#if defined(_MSC_VER) && defined(__has_include) +#if __has_include() +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */ +#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */ +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +#if HAVE_WINAPIFAMILY_H +#include +#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) +#else +#define WINAPI_FAMILY_WINRT 0 +#endif /* HAVE_WINAPIFAMILY_H */ + +#if WINAPI_FAMILY_WINRT +#undef __WINRT__ +#define __WINRT__ 1 +#else +#undef __WINDOWS__ +#define __WINDOWS__ 1 +#endif +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + +#if defined(__WINDOWS__) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +#if defined(__PSP__) +#undef __PSP__ +#define __PSP__ 1 +#endif + +/* The NACL compiler defines __native_client__ and __pnacl__ + * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi + */ +#if defined(__native_client__) +#undef __LINUX__ +#undef __NACL__ +#define __NACL__ 1 +#endif +#if defined(__pnacl__) +#undef __LINUX__ +#undef __PNACL__ +#define __PNACL__ 1 +/* PNACL with newlib supports static linking only */ +#define __SDL_NOGETPROCADDR__ +#endif + +#if defined(__vita__) +#define __VITA__ 1 +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the name of the platform. + * + * Here are the names returned for some (but not all) supported platforms: + * + * - "Windows" + * - "Mac OS X" + * - "Linux" + * - "iOS" + * - "Android" + * + * \returns the name of the platform. If the correct platform name is not + * available, returns a string beginning with the text "Unknown". + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_platform_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_power.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_power.h new file mode 100644 index 000000000..ecb3f4b02 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_power.h @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_power_h_ +#define SDL_power_h_ + +/** + * \file SDL_power.h + * + * Header for the SDL power management routines. + */ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The basic state for the system's power supply. + */ +typedef enum +{ + SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ + SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ + SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ + SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ + SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ +} SDL_PowerState; + + +/** + * Get the current power supply details. + * + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. + * + * Battery status can change at any time; if you are concerned with power + * state, you should call this function frequently, and perhaps ignore changes + * until they seem to be stable for a few seconds. + * + * It's possible a platform can only report battery percentage or time left + * but not both. + * + * \param secs seconds of battery life left, you can pass a NULL here if you + * don't care, will return -1 if we can't determine a value, or + * we're not running on a battery + * \param pct percentage of battery life left, between 0 and 100, you can pass + * a NULL here if you don't care, will return -1 if we can't + * determine a value, or we're not running on a battery + * \returns an SDL_PowerState enum representing the current battery state. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_power_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_quit.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_quit.h new file mode 100644 index 000000000..4090f7f19 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_quit.h @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_quit.h + * + * Include file for SDL quit event handling. + */ + +#ifndef SDL_quit_h_ +#define SDL_quit_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/** + * \file SDL_quit.h + * + * An ::SDL_QUIT event is generated when the user tries to close the application + * window. If it is ignored or filtered out, the window will remain open. + * If it is not ignored or filtered, it is queued normally and the window + * is allowed to close. When the window is closed, screen updates will + * complete, but have no effect. + * + * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) + * and SIGTERM (system termination request), if handlers do not already + * exist, that generate ::SDL_QUIT events as well. There is no way + * to determine the cause of an ::SDL_QUIT event, but setting a signal + * handler in your application will override the default generation of + * quit events for that signal. + * + * \sa SDL_Quit() + */ + +/* There are no functions directly affecting the quit event */ + +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0)) + +#endif /* SDL_quit_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_rect.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_rect.h new file mode 100644 index 000000000..6616ba6a2 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_rect.h @@ -0,0 +1,224 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rect.h + * + * Header file for SDL_rect definition and management functions. + */ + +#ifndef SDL_rect_h_ +#define SDL_rect_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The structure that defines a point (integer) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_Point +{ + int x; + int y; +} SDL_Point; + +/** + * The structure that defines a point (floating point) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_FPoint +{ + float x; + float y; +} SDL_FPoint; + + +/** + * A rectangle, with the origin at the upper left (integer). + * + * \sa SDL_RectEmpty + * \sa SDL_RectEquals + * \sa SDL_HasIntersection + * \sa SDL_IntersectRect + * \sa SDL_UnionRect + * \sa SDL_EnclosePoints + */ +typedef struct SDL_Rect +{ + int x, y; + int w, h; +} SDL_Rect; + + +/** + * A rectangle, with the origin at the upper left (floating point). + */ +typedef struct SDL_FRect +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + + +/** + * Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) +{ + return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) +{ + return (a && b && (a->x == b->x) && (a->y == b->y) && + (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Determine whether two rectangles intersect. + * + * If either pointer is NULL the function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_IntersectRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, + const SDL_Rect * B); + +/** + * Calculate the intersection of two rectangles. + * + * If `result` is NULL then this function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the intersection of + * rectangles `A` and `B` + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasIntersection + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate the union of two rectangles. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the union of rectangles + * `A` and `B` + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate a minimal rectangle enclosing a set of points. + * + * If `clip` is not NULL then only points inside of the clipping rectangle are + * considered. + * + * \param points an array of SDL_Point structures representing points to be + * enclosed + * \param count the number of structures in the `points` array + * \param clip an SDL_Rect used for clipping or NULL to enclose all points + * \param result an SDL_Rect structure filled in with the minimal enclosing + * rectangle + * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + * points were outside of the clipping rectangle. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, + int count, + const SDL_Rect * clip, + SDL_Rect * result); + +/** + * Calculate the intersection of a rectangle and line segment. + * + * This function is used to clip a line segment to a rectangle. A line segment + * contained entirely within the rectangle or that does not intersect will + * remain unchanged. A line segment that crosses the rectangle at either or + * both ends will be clipped to the boundary of the rectangle and the new + * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + * + * \param rect an SDL_Rect structure representing the rectangle to intersect + * \param X1 a pointer to the starting X-coordinate of the line + * \param Y1 a pointer to the starting Y-coordinate of the line + * \param X2 a pointer to the ending X-coordinate of the line + * \param Y2 a pointer to the ending Y-coordinate of the line + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rect_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_render.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_render.h new file mode 100644 index 000000000..a7e4908a6 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_render.h @@ -0,0 +1,1890 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_render.h + * + * Header file for SDL 2D rendering functions. + * + * This API supports the following features: + * * single pixel points + * * single pixel lines + * * filled rectangles + * * texture images + * + * The primitives may be drawn in opaque, blended, or additive modes. + * + * The texture images may be drawn in opaque, blended, or additive modes. + * They can have an additional color tint or alpha modulation applied to + * them, and may also be stretched with linear interpolation. + * + * This API is designed to accelerate simple 2D operations. You may + * want more functionality such as polygons and particle effects and + * in that case you should use SDL's OpenGL/Direct3D support or one + * of the many good 3D engines. + * + * These functions must be called from the main thread. + * See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995 + */ + +#ifndef SDL_render_h_ +#define SDL_render_h_ + +#include "SDL_stdinc.h" +#include "SDL_rect.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Flags used when creating a rendering context + */ +typedef enum +{ + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ +} SDL_RendererFlags; + +/** + * Information on the capabilities of a render driver or context. + */ +typedef struct SDL_RendererInfo +{ + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximum texture width */ + int max_texture_height; /**< The maximum texture height */ +} SDL_RendererInfo; + +/** + * Vertex structure + */ +typedef struct SDL_Vertex +{ + SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */ + SDL_Color color; /**< Vertex color */ + SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ +} SDL_Vertex; + +/** + * The scaling mode for a texture. + */ +typedef enum +{ + SDL_ScaleModeNearest, /**< nearest pixel sampling */ + SDL_ScaleModeLinear, /**< linear filtering */ + SDL_ScaleModeBest /**< anisotropic filtering */ +} SDL_ScaleMode; + +/** + * The access pattern allowed for a texture. + */ +typedef enum +{ + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ +} SDL_TextureAccess; + +/** + * The texture channel modulation used in SDL_RenderCopy(). + */ +typedef enum +{ + SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ + SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ +} SDL_TextureModulate; + +/** + * Flip constants for SDL_RenderCopyEx + */ +typedef enum +{ + SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ + SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ + SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ +} SDL_RendererFlip; + +/** + * A structure representing rendering state + */ +struct SDL_Renderer; +typedef struct SDL_Renderer SDL_Renderer; + +/** + * An efficient driver-specific representation of pixel data + */ +struct SDL_Texture; +typedef struct SDL_Texture SDL_Texture; + +/* Function prototypes */ + +/** + * Get the number of 2D rendering drivers available for the current display. + * + * A render driver is a set of code that handles rendering and texture + * management on a particular display. Normally there is only one, but some + * drivers may have several available with different capabilities. + * + * There may be none if SDL was compiled without render support. + * + * \returns a number >= 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetRenderDriverInfo + */ +extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); + +/** + * Get info about a specific 2D rendering driver for the current display. + * + * \param index the index of the driver to query information about + * \param info an SDL_RendererInfo structure to be filled with information on + * the rendering driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetNumRenderDrivers + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, + SDL_RendererInfo * info); + +/** + * Create a window and default renderer. + * + * \param width the width of the window + * \param height the height of the window + * \param window_flags the flags used to create the window (see + * SDL_CreateWindow()) + * \param window a pointer filled with the window, or NULL on error + * \param renderer a pointer filled with the renderer, or NULL on error + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindow + */ +extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( + int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer); + + +/** + * Create a 2D rendering context for a window. + * + * \param window the window where rendering is displayed + * \param index the index of the rendering driver to initialize, or -1 to + * initialize the first one supporting the requested flags + * \param flags 0, or one or more SDL_RendererFlags OR'd together + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSoftwareRenderer + * \sa SDL_DestroyRenderer + * \sa SDL_GetNumRenderDrivers + * \sa SDL_GetRendererInfo + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, + int index, Uint32 flags); + +/** + * Create a 2D software rendering context for a surface. + * + * Two other API which can be used to create SDL_Renderer: + * SDL_CreateRenderer() and SDL_CreateWindowAndRenderer(). These can _also_ + * create a software renderer, but they are intended to be used with an + * SDL_Window as the final destination and not an SDL_Surface. + * + * \param surface the SDL_Surface structure representing the surface where + * rendering is done + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindowRenderer + * \sa SDL_DestroyRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); + +/** + * Get the renderer associated with a window. + * + * \param window the window to query + * \returns the rendering context on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); + +/** + * Get information about a rendering context. + * + * \param renderer the rendering context + * \param info an SDL_RendererInfo structure filled with information about the + * current renderer + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, + SDL_RendererInfo * info); + +/** + * Get the output size in pixels of a rendering context. + * + * Due to high-dpi displays, you might end up with a rendering context that + * has more pixels than the window that contains it, so use this instead of + * SDL_GetWindowSize() to decide how much drawing area you have. + * + * \param renderer the rendering context + * \param w an int filled with the width + * \param h an int filled with the height + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, + int *w, int *h); + +/** + * Create a texture for a rendering context. + * + * You can set the texture scaling method by setting + * `SDL_HINT_RENDER_SCALE_QUALITY` before creating the texture. + * + * \param renderer the rendering context + * \param format one of the enumerated values in SDL_PixelFormatEnum + * \param access one of the enumerated values in SDL_TextureAccess + * \param w the width of the texture in pixels + * \param h the height of the texture in pixels + * \returns a pointer to the created texture or NULL if no rendering context + * was active, the format was unsupported, or the width or height + * were out of range; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTextureFromSurface + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + * \sa SDL_UpdateTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, + Uint32 format, + int access, int w, + int h); + +/** + * Create a texture from an existing surface. + * + * The surface is not modified or freed by this function. + * + * The SDL_TextureAccess hint for the created texture is + * `SDL_TEXTUREACCESS_STATIC`. + * + * The pixel format of the created texture may be different from the pixel + * format of the surface. Use SDL_QueryTexture() to query the pixel format of + * the texture. + * + * \param renderer the rendering context + * \param surface the SDL_Surface structure containing pixel data used to fill + * the texture + * \returns the created texture or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); + +/** + * Query the attributes of a texture. + * + * \param texture the texture to query + * \param format a pointer filled in with the raw format of the texture; the + * actual format may differ, but pixel transfers will use this + * format (one of the SDL_PixelFormatEnum values) + * \param access a pointer filled in with the actual access to the texture + * (one of the SDL_TextureAccess values) + * \param w a pointer filled in with the width of the texture in pixels + * \param h a pointer filled in with the height of the texture in pixels + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + */ +extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, + Uint32 * format, int *access, + int *w, int *h); + +/** + * Set an additional color value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * Color modulation is not always supported by the renderer; it will return -1 + * if color modulation is not supported. + * + * \param texture the texture to update + * \param r the red color value multiplied into copy operations + * \param g the green color value multiplied into copy operations + * \param b the blue color value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into render copy operations. + * + * \param texture the texture to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * Alpha modulation is not always supported by the renderer; it will return -1 + * if alpha modulation is not supported. + * + * \param texture the texture to update + * \param alpha the source alpha value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, + Uint8 alpha); + +/** + * Get the additional alpha value multiplied into render copy operations. + * + * \param texture the texture to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, + Uint8 * alpha); + +/** + * Set the blend mode for a texture, used by SDL_RenderCopy(). + * + * If the blend mode is not supported, the closest supported mode is chosen + * and this function returns -1. + * + * \param texture the texture to update + * \param blendMode the SDL_BlendMode to use for texture blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureBlendMode + * \sa SDL_RenderCopy + */ +extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for texture copy operations. + * + * \param texture the texture to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextureBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode *blendMode); + +/** + * Set the scale mode used for texture scale operations. + * + * If the scale mode is not supported, the closest supported mode is chosen. + * + * \param texture The texture to update. + * \param scaleMode the SDL_ScaleMode to use for texture scaling. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_SetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode scaleMode); + +/** + * Get the scale mode used for texture scale operations. + * + * \param texture the texture to query. + * \param scaleMode a pointer filled in with the current scale mode. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_SetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode *scaleMode); + +/** + * Associate a user-specified pointer with a texture. + * + * \param texture the texture to update. + * \param userdata the pointer to associate with the texture. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetTextureUserData + */ +extern DECLSPEC int SDLCALL SDL_SetTextureUserData(SDL_Texture * texture, + void *userdata); + +/** + * Get the user-specified pointer associated with a texture + * + * \param texture the texture to query. + * \return the pointer associated with the texture, or NULL if the texture is + * not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetTextureUserData + */ +extern DECLSPEC void * SDLCALL SDL_GetTextureUserData(SDL_Texture * texture); + +/** + * Update the given texture rectangle with new pixel data. + * + * The pixel data must be in the pixel format of the texture. Use + * SDL_QueryTexture() to query the pixel format of the texture. + * + * This is a fairly slow function, intended for use with static textures that + * do not change often. + * + * If the texture is intended to be updated often, it is preferred to create + * the texture as streaming and use the locking functions referenced below. + * While this function will work with streaming textures, for optimization + * reasons you may not get the pixels back if you lock the texture afterward. + * + * \param texture the texture to update + * \param rect an SDL_Rect structure representing the area to update, or NULL + * to update the entire texture + * \param pixels the raw pixel data in the format of the texture + * \param pitch the number of bytes in a row of pixel data, including padding + * between lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const void *pixels, int pitch); + +/** + * Update a rectangle within a planar YV12 or IYUV texture with new pixel + * data. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of Y and U/V planes in the proper order, but this function is + * available if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture + * \param Yplane the raw pixel data for the Y plane + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane + * \param Uplane the raw pixel data for the U plane + * \param Upitch the number of bytes between rows of pixel data for the U + * plane + * \param Vplane the raw pixel data for the V plane + * \param Vpitch the number of bytes between rows of pixel data for the V + * plane + * \returns 0 on success or -1 if the texture is not valid; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_UpdateTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +/** + * Update a rectangle within a planar NV12 or NV21 texture with new pixels. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of NV12/21 planes in the proper order, but this function is available + * if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param Yplane the raw pixel data for the Y plane. + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane. + * \param UVplane the raw pixel data for the UV plane. + * \param UVpitch the number of bytes between rows of pixel data for the UV + * plane. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_UpdateNVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); + +/** + * Lock a portion of the texture for **write-only** pixel access. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect an SDL_Rect structure representing the area to lock for access; + * NULL to lock the entire texture + * \param pixels this is filled in with a pointer to the locked pixels, + * appropriately offset by the locked area + * \param pitch this is filled in with the pitch of the locked pixels; the + * pitch is the length of one row in bytes + * \returns 0 on success or a negative error code if the texture is not valid + * or was not created with `SDL_TEXTUREACCESS_STREAMING`; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, + const SDL_Rect * rect, + void **pixels, int *pitch); + +/** + * Lock a portion of the texture for **write-only** pixel access, and expose + * it as a SDL surface. + * + * Besides providing an SDL_Surface instead of raw pixel data, this function + * operates like SDL_LockTexture. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * The returned surface is freed internally after calling SDL_UnlockTexture() + * or SDL_DestroyTexture(). The caller should not free it. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect a pointer to the rectangle to lock for access. If the rect is + * NULL, the entire texture will be locked + * \param surface this is filled in with an SDL surface representing the + * locked area + * \returns 0 on success, or -1 if the texture is not valid or was not created + * with `SDL_TEXTUREACCESS_STREAMING` + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture, + const SDL_Rect *rect, + SDL_Surface **surface); + +/** + * Unlock a texture, uploading the changes to video memory, if needed. + * + * **Warning**: Please note that SDL_LockTexture() is intended to be + * write-only; it will not guarantee the previous contents of the texture will + * be provided. You must fully initialize any area of a texture that you lock + * before unlocking it, as the pixels might otherwise be uninitialized memory. + * + * Which is to say: locking and immediately unlocking a texture can result in + * corrupted textures, depending on the renderer in use. + * + * \param texture a texture locked by SDL_LockTexture() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockTexture + */ +extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); + +/** + * Determine whether a renderer supports the use of render targets. + * + * \param renderer the renderer that will be checked + * \returns SDL_TRUE if supported or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); + +/** + * Set a texture as the current rendering target. + * + * Before using this function, you should check the + * `SDL_RENDERER_TARGETTEXTURE` bit in the flags of SDL_RendererInfo to see if + * render targets are supported. + * + * The default render target is the window for which the renderer was created. + * To stop rendering to a texture and render to the window again, call this + * function with a NULL `texture`. + * + * \param renderer the rendering context + * \param texture the targeted texture, which must be created with the + * `SDL_TEXTUREACCESS_TARGET` flag, or NULL to render to the + * window instead of a texture. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderTarget + */ +extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +/** + * Get the current render target. + * + * The default render target is the window for which the renderer was created, + * and is reported a NULL here. + * + * \param renderer the rendering context + * \returns the current render target or NULL for the default render target. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * Set a device independent resolution for rendering. + * + * This function uses the viewport and scaling functionality to allow a fixed + * logical resolution for rendering, regardless of the actual output + * resolution. If the actual output resolution doesn't have the same aspect + * ratio the output rendering will be centered within the output display. + * + * If the output display is a window, mouse and touch events in the window + * will be filtered and scaled so they seem to arrive within the logical + * resolution. The SDL_HINT_MOUSE_RELATIVE_SCALING hint controls whether + * relative motion events are also scaled. + * + * If this function results in scaling or subpixel drawing by the rendering + * backend, it will be handled using the appropriate quality hints. + * + * \param renderer the renderer for which resolution should be set + * \param w the width of the logical resolution + * \param h the height of the logical resolution + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * Get device independent resolution for rendering. + * + * This may return 0 for `w` and `h` if the SDL_Renderer has never had its + * logical size set by SDL_RenderSetLogicalSize() and never had a render + * target set. + * + * \param renderer a rendering context + * \param w an int to be filled with the width + * \param h an int to be filled with the height + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); + +/** + * Set whether to force integer scales for resolution-independent rendering. + * + * This function restricts the logical viewport to integer values - that is, + * when a resolution is between two multiples of a logical size, the viewport + * size is rounded down to the lower multiple. + * + * \param renderer the renderer for which integer scaling should be set + * \param enable enable or disable the integer scaling for rendering + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderGetIntegerScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * Get whether integer scales are forced for resolution-independent rendering. + * + * \param renderer the renderer from which integer scaling should be queried + * \returns SDL_TRUE if integer scales are forced or SDL_FALSE if not and on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderSetIntegerScale + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + +/** + * Set the drawing area for rendering on the current target. + * + * When the window is resized, the viewport is reset to fill the entire new + * window size. + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the drawing area, or NULL + * to set the viewport to the entire target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetViewport + */ +extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the drawing area for the current target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure filled in with the current drawing area + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetViewport + */ +extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Set the clip rectangle for rendering on the specified target. + * + * \param renderer the rendering context for which clip rectangle should be + * set + * \param rect an SDL_Rect structure representing the clip area, relative to + * the viewport, or NULL to disable clipping + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderIsClipEnabled + */ +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the clip rectangle for the current target. + * + * \param renderer the rendering context from which clip rectangle should be + * queried + * \param rect an SDL_Rect structure filled in with the current clipping area + * or an empty rectangle if clipping is disabled + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderIsClipEnabled + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Get whether clipping is enabled on the given renderer. + * + * \param renderer the renderer from which clip state should be queried + * \returns SDL_TRUE if clipping is enabled or SDL_FALSE if not; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); + + +/** + * Set the drawing scale for rendering on the current target. + * + * The drawing coordinates are scaled by the x/y scaling factors before they + * are used by the renderer. This allows resolution independent drawing with a + * single coordinate system. + * + * If this results in scaling or subpixel drawing by the rendering backend, it + * will be handled using the appropriate quality hints. For best results use + * integer scaling factors. + * + * \param renderer a rendering context + * \param scaleX the horizontal scaling factor + * \param scaleY the vertical scaling factor + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * Get the drawing scale for the current target. + * + * \param renderer the renderer from which drawing scale should be queried + * \param scaleX a pointer filled in with the horizontal scaling factor + * \param scaleY a pointer filled in with the vertical scaling factor + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetScale + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + +/** + * Get logical coordinates of point in renderer when given real coordinates of + * point in window. + * + * Logical coordinates will differ from real coordinates when render is scaled + * and logical renderer size set + * + * \param renderer the renderer from which the logical coordinates should be + * calcualted + * \param windowX the real X coordinate in the window + * \param windowY the real Y coordinate in the window + * \param logicalX the pointer filled with the logical x coordinate + * \param logicalY the pointer filled with the logical y coordinate + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer, + int windowX, int windowY, + float *logicalX, float *logicalY); + + /** + * Get real coordinates of point in window when given logical coordinates of point in renderer. + * Logical coordinates will differ from real coordinates when render is scaled and logical renderer size set + * + * \param renderer the renderer from which the window coordinates should be calculated + * \param logicalX the logical x coordinate + * \param logicalY the logical y coordinate + * \param windowX the pointer filled with the real X coordinate in the window + * \param windowY the pointer filled with the real Y coordinate in the window + + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer, + float logicalX, float logicalY, + int *windowX, int *windowY); + +/** + * Set the color used for drawing operations (Rect, Line and Clear). + * + * Set the color for drawing or filling rectangles, lines, and points, and for + * SDL_RenderClear(). + * + * \param renderer the rendering context + * \param r the red value used to draw on the rendering target + * \param g the green value used to draw on the rendering target + * \param b the blue value used to draw on the rendering target + * \param a the alpha value used to draw on the rendering target; usually + * `SDL_ALPHA_OPAQUE` (255). Use SDL_SetRenderDrawBlendMode to + * specify how the alpha channel is used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawColor + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * Get the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer the rendering context + * \param r a pointer filled in with the red value used to draw on the + * rendering target + * \param g a pointer filled in with the green value used to draw on the + * rendering target + * \param b a pointer filled in with the blue value used to draw on the + * rendering target + * \param a a pointer filled in with the alpha value used to draw on the + * rendering target; usually `SDL_ALPHA_OPAQUE` (255) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * Set the blend mode used for drawing operations (Fill and Line). + * + * If the blend mode is not supported, the closest supported mode is chosen. + * + * \param renderer the rendering context + * \param blendMode the SDL_BlendMode to use for blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for drawing operations. + * + * \param renderer the rendering context + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode *blendMode); + +/** + * Clear the current rendering target with the drawing color. + * + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); + +/** + * Draw a point on the current rendering target. + * + * SDL_RenderDrawPoint() draws a single point. If you want to draw multiple, + * use SDL_RenderDrawPoints() instead. + * + * \param renderer the rendering context + * \param x the x coordinate of the point + * \param y the y coordinate of the point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, + int x, int y); + +/** + * Draw multiple points on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures that represent the points to + * draw + * \param count the number of points to draw + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a line on the current rendering target. + * + * SDL_RenderDrawLine() draws the line to include both end points. If you want + * to draw multiple, connecting lines use SDL_RenderDrawLines() instead. + * + * \param renderer the rendering context + * \param x1 the x coordinate of the start point + * \param y1 the y coordinate of the start point + * \param x2 the x coordinate of the end point + * \param y2 the y coordinate of the end point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, + int x1, int y1, int x2, int y2); + +/** + * Draw a series of connected lines on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures representing points along + * the lines + * \param count the number of points, drawing count-1 lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a rectangle on the current rendering target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the rectangle to draw, or + * NULL to outline the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Draw some number of rectangles on the current rendering target. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be drawn + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color. + * + * The current drawing color is set by SDL_SetRenderDrawColor(), and the + * color's alpha value is ignored unless blending is enabled with the + * appropriate call to SDL_SetRenderDrawBlendMode(). + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL for the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be filled + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderPresent + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target; the texture will be stretched to fill the + * given rectangle + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopyEx + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); + +/** + * Copy a portion of the texture to the current rendering, with optional + * rotation and flipping. + * + * Copy a portion of the texture to the current rendering target, optionally + * rotating it by angle around the given center and also flipping it + * top-bottom and/or left-right. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target + * \param angle an angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center a pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around `dstrect.w / 2`, `dstrect.h / 2`) + * \param flip a SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopy + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, + const double angle, + const SDL_Point *center, + const SDL_RendererFlip flip); + + +/** + * Draw a point on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer, + float x, float y); + +/** + * Draw multiple points on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a line on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer, + float x1, float y1, float x2, float y2); + +/** + * Draw a series of connected lines on the current rendering target at + * subpixel precision. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a rectangle on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Draw some number of rectangles on the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color at + * subpixel precision. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color at subpixel precision. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect); + +/** + * Copy a portion of the source texture to the current rendering target, with + * rotation and flipping, at subpixel precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center A pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect, + const double angle, + const SDL_FPoint *center, + const SDL_RendererFlip flip); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex array Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param texture (optional) The SDL texture to use. + * \param vertices Vertices. + * \param num_vertices Number of vertices. + * \param indices (optional) An array of integer indices into the 'vertices' + * array, if NULL all vertices will be rendered in sequential + * order. + * \param num_indices Number of indices. + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometryRaw + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Vertex *vertices, int num_vertices, + const int *indices, int num_indices); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex arrays Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param texture (optional) The SDL texture to use. + * \param xy Vertex positions + * \param xy_stride Byte size to move from one element to the next element + * \param color Vertex colors (as SDL_Color) + * \param color_stride Byte size to move from one element to the next element + * \param uv Vertex normalized texture coordinates + * \param uv_stride Byte size to move from one element to the next element + * \param num_vertices Number of vertices. + * \param indices (optional) An array of indices into the 'vertices' arrays, + * if NULL all vertices will be rendered in sequential order. + * \param num_indices Number of indices. + * \param size_indices Index size: 1 (byte), 2 (short), 4 (int) + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometry + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices); + +/** + * Read pixels from the current rendering target to an array of pixels. + * + * **WARNING**: This is a very slow operation, and should not be used + * frequently. + * + * `pitch` specifies the number of bytes between rows in the destination + * `pixels` data. This allows you to write to a subrectangle or have padded + * rows in the destination. Generally, `pitch` should equal the number of + * pixels per row in the `pixels` data times the number of bytes per pixel, + * but it might contain additional padding (for example, 24bit RGB Windows + * Bitmap data pads all rows to multiples of 4 bytes). + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the area to read, or NULL + * for the entire render target + * \param format an SDL_PixelFormatEnum value of the desired format of the + * pixel data, or 0 to use the format of the rendering target + * \param pixels a pointer to the pixel data to copy into + * \param pitch the pitch of the `pixels` parameter + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void *pixels, int pitch); + +/** + * Update the screen with any rendering performed since the previous call. + * + * SDL's rendering functions operate on a backbuffer; that is, calling a + * rendering function such as SDL_RenderDrawLine() does not directly put a + * line on the screen, but rather updates the backbuffer. As such, you compose + * your entire scene and *present* the composed backbuffer to the screen as a + * complete picture. + * + * Therefore, when using SDL's rendering API, one does all drawing intended + * for the frame, and then calls this function once per frame to present the + * final drawing to the user. + * + * The backbuffer should be considered invalidated after each present; do not + * assume that previous contents will exist between frames. You are strongly + * encouraged to call SDL_RenderClear() to initialize the backbuffer before + * starting each new frame's drawing, even if you plan to overwrite every + * pixel. + * + * \param renderer the rendering context + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); + +/** + * Destroy the specified texture. + * + * Passing NULL or an otherwise invalid texture will set the SDL error message + * to "Invalid texture". + * + * \param texture the texture to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_CreateTextureFromSurface + */ +extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); + +/** + * Destroy the rendering context for a window and free associated textures. + * + * \param renderer the rendering context + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); + +/** + * Force the rendering context to flush any pending commands to the underlying + * rendering API. + * + * You do not need to (and in fact, shouldn't) call this function unless you + * are planning to call into OpenGL/Direct3D/Metal/whatever directly in + * addition to using an SDL_Renderer. + * + * This is for a very-specific case: if you are using SDL's render API, you + * asked for a specific renderer backend (OpenGL, Direct3D, etc), you set + * SDL_HINT_RENDER_BATCHING to "1", and you plan to make OpenGL/D3D/whatever + * calls in addition to SDL render API calls. If all of this applies, you + * should call SDL_RenderFlush() between calls to SDL's render API and the + * low-level API you're using in cooperation. + * + * In all other cases, you can ignore this function. This is only here to get + * maximum performance out of a specific situation. In all other cases, SDL + * will do the right thing, perhaps at a performance loss. + * + * This function is first available in SDL 2.0.10, and is not needed in 2.0.9 + * and earlier, as earlier versions did not queue rendering commands at all, + * instead flushing them to the OS immediately. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFlush(SDL_Renderer * renderer); + + +/** + * Bind an OpenGL/ES/ES2 texture to the current context. + * + * This is for use with OpenGL instructions when rendering OpenGL primitives + * directly. + * + * If not NULL, `texw` and `texh` will be filled with the width and height + * values suitable for the provided texture. In most cases, both will be 1.0, + * however, on systems that support the GL_ARB_texture_rectangle extension, + * these values will actually be the pixel width and height used to create the + * texture, so this factor needs to be taken into account when providing + * texture coordinates to OpenGL. + * + * You need a renderer to create an SDL_Texture, therefore you can only use + * this function with an implicit OpenGL context from SDL_CreateRenderer(), + * not with your own OpenGL context. If you need control over your OpenGL + * context, you need to write your own texture-loading methods. + * + * Also note that SDL may upload RGB textures as BGR (or vice-versa), and + * re-order the color channels in the shaders phase, so the uploaded texture + * may have swapped color channels. + * + * \param texture the texture to bind to the current OpenGL/ES/ES2 context + * \param texw a pointer to a float value which will be filled with the + * texture width or NULL if you don't need that value + * \param texh a pointer to a float value which will be filled with the + * texture height or NULL if you don't need that value + * \returns 0 on success, or -1 if the operation is not supported; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + * \sa SDL_GL_UnbindTexture + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * Unbind an OpenGL/ES/ES2 texture from the current context. + * + * See SDL_GL_BindTexture() for examples on how to use these functions + * + * \param texture the texture to unbind from the current OpenGL/ES/ES2 context + * \returns 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_BindTexture + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + +/** + * Get the CAMetalLayer associated with the given Metal renderer. + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to a `CAMetalLayer *`. + * + * \param renderer The renderer to query + * \returns a `CAMetalLayer *` on success, or NULL if the renderer isn't a + * Metal renderer + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalCommandEncoder + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); + +/** + * Get the Metal command encoder for the current frame + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to an `id`. + * + * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give + * SDL a drawable to render to, which might happen if the window is + * hidden/minimized/offscreen. This doesn't apply to command encoders for + * render targets, just the window's backbacker. Check your return values! + * + * \param renderer The renderer to query + * \returns an `id` on success, or NULL if the + * renderer isn't a Metal renderer or there was an error. + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalLayer + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer); + +/** + * Toggle VSync of the given renderer. + * + * \param renderer The renderer to toggle + * \param vsync 1 for on, 0 for off. All other values are reserved + * \returns a 0 int on success, or non-zero on failure + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_RenderSetVSync(SDL_Renderer* renderer, int vsync); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_render_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h new file mode 100644 index 000000000..3253d6df0 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h @@ -0,0 +1,2 @@ +#define SDL_REVISION "https://github.com/libsdl-org/SDL.git@b424665e0899769b200231ba943353a5fee1b6b6" +#define SDL_REVISION_NUMBER 0 diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h.cmake b/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h.cmake new file mode 100644 index 000000000..b27ec11bf --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_revision.h.cmake @@ -0,0 +1,6 @@ +#cmakedefine SDL_REVISION "@SDL_REVISION@" +#define SDL_REVISION_NUMBER 0 + +#ifndef SDL_REVISION +#define SDL_REVISION "" +#endif diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_rwops.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_rwops.h new file mode 100644 index 000000000..71e5c8db8 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_rwops.h @@ -0,0 +1,855 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rwops.h + * + * This file provides a general interface for SDL to read and write + * data streams. It can easily be extended to files, memory, etc. + */ + +#ifndef SDL_rwops_h_ +#define SDL_rwops_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* RWops Types */ +#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ +#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ +#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ +#if defined(__VITA__) +#define SDL_RWOPS_VITAFILE 6U /**< Vita file */ +#endif + +/** + * This is the read/write operation structure -- very basic. + */ +typedef struct SDL_RWops +{ + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + + /** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); + + /** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); + + /** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); + + /** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ + int (SDLCALL * close) (struct SDL_RWops * context); + + Uint32 type; + union + { +#if defined(__ANDROID__) + struct + { + void *asset; + } androidio; +#elif defined(__WIN32__) + struct + { + SDL_bool append; + void *h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } windowsio; +#elif defined(__VITA__) + struct + { + int h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } vitaio; +#endif + +#ifdef HAVE_STDIO_H + struct + { + SDL_bool autoclose; + FILE *fp; + } stdio; +#endif + struct + { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct + { + void *data1; + void *data2; + } unknown; + } hidden; + +} SDL_RWops; + + +/** + * \name RWFrom functions + * + * Functions to create SDL_RWops structures from various data streams. + */ +/* @{ */ + +/** + * Use this function to create a new SDL_RWops structure for reading from + * and/or writing to a named file. + * + * The `mode` string is treated roughly the same as in a call to the C + * library's fopen(), even if SDL doesn't happen to use fopen() behind the + * scenes. + * + * Available `mode` strings: + * + * - "r": Open a file for reading. The file must exist. + * - "w": Create an empty file for writing. If a file with the same name + * already exists its content is erased and the file is treated as a new + * empty file. + * - "a": Append to a file. Writing operations append data at the end of the + * file. The file is created if it does not exist. + * - "r+": Open a file for update both reading and writing. The file must + * exist. + * - "w+": Create an empty file for both reading and writing. If a file with + * the same name already exists its content is erased and the file is + * treated as a new empty file. + * - "a+": Open a file for reading and appending. All writing operations are + * performed at the end of the file, protecting the previous content to be + * overwritten. You can reposition (fseek, rewind) the internal pointer to + * anywhere in the file for reading, but writing operations will move it + * back to the end of file. The file is created if it does not exist. + * + * **NOTE**: In order to open a file as a binary file, a "b" character has to + * be included in the `mode` string. This additional "b" character can either + * be appended at the end of the string (thus making the following compound + * modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the + * letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). + * Additional characters may follow the sequence, although they should have no + * effect. For example, "t" is sometimes appended to make explicit the file is + * a text file. + * + * This function supports Unicode filenames, but they must be encoded in UTF-8 + * format, regardless of the underlying operating system. + * + * As a fallback, SDL_RWFromFile() will transparently open a matching filename + * in an Android app's `assets`. + * + * Closing the SDL_RWops will close the file handle SDL is holding internally. + * + * \param file a UTF-8 string representing the filename to open + * \param mode an ASCII string representing the mode to be used for opening + * the file. + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, + const char *mode); + +#ifdef HAVE_STDIO_H + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, SDL_bool autoclose); + +#else + +/** + * Use this function to create an SDL_RWops structure from a standard I/O file + * pointer (stdio.h's `FILE*`). + * + * This function is not available on Windows, since files opened in an + * application on that platform cannot be used by a dynamically linked + * library. + * + * On some platforms, the first parameter is a `void*`, on others, it's a + * `FILE*`, depending on what system headers are available to SDL. It is + * always intended to be the `FILE*` type from the C runtime's stdio.h. + * + * \param fp the `FILE*` that feeds the SDL_RWops stream + * \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, + * SDL_FALSE to leave the `FILE*` open when the RWops is + * closed + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, + SDL_bool autoclose); +#endif + +/** + * Use this function to prepare a read-write memory buffer for use with + * SDL_RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size, for both read and write access. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to make sure the RWops never writes to the memory buffer, you + * should use SDL_RWFromConstMem() with a read-only buffer of memory instead. + * + * \param mem a pointer to a buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); + +/** + * Use this function to prepare a read-only memory buffer for use with RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size. It assumes the memory area is not writable. + * + * Attempting to write to this RWops stream will report an error without + * writing to the memory buffer. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to write to a memory buffer, you should use SDL_RWFromMem() + * with a writable buffer of memory instead. + * + * \param mem a pointer to a read-only buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, + int size); + +/* @} *//* RWFrom functions */ + + +/** + * Use this function to allocate an empty, unpopulated SDL_RWops structure. + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. + * + * You must free the returned pointer with SDL_FreeRW(). Depending on your + * operating system and compiler, there may be a difference between the + * malloc() and free() your program uses and the versions SDL calls + * internally. Trying to mix the two can cause crashing such as segmentation + * faults. Since all SDL_RWops must free themselves when their **close** + * method is called, all SDL_RWops must be allocated through this function, so + * they can all be freed correctly with SDL_FreeRW(). + * + * \returns a pointer to the allocated memory on success, or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeRW + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); + +/** + * Use this function to free an SDL_RWops structure allocated by + * SDL_AllocRW(). + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and + * call the **close** method on those SDL_RWops pointers when you are done + * with them. + * + * Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is + * invalid as soon as this function returns. Any extra memory allocated during + * creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must + * be responsible for managing that memory in their **close** method. + * + * \param area the SDL_RWops structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocRW + */ +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); + +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ + +/** + * Use this function to get the size of the data stream in an SDL_RWops. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context the SDL_RWops to get the size of the data stream from + * \returns the size of the data stream in the SDL_RWops on success, -1 if + * unknown or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); + +/** + * Seek within an SDL_RWops data stream. + * + * This function seeks to byte `offset`, relative to `whence`. + * + * `whence` may be any of the following values: + * + * - `RW_SEEK_SET`: seek from the beginning of data + * - `RW_SEEK_CUR`: seek relative to current read point + * - `RW_SEEK_END`: seek relative to the end of data + * + * If this stream can not seek, it will return -1. + * + * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's + * `seek` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param offset an offset in bytes, relative to **whence** location; can be + * negative + * \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` + * \returns the final offset in the data stream after the seek or -1 on error. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, + Sint64 offset, int whence); + +/** + * Determine the current read/write offset in an SDL_RWops data stream. + * + * SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` + * method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify + * application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a SDL_RWops data stream object from which to get the current + * offset + * \returns the current offset in the stream, or -1 if the information can not + * be determined. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); + +/** + * Read from a data source. + * + * This function reads up to `maxnum` objects each of size `size` from the + * data source to the area pointed at by `ptr`. This function may read less + * objects than requested. It will return zero when there has been an error or + * the data stream is completely read. + * + * SDL_RWread() is actually a function wrapper that calls the SDL_RWops's + * `read` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer to read data into + * \param size the size of each object to read, in bytes + * \param maxnum the maximum number of objects to be read + * \returns the number of objects read, or 0 at error or end of file; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, + void *ptr, size_t size, + size_t maxnum); + +/** + * Write to an SDL_RWops data stream. + * + * This function writes exactly `num` objects each of size `size` from the + * area pointed at by `ptr` to the stream. If this fails for any reason, it'll + * return less than `num` to demonstrate how far the write progressed. On + * success, it returns `num`. + * + * SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's + * `write` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer containing data to write + * \param size the size of an object to write, in bytes + * \param num the number of objects to write + * \returns the number of objects written, which will be less than **num** on + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + */ +extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, + const void *ptr, size_t size, + size_t num); + +/** + * Close and free an allocated SDL_RWops structure. + * + * SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any + * resources used by the stream and frees the SDL_RWops itself with + * SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to + * flush to its output (e.g. to disk). + * + * Note that if this fails to flush the stream to disk, this function reports + * an error, but the SDL_RWops is still invalid once this function returns. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context SDL_RWops structure to close + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); + +/** + * Load all the data from an SDL data stream. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * \param src the SDL_RWops to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, + size_t *datasize, + int freesrc); + +/** + * Load all the data from a file path. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * Prior to SDL 2.0.10, this function was a macro wrapping around + * SDL_LoadFile_RW. + * + * \param file the path to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); + +/** + * \name Read endian functions + * + * Read an item of the specified endianness and return in native format. + */ +/* @{ */ + +/** + * Use this function to read a byte from an SDL_RWops. + * + * \param src the SDL_RWops to read from + * \returns the read byte on success or 0 on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteU8 + */ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); + +/** + * Use this function to read 16 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); + +/** + * Use this function to read 16 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); + +/** + * Use this function to read 32 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); + +/** + * Use this function to read 32 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); + +/** + * Use this function to read 64 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); + +/** + * Use this function to read 64 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +/* @} *//* Read endian functions */ + +/** + * \name Write endian functions + * + * Write an item of native format to the specified endianness. + */ +/* @{ */ + +/** + * Use this function to write a byte to an SDL_RWops. + * + * \param dst the SDL_RWops to write to + * \param value the byte value to write + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadU8 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +/* @} *//* Write endian functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rwops_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_scancode.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_scancode.h new file mode 100644 index 000000000..5b2c67c8f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_scancode.h @@ -0,0 +1,413 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_scancode.h + * + * Defines keyboard scancodes. + */ + +#ifndef SDL_scancode_h_ +#define SDL_scancode_h_ + +#include "SDL_stdinc.h" + +/** + * \brief The SDL keyboard scancode representation. + * + * Values of this type are used to represent keyboard keys, among other places + * in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the + * SDL_Event structure. + * + * The values in this enumeration are based on the USB usage page standard: + * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf + */ +typedef enum +{ + SDL_SCANCODE_UNKNOWN = 0, + + /** + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + */ + /* @{ */ + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + */ + SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + */ + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + */ + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) */ + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards + */ + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. */ + SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ + SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. */ + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, /**< redo */ + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, +/* not sure whether there's a reason to enable these */ +/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ +/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ +/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see + footnotes in USB doc */ + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ + SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ + SDL_SCANCODE_LANG3 = 146, /**< Katakana */ + SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ + SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ + SDL_SCANCODE_LANG6 = 149, /**< reserved */ + SDL_SCANCODE_LANG7 = 150, /**< reserved */ + SDL_SCANCODE_LANG8 = 151, /**< reserved */ + SDL_SCANCODE_LANG9 = 152, /**< reserved */ + + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, /**< alt, option */ + SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, /**< alt gr, option */ + SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ + + SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special KMOD_MODE for it I'm adding it here + */ + + /* @} *//* Usage page 0x07 */ + + /** + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + /* @} *//* Usage page 0x0C */ + + /** + * \name Walther keys + * + * These are values that Christian Walther added (for mac keyboard?). + */ + /* @{ */ + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display + switch, video mode switch */ + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + /* @} *//* Walther keys */ + + /** + * \name Usage page 0x0C (additional media keys) + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIOREWIND = 285, + SDL_SCANCODE_AUDIOFASTFORWARD = 286, + + /* @} *//* Usage page 0x0C (additional media keys) */ + + /* Add any other keys here. */ + + SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes + for array bounds */ +} SDL_Scancode; + +#endif /* SDL_scancode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_sensor.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_sensor.h new file mode 100644 index 000000000..a2f30e0f8 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_sensor.h @@ -0,0 +1,301 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_sensor.h + * + * Include file for SDL sensor event handling + * + */ + +#ifndef SDL_sensor_h_ +#define SDL_sensor_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief SDL_sensor.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system + * for sensors, and load appropriate drivers. + */ + +struct _SDL_Sensor; +typedef struct _SDL_Sensor SDL_Sensor; + +/** + * This is a unique ID for a sensor for the time it is connected to the system, + * and is never reused for the lifetime of the application. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_SensorID; + +/* The different sensors defined by SDL + * + * Additional sensors may be available, using platform dependent semantics. + * + * Hare are the additional Android sensors: + * https://developer.android.com/reference/android/hardware/SensorEvent.html#values + */ +typedef enum +{ + SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ + SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ + SDL_SENSOR_ACCEL, /**< Accelerometer */ + SDL_SENSOR_GYRO /**< Gyroscope */ +} SDL_SensorType; + +/** + * Accelerometer sensor + * + * The accelerometer returns the current acceleration in SI meters per + * second squared. This measurement includes the force of gravity, so + * a device at rest will have an value of SDL_STANDARD_GRAVITY away + * from the center of the earth. + * + * values[0]: Acceleration on the x axis + * values[1]: Acceleration on the y axis + * values[2]: Acceleration on the z axis + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ +#define SDL_STANDARD_GRAVITY 9.80665f + +/** + * Gyroscope sensor + * + * The gyroscope returns the current rate of rotation in radians per second. + * The rotation is positive in the counter-clockwise direction. That is, + * an observer looking from a positive location on one of the axes would + * see positive rotation on that axis when it appeared to be rotating + * counter-clockwise. + * + * values[0]: Angular speed around the x axis (pitch) + * values[1]: Angular speed around the y axis (yaw) + * values[2]: Angular speed around the z axis (roll) + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone or controller is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the sensor API + * + * If you are using the sensor API or handling events from multiple threads + * you should use these locking functions to protect access to the sensors. + * + * In particular, you are guaranteed that the sensor list won't change, so the + * API functions that take a sensor index will be valid, and sensor events + * will not be delivered. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC void SDLCALL SDL_LockSensors(void); +extern DECLSPEC void SDLCALL SDL_UnlockSensors(void); + +/** + * Count the number of sensors attached to the system right now. + * + * \returns the number of sensors detected. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_NumSensors(void); + +/** + * Get the implementation dependent name of a sensor. + * + * \param device_index The sensor to obtain name from + * \returns the sensor name, or NULL if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index); + +/** + * Get the type of a sensor. + * + * \param device_index The sensor to get the type from + * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `device_index` is + * out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index); + +/** + * Get the platform dependent type of a sensor. + * + * \param device_index The sensor to check + * \returns the sensor platform dependent type, or -1 if `device_index` is out + * of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index); + +/** + * Get the instance ID of a sensor. + * + * \param device_index The sensor to get instance id from + * \returns the sensor instance ID, or -1 if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index); + +/** + * Open a sensor for use. + * + * \param device_index The sensor to open + * \returns an SDL_Sensor sensor object, or NULL if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index); + +/** + * Return the SDL_Sensor associated with an instance id. + * + * \param instance_id The sensor from instance id + * \returns an SDL_Sensor object. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id); + +/** + * Get the implementation dependent name of a sensor + * + * \param sensor The SDL_Sensor object + * \returns the sensor name, or NULL if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor); + +/** + * Get the type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID` if `sensor` is + * NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor); + +/** + * Get the platform dependent type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor platform dependent type, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor); + +/** + * Get the instance ID of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor instance ID, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor); + +/** + * Get the current state of an opened sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor The SDL_Sensor object to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values); + +/** + * Close a sensor previously opened with SDL_SensorOpen(). + * + * \param sensor The SDL_Sensor object to close + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor); + +/** + * Update the current state of the open sensors. + * + * This is called automatically by the event loop if sensor events are + * enabled. + * + * This needs to be called from the thread that initialized the sensor + * subsystem. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorUpdate(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* SDL_sensor_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_shape.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_shape.h new file mode 100644 index 000000000..1bca9270e --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_shape.h @@ -0,0 +1,155 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_shape_h_ +#define SDL_shape_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** \file SDL_shape.h + * + * Header file for the shaped window API. + */ + +#define SDL_NONSHAPEABLE_WINDOW -1 +#define SDL_INVALID_SHAPE_ARGUMENT -2 +#define SDL_WINDOW_LACKS_SHAPE -3 + +/** + * Create a window that can be shaped with the specified position, dimensions, + * and flags. + * + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window. + * \param h The height of the window. + * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with + * any of the following: ::SDL_WINDOW_OPENGL, + * ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN, + * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, + * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set, + * and ::SDL_WINDOW_FULLSCREEN is always unset. + * \return the window created, or NULL if window creation failed. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); + +/** + * Return whether the given window is a shaped window. + * + * \param window The window to query for being shaped. + * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if + * the window is unshaped or NULL. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateShapedWindow + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window); + +/** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. */ +typedef enum { + /** \brief The default mode, a binarized alpha cutoff of 1. */ + ShapeModeDefault, + /** \brief A binarized alpha cutoff with a given integer value. */ + ShapeModeBinarizeAlpha, + /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ + ShapeModeReverseBinarizeAlpha, + /** \brief A color key is applied. */ + ShapeModeColorKey +} WindowShapeMode; + +#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) + +/** \brief A union containing parameters for shaped windows. */ +typedef union { + /** \brief A cutoff alpha value for binarization of the window shape's alpha channel. */ + Uint8 binarizationCutoff; + SDL_Color colorKey; +} SDL_WindowShapeParams; + +/** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ +typedef struct SDL_WindowShapeMode { + /** \brief The mode of these window-shape parameters. */ + WindowShapeMode mode; + /** \brief Window-shape parameters. */ + SDL_WindowShapeParams parameters; +} SDL_WindowShapeMode; + +/** + * Set the shape and parameters of a shaped window. + * + * \param window The shaped window whose parameters should be set. + * \param shape A surface encoding the desired shape for the window. + * \param shape_mode The parameters to set for the shaped window. + * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape + * argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does + * not reference a valid shaped window. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WindowShapeMode + * \sa SDL_GetShapedWindowMode + */ +extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + +/** + * Get the shape parameters of a shaped window. + * + * \param window The shaped window whose parameters should be retrieved. + * \param shape_mode An empty shape-mode structure to fill, or NULL to check + * whether the window has a shape. + * \return 0 if the window has a shape and, provided shape_mode was not NULL, + * shape_mode has been filled with the mode data, + * SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped + * window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a + * shapeable window currently lacking a shape. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WindowShapeMode + * \sa SDL_SetWindowShape + */ +extern DECLSPEC int SDLCALL SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_shape_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_stdinc.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_stdinc.h new file mode 100644 index 000000000..c0d194c4a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_stdinc.h @@ -0,0 +1,719 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_stdinc.h + * + * This is a general header that includes C language support. + */ + +#ifndef SDL_stdinc_h_ +#define SDL_stdinc_h_ + +#include "SDL_config.h" + +#ifdef __APPLE__ +#ifndef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */ +#endif +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_WCHAR_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_MATH_H +# if defined(__WINRT__) +/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on + WinRT. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx + for more information. +*/ +# define _USE_MATH_DEFINES +# endif +# include +#endif +#ifdef HAVE_FLOAT_H +# include +#endif +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +#pragma alloca +# elif defined(__MRC__) +void *alloca(unsigned); +# else +char *alloca(); +# endif +#endif + +/** + * Check if the compiler supports a given builtin. + * Supported by virtually all clang versions and recent gcc. Use this + * instead of checking the clang version if possible. + */ +#ifdef __has_builtin +#define _SDL_HAS_BUILTIN(x) __has_builtin(x) +#else +#define _SDL_HAS_BUILTIN(x) 0 +#endif + +/** + * The number of elements in an array. + */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/** + * Macro useful for building other macros with strings in them + * + * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") + */ +#define SDL_STRINGIFY_ARG(arg) #arg + +/** + * \name Cast operators + * + * Use proper C++ casts when compiled as C++ to be compatible with the option + * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). + */ +/* @{ */ +#ifdef __cplusplus +#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) +#define SDL_static_cast(type, expression) static_cast(expression) +#define SDL_const_cast(type, expression) const_cast(expression) +#else +#define SDL_reinterpret_cast(type, expression) ((type)(expression)) +#define SDL_static_cast(type, expression) ((type)(expression)) +#define SDL_const_cast(type, expression) ((type)(expression)) +#endif +/* @} *//* Cast operators */ + +/* Define a four character code as a Uint32 */ +#define SDL_FOURCC(A, B, C, D) \ + ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) + +/** + * \name Basic data types + */ +/* @{ */ + +#ifdef __CC_ARM +/* ARM's compiler throws warnings if we use an enum: like "SDL_bool x = a < b;" */ +#define SDL_FALSE 0 +#define SDL_TRUE 1 +typedef int SDL_bool; +#else +typedef enum +{ + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; +#endif + +/** + * \brief A signed 8-bit integer type. + */ +#define SDL_MAX_SINT8 ((Sint8)0x7F) /* 127 */ +#define SDL_MIN_SINT8 ((Sint8)(~0x7F)) /* -128 */ +typedef int8_t Sint8; +/** + * \brief An unsigned 8-bit integer type. + */ +#define SDL_MAX_UINT8 ((Uint8)0xFF) /* 255 */ +#define SDL_MIN_UINT8 ((Uint8)0x00) /* 0 */ +typedef uint8_t Uint8; +/** + * \brief A signed 16-bit integer type. + */ +#define SDL_MAX_SINT16 ((Sint16)0x7FFF) /* 32767 */ +#define SDL_MIN_SINT16 ((Sint16)(~0x7FFF)) /* -32768 */ +typedef int16_t Sint16; +/** + * \brief An unsigned 16-bit integer type. + */ +#define SDL_MAX_UINT16 ((Uint16)0xFFFF) /* 65535 */ +#define SDL_MIN_UINT16 ((Uint16)0x0000) /* 0 */ +typedef uint16_t Uint16; +/** + * \brief A signed 32-bit integer type. + */ +#define SDL_MAX_SINT32 ((Sint32)0x7FFFFFFF) /* 2147483647 */ +#define SDL_MIN_SINT32 ((Sint32)(~0x7FFFFFFF)) /* -2147483648 */ +typedef int32_t Sint32; +/** + * \brief An unsigned 32-bit integer type. + */ +#define SDL_MAX_UINT32 ((Uint32)0xFFFFFFFFu) /* 4294967295 */ +#define SDL_MIN_UINT32 ((Uint32)0x00000000) /* 0 */ +typedef uint32_t Uint32; + +/** + * \brief A signed 64-bit integer type. + */ +#define SDL_MAX_SINT64 ((Sint64)0x7FFFFFFFFFFFFFFFll) /* 9223372036854775807 */ +#define SDL_MIN_SINT64 ((Sint64)(~0x7FFFFFFFFFFFFFFFll)) /* -9223372036854775808 */ +typedef int64_t Sint64; +/** + * \brief An unsigned 64-bit integer type. + */ +#define SDL_MAX_UINT64 ((Uint64)0xFFFFFFFFFFFFFFFFull) /* 18446744073709551615 */ +#define SDL_MIN_UINT64 ((Uint64)(0x0000000000000000ull)) /* 0 */ +typedef uint64_t Uint64; + +/* @} *//* Basic data types */ + +/* Make sure we have macros for printing width-based integers. + * should define these but this is not true all platforms. + * (for example win32) */ +#ifndef SDL_PRIs64 +#ifdef PRIs64 +#define SDL_PRIs64 PRIs64 +#elif defined(__WIN32__) +#define SDL_PRIs64 "I64d" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIs64 "ld" +#else +#define SDL_PRIs64 "lld" +#endif +#endif +#ifndef SDL_PRIu64 +#ifdef PRIu64 +#define SDL_PRIu64 PRIu64 +#elif defined(__WIN32__) +#define SDL_PRIu64 "I64u" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIu64 "lu" +#else +#define SDL_PRIu64 "llu" +#endif +#endif +#ifndef SDL_PRIx64 +#ifdef PRIx64 +#define SDL_PRIx64 PRIx64 +#elif defined(__WIN32__) +#define SDL_PRIx64 "I64x" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIx64 "lx" +#else +#define SDL_PRIx64 "llx" +#endif +#endif +#ifndef SDL_PRIX64 +#ifdef PRIX64 +#define SDL_PRIX64 PRIX64 +#elif defined(__WIN32__) +#define SDL_PRIX64 "I64X" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIX64 "lX" +#else +#define SDL_PRIX64 "llX" +#endif +#endif +#ifndef SDL_PRIs32 +#ifdef PRId32 +#define SDL_PRIs32 PRId32 +#else +#define SDL_PRIs32 "d" +#endif +#endif +#ifndef SDL_PRIu32 +#ifdef PRIu32 +#define SDL_PRIu32 PRIu32 +#else +#define SDL_PRIu32 "u" +#endif +#endif +#ifndef SDL_PRIx32 +#ifdef PRIx32 +#define SDL_PRIx32 PRIx32 +#else +#define SDL_PRIx32 "x" +#endif +#endif +#ifndef SDL_PRIX32 +#ifdef PRIX32 +#define SDL_PRIX32 PRIX32 +#else +#define SDL_PRIX32 "X" +#endif +#endif + +/* Annotations to help code analysis tools */ +#ifdef SDL_DISABLE_ANALYZE_MACROS +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#else +#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ +#include + +#define SDL_IN_BYTECAP(x) _In_bytecount_(x) +#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x) +#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x) +#define SDL_OUT_CAP(x) _Out_cap_(x) +#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x) +#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x) + +#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_ +#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_ +#else +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#endif +#if defined(__GNUC__) +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) +#else +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#endif +#endif /* SDL_DISABLE_ANALYZE_MACROS */ + +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#if !defined(__ANDROID__) && !defined(__VITA__) + /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ +typedef enum +{ + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); +extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); +extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); +extern DECLSPEC void SDLCALL SDL_free(void *mem); + +typedef void *(SDLCALL *SDL_malloc_func)(size_t size); +typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); +typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); +typedef void (SDLCALL *SDL_free_func)(void *mem); + +/** + * Get the current set of SDL memory functions + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * Replace SDL's memory allocation functions with a custom set + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func); + +/** + * Get the number of outstanding (unfreed) allocations + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); + +extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); + +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)); + +extern DECLSPEC int SDLCALL SDL_abs(int x); + +/* NOTE: these double-evaluate their arguments, so you should never have side effects in the parameters */ +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) +#define SDL_clamp(x, a, b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x))) + +extern DECLSPEC int SDLCALL SDL_isalpha(int x); +extern DECLSPEC int SDLCALL SDL_isalnum(int x); +extern DECLSPEC int SDLCALL SDL_isblank(int x); +extern DECLSPEC int SDLCALL SDL_iscntrl(int x); +extern DECLSPEC int SDLCALL SDL_isdigit(int x); +extern DECLSPEC int SDLCALL SDL_isxdigit(int x); +extern DECLSPEC int SDLCALL SDL_ispunct(int x); +extern DECLSPEC int SDLCALL SDL_isspace(int x); +extern DECLSPEC int SDLCALL SDL_isupper(int x); +extern DECLSPEC int SDLCALL SDL_islower(int x); +extern DECLSPEC int SDLCALL SDL_isprint(int x); +extern DECLSPEC int SDLCALL SDL_isgraph(int x); +extern DECLSPEC int SDLCALL SDL_toupper(int x); +extern DECLSPEC int SDLCALL SDL_tolower(int x); + +extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); + +#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) +#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) +#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) + +/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ +SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) +{ +#ifdef __APPLE__ + memset_pattern4(dst, &val, dwords * 4); +#elif defined(__GNUC__) && defined(__i386__) + int u0, u1, u2; + __asm__ __volatile__ ( + "cld \n\t" + "rep ; stosl \n\t" + : "=&D" (u0), "=&a" (u1), "=&c" (u2) + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords)) + : "memory" + ); +#else + size_t _n = (dwords + 3) / 4; + Uint32 *_p = SDL_static_cast(Uint32 *, dst); + Uint32 _val = (val); + if (dwords == 0) { + return; + } + switch (dwords % 4) { + case 0: do { *_p++ = _val; SDL_FALLTHROUGH; + case 3: *_p++ = _val; SDL_FALLTHROUGH; + case 2: *_p++ = _val; SDL_FALLTHROUGH; + case 1: *_p++ = _val; + } while ( --_n ); + } +#endif +} + +extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); + +extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr); +extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr); +extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle); + +extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2); +extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_wcscasecmp(const wchar_t *str1, const wchar_t *str2); +extern DECLSPEC int SDLCALL SDL_wcsncasecmp(const wchar_t *str1, const wchar_t *str2, size_t len); + +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes); +extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC char *SDLCALL SDL_strdup(const char *str); +extern DECLSPEC char *SDLCALL SDL_strrev(char *str); +extern DECLSPEC char *SDLCALL SDL_strupr(char *str); +extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); +extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); +extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr); +extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str); + +extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix); + +extern DECLSPEC int SDLCALL SDL_atoi(const char *str); +extern DECLSPEC double SDLCALL SDL_atof(const char *str); +extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base); +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base); +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base); +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base); +extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp); + +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); + +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); +extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, const char *fmt, va_list ap); + +#ifndef HAVE_M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 /**< pi */ +#endif +#endif + +/** + * Use this function to compute arc cosine of `x`. + * + * The definition of `y = acos(x)` is `x = cos(y)`. + * + * Domain: `-1 <= x <= 1` + * + * Range: `0 <= y <= Pi` + * + * \param x floating point value, in radians. + * \returns arc cosine of `x`. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC double SDLCALL SDL_acos(double x); +extern DECLSPEC float SDLCALL SDL_acosf(float x); +extern DECLSPEC double SDLCALL SDL_asin(double x); +extern DECLSPEC float SDLCALL SDL_asinf(float x); +extern DECLSPEC double SDLCALL SDL_atan(double x); +extern DECLSPEC float SDLCALL SDL_atanf(float x); +extern DECLSPEC double SDLCALL SDL_atan2(double y, double x); +extern DECLSPEC float SDLCALL SDL_atan2f(float y, float x); +extern DECLSPEC double SDLCALL SDL_ceil(double x); +extern DECLSPEC float SDLCALL SDL_ceilf(float x); +extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); +extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y); +extern DECLSPEC double SDLCALL SDL_cos(double x); +extern DECLSPEC float SDLCALL SDL_cosf(float x); +extern DECLSPEC double SDLCALL SDL_exp(double x); +extern DECLSPEC float SDLCALL SDL_expf(float x); +extern DECLSPEC double SDLCALL SDL_fabs(double x); +extern DECLSPEC float SDLCALL SDL_fabsf(float x); +extern DECLSPEC double SDLCALL SDL_floor(double x); +extern DECLSPEC float SDLCALL SDL_floorf(float x); +extern DECLSPEC double SDLCALL SDL_trunc(double x); +extern DECLSPEC float SDLCALL SDL_truncf(float x); +extern DECLSPEC double SDLCALL SDL_fmod(double x, double y); +extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y); +extern DECLSPEC double SDLCALL SDL_log(double x); +extern DECLSPEC float SDLCALL SDL_logf(float x); +extern DECLSPEC double SDLCALL SDL_log10(double x); +extern DECLSPEC float SDLCALL SDL_log10f(float x); +extern DECLSPEC double SDLCALL SDL_pow(double x, double y); +extern DECLSPEC float SDLCALL SDL_powf(float x, float y); +extern DECLSPEC double SDLCALL SDL_round(double x); +extern DECLSPEC float SDLCALL SDL_roundf(float x); +extern DECLSPEC long SDLCALL SDL_lround(double x); +extern DECLSPEC long SDLCALL SDL_lroundf(float x); +extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); +extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n); +extern DECLSPEC double SDLCALL SDL_sin(double x); +extern DECLSPEC float SDLCALL SDL_sinf(float x); +extern DECLSPEC double SDLCALL SDL_sqrt(double x); +extern DECLSPEC float SDLCALL SDL_sqrtf(float x); +extern DECLSPEC double SDLCALL SDL_tan(double x); +extern DECLSPEC float SDLCALL SDL_tanf(float x); + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +/* SDL_iconv_* are now always real symbols/types, not macros or inlined. */ +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, + const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, + size_t * inbytesleft, char **outbuf, + size_t * outbytesleft); + +/** + * This function converts a string between encodings in one pass, returning a + * string that must be freed with SDL_free() or NULL on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, + const char *fromcode, + const char *inbuf, + size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t)) + +/* force builds using Clang's static analysis tools to use literal C runtime + here, since there are possibly tests that are ineffective otherwise. */ +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) + +/* The analyzer knows about strlcpy even when the system doesn't provide it */ +#ifndef HAVE_STRLCPY +size_t strlcpy(char* dst, const char* src, size_t size); +#endif + +/* The analyzer knows about strlcat even when the system doesn't provide it */ +#ifndef HAVE_STRLCAT +size_t strlcat(char* dst, const char* src, size_t size); +#endif + +#define SDL_malloc malloc +#define SDL_calloc calloc +#define SDL_realloc realloc +#define SDL_free free +#define SDL_memset memset +#define SDL_memcpy memcpy +#define SDL_memmove memmove +#define SDL_memcmp memcmp +#define SDL_strlcpy strlcpy +#define SDL_strlcat strlcat +#define SDL_strlen strlen +#define SDL_wcslen wcslen +#define SDL_wcslcpy wcslcpy +#define SDL_wcslcat wcslcat +#define SDL_strdup strdup +#define SDL_wcsdup wcsdup +#define SDL_strchr strchr +#define SDL_strrchr strrchr +#define SDL_strstr strstr +#define SDL_wcsstr wcsstr +#define SDL_strtokr strtok_r +#define SDL_strcmp strcmp +#define SDL_wcscmp wcscmp +#define SDL_strncmp strncmp +#define SDL_wcsncmp wcsncmp +#define SDL_strcasecmp strcasecmp +#define SDL_strncasecmp strncasecmp +#define SDL_sscanf sscanf +#define SDL_vsscanf vsscanf +#define SDL_snprintf snprintf +#define SDL_vsnprintf vsnprintf +#endif + +SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords) +{ + return SDL_memcpy(dst, src, dwords * 4); +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_stdinc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_surface.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_surface.h new file mode 100644 index 000000000..441237617 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_surface.h @@ -0,0 +1,995 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_surface.h + * + * Header file for ::SDL_Surface definition and management functions. + */ + +#ifndef SDL_surface_h_ +#define SDL_surface_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_blendmode.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Surface flags + * + * These are the currently supported flags for the ::SDL_Surface. + * + * \internal + * Used internally (read-only). + */ +/* @{ */ +#define SDL_SWSURFACE 0 /**< Just here for compatibility */ +#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ +#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ +#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ +#define SDL_SIMD_ALIGNED 0x00000008 /**< Surface uses aligned memory */ +/* @} *//* Surface flags */ + +/** + * Evaluates to true if the surface needs to be locked before access. + */ +#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) + +/** + * \brief A collection of pixels used in software blitting. + * + * \note This structure should be treated as read-only, except for \c pixels, + * which, if not NULL, contains the raw pixel data for the surface. + */ +typedef struct SDL_Surface +{ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + int pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + + /** Application data associated with the surface */ + void *userdata; /**< Read-write */ + + /** information needed for surfaces requiring locks */ + int locked; /**< Read-only */ + + /** list of BlitMap that hold a reference to this surface */ + void *list_blitmap; /**< Private */ + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + + /** info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ +} SDL_Surface; + +/** + * \brief The type of function used for surface blitting functions. + */ +typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, + struct SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief The formula used for converting between YUV and RGB + */ +typedef enum +{ + SDL_YUV_CONVERSION_JPEG, /**< Full range JPEG */ + SDL_YUV_CONVERSION_BT601, /**< BT.601 (the default) */ + SDL_YUV_CONVERSION_BT709, /**< BT.709 */ + SDL_YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */ +} SDL_YUV_CONVERSION_MODE; + +/** + * Allocate a new RGB surface. + * + * If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. + * If `depth` is greater than 8 bits, the pixel format is set using the + * [RGBA]mask parameters. + * + * The [RGBA]mask parameters are the bitmasks used to extract that color from + * a pixel. For instance, `Rmask` being 0xFF000000 means the red data is + * stored in the most significant byte. Using zeros for the RGB masks sets a + * default value, based on the depth. For example: + * + * ```c++ + * SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); + * ``` + * + * However, using zero for the Amask results in an Amask of 0. + * + * By default surfaces with an alpha mask are set up for blending as with: + * + * ```c++ + * SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) + * ``` + * + * You can change this by calling SDL_SetSurfaceBlendMode() and selecting a + * different `blendMode`. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with a specific pixel format. + * + * This function operates mostly like SDL_CreateRGBSurface(), except instead + * of providing pixel color masks, you provide it with a predefined format + * from SDL_PixelFormatEnum. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); + +/** + * Allocate a new RGB surface with existing pixel data. + * + * This function operates mostly like SDL_CreateRGBSurface(), except it does + * not allocate memory for the pixel data, instead the caller provides an + * existing buffer of data for the surface to use. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, + int height, + int depth, + int pitch, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with with a specific pixel format and existing + * pixel data. + * + * This function operates mostly like SDL_CreateRGBSurfaceFrom(), except + * instead of providing pixel color masks, you provide it with a predefined + * format from SDL_PixelFormatEnum. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); + +/** + * Free an RGB surface. + * + * It is safe to pass NULL to this function. + * + * \param surface the SDL_Surface to free. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_LoadBMP + * \sa SDL_LoadBMP_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); + +/** + * Set the palette used by a surface. + * + * A single palette can be shared with many surfaces. + * + * \param surface the SDL_Surface structure to update + * \param palette the SDL_Palette structure to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, + SDL_Palette * palette); + +/** + * Set up a surface for directly accessing the pixels. + * + * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to + * and read from `surface->pixels`, using the pixel format stored in + * `surface->format`. Once you are done accessing the surface, you should use + * SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to + * 0, then you can read and write to the surface at any time, and the pixel + * format of the surface will not change. + * + * \param surface the SDL_Surface structure to be locked + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MUSTLOCK + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); + +/** + * Release a surface after directly accessing the pixels. + * + * \param surface the SDL_Surface structure to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockSurface + */ +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); + +/** + * Load a BMP image from a seekable SDL data stream. + * + * The new surface should be freed with SDL_FreeSurface(). Not doing so will + * result in a memory leak. + * + * src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. + * Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap + * from a file, convert it to an SDL_Surface and then close the file. + * + * \param src the data stream for the surface + * \param freesrc non-zero to close the stream after being read + * \returns a pointer to a new SDL_Surface structure or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeSurface + * \sa SDL_RWFromFile + * \sa SDL_LoadBMP + * \sa SDL_SaveBMP_RW + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, + int freesrc); + +/** + * Load a surface from a file. + * + * Convenience macro. + */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Save a surface to a seekable SDL data stream in BMP format. + * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * + * \param surface the SDL_Surface structure containing the image to be saved + * \param dst a data stream to save to + * \param freedst non-zero to close the stream after being written + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadBMP_RW + * \sa SDL_SaveBMP + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface * surface, SDL_RWops * dst, int freedst); + +/** + * Save a surface to a file. + * + * Convenience macro. + */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/** + * Set the RLE acceleration hint for a surface. + * + * If RLE is enabled, color key and alpha blending blits are much faster, but + * the surface must be locked before directly accessing the pixels. + * + * \param surface the SDL_Surface structure to optimize + * \param flag 0 to disable, non-zero to enable RLE acceleration + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_LockSurface + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, + int flag); + +/** + * Returns whether the surface is RLE enabled + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SetSurfaceRLE + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSurfaceRLE(SDL_Surface * surface); + +/** + * Set the color key (transparent pixel) in a surface. + * + * The color key defines a pixel value that will be treated as transparent in + * a blit. For example, one can use this to specify that cyan pixels should be + * considered transparent, and therefore not rendered. + * + * It is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * RLE acceleration can substantially speed up blitting of images with large + * horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. + * + * \param surface the SDL_Surface structure to update + * \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key + * \param key the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetColorKey + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, + int flag, Uint32 key); + +/** + * Returns whether the surface has a color key + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_SetColorKey + * \sa SDL_GetColorKey + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface); + +/** + * Get the color key (transparent pixel) for a surface. + * + * The color key is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * If the surface doesn't have color key enabled this function returns -1. + * + * \param surface the SDL_Surface structure to query + * \param key a pointer filled in with the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetColorKey + */ +extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, + Uint32 * key); + +/** + * Set an additional color value multiplied into blit operations. + * + * When this surface is blitted, during the blit operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * \param surface the SDL_Surface structure to update + * \param r the red color value multiplied into blit operations + * \param g the green color value multiplied into blit operations + * \param b the blue color value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into blit operations. + * + * \param surface the SDL_Surface structure to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value used in blit operations. + * + * When this surface is blitted, during the blit operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * \param surface the SDL_Surface structure to update + * \param alpha the alpha value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 alpha); + +/** + * Get the additional alpha value used in blit operations. + * + * \param surface the SDL_Surface structure to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 * alpha); + +/** + * Set the blend mode used for blit operations. + * + * To copy a surface to another surface (or texture) without blending with the + * existing data, the blendmode of the SOURCE surface should be set to + * `SDL_BLENDMODE_NONE`. + * + * \param surface the SDL_Surface structure to update + * \param blendMode the SDL_BlendMode to use for blit blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for blit operations. + * + * \param surface the SDL_Surface structure to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode *blendMode); + +/** + * Set the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * Note that blits are automatically clipped to the edges of the source and + * destination surfaces. + * + * \param surface the SDL_Surface structure to be clipped + * \param rect the SDL_Rect structure representing the clipping rectangle, or + * NULL to disable clipping + * \returns SDL_TRUE if the rectangle intersects the surface, otherwise + * SDL_FALSE and blits will be completely clipped. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, + const SDL_Rect * rect); + +/** + * Get the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * \param surface the SDL_Surface structure representing the surface to be + * clipped + * \param rect an SDL_Rect structure filled in with the clipping rectangle for + * the surface + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetClipRect + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, + SDL_Rect * rect); + +/* + * Creates a new surface identical to the existing surface. + * + * The returned surface should be freed with SDL_FreeSurface(). + * + * \param surface the surface to duplicate. + * \returns a copy of the surface, or NULL on failure; call SDL_GetError() for + * more information. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_DuplicateSurface(SDL_Surface * surface); + +/** + * Copy an existing surface to a new surface of the specified format. + * + * This function is used to optimize images for faster *repeat* blitting. This + * is accomplished by converting the original and storing the result as a new + * surface. The new, optimized surface can then be used as the source for + * future blits, making them faster. + * + * \param src the existing SDL_Surface structure to convert + * \param fmt the SDL_PixelFormat structure that the new surface is optimized + * for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurfaceFormat + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface + (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); + +/** + * Copy an existing surface to a new surface of the specified format enum. + * + * This function operates just like SDL_ConvertSurface(), but accepts an + * SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, + * it might be easier to call but it doesn't have access to palette + * information for the destination surface, in case that would be important. + * + * \param src the existing SDL_Surface structure to convert + * \param pixel_format the SDL_PixelFormatEnum that the new surface is + * optimized for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurface + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat + (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); + +/** + * Copy a block of pixels of one format to another format. + * + * \param width the width of the block to copy, in pixels + * \param height the height of the block to copy, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with new pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Premultiply the alpha on a block of pixels. + * + * This is safe to use with src == dst, but not for other overlapping areas. + * + * This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. + * + * \param width the width of the block to convert, in pixels + * \param height the height of the block to convert, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with premultiplied pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_PremultiplyAlpha(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Perform a fast fill of a rectangle with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL to fill the entire surface + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRects + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); + +/** + * Perform a fast fill of a set of rectangles with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rects an array of SDL_Rects representing the rectangles to fill. + * \param count the number of rectangles in the array + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRect + */ +extern DECLSPEC int SDLCALL SDL_FillRects + (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); + +/* !!! FIXME: merge this documentation with the wiki */ +/** + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \returns 0 if the blit is successful, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + */ +#define SDL_BlitSurface SDL_UpperBlit + +/** + * Perform a fast blit from the source surface to the destination surface. + * + * SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a + * macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface blitting only. + * + * This is a semi-private blit function and it performs low-level surface + * blitting, assuming the input rectangles have already been clipped. + * + * Unless you know what you're doing, you should be using SDL_BlitSurface() + * instead. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied, or NULL to copy the entire surface + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + + +/** + * Perform a fast, low quality, stretch blit between two surfaces of the same + * format. + * + * Please use SDL_BlitScaled() instead. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + +/** + * Perform bilinear scaling between two surfaces of the same format, 32BPP. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + + +#define SDL_BlitScaled SDL_UpperBlitScaled + +/** + * Perform a scaled surface copy to a destination surface. + * + * SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is + * merely a macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_UpperBlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface scaled blitting only. + * + * This is a semi-private function and it performs low-level surface blitting, + * assuming the input rectangles have already been clipped. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_LowerBlitScaled + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Set the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode); + +/** + * Get the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void); + +/** + * Get the YUV conversion mode, returning the correct mode for the resolution + * when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_surface_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_system.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_system.h new file mode 100644 index 000000000..e2fa7b5fe --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_system.h @@ -0,0 +1,563 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef SDL_system_h_ +#define SDL_system_h_ + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#ifdef __WIN32__ + +typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); + +/** + * Set a callback for every Windows message, run before TranslateMessage(). + * + * \param callback The SDL_WindowsMessageHook function to call. + * \param userdata a pointer to pass to every iteration of `callback` + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); + +/** + * Get the D3D9 adapter index that matches the specified display index. + * + * The returned adapter index can be passed to `IDirect3D9::CreateDevice` and + * controls on which monitor a full screen application will appear. + * + * \param displayIndex the display index for which to get the D3D9 adapter + * index + * \returns the D3D9 adapter index on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +typedef struct IDirect3DDevice9 IDirect3DDevice9; + +/** + * Get the D3D9 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D device + * \returns the D3D9 device associated with given renderer or NULL if it is + * not a D3D9 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +typedef struct ID3D11Device ID3D11Device; + +/** + * Get the D3D11 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D11 device + * \returns the D3D11 device associated with given renderer or NULL if it is + * not a D3D11 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC ID3D11Device* SDLCALL SDL_RenderGetD3D11Device(SDL_Renderer * renderer); + +/** + * Get the DXGI Adapter and Output indices for the specified display index. + * + * The DXGI Adapter and Output indices can be passed to `EnumAdapters` and + * `EnumOutputs` respectively to get the objects required to create a DX10 or + * DX11 device and swap chain. + * + * Before SDL 2.0.4 this function did not return a value. Since SDL 2.0.4 it + * returns an SDL_bool. + * + * \param displayIndex the display index for which to get both indices + * \param adapterIndex a pointer to be filled in with the adapter index + * \param outputIndex a pointer to be filled in with the output index + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); + +#endif /* __WIN32__ */ + + +/* Platform specific functions for Linux */ +#ifdef __LINUX__ + +/** + * Sets the UNIX nice value for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID the Unix thread ID to change priority of. + * \param priority The new, Unix-specific, priority value. + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority); + +/** + * Sets the priority (not nice level) and scheduling policy for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID The Unix thread ID to change priority of. + * \param sdlPriority The new SDL_ThreadPriority value. + * \param schedPolicy The new scheduling policy (SCHED_FIFO, SCHED_RR, + * SCHED_OTHER, etc...) + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy); + +#endif /* __LINUX__ */ + +/* Platform specific functions for iOS */ +#ifdef __IPHONEOS__ + +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) + +/** + * Use this function to set the animation callback on Apple iOS. + * + * The function prototype for `callback` is: + * + * ```c + * void callback(void* callbackParam); + * ``` + * + * Where its parameter, `callbackParam`, is what was passed as `callbackParam` + * to SDL_iPhoneSetAnimationCallback(). + * + * This function is only available on Apple iOS. + * + * For more information see: + * [README-ios.md](https://hg.libsdl.org/SDL/file/default/docs/README-ios.md) + * + * This functions is also accessible using the macro + * SDL_iOSSetAnimationCallback() since SDL 2.0.4. + * + * \param window the window for which the animation callback should be set + * \param interval the number of frames after which **callback** will be + * called + * \param callback the function to call for every frame. + * \param callbackParam a pointer that is passed to `callback`. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetEventPump + */ +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); + +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) + +/** + * Use this function to enable or disable the SDL event pump on Apple iOS. + * + * This function is only available on Apple iOS. + * + * This functions is also accessible using the macro SDL_iOSSetEventPump() + * since SDL 2.0.4. + * + * \param enabled SDL_TRUE to enable the event pump, SDL_FALSE to disable it + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetAnimationCallback + */ +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#ifdef __ANDROID__ + +/** + * Get the Android Java Native Interface Environment of the current thread. + * + * This is the JNIEnv one needs to access the Java virtual machine from native + * code, and is needed for many Android APIs to be usable from C. + * + * The prototype of the function in SDL's code actually declare a void* return + * type, even if the implementation returns a pointer to a JNIEnv. The + * rationale being that the SDL headers can avoid including jni.h. + * + * \returns a pointer to Java native interface object (JNIEnv) to which the + * current thread is attached, or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetActivity + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void); + +/** + * Retrieve the Java instance of the Android activity class. + * + * The prototype of the function in SDL's code actually declares a void* + * return type, even if the implementation returns a jobject. The rationale + * being that the SDL headers can avoid including jni.h. + * + * The jobject returned by the function is a local reference and must be + * released by the caller. See the PushLocalFrame() and PopLocalFrame() or + * DeleteLocalRef() functions of the Java native interface: + * + * https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html + * + * \returns the jobject representing the instance of the Activity class of the + * Android application, or NULL on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetJNIEnv + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void); + +/** + * Query Android API level of the current device. + * + * - API level 31: Android 12 + * - API level 30: Android 11 + * - API level 29: Android 10 + * - API level 28: Android 9 + * - API level 27: Android 8.1 + * - API level 26: Android 8.0 + * - API level 25: Android 7.1 + * - API level 24: Android 7.0 + * - API level 23: Android 6.0 + * - API level 22: Android 5.1 + * - API level 21: Android 5.0 + * - API level 20: Android 4.4W + * - API level 19: Android 4.4 + * - API level 18: Android 4.3 + * - API level 17: Android 4.2 + * - API level 16: Android 4.1 + * - API level 15: Android 4.0.3 + * - API level 14: Android 4.0 + * - API level 13: Android 3.2 + * - API level 12: Android 3.1 + * - API level 11: Android 3.0 + * - API level 10: Android 2.3.3 + * + * \returns the Android API level. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void); + +/** + * Query if the application is running on Android TV. + * + * \returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void); + +/** + * Query if the application is running on a Chromebook. + * + * \returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void); + +/** + * Query if the application is running on a Samsung DeX docking station. + * + * \returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); + +/** + * Trigger the Android system back button behavior. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void); + +/** + See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/** + * Get the path used for internal storage for this application. + * + * This path is unique to your application and cannot be written to by other + * applications. + * + * Your internal storage path is typically: + * `/data/data/your.app.package/files`. + * + * \returns the path used for internal storage or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void); + +/** + * Get the current state of external storage. + * + * The current state of external storage, a bitmask of these values: + * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`. + * + * If external storage is currently unavailable, this will return 0. + * + * \returns the current state of external storage on success or 0 on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStoragePath + */ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(void); + +/** + * Get the path used for external storage for this application. + * + * This path is unique to your application, but is public and can be written + * to by other applications. + * + * Your external storage path is typically: + * `/storage/sdcard0/Android/data/your.app.package/files`. + * + * \returns the path used for external storage for this application on success + * or NULL on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void); + +/** + * Request permissions at runtime. + * + * This blocks the calling thread until the permission is granted or denied. + * + * \param permission The permission to request. + * \returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AndroidRequestPermission(const char *permission); + +/** + * Shows an Android toast notification. + * + * Toasts are a sort of lightweight notification that are unique to Android. + * + * https://developer.android.com/guide/topics/ui/notifiers/toasts + * + * Shows toast in UI thread. + * + * For the `gravity` parameter, choose a value from here, or -1 if you don't + * have a preference: + * + * https://developer.android.com/reference/android/view/Gravity + * + * \param message text message to be shown + * \param duration 0=short, 1=long + * \param gravity where the notification should appear on the screen. + * \param xoffset set this parameter only when gravity >=0 + * \param yoffset set this parameter only when gravity >=0 + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int duration, int gravity, int xoffset, int yoffset); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#ifdef __WINRT__ + +/** + * \brief WinRT / Windows Phone path types + */ +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, + + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, + + /** \brief The app's roaming data store. Unsupported on Windows Phone. + Files written here may be copied to other machines via a network + connection. + */ + SDL_WINRT_PATH_ROAMING_FOLDER, + + /** \brief The app's temporary data store. Unsupported on Windows Phone. + Files written here may be deleted at any time. */ + SDL_WINRT_PATH_TEMP_FOLDER +} SDL_WinRT_Path; + + +/** + * \brief WinRT Device Family + */ +typedef enum +{ + /** \brief Unknown family */ + SDL_WINRT_DEVICEFAMILY_UNKNOWN, + + /** \brief Desktop family*/ + SDL_WINRT_DEVICEFAMILY_DESKTOP, + + /** \brief Mobile family (for example smartphone) */ + SDL_WINRT_DEVICEFAMILY_MOBILE, + + /** \brief XBox family */ + SDL_WINRT_DEVICEFAMILY_XBOX, +} SDL_WinRT_DeviceFamily; + + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UCS-2 string (16-bit, wide-char) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUTF8 + */ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UTF-8 string (8-bit, multi-byte) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUNICODE + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); + +/** + * Detects the device family of WinRT plattform at runtime. + * + * \returns a value from the SDL_WinRT_DeviceFamily enum. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); + +#endif /* __WINRT__ */ + +/** + * Query if the current device is a tablet. + * + * If SDL can't determine this, it will return SDL_FALSE. + * + * \returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void); + +/* Functions used by iOS application delegates to notify SDL about state changes */ +extern DECLSPEC void SDLCALL SDL_OnApplicationWillTerminate(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidReceiveMemoryWarning(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillResignActive(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidEnterBackground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillEnterForeground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidBecomeActive(void); +#ifdef __IPHONEOS__ +extern DECLSPEC void SDLCALL SDL_OnApplicationDidChangeStatusBarOrientation(void); +#endif + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_system_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_syswm.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_syswm.h new file mode 100644 index 000000000..f7cd670cd --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_syswm.h @@ -0,0 +1,384 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_syswm.h + * + * Include file for SDL custom system window manager hooks. + */ + +#ifndef SDL_syswm_h_ +#define SDL_syswm_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_version.h" + +/** + * \brief SDL_syswm.h + * + * Your application has access to a special type of event ::SDL_SYSWMEVENT, + * which contains window-manager specific information and arrives whenever + * an unhandled window event occurs. This event is ignored by default, but + * you can enable it with SDL_EventState(). + */ +struct SDL_SysWMinfo; + +#if !defined(SDL_PROTOTYPES_ONLY) + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + +/* This is the structure for custom window manager events */ +#if defined(SDL_VIDEO_DRIVER_X11) +#if defined(__APPLE__) && defined(__MACH__) +/* conflicts with Quickdraw.h */ +#define Cursor X11Cursor +#endif + +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +/* matches the re-define above */ +#undef Cursor +#endif + +#endif /* defined(SDL_VIDEO_DRIVER_X11) */ + +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_COCOA) +#ifdef __OBJC__ +@class NSWindow; +#else +typedef struct _NSWindow NSWindow; +#endif +#endif + +#if defined(SDL_VIDEO_DRIVER_UIKIT) +#ifdef __OBJC__ +#include +#else +typedef struct _UIWindow UIWindow; +typedef struct _UIViewController UIViewController; +#endif +typedef Uint32 GLuint; +#endif + +#if defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL) +#define SDL_METALVIEW_TAG 255 +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) +typedef struct ANativeWindow ANativeWindow; +typedef void *EGLSurface; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) +#include "SDL_egl.h" +#endif + +#if defined(SDL_VIDEO_DRIVER_OS2) +#define INCL_WIN +#include +#endif +#endif /* SDL_PROTOTYPES_ONLY */ + +#if defined(SDL_VIDEO_DRIVER_KMSDRM) +struct gbm_device; +#endif + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(SDL_PROTOTYPES_ONLY) +/** + * These are the various supported windowing subsystems + */ +typedef enum +{ + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE, + SDL_SYSWM_OS2, + SDL_SYSWM_HAIKU, + SDL_SYSWM_KMSDRM, + SDL_SYSWM_RISCOS +} SDL_SYSWM_TYPE; + +/** + * The custom event structure. + */ +struct SDL_SysWMmsg +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct { + HWND hwnd; /**< The window for the message */ + UINT msg; /**< The type of message */ + WPARAM wParam; /**< WORD message parameter */ + LPARAM lParam; /**< LONG message parameter */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct { + XEvent event; + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct { + DFBEvent event; + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { + /* Latest version of Xcode clang complains about empty structs in C v. C++: + error: empty struct has size 0 in C, size 1 in C++ + */ + int dummy; + /* No Cocoa window events yet */ + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { + int dummy; + /* No UIKit window events yet */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + int dummy; + /* No Vivante window events yet */ + } vivante; +#endif +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + BOOL fFrame; /**< TRUE if hwnd is a frame window */ + HWND hwnd; /**< The window receiving the message */ + ULONG msg; /**< The message identifier */ + MPARAM mp1; /**< The first first message parameter */ + MPARAM mp2; /**< The second first message parameter */ + } os2; +#endif + /* Can't have an empty union */ + int dummy; + } msg; +}; + +/** + * The custom window manager information structure. + * + * When this structure is returned, it holds information about which + * low level system it is using, and will be one of SDL_SYSWM_TYPE. + */ +struct SDL_SysWMinfo +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct + { + HWND window; /**< The window handle */ + HDC hdc; /**< The window device context */ + HINSTANCE hinstance; /**< The instance handle */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + struct + { + IInspectable * window; /**< The WinRT CoreWindow */ + } winrt; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct + { + Display *display; /**< The X11 display */ + Window window; /**< The X11 window */ + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct + { + IDirectFB *dfb; /**< The directfb main interface */ + IDirectFBWindow *window; /**< The directfb window handle */ + IDirectFBSurface *surface; /**< The directfb client surface */ + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) + NSWindow __unsafe_unretained *window; /**< The Cocoa window */ + #else + NSWindow *window; /**< The Cocoa window */ + #endif +#else + NSWindow *window; /**< The Cocoa window */ +#endif + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) + UIWindow __unsafe_unretained *window; /**< The UIKit window */ + #else + UIWindow *window; /**< The UIKit window */ + #endif +#else + UIWindow *window; /**< The UIKit window */ +#endif + GLuint framebuffer; /**< The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. */ + GLuint colorbuffer; /**< The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. */ + GLuint resolveFramebuffer; /**< The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + struct + { + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ + void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */ + struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ + struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */ + struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */ + } wl; +#endif +#if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + struct + { + void *connection; /**< Mir display server connection */ + void *surface; /**< Mir surface */ + } mir; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) + struct + { + ANativeWindow *window; + EGLSurface surface; + } android; +#endif + +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + HWND hwnd; /**< The window handle */ + HWND hwndFrame; /**< The frame window handle */ + } os2; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + EGLNativeDisplayType display; + EGLNativeWindowType window; + } vivante; +#endif + +#if defined(SDL_VIDEO_DRIVER_KMSDRM) + struct + { + int dev_index; /**< Device index (ex: the X in /dev/dri/cardX) */ + int drm_fd; /**< DRM FD (unavailable on Vulkan windows) */ + struct gbm_device *gbm_dev; /**< GBM device (unavailable on Vulkan windows) */ + } kmsdrm; +#endif + + /* Make sure this union is always 64 bytes (8 64-bit pointers). */ + /* Be careful not to overflow this if you add a new target! */ + Uint8 dummy[64]; + } info; +}; + +#endif /* SDL_PROTOTYPES_ONLY */ + +typedef struct SDL_SysWMinfo SDL_SysWMinfo; + + +/** + * Get driver-specific information about a window. + * + * You must include SDL_syswm.h for the declaration of SDL_SysWMinfo. + * + * The caller must initialize the `info` structure's version by using + * `SDL_VERSION(&info.version)`, and then this function will fill in the rest + * of the structure with information about the given window. + * + * \param window the window about which information is being requested + * \param info an SDL_SysWMinfo structure filled in with window information + * \returns SDL_TRUE if the function is implemented and the `version` member + * of the `info` struct is valid, or SDL_FALSE if the information + * could not be retrieved; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, + SDL_SysWMinfo * info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_syswm_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test.h new file mode 100644 index 000000000..8cc9d616a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_h_ +#define SDL_test_h_ + +#include "SDL.h" +#include "SDL_test_assert.h" +#include "SDL_test_common.h" +#include "SDL_test_compare.h" +#include "SDL_test_crc32.h" +#include "SDL_test_font.h" +#include "SDL_test_fuzzer.h" +#include "SDL_test_harness.h" +#include "SDL_test_images.h" +#include "SDL_test_log.h" +#include "SDL_test_md5.h" +#include "SDL_test_memory.h" +#include "SDL_test_random.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Global definitions */ + +/* + * Note: Maximum size of SDLTest log message is less than SDL's limit + * to ensure we can fit additional information such as the timestamp. + */ +#define SDLTEST_MAX_LOGMESSAGE_LENGTH 3584 + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_assert.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_assert.h new file mode 100644 index 000000000..734230529 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_assert.h @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_assert.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Assert API for test code and test cases + * + */ + +#ifndef SDL_test_assert_h_ +#define SDL_test_assert_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Fails the assert. + */ +#define ASSERT_FAIL 0 + +/** + * \brief Passes the assert. + */ +#define ASSERT_PASS 1 + +/** + * \brief Assert that logs and break execution flow on failures. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Assert for test cases that logs but does not break execution flow on failures. Updates assertion counters. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + * + * \returns the assertCondition so it can be used to externally to break execution flow if desired. + */ +int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Explicitly pass without checking an assertion condition. Updates assertion counter. + * + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Resets the assert summary counters to zero. + */ +void SDLTest_ResetAssertSummary(void); + +/** + * \brief Logs summary of all assertions (total, pass, fail) since last reset as INFO or ERROR. + */ +void SDLTest_LogAssertSummary(void); + + +/** + * \brief Converts the current assert summary state to a test result. + * + * \returns TEST_RESULT_PASSED, TEST_RESULT_FAILED, or TEST_RESULT_NO_ASSERT + */ +int SDLTest_AssertSummaryToTestResult(void); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_assert_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_common.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_common.h new file mode 100644 index 000000000..0f5096789 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_common.h @@ -0,0 +1,235 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_common.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* Ported from original test\common.h file. */ + +#ifndef SDL_test_common_h_ +#define SDL_test_common_h_ + +#include "SDL.h" + +#if defined(__PSP__) +#define DEFAULT_WINDOW_WIDTH 480 +#define DEFAULT_WINDOW_HEIGHT 272 +#elif defined(__VITA__) +#define DEFAULT_WINDOW_WIDTH 960 +#define DEFAULT_WINDOW_HEIGHT 544 +#else +#define DEFAULT_WINDOW_WIDTH 640 +#define DEFAULT_WINDOW_HEIGHT 480 +#endif + +#define VERBOSE_VIDEO 0x00000001 +#define VERBOSE_MODES 0x00000002 +#define VERBOSE_RENDER 0x00000004 +#define VERBOSE_EVENT 0x00000008 +#define VERBOSE_AUDIO 0x00000010 + +typedef struct +{ + /* SDL init flags */ + char **argv; + Uint32 flags; + Uint32 verbose; + + /* Video info */ + const char *videodriver; + int display; + const char *window_title; + const char *window_icon; + Uint32 window_flags; + SDL_bool flash_on_focus_loss; + int window_x; + int window_y; + int window_w; + int window_h; + int window_minW; + int window_minH; + int window_maxW; + int window_maxH; + int logical_w; + int logical_h; + float scale; + int depth; + int refresh_rate; + int num_windows; + SDL_Window **windows; + + /* Renderer info */ + const char *renderdriver; + Uint32 render_flags; + SDL_bool skip_renderer; + SDL_Renderer **renderers; + SDL_Texture **targets; + + /* Audio info */ + const char *audiodriver; + SDL_AudioSpec audiospec; + + /* GL settings */ + int gl_red_size; + int gl_green_size; + int gl_blue_size; + int gl_alpha_size; + int gl_buffer_size; + int gl_depth_size; + int gl_stencil_size; + int gl_double_buffer; + int gl_accum_red_size; + int gl_accum_green_size; + int gl_accum_blue_size; + int gl_accum_alpha_size; + int gl_stereo; + int gl_multisamplebuffers; + int gl_multisamplesamples; + int gl_retained_backing; + int gl_accelerated; + int gl_major_version; + int gl_minor_version; + int gl_debug; + int gl_profile_mask; + + /* Additional fields added in 2.0.18 */ + SDL_Rect confine; + +} SDLTest_CommonState; + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * \brief Parse command line parameters and create common state. + * + * \param argv Array of command line parameters + * \param flags Flags indicating which subsystem to initialize (i.e. SDL_INIT_VIDEO | SDL_INIT_AUDIO) + * + * \returns a newly allocated common state object. + */ +SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); + +/** + * \brief Process one common argument. + * + * \param state The common state describing the test window to create. + * \param index The index of the argument to process in argv[]. + * + * \returns the number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. + */ +int SDLTest_CommonArg(SDLTest_CommonState * state, int index); + + +/** + * \brief Logs command line usage info. + * + * This logs the appropriate command line options for the subsystems in use + * plus other common options, and then any application-specific options. + * This uses the SDL_Log() function and splits up output to be friendly to + * 80-character-wide terminals. + * + * \param state The common state describing the test window for the app. + * \param argv0 argv[0], as passed to main/SDL_main. + * \param options an array of strings for application specific options. The last element of the array should be NULL. + */ +void SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, const char **options); + +/** + * \brief Returns common usage information + * + * You should (probably) be using SDLTest_CommonLogUsage() instead, but this + * function remains for binary compatibility. Strings returned from this + * function are valid until SDLTest_CommonQuit() is called, in which case + * those strings' memory is freed and can no longer be used. + * + * \param state The common state describing the test window to create. + * \returns a string with usage information + */ +const char *SDLTest_CommonUsage(SDLTest_CommonState * state); + +/** + * \brief Open test window. + * + * \param state The common state describing the test window to create. + * + * \returns SDL_TRUE if initialization succeeded, false otherwise + */ +SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); + +/** + * \brief Easy argument handling when test app doesn't need any custom args. + * + * \param state The common state describing the test window to create. + * \param argc argc, as supplied to SDL_main + * \param argv argv, as supplied to SDL_main + * + * \returns SDL_FALSE if app should quit, true otherwise. + */ +SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState * state, const int argc, char **argv); + +/** + * \brief Common event handler for test windows. + * + * \param state The common state used to create test window. + * \param event The event to handle. + * \param done Flag indicating we are done. + * + */ +void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done); + +/** + * \brief Close test window. + * + * \param state The common state used to create test window. + * + */ +void SDLTest_CommonQuit(SDLTest_CommonState * state); + +/** + * \brief Draws various window information (position, size, etc.) to the renderer. + * + * \param renderer The renderer to draw to. + * \param window The window whose information should be displayed. + * \param usedHeight Returns the height used, so the caller can draw more below. + * + */ +void SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * usedHeight); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_common_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_compare.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_compare.h new file mode 100644 index 000000000..8a7a07008 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_compare.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_compare.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines comparison functions (i.e. for surfaces). + +*/ + +#ifndef SDL_test_compare_h_ +#define SDL_test_compare_h_ + +#include "SDL.h" + +#include "SDL_test_images.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compares a surface and with reference image data for equality + * + * \param surface Surface used in comparison + * \param referenceSurface Test Surface used in comparison + * \param allowable_error Allowable difference (=sum of squared difference for each RGB component) in blending accuracy. + * + * \returns 0 if comparison succeeded, >0 (=number of pixels for which the comparison failed) if comparison failed, -1 if any of the surfaces were NULL, -2 if the surface sizes differ. + */ +int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_compare_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_crc32.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_crc32.h new file mode 100644 index 000000000..049da7406 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_crc32.h @@ -0,0 +1,124 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_crc32.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Implements CRC32 calculations (default output is Perl String::CRC32 compatible). + +*/ + +#ifndef SDL_test_crc32_h_ +#define SDL_test_crc32_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ------------ Definitions --------- */ + +/* Definition shared by all CRC routines */ + +#ifndef CrcUint32 + #define CrcUint32 unsigned int +#endif +#ifndef CrcUint8 + #define CrcUint8 unsigned char +#endif + +#ifdef ORIGINAL_METHOD + #define CRC32_POLY 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */ +#else + #define CRC32_POLY 0xEDB88320 /* Perl String::CRC32 compatible */ +#endif + +/** + * Data structure for CRC32 (checksum) computation + */ + typedef struct { + CrcUint32 crc32_table[256]; /* CRC table */ + } SDLTest_Crc32Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief Initialize the CRC context + * + * Note: The function initializes the crc table required for all crc calculations. + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * + */ + int SDLTest_Crc32Init(SDLTest_Crc32Context * crcContext); + + +/** + * \brief calculate a crc32 from a data block + * + * \param crcContext pointer to context variable + * \param inBuf input buffer to checksum + * \param inLen length of input buffer + * \param crc32 pointer to Uint32 to store the final CRC into + * + * \returns 0 for OK, -1 on error + * + */ +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + +/* Same routine broken down into three steps */ +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + + +/** + * \brief clean up CRC context + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * +*/ + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_crc32_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_font.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_font.h new file mode 100644 index 000000000..c5cbbbbd3 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_font.h @@ -0,0 +1,81 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_font.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_font_h_ +#define SDL_test_font_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +#define FONT_CHARACTER_SIZE 8 + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the character. + * \param y The Y coordinate of the upper left corner of the character. + * \param c The character to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c); + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the string. + * \param y The Y coordinate of the upper left corner of the string. + * \param s The string to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawString(SDL_Renderer *renderer, int x, int y, const char *s); + + +/** + * \brief Cleanup textures used by font drawing functions. + */ +void SDLTest_CleanupTextDrawing(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_font_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_fuzzer.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_fuzzer.h new file mode 100644 index 000000000..bbe8eb874 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_fuzzer.h @@ -0,0 +1,386 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_fuzzer.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Data generators for fuzzing test data in a reproducible way. + +*/ + +#ifndef SDL_test_fuzzer_h_ +#define SDL_test_fuzzer_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* + Based on GSOC code by Markus Kauppila +*/ + + +/** + * \file + * Note: The fuzzer implementation uses a static instance of random context + * internally which makes it thread-UNsafe. + */ + +/** + * Initializes the fuzzer for a test + * + * \param execKey Execution "Key" that initializes the random number generator uniquely for the test. + * + */ +void SDLTest_FuzzerInit(Uint64 execKey); + + +/** + * Returns a random Uint8 + * + * \returns a generated integer + */ +Uint8 SDLTest_RandomUint8(void); + +/** + * Returns a random Sint8 + * + * \returns a generated signed integer + */ +Sint8 SDLTest_RandomSint8(void); + + +/** + * Returns a random Uint16 + * + * \returns a generated integer + */ +Uint16 SDLTest_RandomUint16(void); + +/** + * Returns a random Sint16 + * + * \returns a generated signed integer + */ +Sint16 SDLTest_RandomSint16(void); + + +/** + * Returns a random integer + * + * \returns a generated integer + */ +Sint32 SDLTest_RandomSint32(void); + + +/** + * Returns a random positive integer + * + * \returns a generated integer + */ +Uint32 SDLTest_RandomUint32(void); + +/** + * Returns random Uint64. + * + * \returns a generated integer + */ +Uint64 SDLTest_RandomUint64(void); + + +/** + * Returns random Sint64. + * + * \returns a generated signed integer + */ +Sint64 SDLTest_RandomSint64(void); + +/** + * \returns a random float in range [0.0 - 1.0] + */ +float SDLTest_RandomUnitFloat(void); + +/** + * \returns a random double in range [0.0 - 1.0] + */ +double SDLTest_RandomUnitDouble(void); + +/** + * \returns a random float. + * + */ +float SDLTest_RandomFloat(void); + +/** + * \returns a random double. + * + */ +double SDLTest_RandomDouble(void); + +/** + * Returns a random boundary value for Uint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint8BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint8BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint8BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint8BoundaryValue(0, 255, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint16BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint16BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint16BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint16BoundaryValue(0, 0xFFFF, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint32BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint32BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint32BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint32BoundaryValue(0, 0xFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint64BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint64BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint64BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint64BoundaryValue(0, 0xFFFFFFFFFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or 0 with error set + */ +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint8BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint8BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint8BoundaryValue(SINT8_MIN, 99, SDL_FALSE) returns 100 + * RandomSint8BoundaryValue(SINT8_MIN, SINT8_MAX, SDL_FALSE) returns SINT8_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT8_MIN with error set + */ +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain); + + +/** + * Returns a random boundary value for Sint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint16BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint16BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint16BoundaryValue(SINT16_MIN, 99, SDL_FALSE) returns 100 + * RandomSint16BoundaryValue(SINT16_MIN, SINT16_MAX, SDL_FALSE) returns SINT16_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT16_MIN with error set + */ +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint32BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint32BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint32BoundaryValue(SINT32_MIN, 99, SDL_FALSE) returns 100 + * RandomSint32BoundaryValue(SINT32_MIN, SINT32_MAX, SDL_FALSE) returns SINT32_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT32_MIN with error set + */ +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint64BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint64BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint64BoundaryValue(SINT64_MIN, 99, SDL_FALSE) returns 100 + * RandomSint64BoundaryValue(SINT64_MIN, SINT64_MAX, SDL_FALSE) returns SINT64_MIN (== error value) and error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns a random boundary value for the given range and domain or SINT64_MIN with error set + */ +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain); + + +/** + * Returns integer in range [min, max] (inclusive). + * Min and max values can be negative values. + * If Max in smaller than min, then the values are swapped. + * Min and max are the same value, that value will be returned. + * + * \param min Minimum inclusive value of returned random number + * \param max Maximum inclusive value of returned random number + * + * \returns a generated random integer in range + */ +Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); + + +/** + * Generates random null-terminated string. The minimum length for + * the string is 1 character, maximum length for the string is 255 + * characters and it can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \returns a newly allocated random string; or NULL if length was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiString(void); + + +/** + * Generates random null-terminated string. The maximum length for + * the string is defined by the maxLength parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param maxLength The maximum length of the generated string. + * + * \returns a newly allocated random string; or NULL if maxLength was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); + + +/** + * Generates random null-terminated string. The length for + * the string is defined by the size parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param size The length of the generated string + * + * \returns a newly allocated random string; or NULL if size was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringOfSize(int size); + +/** + * Get the invocation count for the fuzzer since last ...FuzzerInit. + * + * \returns the invocation count. + */ +int SDLTest_GetFuzzerInvocationCount(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_fuzzer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_harness.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_harness.h new file mode 100644 index 000000000..1fd4236be --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_harness.h @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_harness.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + Defines types for test case definitions and the test execution harness API. + + Based on original GSOC code by Markus Kauppila +*/ + +#ifndef SDL_test_h_arness_h +#define SDL_test_h_arness_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ! Definitions for test case structures */ +#define TEST_ENABLED 1 +#define TEST_DISABLED 0 + +/* ! Definition of all the possible test return values of the test case method */ +#define TEST_ABORTED -1 +#define TEST_STARTED 0 +#define TEST_COMPLETED 1 +#define TEST_SKIPPED 2 + +/* ! Definition of all the possible test results for the harness */ +#define TEST_RESULT_PASSED 0 +#define TEST_RESULT_FAILED 1 +#define TEST_RESULT_NO_ASSERT 2 +#define TEST_RESULT_SKIPPED 3 +#define TEST_RESULT_SETUP_FAILURE 4 + +/* !< Function pointer to a test case setup function (run before every test) */ +typedef void (*SDLTest_TestCaseSetUpFp)(void *arg); + +/* !< Function pointer to a test case function */ +typedef int (*SDLTest_TestCaseFp)(void *arg); + +/* !< Function pointer to a test case teardown function (run after every test) */ +typedef void (*SDLTest_TestCaseTearDownFp)(void *arg); + +/** + * Holds information about a single test case. + */ +typedef struct SDLTest_TestCaseReference { + /* !< Func2Stress */ + SDLTest_TestCaseFp testCase; + /* !< Short name (or function name) "Func2Stress" */ + const char *name; + /* !< Long name or full description "This test pushes func2() to the limit." */ + const char *description; + /* !< Set to TEST_ENABLED or TEST_DISABLED (test won't be run) */ + int enabled; +} SDLTest_TestCaseReference; + +/** + * Holds information about a test suite (multiple test cases). + */ +typedef struct SDLTest_TestSuiteReference { + /* !< "PlatformSuite" */ + const char *name; + /* !< The function that is run before each test. NULL skips. */ + SDLTest_TestCaseSetUpFp testSetUp; + /* !< The test cases that are run as part of the suite. Last item should be NULL. */ + const SDLTest_TestCaseReference **testCases; + /* !< The function that is run after each test. NULL skips. */ + SDLTest_TestCaseTearDownFp testTearDown; +} SDLTest_TestSuiteReference; + + +/** + * \brief Generates a random run seed string for the harness. The generated seed will contain alphanumeric characters (0-9A-Z). + * + * Note: The returned string needs to be deallocated by the caller. + * + * \param length The length of the seed string to generate + * + * \returns the generated seed string + */ +char *SDLTest_GenerateRunSeed(const int length); + +/** + * \brief Execute a test suite using the given run seed and execution key. + * + * \param testSuites Suites containing the test case. + * \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. + * \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. + * \param filter Filter specification. NULL disables. Case sensitive. + * \param testIterations Number of iterations to run each test case. + * + * \returns the test run result: 0 when all tests passed, 1 if any tests failed. + */ +int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_h_arness_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_images.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_images.h new file mode 100644 index 000000000..e2bfc3600 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_images.h @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_images.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines some images for tests. + +*/ + +#ifndef SDL_test_images_h_ +#define SDL_test_images_h_ + +#include "SDL.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + *Type for test images. + */ +typedef struct SDLTest_SurfaceImage_s { + int width; + int height; + unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ + const char *pixel_data; +} SDLTest_SurfaceImage_t; + +/* Test images */ +SDL_Surface *SDLTest_ImageBlit(void); +SDL_Surface *SDLTest_ImageBlitColor(void); +SDL_Surface *SDLTest_ImageBlitAlpha(void); +SDL_Surface *SDLTest_ImageBlitBlendAdd(void); +SDL_Surface *SDLTest_ImageBlitBlend(void); +SDL_Surface *SDLTest_ImageBlitBlendMod(void); +SDL_Surface *SDLTest_ImageBlitBlendNone(void); +SDL_Surface *SDLTest_ImageBlitBlendAll(void); +SDL_Surface *SDLTest_ImageFace(void); +SDL_Surface *SDLTest_ImagePrimitives(void); +SDL_Surface *SDLTest_ImagePrimitivesBlend(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_images_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_log.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_log.h new file mode 100644 index 000000000..e3d39ad27 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_log.h @@ -0,0 +1,67 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_log.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Wrapper to log in the TEST category + * + */ + +#ifndef SDL_test_log_h_ +#define SDL_test_log_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Prints given message with a timestamp in the TEST category and INFO priority. + * + * \param fmt Message to be logged + */ +void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Prints given message with a timestamp in the TEST category and the ERROR priority. + * + * \param fmt Message to be logged + */ +void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_md5.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_md5.h new file mode 100644 index 000000000..17b1d2be7 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_md5.h @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_md5.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + *********************************************************************** + ** Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** +*/ + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** +*/ + +#ifndef SDL_test_md5_h_ +#define SDL_test_md5_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------ Definitions --------- */ + +/* typedef a 32-bit type */ + typedef unsigned long int MD5UINT4; + +/* Data structure for MD5 (Message-Digest) computation */ + typedef struct { + MD5UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + MD5UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after Md5Final call */ + } SDLTest_Md5Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief initialize the context + * + * \param mdContext pointer to context variable + * + * Note: The function initializes the message-digest context + * mdContext. Call before each new use of the context - + * all fields are set to zero. + */ + void SDLTest_Md5Init(SDLTest_Md5Context * mdContext); + + +/** + * \brief update digest from variable length data + * + * \param mdContext pointer to context variable + * \param inBuf pointer to data array/string + * \param inLen length of data array/string + * + * Note: The function updates the message-digest context to account + * for the presence of each of the characters inBuf[0..inLen-1] + * in the message whose digest is being computed. +*/ + + void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf, + unsigned int inLen); + + +/** + * \brief complete digest computation + * + * \param mdContext pointer to context variable + * + * Note: The function terminates the message-digest computation and + * ends with the desired message digest in mdContext.digest[0..15]. + * Always call before using the digest[] variable. +*/ + + void SDLTest_Md5Final(SDLTest_Md5Context * mdContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_md5_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_memory.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_memory.h new file mode 100644 index 000000000..cc2edc1b9 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_memory.h @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_memory.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_memory_h_ +#define SDL_test_memory_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Start tracking SDL memory allocations + * + * \note This should be called before any other SDL functions for complete tracking coverage + */ +int SDLTest_TrackAllocations(void); + +/** + * \brief Print a log of any outstanding allocations + * + * \note This can be called after SDL_Quit() + */ +void SDLTest_LogAllocations(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_memory_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_random.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_random.h new file mode 100644 index 000000000..b1d6060cb --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_test_random.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_random.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + A "32-bit Multiply with carry random number generator. Very fast. + Includes a list of recommended multipliers. + + multiply-with-carry generator: x(n) = a*x(n-1) + carry mod 2^32. + period: (a*2^31)-1 + +*/ + +#ifndef SDL_test_random_h_ +#define SDL_test_random_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Definitions */ + +/* + * Macros that return a random number in a specific format. + */ +#define SDLTest_RandomInt(c) ((int)SDLTest_Random(c)) + +/* + * Context structure for the random number generator state. + */ + typedef struct { + unsigned int a; + unsigned int x; + unsigned int c; + unsigned int ah; + unsigned int al; + } SDLTest_RandomContext; + + +/* --- Function prototypes */ + +/** + * \brief Initialize random number generator with two integers. + * + * Note: The random sequence of numbers returned by ...Random() is the + * same for the same two integers and has a period of 2^31. + * + * \param rndContext pointer to context structure + * \param xi integer that defines the random sequence + * \param ci integer that defines the random sequence + * + */ + void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi, + unsigned int ci); + +/** + * \brief Initialize random number generator based on current system time. + * + * \param rndContext pointer to context structure + * + */ + void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext); + + +/** + * \brief Initialize random number generator based on current system time. + * + * Note: ...RandomInit() or ...RandomInitTime() must have been called + * before using this function. + * + * \param rndContext pointer to context structure + * + * \returns a random number (32bit unsigned integer) + * + */ + unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_random_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_thread.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_thread.h new file mode 100644 index 000000000..35e680ddf --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_thread.h @@ -0,0 +1,464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_thread_h_ +#define SDL_thread_h_ + +/** + * \file SDL_thread.h + * + * Header for the SDL thread management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_atomic.h" +#include "SDL_mutex.h" + +#if defined(__WIN32__) +#include /* _beginthreadex() and _endthreadex() */ +#endif +#if defined(__OS2__) /* for _beginthread() and _endthread() */ +#ifndef __EMX__ +#include +#else +#include +#endif +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* The SDL thread ID */ +typedef unsigned long SDL_threadID; + +/* Thread local storage ID, 0 is the invalid ID */ +typedef unsigned int SDL_TLSID; + +/** + * The SDL thread priority. + * + * SDL will make system changes as necessary in order to apply the thread priority. + * Code which attempts to control thread state related to priority should be aware + * that calling SDL_SetThreadPriority may alter such state. + * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior. + * + * \note On many systems you require special privileges to set high or time critical priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH, + SDL_THREAD_PRIORITY_TIME_CRITICAL +} SDL_ThreadPriority; + +/** + * The function passed to SDL_CreateThread(). + * + * \param data what was passed as `data` to SDL_CreateThread() + * \returns a value that can be reported through SDL_WaitThread(). + */ +typedef int (SDLCALL * SDL_ThreadFunction) (void *data); + + +#if defined(__WIN32__) +/** + * \file SDL_thread.h + * + * We compile SDL into a DLL. This means, that it's the DLL which + * creates a new thread for the calling process with the SDL_CreateThread() + * API. There is a problem with this, that only the RTL of the SDL2.DLL will + * be initialized for those threads, and not the RTL of the calling + * application! + * + * To solve this, we make a little hack here. + * + * We'll always use the caller's _beginthread() and _endthread() APIs to + * start a new thread. This way, if it's the SDL2.DLL which uses this API, + * then the RTL of SDL2.DLL will be used to create the new thread, and if it's + * the application, then the RTL of the application will be used. + * + * So, in short: + * Always use the _beginthread() and _endthread() of the calling runtime + * library! + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) + (void *, unsigned, unsigned (__stdcall *func)(void *), + void * /*arg*/, unsigned, unsigned * /* threadID */); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthreadex +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthreadex +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#elif defined(__OS2__) +/* + * just like the windows case above: We compile SDL2 + * into a dll with Watcom's runtime statically linked. + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); +typedef void (*pfnSDL_CurrentEndThread)(void); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthread +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthread +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#else + +/** + * Create a new thread with a default stack size. + * + * This is equivalent to calling: + * + * ```c + * SDL_CreateThreadWithStackSize(fn, name, 0, data); + * ``` + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThreadWithStackSize + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); + +/** + * Create a new thread with a specific stack size. + * + * SDL makes an attempt to report `name` to the system, so that debuggers can + * display it. Not all platforms support this. + * + * Thread naming is a little complicated: Most systems have very small limits + * for the string length (Haiku has 32 bytes, Linux currently has 16, Visual + * C++ 6.0 has _nine_!), and possibly other arbitrary rules. You'll have to + * see what happens with your system's debugger. The name should be UTF-8 (but + * using the naming limits of C identifiers is a better bet). There are no + * requirements for thread naming conventions, so long as the string is + * null-terminated UTF-8, but these guidelines are helpful in choosing a name: + * + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for it + * (truncate, etc), but the original string contents will be available from + * SDL_GetThreadName(). + * + * The size (in bytes) of the new stack can be specified. Zero means "use the + * system default" which might be wildly different between platforms. x86 + * Linux generally defaults to eight megabytes, an embedded device might be a + * few kilobytes instead. You generally need to specify a stack that is a + * multiple of the system's page size (in many cases, this is 4 kilobytes, but + * check your system documentation). + * + * In SDL 2.1, stack size will be folded into the original SDL_CreateThread + * function, but for backwards compatibility, this is currently a separate + * function. + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param stacksize the size, in bytes, to allocate for the new thread stack. + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data); + +#endif + +/** + * Get the thread name as it was specified in SDL_CreateThread(). + * + * This is internal memory, not to be freed by the caller, and remains valid + * until the specified thread is cleaned up by SDL_WaitThread(). + * + * \param thread the thread to query + * \returns a pointer to a UTF-8 string that names the specified thread, or + * NULL if it doesn't have a name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + +/** + * Get the thread identifier for the current thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * This function also returns a valid thread ID when called from the main + * thread. + * + * \returns the ID of the current thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); + +/** + * Get the thread identifier for the specified thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * \param thread the thread to query + * \returns the ID of the specified thread, or the ID of the current thread if + * `thread` is NULL. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); + +/** + * Set the priority for the current thread. + * + * Note that some platforms will not let you alter the priority (or at least, + * promote the thread to a higher priority) at all, and some require you to be + * an administrator account. Be prepared for this to fail. + * + * \param priority the SDL_ThreadPriority to set + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); + +/** + * Wait for a thread to finish. + * + * Threads that haven't been detached will remain (as a "zombie") until this + * function cleans them up. Not doing so is a resource leak. + * + * Once a thread has been cleaned up through this function, the SDL_Thread + * that references it becomes invalid and should not be referenced again. As + * such, only one thread may call SDL_WaitThread() on another. + * + * The return code for the thread function is placed in the area pointed to by + * `status`, if `status` is not NULL. + * + * You may not wait on a thread that has been used in a call to + * SDL_DetachThread(). Use either that function or this one, but not both, or + * behavior is undefined. + * + * It is safe to pass a NULL thread to this function; it is a no-op. + * + * Note that the thread pointer is freed by this function and is not valid + * afterward. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * \param status pointer to an integer that will receive the value returned + * from the thread function by its 'return', or NULL to not + * receive such value back. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + * \sa SDL_DetachThread + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); + +/** + * Let a thread clean up on exit without intervention. + * + * A thread may be "detached" to signify that it should not remain until + * another thread has called SDL_WaitThread() on it. Detaching a thread is + * useful for long-running threads that nothing needs to synchronize with or + * further manage. When a detached thread is done, it simply goes away. + * + * There is no way to recover the return code of a detached thread. If you + * need this, don't detach the thread and instead use SDL_WaitThread(). + * + * Once a thread is detached, you should usually assume the SDL_Thread isn't + * safe to reference again, as it will become invalid immediately upon the + * detached thread's exit, instead of remaining until someone has called + * SDL_WaitThread() to finally clean it up. As such, don't detach the same + * thread more than once. + * + * If a thread has already exited when passed to SDL_DetachThread(), it will + * stop waiting for a call to SDL_WaitThread() and clean up immediately. It is + * not safe to detach a thread that might be used with SDL_WaitThread(). + * + * You may not call SDL_WaitThread() on a thread that has been detached. Use + * either that function or this one, but not both, or behavior is undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_CreateThread + * \sa SDL_WaitThread + */ +extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); + +/** + * Create a piece of thread-local storage. + * + * This creates an identifier that is globally visible to all threads but + * refers to data that is thread-specific. + * + * \returns the newly created thread local storage identifier or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSGet + * \sa SDL_TLSSet + */ +extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); + +/** + * Get the current thread's value associated with a thread local storage ID. + * + * \param id the thread local storage ID + * \returns the value associated with the ID for the current thread or NULL if + * no value has been set; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSSet + */ +extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); + +/** + * Set the current thread's value associated with a thread local storage ID. + * + * The function prototype for `destructor` is: + * + * ```c + * void destructor(void *value) + * ``` + * + * where its parameter `value` is what was passed as `value` to SDL_TLSSet(). + * + * \param id the thread local storage ID + * \param value the value to associate with the ID for the current thread + * \param destructor a function called when the thread exits, to free the + * value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSGet + */ +extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); + +/** + * Cleanup all TLS data for this thread. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC void SDLCALL SDL_TLSCleanup(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_thread_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_timer.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_timer.h new file mode 100644 index 000000000..62f81d42d --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_timer.h @@ -0,0 +1,222 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as 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 SDL_timer_h_ +#define SDL_timer_h_ + +/** + * \file SDL_timer.h + * + * Header for the SDL time management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the number of milliseconds since SDL library initialization. + * + * This value wraps if the program runs for more than ~49 days. + * + * This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64() + * instead, where the value doesn't wrap every ~49 days. There are places in + * SDL where we provide a 32-bit timestamp that can not change without + * breaking binary compatibility, though, so this function isn't officially + * deprecated. + * + * \returns an unsigned 32-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TICKS_PASSED + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/** + * Get the number of milliseconds since SDL library initialization. + * + * Note that you should not use the SDL_TICKS_PASSED macro with values + * returned by this function, as that macro does clever math to compensate for + * the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit + * values from this function can be safely compared directly. + * + * For example, if you want to wait 100 ms, you could do this: + * + * ```c + * const Uint64 timeout = SDL_GetTicks64() + 100; + * while (SDL_GetTicks64() < timeout) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * \returns an unsigned 64-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void); + +/** + * Compare 32-bit SDL ticks values, and return true if `A` has passed `B`. + * + * This should be used with results from SDL_GetTicks(), as this macro + * attempts to deal with the 32-bit counter wrapping back to zero every ~49 + * days, but should _not_ be used with SDL_GetTicks64(), which does not have + * that problem. + * + * For example, with SDL_GetTicks(), if you want to wait 100 ms, you could + * do this: + * + * ```c + * const Uint32 timeout = SDL_GetTicks() + 100; + * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * Note that this does not handle tick differences greater + * than 2^31 so take care when using the above kind of code + * with large timeout delays (tens of days). + */ +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) + +/** + * Get the current value of the high resolution counter. + * + * This function is typically used for profiling. + * + * The counter values are only meaningful relative to each other. Differences + * between values can be converted to times by using + * SDL_GetPerformanceFrequency(). + * + * \returns the current counter value. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceFrequency + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); + +/** + * Get the count per second of the high resolution counter. + * + * \returns a platform-specific count per second. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceCounter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); + +/** + * Wait a specified number of milliseconds before returning. + * + * This function waits a specified number of milliseconds before returning. It + * waits at least the specified time, but possibly longer due to OS + * scheduling. + * + * \param ms the number of milliseconds to delay + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/** + * Function prototype for the timer callback function. + * + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); + +/** + * Definition of the timer ID type. + */ +typedef int SDL_TimerID; + +/** + * Call a callback function at a future time. + * + * If you use this function, you must pass `SDL_INIT_TIMER` to SDL_Init(). + * + * The callback function is passed the current timer interval and the user + * supplied parameter from the SDL_AddTimer() call and should return the next + * timer interval. If the value returned from the callback is 0, the timer is + * canceled. + * + * The callback is run on a separate thread. + * + * Timers take into account the amount of time it took to execute the + * callback. For example, if the callback took 250 ms to execute and returned + * 1000 (ms), the timer would only wait another 750 ms before its next + * iteration. + * + * Timing may be inexact due to OS scheduling. Be sure to note the current + * time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your + * callback needs to adjust for variances. + * + * \param interval the timer delay, in milliseconds, passed to `callback` + * \param callback the SDL_TimerCallback function to call when the specified + * `interval` elapses + * \param param a pointer that is passed to `callback` + * \returns a timer ID or 0 if an error occurs; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RemoveTimer + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, + SDL_TimerCallback callback, + void *param); + +/** + * Remove a timer created with SDL_AddTimer(). + * + * \param id the ID of the timer to remove + * \returns SDL_TRUE if the timer is removed or SDL_FALSE if the timer wasn't + * found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddTimer + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_timer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_touch.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_touch.h new file mode 100644 index 000000000..9b00716b2 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_touch.h @@ -0,0 +1,142 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_touch.h + * + * Include file for SDL touch event handling. + */ + +#ifndef SDL_touch_h_ +#define SDL_touch_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_TouchID; +typedef Sint64 SDL_FingerID; + +typedef enum +{ + SDL_TOUCH_DEVICE_INVALID = -1, + SDL_TOUCH_DEVICE_DIRECT, /* touch screen with window-relative coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, /* trackpad with absolute device coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_RELATIVE /* trackpad with screen cursor-relative coordinates */ +} SDL_TouchDeviceType; + +typedef struct SDL_Finger +{ + SDL_FingerID id; + float x; + float y; + float pressure; +} SDL_Finger; + +/* Used as the device ID for mouse events simulated with touch input */ +#define SDL_TOUCH_MOUSEID ((Uint32)-1) + +/* Used as the SDL_TouchID for touch events simulated with mouse input */ +#define SDL_MOUSE_TOUCHID ((Sint64)-1) + + +/** + * Get the number of registered touch devices. + * + * On some platforms SDL first sees the touch device if it was actually used. + * Therefore SDL_GetNumTouchDevices() may return 0 although devices are + * available. After using all devices at least once the number will be + * correct. + * + * This was fixed for Android in SDL 2.0.1. + * + * \returns the number of registered touch devices. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); + +/** + * Get the touch ID with the given index. + * + * \param index the touch device index + * \returns the touch ID with the given index on success or 0 if the index is + * invalid; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumTouchDevices + */ +extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); + +/** + * Get the type of the given touch device. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); + +/** + * Get the number of active fingers for a given touch device. + * + * \param touchID the ID of a touch device + * \returns the number of active fingers for a given touch device on success + * or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchFinger + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); + +/** + * Get the finger object for specified touch device ID and finger index. + * + * The returned resource is owned by SDL and should not be deallocated. + * + * \param touchID the ID of the requested touch device + * \param index the index of the requested finger + * \returns a pointer to the SDL_Finger object or NULL if no object at the + * given ID and index could be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RecordGesture + */ +extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_touch_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_types.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_types.h new file mode 100644 index 000000000..355fb501a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_types.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_types.h + * + * \deprecated + */ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_version.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_version.h new file mode 100644 index 000000000..2716eba7b --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_version.h @@ -0,0 +1,188 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_version.h + * + * This header defines the current SDL version. + */ + +#ifndef SDL_version_h_ +#define SDL_version_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Information about the version of SDL in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa SDL_VERSION + * \sa SDL_GetVersion + */ +typedef struct SDL_version +{ + Uint8 major; /**< major version */ + Uint8 minor; /**< minor version */ + Uint8 patch; /**< update version */ +} SDL_version; + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 2 +#define SDL_MINOR_VERSION 0 +#define SDL_PATCHLEVEL 20 + +/** + * Macro to determine SDL version program was compiled against. + * + * This macro fills in a SDL_version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), + * is not a macro. + * + * \param x A pointer to a SDL_version struct to initialize. + * + * \sa SDL_version + * \sa SDL_GetVersion + */ +#define SDL_VERSION(x) \ +{ \ + (x)->major = SDL_MAJOR_VERSION; \ + (x)->minor = SDL_MINOR_VERSION; \ + (x)->patch = SDL_PATCHLEVEL; \ +} + +/** + * This macro turns the version numbers into a numeric value: + * \verbatim + (1,2,3) -> (1203) + \endverbatim + * + * This assumes that there will never be more than 100 patchlevels. + */ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/** + * This is the version number macro for the current SDL version. + */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) + +/** + * This macro will evaluate to true if compiled with SDL at least X.Y.Z. + */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + +/** + * Get the version of SDL that is linked against your program. + * + * If you are linking to SDL dynamically, then it is possible that the current + * version will be different than the version you compiled against. This + * function returns the current version, while SDL_VERSION() is a macro that + * tells you what version you compiled with. + * + * This function may be called safely at any time, even before SDL_Init(). + * + * \param ver the SDL_version structure that contains the version information + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); + +/** + * Get the code revision of SDL that is linked against your program. + * + * This value is the revision of the code you are linked with and may be + * different from the code you are compiling with, which is found in the + * constant SDL_REVISION. + * + * The revision is arbitrary string (a hash value) uniquely identifying the + * exact revision of the SDL library in use, and is only useful in comparing + * against other revisions. It is NOT an incrementing number. + * + * If SDL wasn't built from a git repository with the appropriate tools, this + * will return an empty string. + * + * Prior to SDL 2.0.16, before development moved to GitHub, this returned a + * hash for a Mercurial repository. + * + * You shouldn't use this function for anything but logging it for debugging + * purposes. The string is not intended to be reliable in any way. + * + * \returns an arbitrary string, uniquely identifying the exact revision of + * the SDL library in use. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVersion + */ +extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); + +/** + * Obsolete function, do not use. + * + * When SDL was hosted in a Mercurial repository, and was built carefully, + * this would return the revision number that the build was created from. This + * number was not reliable for several reasons, but more importantly, SDL is + * now hosted in a git repository, which does not offer numbers at all, only + * hashes. This function only ever returns zero now. Don't use it. + * + * Before SDL 2.0.16, this might have returned an unreliable, but non-zero + * number. + * + * \deprecated Use SDL_GetRevision() instead; if SDL was carefully built, it + * will return a git hash. + * + * \returns zero, always, in modern SDL releases. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern SDL_DEPRECATED DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_version_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_video.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_video.h new file mode 100644 index 000000000..e43cb27ec --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_video.h @@ -0,0 +1,2088 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_video.h + * + * Header file for SDL video functions. + */ + +#ifndef SDL_video_h_ +#define SDL_video_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a display mode + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + * \sa SDL_GetDesktopDisplayMode() + * \sa SDL_GetCurrentDisplayMode() + * \sa SDL_GetClosestDisplayMode() + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +typedef struct +{ + Uint32 format; /**< pixel format */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ + int refresh_rate; /**< refresh rate (or zero for unspecified) */ + void *driverdata; /**< driver-specific data, initialize to 0 */ +} SDL_DisplayMode; + +/** + * \brief The type used to identify a window + * + * \sa SDL_CreateWindow() + * \sa SDL_CreateWindowFrom() + * \sa SDL_DestroyWindow() + * \sa SDL_FlashWindow() + * \sa SDL_GetWindowData() + * \sa SDL_GetWindowFlags() + * \sa SDL_GetWindowGrab() + * \sa SDL_GetWindowKeyboardGrab() + * \sa SDL_GetWindowMouseGrab() + * \sa SDL_GetWindowPosition() + * \sa SDL_GetWindowSize() + * \sa SDL_GetWindowTitle() + * \sa SDL_HideWindow() + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + * \sa SDL_RaiseWindow() + * \sa SDL_RestoreWindow() + * \sa SDL_SetWindowData() + * \sa SDL_SetWindowFullscreen() + * \sa SDL_SetWindowGrab() + * \sa SDL_SetWindowKeyboardGrab() + * \sa SDL_SetWindowMouseGrab() + * \sa SDL_SetWindowIcon() + * \sa SDL_SetWindowPosition() + * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() + * \sa SDL_SetWindowTitle() + * \sa SDL_ShowWindow() + */ +typedef struct SDL_Window SDL_Window; + +/** + * \brief The flags on a window + * + * \sa SDL_GetWindowFlags() + */ +typedef enum +{ + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ + SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ + SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ + SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ + SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ + SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ + SDL_WINDOW_MOUSE_GRABBED = 0x00000100, /**< window has grabbed mouse input */ + SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), + SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, /**< window should be created in high-DPI mode if supported. + On macOS NSHighResolutionCapable must be set true in the + application's Info.plist for this to have any effect. */ + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, /**< window has mouse captured (unrelated to MOUSE_GRABBED) */ + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */ + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */ + SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */ + SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */ + SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */ + SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000, /**< window has grabbed keyboard input */ + SDL_WINDOW_VULKAN = 0x10000000, /**< window usable for Vulkan surface */ + SDL_WINDOW_METAL = 0x20000000, /**< window usable for Metal view */ + + SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */ +} SDL_WindowFlags; + +/** + * \brief Used to indicate that you don't care what the window position is. + */ +#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u +#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) +#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) +#define SDL_WINDOWPOS_ISUNDEFINED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) + +/** + * \brief Used to indicate that the window position should be centered. + */ +#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u +#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X)) +#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0) +#define SDL_WINDOWPOS_ISCENTERED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) + +/** + * \brief Event subtype for window events + */ +typedef enum +{ + SDL_WINDOWEVENT_NONE, /**< Never used */ + SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ + SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ + SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be + redrawn */ + SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 + */ + SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ + SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as + a result of an API call or through the + system or user changing the window size. */ + SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ + SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ + SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size + and position */ + SDL_WINDOWEVENT_ENTER, /**< Window has gained mouse focus */ + SDL_WINDOWEVENT_LEAVE, /**< Window has lost mouse focus */ + SDL_WINDOWEVENT_FOCUS_GAINED, /**< Window has gained keyboard focus */ + SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */ + SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ + SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */ + SDL_WINDOWEVENT_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ + SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */ + SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */ +} SDL_WindowEventID; + +/** + * \brief Event subtype for display events + */ +typedef enum +{ + SDL_DISPLAYEVENT_NONE, /**< Never used */ + SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ + SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */ + SDL_DISPLAYEVENT_DISCONNECTED /**< Display has been removed from the system */ +} SDL_DisplayEventID; + +/** + * \brief Display orientation + */ +typedef enum +{ + SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */ + SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ + SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ + SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ + SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */ +} SDL_DisplayOrientation; + +/** + * \brief Window flash operation + */ +typedef enum +{ + SDL_FLASH_CANCEL, /**< Cancel any window flash state */ + SDL_FLASH_BRIEFLY, /**< Flash the window briefly to get attention */ + SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */ +} SDL_FlashOperation; + +/** + * \brief An opaque handle to an OpenGL context. + */ +typedef void *SDL_GLContext; + +/** + * \brief OpenGL configuration attributes + */ +typedef enum +{ + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR +} SDL_GLattr; + +typedef enum +{ + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +} SDL_GLprofile; + +typedef enum +{ + SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 +} SDL_GLcontextFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 +} SDL_GLcontextReleaseFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, + SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001 +} SDL_GLContextResetNotification; + +/* Function prototypes */ + +/** + * Get the number of video drivers compiled into SDL. + * + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void); + +/** + * Get the name of a built in video driver. + * + * The video drivers are presented in the order in which they are normally + * checked during initialization. + * + * \param index the index of a video driver + * \returns the name of the video driver with the given **index**. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); + +/** + * Initialize the video subsystem, optionally specifying a video driver. + * + * This function initializes the video subsystem, setting up a connection to + * the window manager, etc, and determines the available display modes and + * pixel formats, but does not initialize a window or graphics mode. + * + * If you use this function and you haven't used the SDL_INIT_VIDEO flag with + * either SDL_Init() or SDL_InitSubSystem(), you should call SDL_VideoQuit() + * before calling SDL_Quit(). + * + * It is safe to call this function multiple times. SDL_VideoInit() will call + * SDL_VideoQuit() itself if the video subsystem has already been initialized. + * + * You can use SDL_GetNumVideoDrivers() and SDL_GetVideoDriver() to find a + * specific `driver_name`. + * + * \param driver_name the name of a video driver to initialize, or NULL for + * the default driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + * \sa SDL_InitSubSystem + * \sa SDL_VideoQuit + */ +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); + +/** + * Shut down the video subsystem, if initialized with SDL_VideoInit(). + * + * This function closes all windows, and restores the original video mode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_VideoInit + */ +extern DECLSPEC void SDLCALL SDL_VideoQuit(void); + +/** + * Get the name of the currently initialized video driver. + * + * \returns the name of the current video driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); + +/** + * Get the number of available video displays. + * + * \returns a number >= 1 or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); + +/** + * Get the name of a display in UTF-8 encoding. + * + * \param displayIndex the index of display from which the name should be + * queried + * \returns the name of a display or NULL for an invalid display index or + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex); + +/** + * Get the desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * \param displayIndex the index of the display to query + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the usable desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * This is the same area as SDL_GetDisplayBounds() reports, but with portions + * reserved by the system removed. For example, on Apple's macOS, this + * subtracts the area occupied by the menu bar and dock. + * + * Setting a window to be fullscreen generally bypasses these unusable areas, + * so these are good guidelines for the maximum space available to a + * non-fullscreen window. + * + * The parameter `rect` is ignored if it is NULL. + * + * This function also returns -1 if the parameter `displayIndex` is out of + * range. + * + * \param displayIndex the index of the display to query the usable bounds + * from + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the dots/pixels-per-inch for a display. + * + * Diagonal, horizontal and vertical DPI can all be optionally returned if the + * appropriate parameter is non-NULL. + * + * A failure of this function usually means that either no DPI information is + * available or the `displayIndex` is out of range. + * + * \param displayIndex the index of the display from which DPI information + * should be queried + * \param ddpi a pointer filled in with the diagonal DPI of the display; may + * be NULL + * \param hdpi a pointer filled in with the horizontal DPI of the display; may + * be NULL + * \param vdpi a pointer filled in with the vertical DPI of the display; may + * be NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi); + +/** + * Get the orientation of a display. + * + * \param displayIndex the index of the display to query + * \returns The SDL_DisplayOrientation enum value of the display, or + * `SDL_ORIENTATION_UNKNOWN` if it isn't available. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex); + +/** + * Get the number of available display modes. + * + * The `displayIndex` needs to be in the range from 0 to + * SDL_GetNumVideoDisplays() - 1. + * + * \param displayIndex the index of the display to query + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex); + +/** + * Get information about a specific display mode. + * + * The display modes are sorted in this priority: + * + * - width -> largest to smallest + * - height -> largest to smallest + * - bits per pixel -> more colors to fewer colors + * - packed pixel layout -> largest to smallest + * - refresh rate -> highest to lowest + * + * \param displayIndex the index of the display to query + * \param modeIndex the index of the display mode to query + * \param mode an SDL_DisplayMode structure filled in with the mode at + * `modeIndex` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayMode(int displayIndex, int modeIndex, + SDL_DisplayMode * mode); + +/** + * Get information about the desktop's display mode. + * + * There's a difference between this function and SDL_GetCurrentDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the previous native display mode, and not the current + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetCurrentDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode); + +/** + * Get information about the current display mode. + * + * There's a difference between this function and SDL_GetDesktopDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the current display mode, and not the previous native + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDesktopDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode); + + +/** + * Get the closest match to the requested display mode. + * + * The available display modes are scanned and `closest` is filled in with the + * closest mode matching the requested mode and returned. The mode format and + * refresh rate default to the desktop mode if they are set to 0. The modes + * are scanned with size being first priority, format being second priority, + * and finally checking the refresh rate. If all the available modes are too + * small, then NULL is returned. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure containing the desired display + * mode + * \param closest an SDL_DisplayMode structure filled in with the closest + * match of the available display modes + * \returns the passed in value `closest` or NULL if no matching video mode + * was available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest); + +/** + * Get the index of the display associated with a window. + * + * \param window the window to query + * \returns the index of the display containing the center of the window on + * success or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayIndex(SDL_Window * window); + +/** + * Set the display mode to use when a window is visible at fullscreen. + * + * This only affects the display mode used when the window is fullscreen. To + * change the window size when the window is not fullscreen, use + * SDL_SetWindowSize(). + * + * \param window the window to affect + * \param mode the SDL_DisplayMode structure representing the mode to use, or + * NULL to use the window's dimensions and the desktop's format + * and refresh rate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window, + const SDL_DisplayMode * mode); + +/** + * Query the display mode to use when a window is visible at fullscreen. + * + * \param window the window to query + * \param mode an SDL_DisplayMode structure filled in with the fullscreen + * display mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window, + SDL_DisplayMode * mode); + +/** + * Get the raw ICC profile data for the screen the window is currently on. + * + * Data returned should be freed with SDL_free. + * + * \param window the window to query + * \param size the size of the ICC profile + * \returns the raw ICC profile data on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void* SDLCALL SDL_GetWindowICCProfile(SDL_Window * window, size_t* size); + +/** + * Get the pixel format associated with the window. + * + * \param window the window to query + * \returns the pixel format of the window on success or + * SDL_PIXELFORMAT_UNKNOWN on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); + +/** + * Create a window with the specified position, dimensions, and flags. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_WINDOW_FULLSCREEN`: fullscreen window + * - `SDL_WINDOW_FULLSCREEN_DESKTOP`: fullscreen window at desktop resolution + * - `SDL_WINDOW_OPENGL`: window usable with an OpenGL context + * - `SDL_WINDOW_VULKAN`: window usable with a Vulkan instance + * - `SDL_WINDOW_METAL`: window usable with a Metal instance + * - `SDL_WINDOW_HIDDEN`: window is not visible + * - `SDL_WINDOW_BORDERLESS`: no window decoration + * - `SDL_WINDOW_RESIZABLE`: window can be resized + * - `SDL_WINDOW_MINIMIZED`: window is minimized + * - `SDL_WINDOW_MAXIMIZED`: window is maximized + * - `SDL_WINDOW_INPUT_GRABBED`: window has grabbed input focus + * - `SDL_WINDOW_ALLOW_HIGHDPI`: window should be created in high-DPI mode if + * supported (>= SDL 2.0.1) + * + * `SDL_WINDOW_SHOWN` is ignored by SDL_CreateWindow(). The SDL_Window is + * implicitly shown if SDL_WINDOW_HIDDEN is not set. `SDL_WINDOW_SHOWN` may be + * queried later using SDL_GetWindowFlags(). + * + * On Apple's macOS, you **must** set the NSHighResolutionCapable Info.plist + * property to YES, otherwise you will not receive a High-DPI OpenGL canvas. + * + * If the window is created with the `SDL_WINDOW_ALLOW_HIGHDPI` flag, its size + * in pixels may differ from its size in screen coordinates on platforms with + * high-DPI support (e.g. iOS and macOS). Use SDL_GetWindowSize() to query the + * client area's size in screen coordinates, and SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to query the drawable size in pixels. + * + * If the window is set fullscreen, the width and height parameters `w` and + * `h` will not be used. However, invalid size parameters (e.g. too large) may + * still fail. Window size is actually limited to 16384 x 16384 for all + * platforms at window creation. + * + * If the window is created with any of the SDL_WINDOW_OPENGL or + * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function + * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the + * corresponding UnloadLibrary function is called by SDL_DestroyWindow(). + * + * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, + * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. + * + * If SDL_WINDOW_METAL is specified on an OS that does not support Metal, + * SDL_CreateWindow() will fail. + * + * On non-Apple devices, SDL requires you to either not link to the Vulkan + * loader or link to a dynamic library version. This limitation may be removed + * in a future version of SDL. + * + * \param title the title of the window, in UTF-8 encoding + * \param x the x position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param y the y position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param w the width of the window, in screen coordinates + * \param h the height of the window, in screen coordinates + * \param flags 0, or one or more SDL_WindowFlags OR'd together + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindowFrom + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, + int x, int y, int w, + int h, Uint32 flags); + +/** + * Create an SDL window from an existing native window. + * + * In some cases (e.g. OpenGL) and on some platforms (e.g. Microsoft Windows) + * the hint `SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT` needs to be configured + * before using SDL_CreateWindowFrom(). + * + * \param data a pointer to driver-dependent window creation data, typically + * your native window cast to a void* + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowFrom(const void *data); + +/** + * Get the numeric ID of a window. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param window the window to query + * \returns the ID of the window on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFromID + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowID(SDL_Window * window); + +/** + * Get a window from a stored ID. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param id the ID of the window + * \returns the window associated with `id` or NULL if it doesn't exist; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowID + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromID(Uint32 id); + +/** + * Get the window flags. + * + * \param window the window to query + * \returns a mask of the SDL_WindowFlags associated with `window` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_HideWindow + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + * \sa SDL_SetWindowFullscreen + * \sa SDL_SetWindowGrab + * \sa SDL_ShowWindow + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window * window); + +/** + * Set the title of a window. + * + * This string is expected to be in UTF-8 encoding. + * + * \param window the window to change + * \param title the desired window title in UTF-8 format + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowTitle + */ +extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_Window * window, + const char *title); + +/** + * Get the title of a window. + * + * \param window the window to query + * \returns the title of the window in UTF-8 format or "" if there is no + * title. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowTitle + */ +extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window * window); + +/** + * Set the icon for a window. + * + * \param window the window to change + * \param icon an SDL_Surface structure containing the icon for the window + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, + SDL_Surface * icon); + +/** + * Associate an arbitrary named pointer with a window. + * + * `name` is case-sensitive. + * + * \param window the window to associate with the pointer + * \param name the name of the pointer + * \param userdata the associated pointer + * \returns the previous value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowData + */ +extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, + const char *name, + void *userdata); + +/** + * Retrieve the data pointer associated with a window. + * + * \param window the window to query + * \param name the name of the pointer + * \returns the value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowData + */ +extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, + const char *name); + +/** + * Set the position of a window. + * + * The window coordinate origin is the upper left of the display. + * + * \param window the window to reposition + * \param x the x coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * \param y the y coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, + int x, int y); + +/** + * Get the position of a window. + * + * If you do not need the value for one of the positions a NULL may be passed + * in the `x` or `y` parameter. + * + * \param window the window to query + * \param x a pointer filled in with the x position of the window, in screen + * coordinates, may be NULL + * \param y a pointer filled in with the y position of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, + int *x, int *y); + +/** + * Set the size of a window's client area. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to get the real client area size in pixels. + * + * Fullscreen windows automatically match the size of the display mode, and + * you should use SDL_SetWindowDisplayMode() to change their size. + * + * \param window the window to change + * \param w the width of the window in pixels, in screen coordinates, must be + * > 0 + * \param h the height of the window in pixels, in screen coordinates, must be + * > 0 + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSize + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, + int h); + +/** + * Get the size of a window's client area. + * + * NULL can safely be passed as the `w` or `h` parameter if the width or + * height value is not desired. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize(), + * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to get the + * real client area size in pixels. + * + * \param window the window to query the width and height from + * \param w a pointer filled in with the width of the window, in screen + * coordinates, may be NULL + * \param h a pointer filled in with the height of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetDrawableSize + * \sa SDL_Vulkan_GetDrawableSize + * \sa SDL_SetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, + int *h); + +/** + * Get the size of a window's borders (decorations) around the client area. + * + * Note: If this function fails (returns -1), the size values will be + * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as if the + * window in question was borderless. + * + * Note: This function may fail on systems where the window has not yet been + * decorated by the display server (for example, immediately after calling + * SDL_CreateWindow). It is recommended that you wait at least until the + * window has been presented and composited, so that the window system has a + * chance to decorate the window and provide the border dimensions to SDL. + * + * This function also returns -1 if getting the information is not supported. + * + * \param window the window to query the size values of the border + * (decorations) from + * \param top pointer to variable for storing the size of the top border; NULL + * is permitted + * \param left pointer to variable for storing the size of the left border; + * NULL is permitted + * \param bottom pointer to variable for storing the size of the bottom + * border; NULL is permitted + * \param right pointer to variable for storing the size of the right border; + * NULL is permitted + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowSize + */ +extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, + int *top, int *left, + int *bottom, int *right); + +/** + * Set the minimum size of a window's client area. + * + * \param window the window to change + * \param min_w the minimum width of the window in pixels + * \param min_h the minimum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, + int min_w, int min_h); + +/** + * Get the minimum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the minimum width of the window, may be + * NULL + * \param h a pointer filled in with the minimum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the maximum size of a window's client area. + * + * \param window the window to change + * \param max_w the maximum width of the window in pixels + * \param max_h the maximum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, + int max_w, int max_h); + +/** + * Get the maximum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the maximum width of the window, may be + * NULL + * \param h a pointer filled in with the maximum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the border state of a window. + * + * This will add or remove the window's `SDL_WINDOW_BORDERLESS` flag and add + * or remove the border from the actual window. This is a no-op if the + * window's border already matches the requested state. + * + * You can't change the border state of a fullscreen window. + * + * \param window the window of which to change the border state + * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, + SDL_bool bordered); + +/** + * Set the user-resizable state of a window. + * + * This will add or remove the window's `SDL_WINDOW_RESIZABLE` flag and + * allow/disallow user resizing of the window. This is a no-op if the window's + * resizable state already matches the requested state. + * + * You can't change the resizable state of a fullscreen window. + * + * \param window the window of which to change the resizable state + * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, + SDL_bool resizable); + +/** + * Set the window to always be above the others. + * + * This will add or remove the window's `SDL_WINDOW_ALWAYS_ON_TOP` flag. This + * will bring the window to the front and keep the window above the rest. + * + * \param window The window of which to change the always on top state + * \param on_top SDL_TRUE to set the window always on top, SDL_FALSE to + * disable + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowAlwaysOnTop(SDL_Window * window, + SDL_bool on_top); + +/** + * Show a window. + * + * \param window the window to show + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HideWindow + * \sa SDL_RaiseWindow + */ +extern DECLSPEC void SDLCALL SDL_ShowWindow(SDL_Window * window); + +/** + * Hide a window. + * + * \param window the window to hide + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowWindow + */ +extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_Window * window); + +/** + * Raise a window above other windows and set the input focus. + * + * \param window the window to raise + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_Window * window); + +/** + * Make a window as large as possible. + * + * \param window the window to maximize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MinimizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window * window); + +/** + * Minimize a window to an iconic representation. + * + * \param window the window to minimize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MinimizeWindow(SDL_Window * window); + +/** + * Restore the size and position of a minimized or maximized window. + * + * \param window the window to restore + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + */ +extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); + +/** + * Set a window's fullscreen state. + * + * `flags` may be `SDL_WINDOW_FULLSCREEN`, for "real" fullscreen with a + * videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" fullscreen + * that takes the size of the desktop; and 0 for windowed mode. + * + * \param window the window to change + * \param flags `SDL_WINDOW_FULLSCREEN`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0 + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, + Uint32 flags); + +/** + * Get the SDL surface associated with the window. + * + * A new surface will be created with the optimal format for the window, if + * necessary. This surface will be freed when the window is destroyed. Do not + * free this surface. + * + * This surface will be invalidated if the window is resized. After resizing a + * window this function must be called again to return a valid surface. + * + * You may not combine this with 3D or the rendering API on this window. + * + * This function is affected by `SDL_HINT_FRAMEBUFFER_ACCELERATION`. + * + * \param window the window to query + * \returns the surface associated with the window, or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UpdateWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window); + +/** + * Copy the window surface to the screen. + * + * This is the function you use to reflect any changes to the surface on the + * screen. + * + * This function is equivalent to the SDL 1.2 API SDL_Flip(). + * + * \param window the window to update + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); + +/** + * Copy areas of the window surface to the screen. + * + * This is the function you use to reflect changes to portions of the surface + * on the screen. + * + * This function is equivalent to the SDL 1.2 API SDL_UpdateRects(). + * + * \param window the window to update + * \param rects an array of SDL_Rect structures representing areas of the + * surface to copy + * \param numrects the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurface + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, + const SDL_Rect * rects, + int numrects); + +/** + * Set a window's input grab mode. + * + * When input is grabbed, the mouse is confined to the window. This function + * will also grab the keyboard if `SDL_HINT_GRAB_KEYBOARD` is set. To grab the + * keyboard without also grabbing the mouse, use SDL_SetWindowKeyboardGrab(). + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window the window for which the input grab mode should be set + * \param grabbed SDL_TRUE to grab input or SDL_FALSE to release input + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGrabbedWindow + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's keyboard grab mode. + * + * Keyboard grab enables capture of system keyboard shortcuts like Alt+Tab or + * the Meta/Super key. Note that not all system keyboard shortcuts can be + * captured by applications (one example is Ctrl+Alt+Del on Windows). + * + * This is primarily intended for specialized applications such as VNC clients + * or VM frontends. Normal games should not use keyboard grab. + * + * When keyboard grab is enabled, SDL will continue to handle Alt+Tab when the + * window is full-screen to ensure the user is not trapped in your + * application. If you have a custom keyboard shortcut to exit fullscreen + * mode, you may suppress this behavior with + * `SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED`. + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window The window for which the keyboard grab mode should be set. + * \param grabbed This is SDL_TRUE to grab keyboard, and SDL_FALSE to release. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowKeyboardGrab + * \sa SDL_SetWindowMouseGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's mouse grab mode. + * + * Mouse grab confines the mouse cursor to the window. + * + * \param window The window for which the mouse grab mode should be set. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowMouseGrab + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMouseGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Get a window's input grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if input is grabbed, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); + +/** + * Get a window's keyboard grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if keyboard is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowKeyboardGrab(SDL_Window * window); + +/** + * Get a window's mouse grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if mouse is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowMouseGrab(SDL_Window * window); + +/** + * Get the window that currently has an input grab enabled. + * + * \returns the window if input is grabbed or NULL otherwise. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetWindowGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void); + +/** + * Confines the cursor to the specified area of a window. + * + * Note that this does NOT grab the cursor, it only defines the area a cursor + * is restricted to when the window has mouse focus. + * + * \param window The window that will be associated with the barrier. + * \param rect A rectangle area in window-relative coordinates. If NULL the + * barrier for the specified window will be destroyed. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetWindowMouseRect + * \sa SDL_SetWindowMouseGrab + */ +extern DECLSPEC int SDLCALL SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect); + +/** + * Get the mouse confinement rectangle of a window. + * + * \param window The window to query + * \returns A pointer to the mouse confinement rectangle of a window, or NULL + * if there isn't one. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetWindowMouseRect + */ +extern DECLSPEC const SDL_Rect * SDLCALL SDL_GetWindowMouseRect(SDL_Window * window); + +/** + * Set the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method sets the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The + * brightness set will not follow the window if it is moved to another + * display. + * + * Many platforms will refuse to set the display brightness in modern times. + * You are better off using a shader to adjust gamma during rendering, or + * something similar. + * + * \param window the window used to select the display whose brightness will + * be changed + * \param brightness the brightness (gamma multiplier) value to set where 0.0 + * is completely dark and 1.0 is normal brightness + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowBrightness + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float brightness); + +/** + * Get the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method retrieves the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose brightness will + * be queried + * \returns the brightness for the display where 0.0 is completely dark and + * 1.0 is normal brightness. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowBrightness + */ +extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window); + +/** + * Set the opacity for a window. + * + * The parameter `opacity` will be clamped internally between 0.0f + * (transparent) and 1.0f (opaque). + * + * This function also returns -1 if setting the opacity isn't supported. + * + * \param window the window which will be made transparent or opaque + * \param opacity the opacity value (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity); + +/** + * Get the opacity of a window. + * + * If transparency isn't supported on this platform, opacity will be reported + * as 1.0f without error. + * + * The parameter `opacity` is ignored if it is NULL. + * + * This function also returns -1 if an invalid window was provided. + * + * \param window the window to get the current opacity value from + * \param out_opacity the float filled in (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_SetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity); + +/** + * Set the window as a modal for another window. + * + * \param modal_window the window that should be set modal + * \param parent_window the parent window for the modal window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window); + +/** + * Explicitly set input focus to the window. + * + * You almost certainly want SDL_RaiseWindow() instead of this function. Use + * this with caution, as you might give focus to a window that is completely + * obscured by other windows. + * + * \param window the window that should get the input focus + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RaiseWindow + */ +extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window); + +/** + * Set the gamma ramp for the display that owns a given window. + * + * Set the gamma translation table for the red, green, and blue channels of + * the video hardware. Each table is an array of 256 16-bit quantities, + * representing a mapping between the input and output for that channel. The + * input is the index into the array, and the output is the 16-bit gamma value + * at that index, scaled to the output color precision. + * + * Despite the name and signature, this method sets the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The gamma + * ramp set will not follow the window if it is moved to another display. + * + * \param window the window used to select the display whose gamma ramp will + * be changed + * \param red a 256 element array of 16-bit quantities representing the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities representing the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities representing the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowGammaRamp(SDL_Window * window, + const Uint16 * red, + const Uint16 * green, + const Uint16 * blue); + +/** + * Get the gamma ramp for a given window's display. + * + * Despite the name and signature, this method retrieves the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose gamma ramp will + * be queried + * \param red a 256 element array of 16-bit quantities filled in with the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities filled in with the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities filled in with the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window, + Uint16 * red, + Uint16 * green, + Uint16 * blue); + +/** + * Possible return values from the SDL_HitTest callback. + * + * \sa SDL_HitTest + */ +typedef enum +{ + SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */ + SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */ + SDL_HITTEST_RESIZE_TOPLEFT, + SDL_HITTEST_RESIZE_TOP, + SDL_HITTEST_RESIZE_TOPRIGHT, + SDL_HITTEST_RESIZE_RIGHT, + SDL_HITTEST_RESIZE_BOTTOMRIGHT, + SDL_HITTEST_RESIZE_BOTTOM, + SDL_HITTEST_RESIZE_BOTTOMLEFT, + SDL_HITTEST_RESIZE_LEFT +} SDL_HitTestResult; + +/** + * Callback used for hit-testing. + * + * \param win the SDL_Window where hit-testing was set on + * \param area an SDL_Point which should be hit-tested + * \param data what was passed as `callback_data` to SDL_SetWindowHitTest() + * \return an SDL_HitTestResult value. + * + * \sa SDL_SetWindowHitTest + */ +typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win, + const SDL_Point *area, + void *data); + +/** + * Provide a callback that decides if a window region has special properties. + * + * Normally windows are dragged and resized by decorations provided by the + * system window manager (a title bar, borders, etc), but for some apps, it + * makes sense to drag them from somewhere else inside the window itself; for + * example, one might have a borderless window that wants to be draggable from + * any part, or simulate its own title bar, etc. + * + * This function lets the app provide a callback that designates pieces of a + * given window as special. This callback is run during event processing if we + * need to tell the OS to treat a region of the window specially; the use of + * this callback is known as "hit testing." + * + * Mouse input may not be delivered to your application if it is within a + * special area; the OS will often apply that input to moving the window or + * resizing the window and not deliver it to the application. + * + * Specifying NULL for a callback disables hit-testing. Hit-testing is + * disabled by default. + * + * Platforms that don't support this functionality will return -1 + * unconditionally, even if you're attempting to disable hit-testing. + * + * Your callback may fire at any time, and its firing does not indicate any + * specific behavior (for example, on Windows, this certainly might fire when + * the OS is deciding whether to drag your window, but it fires for lots of + * other reasons, too, some unrelated to anything you probably care about _and + * when the mouse isn't actually at the location it is testing_). Since this + * can fire at any time, you should try to keep your callback efficient, + * devoid of allocations, etc. + * + * \param window the window to set hit-testing on + * \param callback the function to call when doing a hit-test + * \param callback_data an app-defined void pointer passed to **callback** + * \returns 0 on success or -1 on error (including unsupported); call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window, + SDL_HitTest callback, + void *callback_data); + +/** + * Request a window to demand attention from the user. + * + * \param window the window to be flashed + * \param operation the flash operation + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation); + +/** + * Destroy a window. + * + * If `window` is NULL, this function will return immediately after setting + * the SDL error message to "Invalid window". See SDL_GetError(). + * + * \param window the window to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_CreateWindowFrom + */ +extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window); + + +/** + * Check whether the screensaver is currently enabled. + * + * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 + * the screensaver was enabled by default. + * + * The default can also be changed using `SDL_HINT_VIDEO_ALLOW_SCREENSAVER`. + * + * \returns SDL_TRUE if the screensaver is enabled, SDL_FALSE if it is + * disabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_EnableScreenSaver + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenSaverEnabled(void); + +/** + * Allow the screen to be blanked by a screen saver. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void); + +/** + * Prevent the screen from being blanked by a screen saver. + * + * If you disable the screensaver, it is automatically re-enabled when SDL + * quits. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_EnableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); + + +/** + * \name OpenGL support functions + */ +/* @{ */ + +/** + * Dynamically load an OpenGL library. + * + * This should be done after initializing the video driver, but before + * creating any OpenGL windows. If no OpenGL library is loaded, the default + * library will be loaded upon creation of the first OpenGL window. + * + * If you do this, you need to retrieve all of the GL functions used in your + * program from the dynamic library using SDL_GL_GetProcAddress(). + * + * \param path the platform dependent OpenGL library name, or NULL to open the + * default OpenGL library + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetProcAddress + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); + +/** + * Get an OpenGL function by name. + * + * If the GL library is loaded at runtime with SDL_GL_LoadLibrary(), then all + * GL functions must be retrieved this way. Usually this is used to retrieve + * function pointers to OpenGL extensions. + * + * There are some quirks to looking up OpenGL functions that require some + * extra care from the application. If you code carefully, you can handle + * these quirks without any platform-specific code, though: + * + * - On Windows, function pointers are specific to the current GL context; + * this means you need to have created a GL context and made it current + * before calling SDL_GL_GetProcAddress(). If you recreate your context or + * create a second context, you should assume that any existing function + * pointers aren't valid to use with it. This is (currently) a + * Windows-specific limitation, and in practice lots of drivers don't suffer + * this limitation, but it is still the way the wgl API is documented to + * work and you should expect crashes if you don't respect it. Store a copy + * of the function pointers that comes and goes with context lifespan. + * - On X11, function pointers returned by this function are valid for any + * context, and can even be looked up before a context is created at all. + * This means that, for at least some common OpenGL implementations, if you + * look up a function that doesn't exist, you'll get a non-NULL result that + * is _NOT_ safe to call. You must always make sure the function is actually + * available for a given GL context before calling it, by checking for the + * existence of the appropriate extension with SDL_GL_ExtensionSupported(), + * or verifying that the version of OpenGL you're using offers the function + * as core functionality. + * - Some OpenGL drivers, on all platforms, *will* return NULL if a function + * isn't supported, but you can't count on this behavior. Check for + * extensions you use, and if you get a NULL anyway, act as if that + * extension wasn't available. This is probably a bug in the driver, but you + * can code defensively for this scenario anyhow. + * - Just because you're on Linux/Unix, don't assume you'll be using X11. + * Next-gen display servers are waiting to replace it, and may or may not + * make the same promises about function pointers. + * - OpenGL function pointers must be declared `APIENTRY` as in the example + * code. This will ensure the proper calling convention is followed on + * platforms where this matters (Win32) thereby avoiding stack corruption. + * + * \param proc the name of an OpenGL function + * \returns a pointer to the named OpenGL function. The returned pointer + * should be cast to the appropriate function signature. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ExtensionSupported + * \sa SDL_GL_LoadLibrary + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); + +/** + * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void); + +/** + * Check if an OpenGL extension is supported for the current context. + * + * This function operates on the current GL context; you must have created a + * context and it must be current before calling this function. Do not assume + * that all contexts you create will have the same set of extensions + * available, or that recreating an existing context will offer the same + * extensions again. + * + * While it's probably not a massive overhead, this function is not an O(1) + * operation. Check the extensions you care about after creating the GL + * context and save that information somewhere instead of calling the function + * every time you need to know. + * + * \param extension the name of the extension to check + * \returns SDL_TRUE if the extension is supported, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char + *extension); + +/** + * Reset all previously set OpenGL context attributes to their default values. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC void SDLCALL SDL_GL_ResetAttributes(void); + +/** + * Set an OpenGL window attribute before window creation. + * + * This function sets the OpenGL attribute `attr` to `value`. The requested + * attributes should be set before creating an OpenGL window. You should use + * SDL_GL_GetAttribute() to check the values after creating the OpenGL + * context, since the values obtained can differ from the requested ones. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to set + * \param value the desired value for the attribute + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_ResetAttributes + */ +extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/** + * Get the actual value for an attribute from the current context. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to get + * \param value a pointer filled in with the current value of `attr` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ResetAttributes + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); + +/** + * Create an OpenGL context for an OpenGL window, and make it current. + * + * Windows users new to OpenGL should note that, for historical reasons, GL + * functions added after OpenGL version 1.1 are not available by default. + * Those functions must be loaded at run-time, either with an OpenGL + * extension-handling library or with SDL_GL_GetProcAddress() and its related + * functions. + * + * SDL_GLContext is an alias for `void *`. It's opaque to the application. + * + * \param window the window to associate with the context + * \returns the OpenGL context associated with `window` or NULL on error; call + * SDL_GetError() for more details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_DeleteContext + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * + window); + +/** + * Set up an OpenGL context for rendering into an OpenGL window. + * + * The context must have been created with a compatible window. + * + * \param window the window to associate with the context + * \param context the OpenGL context to associate with the window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, + SDL_GLContext context); + +/** + * Get the currently active OpenGL window. + * + * \returns the currently active OpenGL window on success or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); + +/** + * Get the currently active OpenGL context. + * + * \returns the currently active OpenGL context or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); + +/** + * Get the size of a window's underlying drawable in pixels. + * + * This returns info useful for calling glViewport(). + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window the window from which the drawable size should be queried + * \param w a pointer to variable for storing the width in pixels, may be NULL + * \param h a pointer to variable for storing the height in pixels, may be + * NULL + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_CreateWindow + * \sa SDL_GetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w, + int *h); + +/** + * Set the swap interval for the current OpenGL context. + * + * Some systems allow specifying -1 for the interval, to enable adaptive + * vsync. Adaptive vsync works the same as vsync, but if you've already missed + * the vertical retrace for a given frame, it swaps buffers immediately, which + * might be less jarring for the user during occasional framerate drops. If an + * application requests adaptive vsync and the system does not support it, + * this function will fail and return -1. In such a case, you should probably + * retry the call with 1 for the interval. + * + * Adaptive vsync is implemented for some glX drivers with + * GLX_EXT_swap_control_tear: + * + * https://www.opengl.org/registry/specs/EXT/glx_swap_control_tear.txt + * + * and for some Windows drivers with WGL_EXT_swap_control_tear: + * + * https://www.opengl.org/registry/specs/EXT/wgl_swap_control_tear.txt + * + * Read more on the Khronos wiki: + * https://www.khronos.org/opengl/wiki/Swap_Interval#Adaptive_Vsync + * + * \param interval 0 for immediate updates, 1 for updates synchronized with + * the vertical retrace, -1 for adaptive vsync + * \returns 0 on success or -1 if setting the swap interval is not supported; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); + +/** + * Get the swap interval for the current OpenGL context. + * + * If the system can't determine the swap interval, or there isn't a valid + * current context, this function will return 0 as a safe default. + * + * \returns 0 if there is no vertical retrace synchronization, 1 if the buffer + * swap is synchronized with the vertical retrace, and -1 if late + * swaps happen immediately instead of waiting for the next retrace; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_SetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); + +/** + * Update a window with OpenGL rendering. + * + * This is used with double-buffered OpenGL contexts, which are the default. + * + * On macOS, make sure you bind 0 to the draw framebuffer before swapping the + * window, otherwise nothing will happen. If you aren't using + * glBindFramebuffer(), this is the default and you won't have to do anything + * extra. + * + * \param window the window to change + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window * window); + +/** + * Delete an OpenGL context. + * + * \param context the OpenGL context to be deleted + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context); + +/* @} *//* OpenGL support functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/SDL_vulkan.h b/libultraship/libultraship/Lib/SDL/SDL2/SDL_vulkan.h new file mode 100644 index 000000000..ab86a0b86 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/SDL_vulkan.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef SDL_vulkan_h_ +#define SDL_vulkan_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid including vulkan.h, don't define VkInstance if it's already included */ +#ifdef VULKAN_H_ +#define NO_SDL_VULKAN_TYPEDEFS +#endif +#ifndef NO_SDL_VULKAN_TYPEDEFS +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#endif /* !NO_SDL_VULKAN_TYPEDEFS */ + +typedef VkInstance SDL_vulkanInstance; +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */ + +/** + * \name Vulkan support functions + * + * \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API + * is compatable with Tizen's implementation of Vulkan in SDL. + */ +/* @{ */ + +/** + * Dynamically load the Vulkan loader library. + * + * This should be called after initializing the video driver, but before + * creating any Vulkan windows. If no Vulkan loader library is loaded, the + * default library will be loaded upon creation of the first Vulkan window. + * + * It is fairly common for Vulkan applications to link with libvulkan instead + * of explicitly loading it at run time. This will work with SDL provided the + * application links to a dynamic library and both it and SDL use the same + * search path. + * + * If you specify a non-NULL `path`, an application should retrieve all of the + * Vulkan functions it uses from the dynamic library using + * SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points + * to the same vulkan loader library the application linked to. + * + * On Apple devices, if `path` is NULL, SDL will attempt to find the + * `vkGetInstanceProcAddr` address within all the Mach-O images of the current + * process. This is because it is fairly common for Vulkan applications to + * link with libvulkan (and historically MoltenVK was provided as a static + * library). If it is not found, on macOS, SDL will attempt to load + * `vulkan.framework/vulkan`, `libvulkan.1.dylib`, + * `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On + * iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a + * dynamic framework or .dylib must ensure it is included in its application + * bundle. + * + * On non-Apple devices, application linking with a static libvulkan is not + * supported. Either do not link to the Vulkan loader or link to a dynamic + * library version. + * + * \param path The platform dependent Vulkan loader library name or NULL + * \returns 0 on success or -1 if the library couldn't be loaded; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetVkInstanceProcAddr + * \sa SDL_Vulkan_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path); + +/** + * Get the address of the `vkGetInstanceProcAddr` function. + * + * This should be called after either calling SDL_Vulkan_LoadLibrary() or + * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag. + * + * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void); + +/** + * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary() + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void); + +/** + * Get the names of the Vulkan instance extensions needed to create a surface + * with SDL_Vulkan_CreateSurface. + * + * If `pNames` is NULL, then the number of required Vulkan instance extensions + * is returned in `pCount`. Otherwise, `pCount` must point to a variable set + * to the number of elements in the `pNames` array, and on return the variable + * is overwritten with the number of names actually written to `pNames`. If + * `pCount` is less than the number of required extensions, at most `pCount` + * structures will be written. If `pCount` is smaller than the number of + * required extensions, SDL_FALSE will be returned instead of SDL_TRUE, to + * indicate that not all the required extensions were returned. + * + * The `window` parameter is currently needed to be valid as of SDL 2.0.8, + * however, this parameter will likely be removed in future releases + * + * \param window A window for which the required Vulkan instance extensions + * should be retrieved (will be deprecated in a future release) + * \param pCount A pointer to an unsigned int corresponding to the number of + * extensions to be returned + * \param pNames NULL or a pointer to an array to be filled with required + * Vulkan instance extensions + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, + unsigned int *pCount, + const char **pNames); + +/** + * Create a Vulkan rendering surface for a window. + * + * The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and + * `instance` must have been created with extensions returned by + * SDL_Vulkan_GetInstanceExtensions() enabled. + * + * \param window The window to which to attach the Vulkan surface + * \param instance The Vulkan instance handle + * \param surface A pointer to a VkSurfaceKHR handle to output the newly + * created surface + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetInstanceExtensions + * \sa SDL_Vulkan_GetDrawableSize + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * Get the size of the window's underlying drawable dimensions in pixels. + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window an SDL_Window for which the size is to be queried + * \param w Pointer to the variable to write the width to or NULL + * \param h Pointer to the variable to write the height to or NULL + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + +/* @} *//* Vulkan support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_vulkan_h_ */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/begin_code.h b/libultraship/libultraship/Lib/SDL/SDL2/begin_code.h new file mode 100644 index 000000000..63f064b6f --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/begin_code.h @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file begin_code.h + * + * This file sets things up for C dynamic library function definitions, + * static inlined functions, and structures aligned at 4-byte alignment. + * If you don't like ugly C preprocessor code, don't look at this file. :) + */ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +#ifndef SDL_DEPRECATED +# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# define SDL_DEPRECATED __attribute__((deprecated)) +# else +# define SDL_DEPRECATED +# endif +#endif + +#ifndef SDL_UNUSED +# ifdef __GNUC__ +# define SDL_UNUSED __attribute__((unused)) +# else +# define SDL_UNUSED +# endif +#endif + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) +# ifdef DLL_EXPORT +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# elif defined(__OS2__) +# ifdef BUILD_SDL +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) +#define SDLCALL __cdecl +#elif defined(__OS2__) || defined(__EMX__) +#define SDLCALL _System +# if defined (__GNUC__) && !defined(_System) +# define _System /* for old EMX/GCC compat. */ +# endif +#else +#define SDLCALL +#endif +#endif /* SDLCALL */ + +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ +#ifdef __SYMBIAN32__ +#undef DECLSPEC +#define DECLSPEC +#endif /* __SYMBIAN32__ */ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpragma-pack" +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#ifdef _M_X64 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ +#pragma pack(push,8) +#else +#pragma pack(push,4) +#endif +#endif /* Compiler needs structure packing set */ + +#ifndef SDL_INLINE +#if defined(__GNUC__) +#define SDL_INLINE __inline__ +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) || defined(__CC_ARM) +#define SDL_INLINE __inline +#ifndef __inline__ +#define __inline__ __inline +#endif +#else +#define SDL_INLINE inline +#ifndef __inline__ +#define __inline__ inline +#endif +#endif +#endif /* SDL_INLINE not defined */ + +#ifndef SDL_FORCE_INLINE +#if defined(_MSC_VER) +#define SDL_FORCE_INLINE __forceinline +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ +#else +#define SDL_FORCE_INLINE static SDL_INLINE +#endif +#endif /* SDL_FORCE_INLINE not defined */ + +#ifndef SDL_NORETURN +#if defined(__GNUC__) +#define SDL_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define SDL_NORETURN __declspec(noreturn) +#else +#define SDL_NORETURN +#endif +#endif /* SDL_NORETURN not defined */ + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ + +#ifndef SDL_FALLTHROUGH +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) +#define SDL_FALLTHROUGH [[fallthrough]] +#else +#if defined(__has_attribute) +#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__) +#else +#define _HAS_FALLTHROUGH 0 +#endif /* __has_attribute */ +#if _HAS_FALLTHROUGH && \ + ((defined(__GNUC__) && __GNUC__ >= 7) || \ + (defined(__clang_major__) && __clang_major__ >= 10)) +#define SDL_FALLTHROUGH __attribute__((__fallthrough__)) +#else +#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ +#endif /* _HAS_FALLTHROUGH */ +#undef _HAS_FALLTHROUGH +#endif /* C++17 or C2x */ +#endif /* SDL_FALLTHROUGH not defined */ diff --git a/libultraship/libultraship/Lib/SDL/SDL2/close_code.h b/libultraship/libultraship/Lib/SDL/SDL2/close_code.h new file mode 100644 index 000000000..dc73432f6 --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/SDL2/close_code.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file close_code.h + * + * This file reverses the effects of begin_code.h and should be included + * after you finish any function and structure declarations in your headers + */ + +#ifndef _begin_code_h +#error close_code.h included without matching begin_code.h +#endif +#undef _begin_code_h + +/* Reset structure packing at previous byte alignment */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(pop) +#endif /* Compiler needs structure packing set */ diff --git a/libultraship/libultraship/Lib/SDL/WhatsNew.txt b/libultraship/libultraship/Lib/SDL/WhatsNew.txt new file mode 100644 index 000000000..257fb756a --- /dev/null +++ b/libultraship/libultraship/Lib/SDL/WhatsNew.txt @@ -0,0 +1,643 @@ + +This is a list of major changes in SDL's version history. + +--------------------------------------------------------------------------- +2.0.16: +--------------------------------------------------------------------------- +General: +* Added SDL_FlashWindow() to get a user's attention +* Added SDL_GetAudioDeviceSpec() to get the preferred audio format of a device +* Added SDL_SetWindowAlwaysOnTop() to dynamically change the SDL_WINDOW_ALWAYS_ON_TOP flag for a window +* Added SDL_SetWindowKeyboardGrab() to support grabbing the keyboard independently of the mouse +* Added SDL_SoftStretchLinear() to do bilinear scaling between 32-bit software surfaces +* Added SDL_UpdateNVTexture() to update streaming NV12/21 textures +* Added SDL_GameControllerSendEffect() and SDL_JoystickSendEffect() to allow sending custom trigger effects to the DualSense controller +* Added SDL_GameControllerGetSensorDataRate() to get the sensor data rate for PlayStation and Nintendo Switch controllers +* Added support for the Amazon Luna game controller +* Added rumble support for the Google Stadia controller using the HIDAPI driver +* Added SDL_GameControllerType constants for the Amazon Luna and Google Stadia controllers +* Added analog rumble for Nintendo Switch Pro controllers using the HIDAPI driver +* Reduced CPU usage when using SDL_WaitEvent() and SDL_WaitEventTimeout() + +Windows: +* Added SDL_SetWindowsMessageHook() to set a function that is called for all Windows messages +* Added SDL_RenderGetD3D11Device() to get the D3D11 device used by the SDL renderer + +Linux: +* Greatly improved Wayland support +* Added support for audio output and capture using Pipewire +* Added the hint SDL_HINT_AUDIO_INCLUDE_MONITORS to control whether PulseAudio recording should include monitor devices +* Added the hint SDL_HINT_AUDIO_DEVICE_STREAM_ROLE to describe the role of your application for audio control panels + +Android: +* Added support for audio output and capture using AAudio +* Added SDL_AndroidShowToast() to show a lightweight notification + +iOS: +* Added support for mouse relative mode on iOS 14.1 and newer +* Added support for the Xbox Series X controller + +tvOS: +* Added support for the Xbox Series X controller + + +--------------------------------------------------------------------------- +2.0.14: +--------------------------------------------------------------------------- +General: +* Added support for PS5 DualSense and Xbox Series X controllers to the HIDAPI controller driver +* Added game controller button constants for paddles and new buttons +* Added game controller functions to get additional information: + * SDL_GameControllerGetSerial() + * SDL_GameControllerHasAxis() + * SDL_GameControllerHasButton() + * SDL_GameControllerGetNumTouchpads() + * SDL_GameControllerGetNumTouchpadFingers() + * SDL_GameControllerGetTouchpadFinger() + * SDL_GameControllerHasSensor() + * SDL_GameControllerSetSensorEnabled() + * SDL_GameControllerIsSensorEnabled() + * SDL_GameControllerGetSensorData() + * SDL_GameControllerRumbleTriggers() + * SDL_GameControllerHasLED() + * SDL_GameControllerSetLED() +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_PS5 to control whether the HIDAPI driver for PS5 controllers should be used. +* Added joystick functions to get additional information: + * SDL_JoystickGetSerial() + * SDL_JoystickRumbleTriggers() + * SDL_JoystickHasLED() + * SDL_JoystickSetLED() +* Added an API to allow the application to create virtual joysticks: + * SDL_JoystickAttachVirtual() + * SDL_JoystickDetachVirtual() + * SDL_JoystickIsVirtual() + * SDL_JoystickSetVirtualAxis() + * SDL_JoystickSetVirtualButton() + * SDL_JoystickSetVirtualHat() +* Added SDL_LockSensors() and SDL_UnlockSensors() to guarantee exclusive access to the sensor list +* Added SDL_HAPTIC_STEERING_AXIS to play an effect on the steering wheel +* Added the hint SDL_HINT_MOUSE_RELATIVE_SCALING to control whether relative motion is scaled by the screen DPI or renderer logical size +* The default value for SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS is now false for better compatibility with modern window managers +* Added SDL_GetPreferredLocales() to get the application's current locale setting +* Added the hint SDL_HINT_PREFERRED_LOCALES to override your application's default locale setting +* Added SDL_OpenURL() to open a URL in the system's default browser +* Added SDL_HasSurfaceRLE() to tell whether a surface is currently using RLE encoding +* Added SDL_SIMDRealloc() to reallocate memory obtained from SDL_SIMDAlloc() +* Added SDL_GetErrorMsg() to get the last error in a thread-safe way +* Added SDL_crc32(), SDL_wcscasecmp(), SDL_wcsncasecmp(), SDL_trunc(), SDL_truncf() +* Added clearer names for RGB pixel formats, e.g. SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_XBGR8888, etc. + +Windows: +* Added the RAWINPUT controller driver to support more than 4 Xbox controllers simultaneously +* Added the hint SDL_HINT_JOYSTICK_RAWINPUT to control whether the RAWINPUT driver should be used +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT to control whether XInput and WGI should be used to for complete controller functionality with the RAWINPUT driver. + +macOS: +* Added the SDL_WINDOW_METAL flag to specify that a window should be created with a Metal view +* Added SDL_Metal_GetLayer() to get the CAMetalLayer backing a Metal view +* Added SDL_Metal_GetDrawableSize() to get the size of a window's drawable, in pixels + +Linux: +* Added the hint SDL_HINT_AUDIO_DEVICE_APP_NAME to specify the name that shows up in PulseAudio for your application +* Added the hint SDL_HINT_AUDIO_DEVICE_STREAM_NAME to specify the name that shows up in PulseAudio associated with your audio stream +* Added the hint SDL_HINT_LINUX_JOYSTICK_DEADZONES to control whether HID defined dead zones should be respected on Linux +* Added the hint SDL_HINT_THREAD_PRIORITY_POLICY to specify the thread scheduler policy +* Added the hint SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL to allow time critical threads to use a realtime scheduling policy + +Android: +* Added SDL_AndroidRequestPermission() to request a specific system permission +* Added the hint SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO to control whether audio will pause when the application goes intot he background + +OS/2: +* Added support for OS/2, see docs/README-os2.md for details + +Emscripten (running in a web browser): +* Added the hint SDL_HINT_EMSCRIPTEN_ASYNCIFY to control whether SDL should call emscripten_sleep internally + + +--------------------------------------------------------------------------- +2.0.12: +--------------------------------------------------------------------------- + +General: +* Added SDL_GetTextureScaleMode() and SDL_SetTextureScaleMode() to get and set the scaling mode used for a texture +* Added SDL_LockTextureToSurface(), similar to SDL_LockTexture() but the locked area is exposed as a SDL surface. +* Added new blend mode, SDL_BLENDMODE_MUL, which does a modulate and blend operation +* Added the hint SDL_HINT_DISPLAY_USABLE_BOUNDS to override the results of SDL_GetDisplayUsableBounds() for display index 0. +* Added the window underneath the finger to the SDL_TouchFingerEvent +* Added SDL_GameControllerTypeForIndex(), SDL_GameControllerGetType() to return the type of a game controller (Xbox 360, Xbox One, PS3, PS4, or Nintendo Switch Pro) +* Added the hint SDL_HINT_GAMECONTROLLERTYPE to override the automatic game controller type detection +* Added SDL_JoystickFromPlayerIndex() and SDL_GameControllerFromPlayerIndex() to get the device associated with a player index +* Added SDL_JoystickSetPlayerIndex() and SDL_GameControllerSetPlayerIndex() to set the player index associated with a device +* Added the hint SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS to specify whether Nintendo Switch Pro controllers should use the buttons as labeled or swapped to match positional layout. The default is to use the buttons as labeled. +* Added support for Nintendo GameCube controllers to the HIDAPI driver, and a hint SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE to control whether this is used. +* Improved support for Xbox 360 and Xbox One controllers when using the HIDAPI driver +* Added support for many game controllers, including: + * 8BitDo FC30 Pro + * 8BitDo M30 GamePad + * BDA PS4 Fightpad + * HORI Fighting Commander + * Hyperkin Duke + * Hyperkin X91 + * MOGA XP5-A Plus + * NACON GC-400ES + * NVIDIA Controller v01.04 + * PDP Versus Fighting Pad + * Razer Raion Fightpad for PS4 + * Razer Serval + * Stadia Controller + * SteelSeries Stratus Duo + * Victrix Pro Fight Stick for PS4 + * Xbox One Elite Series 2 +* Fixed blocking game controller rumble calls when using the HIDAPI driver +* Added SDL_zeroa() macro to zero an array of elements +* Added SDL_HasARMSIMD() which returns true if the CPU has ARM SIMD (ARMv6+) features + +Windows: +* Fixed crash when using the release SDL DLL with applications built with gcc +* Fixed performance regression in event handling introduced in 2.0.10 +* Added support for SDL_SetThreadPriority() for UWP applications + +Linux: +* Added the hint SDL_HINT_VIDEO_X11_WINDOW_VISUALID to specify the visual chosen for new X11 windows +* Added the hint SDL_HINT_VIDEO_X11_FORCE_EGL to specify whether X11 should use GLX or EGL by default + +iOS / tvOS / macOS: +* Added SDL_Metal_CreateView() and SDL_Metal_DestroyView() to create CAMetalLayer-backed NSView/UIView and attach it to the specified window. + +iOS/ tvOS: +* Added support for Bluetooth Steam Controllers as game controllers + +tvOS: +* Fixed support for surround sound on Apple TV + +Android: +* Added SDL_GetAndroidSDKVersion() to return the API level of the current device +* Added support for audio capture using OpenSL-ES +* Added support for Bluetooth Steam Controllers as game controllers +* Fixed rare crashes when the app goes into the background or terminates + + +--------------------------------------------------------------------------- +2.0.10: +--------------------------------------------------------------------------- + +General: +* The SDL_RW* macros have been turned into functions that are available only in 2.0.10 and onward +* Added SDL_SIMDGetAlignment(), SDL_SIMDAlloc(), and SDL_SIMDFree(), to allocate memory aligned for SIMD operations for the current CPU +* Added SDL_RenderDrawPointF(), SDL_RenderDrawPointsF(), SDL_RenderDrawLineF(), SDL_RenderDrawLinesF(), SDL_RenderDrawRectF(), SDL_RenderDrawRectsF(), SDL_RenderFillRectF(), SDL_RenderFillRectsF(), SDL_RenderCopyF(), SDL_RenderCopyExF(), to allow floating point precision in the SDL rendering API. +* Added SDL_GetTouchDeviceType() to get the type of a touch device, which can be a touch screen or a trackpad in relative or absolute coordinate mode. +* The SDL rendering API now uses batched rendering by default, for improved performance +* Added SDL_RenderFlush() to force batched render commands to execute, if you're going to mix SDL rendering with native rendering +* Added the hint SDL_HINT_RENDER_BATCHING to control whether batching should be used for the rendering API. This defaults to "1" if you don't specify what rendering driver to use when creating the renderer. +* Added the hint SDL_HINT_EVENT_LOGGING to enable logging of SDL events for debugging purposes +* Added the hint SDL_HINT_GAMECONTROLLERCONFIG_FILE to specify a file that will be loaded at joystick initialization with game controller bindings +* Added the hint SDL_HINT_MOUSE_TOUCH_EVENTS to control whether SDL will synthesize touch events from mouse events +* Improved handling of malformed WAVE and BMP files, fixing potential security exploits + +Linux: +* Removed the Mir video driver in favor of Wayland + +iOS / tvOS: +* Added support for Xbox and PS4 wireless controllers in iOS 13 and tvOS 13 +* Added support for text input using Bluetooth keyboards + +Android: +* Added low latency audio using OpenSL ES +* Removed SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH (replaced by SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS) + SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH=1, should be replaced by setting both previous hints to 0. + SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH=0, should be replaced by setting both previous hints to 1. +* Added the hint SDL_HINT_ANDROID_BLOCK_ON_PAUSE to set whether the event loop will block itself when the app is paused. + + +--------------------------------------------------------------------------- +2.0.9: +--------------------------------------------------------------------------- + +General: +* Added a new sensor API, initialized by passing SDL_INIT_SENSOR to SDL_Init(), and defined in SDL_sensor.h +* Added an event SDL_SENSORUPDATE which is sent when a sensor is updated +* Added SDL_GetDisplayOrientation() to return the current display orientation +* Added an event SDL_DISPLAYEVENT which is sent when the display orientation changes +* Added HIDAPI joystick drivers for more consistent support for Xbox, PS4 and Nintendo Switch Pro controller support across platforms. (Thanks to Valve for contributing the PS4 and Nintendo Switch Pro controller support) +* Added support for many other popular game controllers +* Added SDL_JoystickGetDevicePlayerIndex(), SDL_JoystickGetPlayerIndex(), and SDL_GameControllerGetPlayerIndex() to get the player index for a controller. For XInput controllers this returns the XInput index for the controller. +* Added SDL_GameControllerRumble() and SDL_JoystickRumble() which allow simple rumble without using the haptics API +* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened +* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_TIME to control the mouse double-click time +* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS to control the mouse double-click radius, in pixels +* Added SDL_HasColorKey() to return whether a surface has a colorkey active +* Added SDL_HasAVX512F() to return whether the CPU has AVX-512F features +* Added SDL_IsTablet() to return whether the application is running on a tablet +* Added SDL_THREAD_PRIORITY_TIME_CRITICAL for threads that must run at the highest priority + +Mac OS X: +* Fixed black screen at start on Mac OS X Mojave + +Linux: +* Added SDL_LinuxSetThreadPriority() to allow adjusting the thread priority of native threads using RealtimeKit if available. + +iOS: +* Fixed Asian IME input + +Android: +* Updated required Android SDK to API 26, to match Google's new App Store requirements +* Added support for wired USB Xbox, PS4, and Nintendo Switch Pro controllers +* Added support for relative mouse mode on Android 7.0 and newer (except where it's broken, on Chromebooks and when in DeX mode with Samsung Experience 9.0) +* Added support for custom mouse cursors on Android 7.0 and newer +* Added the hint SDL_HINT_ANDROID_TRAP_BACK_BUTTON to control whether the back button will back out of the app (the default) or be passed to the application as SDL_SCANCODE_AC_BACK +* Added SDL_AndroidBackButton() to trigger the Android system back button behavior when handling the back button in the application +* Added SDL_IsChromebook() to return whether the app is running in the Chromebook Android runtime +* Added SDL_IsDeXMode() to return whether the app is running while docked in the Samsung DeX + + +--------------------------------------------------------------------------- +2.0.8: +--------------------------------------------------------------------------- + +General: +* Added SDL_fmod() and SDL_log10() +* Each of the SDL math functions now has the corresponding float version +* Added SDL_SetYUVConversionMode() and SDL_GetYUVConversionMode() to control the formula used when converting to and from YUV colorspace. The options are JPEG, BT.601, and BT.709 + +Windows: +* Implemented WASAPI support on Windows UWP and removed the deprecated XAudio2 implementation +* Added resampling support on WASAPI on Windows 7 and above + +Windows UWP: +* Added SDL_WinRTGetDeviceFamily() to find out what type of device your application is running on + +Mac OS X: +* Added support for the Vulkan SDK for Mac: + https://www.lunarg.com/lunarg-releases-vulkan-sdk-1-0-69-0-for-mac/ +* Added support for OpenGL ES using ANGLE when it's available + +Mac OS X / iOS / tvOS: +* Added a Metal 2D render implementation +* Added SDL_RenderGetMetalLayer() and SDL_RenderGetMetalCommandEncoder() to insert your own drawing into SDL rendering when using the Metal implementation + +iOS: +* Added the hint SDL_HINT_IOS_HIDE_HOME_INDICATOR to control whether the home indicator bar on iPhone X should be hidden. This defaults to dimming the indicator for fullscreen applications and showing the indicator for windowed applications. + +iOS / Android: +* Added the hint SDL_HINT_RETURN_KEY_HIDES_IME to control whether the return key on the software keyboard should hide the keyboard or send a key event (the default) + +Android: +* SDL now supports building with Android Studio and Gradle by default, and the old Ant project is available in android-project-ant +* SDL now requires the API 19 SDK to build, but can still target devices down to API 14 (Android 4.0.1) +* Added SDL_IsAndroidTV() to tell whether the application is running on Android TV + +Android / tvOS: +* Added the hint SDL_HINT_TV_REMOTE_AS_JOYSTICK to control whether TV remotes should be listed as joystick devices (the default) or send keyboard events. + +Linux: +* Added the hint SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR to control whether the X server should skip the compositor for the SDL application. This defaults to "1" +* Added the hint SDL_HINT_VIDEO_DOUBLE_BUFFER to control whether the Raspberry Pi and KMSDRM video drivers should use double or triple buffering (the default) + + +--------------------------------------------------------------------------- +2.0.7: +--------------------------------------------------------------------------- + +General: +* Added audio stream conversion functions: + SDL_NewAudioStream + SDL_AudioStreamPut + SDL_AudioStreamGet + SDL_AudioStreamAvailable + SDL_AudioStreamFlush + SDL_AudioStreamClear + SDL_FreeAudioStream +* Added functions to query and set the SDL memory allocation functions: + SDL_GetMemoryFunctions() + SDL_SetMemoryFunctions() + SDL_GetNumAllocations() +* Added locking functions for multi-threaded access to the joystick and game controller APIs: + SDL_LockJoysticks() + SDL_UnlockJoysticks() +* The following functions are now thread-safe: + SDL_SetEventFilter() + SDL_GetEventFilter() + SDL_AddEventWatch() + SDL_DelEventWatch() + + +General: +--------------------------------------------------------------------------- +2.0.6: +--------------------------------------------------------------------------- + +General: +* Added cross-platform Vulkan graphics support in SDL_vulkan.h + SDL_Vulkan_LoadLibrary() + SDL_Vulkan_GetVkGetInstanceProcAddr() + SDL_Vulkan_GetInstanceExtensions() + SDL_Vulkan_CreateSurface() + SDL_Vulkan_GetDrawableSize() + SDL_Vulkan_UnloadLibrary() + This is all the platform-specific code you need to bring up Vulkan on all SDL platforms. You can look at an example in test/testvulkan.c +* Added SDL_ComposeCustomBlendMode() to create custom blend modes for 2D rendering +* Added SDL_HasNEON() which returns whether the CPU has NEON instruction support +* Added support for many game controllers, including the Nintendo Switch Pro Controller +* Added support for inverted axes and separate axis directions in game controller mappings +* Added functions to return information about a joystick before it's opened: + SDL_JoystickGetDeviceVendor() + SDL_JoystickGetDeviceProduct() + SDL_JoystickGetDeviceProductVersion() + SDL_JoystickGetDeviceType() + SDL_JoystickGetDeviceInstanceID() +* Added functions to return information about an open joystick: + SDL_JoystickGetVendor() + SDL_JoystickGetProduct() + SDL_JoystickGetProductVersion() + SDL_JoystickGetType() + SDL_JoystickGetAxisInitialState() +* Added functions to return information about an open game controller: + SDL_GameControllerGetVendor() + SDL_GameControllerGetProduct() + SDL_GameControllerGetProductVersion() +* Added SDL_GameControllerNumMappings() and SDL_GameControllerMappingForIndex() to be able to enumerate the built-in game controller mappings +* Added SDL_LoadFile() and SDL_LoadFile_RW() to load a file into memory +* Added SDL_DuplicateSurface() to make a copy of a surface +* Added an experimental JACK audio driver +* Implemented non-power-of-two audio resampling, optionally using libsamplerate to perform the resampling +* Added the hint SDL_HINT_AUDIO_RESAMPLING_MODE to control the quality of resampling +* Added the hint SDL_HINT_RENDER_LOGICAL_SIZE_MODE to control the scaling policy for SDL_RenderSetLogicalSize(): + "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen (the default) + "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen +* Added the hints SDL_HINT_MOUSE_NORMAL_SPEED_SCALE and SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE to scale the mouse speed when being read from raw mouse input +* Added the hint SDL_HINT_TOUCH_MOUSE_EVENTS to control whether SDL will synthesize mouse events from touch events + +Windows: +* The new default audio driver on Windows is WASAPI and supports hot-plugging devices and changing the default audio device +* The old XAudio2 audio driver is deprecated and will be removed in the next release +* Added hints SDL_HINT_WINDOWS_INTRESOURCE_ICON and SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL to specify a custom icon resource ID for SDL windows +* The hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING is now on by default for compatibility with .NET languages and various Windows debuggers +* Updated the GUID format for game controller mappings, older mappings will be automatically converted on load +* Implemented the SDL_WINDOW_ALWAYS_ON_TOP flag on Windows + +Linux: +* Added an experimental KMS/DRM video driver for embedded development + +iOS: +* Added a hint SDL_HINT_AUDIO_CATEGORY to control the audio category, determining whether the phone mute switch affects the audio + +--------------------------------------------------------------------------- +2.0.5: +--------------------------------------------------------------------------- + +General: +* Implemented audio capture support for some platforms +* Added SDL_DequeueAudio() to retrieve audio when buffer queuing is turned on for audio capture +* Added events for dragging and dropping text +* Added events for dragging and dropping multiple items +* By default the click raising a window will not be delivered to the SDL application. You can set the hint SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to "1" to allow that click through to the window. +* Saving a surface with an alpha channel as a BMP will use a newer BMP format that supports alpha information. You can set the hint SDL_HINT_BMP_SAVE_LEGACY_FORMAT to "1" to use the old format. +* Added SDL_GetHintBoolean() to get the boolean value of a hint +* Added SDL_RenderSetIntegerScale() to set whether to smoothly scale or use integral multiples of the viewport size when scaling the rendering output +* Added SDL_CreateRGBSurfaceWithFormat() and SDL_CreateRGBSurfaceWithFormatFrom() to create an SDL surface with a specific pixel format +* Added SDL_GetDisplayUsableBounds() which returns the area usable for windows. For example, on Mac OS X, this subtracts the area occupied by the menu bar and dock. +* Added SDL_GetWindowBordersSize() which returns the size of the window's borders around the client area +* Added a window event SDL_WINDOWEVENT_HIT_TEST when a window had a hit test that wasn't SDL_HITTEST_NORMAL (e.g. in the title bar or window frame) +* Added SDL_SetWindowResizable() to change whether a window is resizable +* Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity() to affect the window transparency +* Added SDL_SetWindowModalFor() to set a window as modal for another window +* Added support for AUDIO_U16LSB and AUDIO_U16MSB to SDL_MixAudioFormat() +* Fixed flipped images when reading back from target textures when using the OpenGL renderer +* Fixed texture color modulation with SDL_BLENDMODE_NONE when using the OpenGL renderer +* Fixed bug where the alpha value of colorkeys was ignored when blitting in some cases + +Windows: +* Added a hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING to prevent SDL from raising a debugger exception to name threads. This exception can cause problems with .NET applications when running under a debugger. +* The hint SDL_HINT_THREAD_STACK_SIZE is now supported on Windows +* Fixed XBox controller triggers automatically being pulled at startup +* The first icon from the executable is used as the default window icon at runtime +* Fixed SDL log messages being printed twice if SDL was built with C library support +* Reset dead keys when the SDL window loses focus, so dead keys pressed in SDL applications don't affect text input into other applications. + +Mac OS X: +* Fixed selecting the dummy video driver +* The caps lock key now generates a pressed event when pressed and a released event when released, instead of a press/release event pair when pressed. +* Fixed mouse wheel events on Mac OS X 10.12 +* The audio driver has been updated to use AVFoundation for better compatibility with newer versions of Mac OS X + +Linux: +* Added support for the Fcitx IME +* Added a window event SDL_WINDOWEVENT_TAKE_FOCUS when a window manager asks the SDL window whether it wants to take focus. +* Refresh rates are now rounded instead of truncated, e.g. 59.94 Hz is rounded up to 60 Hz instead of 59. +* Added initial support for touchscreens on Raspberry Pi + +OpenBSD: +* SDL_GetBasePath() is now implemented on OpenBSD + +iOS: +* Added support for dynamically loaded objects on iOS 8 and newer + +tvOS: +* Added support for Apple TV +* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. + +Android: +* Fixed SDL not resizing window when Android screen resolution changes +* Corrected the joystick Z axis reporting for the accelerometer + +Emscripten (running in a web browser): +* Many bug fixes and improvements + + +--------------------------------------------------------------------------- +2.0.4: +--------------------------------------------------------------------------- + +General: +* Added support for web applications using Emscripten, see docs/README-emscripten.md for more information +* Added support for web applications using Native Client (NaCl), see docs/README-nacl.md for more information +* Added an API to queue audio instead of using the audio callback: + SDL_QueueAudio(), SDL_GetQueuedAudioSize(), SDL_ClearQueuedAudio() +* Added events for audio device hot plug support: + SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED +* Added SDL_PointInRect() +* Added SDL_HasAVX2() to detect CPUs with AVX2 support +* Added SDL_SetWindowHitTest() to let apps treat parts of their SDL window like traditional window decorations (drag areas, resize areas) +* Added SDL_GetGrabbedWindow() to get the window that currently has input grab, if any +* Added SDL_RenderIsClipEnabled() to tell whether clipping is currently enabled in a renderer +* Added SDL_CaptureMouse() to capture the mouse to get events while the mouse is not in your window +* Added SDL_WarpMouseGlobal() to warp the mouse cursor in global screen space +* Added SDL_GetGlobalMouseState() to get the current mouse state outside of an SDL window +* Added a direction field to mouse wheel events to tell whether they are flipped (natural) or not +* Added GL_CONTEXT_RELEASE_BEHAVIOR GL attribute (maps to [WGL|GLX]_ARB_context_flush_control extension) +* Added EGL_KHR_create_context support to allow OpenGL ES version selection on some platforms +* Added NV12 and NV21 YUV texture support for OpenGL and OpenGL ES 2.0 renderers +* Added a Vivante video driver that is used on various SoC platforms +* Added an event SDL_RENDER_DEVICE_RESET that is sent from the D3D renderers when the D3D device is lost, and from Android's event loop when the GLES context had to be recreated +* Added a hint SDL_HINT_NO_SIGNAL_HANDLERS to disable SDL's built in signal handling +* Added a hint SDL_HINT_THREAD_STACK_SIZE to set the stack size of SDL's threads +* Added SDL_sqrtf(), SDL_tan(), and SDL_tanf() to the stdlib routines +* Improved support for WAV and BMP files with unusual chunks in them +* Renamed SDL_assert_data to SDL_AssertData and SDL_assert_state to SDL_AssertState +* Added a hint SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN to prevent window interaction while cursor is hidden +* Added SDL_GetDisplayDPI() to get the DPI information for a display +* Added SDL_JoystickCurrentPowerLevel() to get the battery level of a joystick +* Added SDL_JoystickFromInstanceID(), as a helper function, to get the SDL_Joystick* that an event is referring to. +* Added SDL_GameControllerFromInstanceID(), as a helper function, to get the SDL_GameController* that an event is referring to. + +Windows: +* Added support for Windows Phone 8.1 and Windows 10/UWP (Universal Windows Platform) +* Timer resolution is now 1 ms by default, adjustable with the SDL_HINT_TIMER_RESOLUTION hint +* SDLmain no longer depends on the C runtime, so you can use the same .lib in both Debug and Release builds +* Added SDL_SetWindowsMessageHook() to set a function to be called for every windows message before TranslateMessage() +* Added a hint SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP to control whether SDL_PumpEvents() processes the Windows message loop +* You can distinguish between real mouse and touch events by looking for SDL_TOUCH_MOUSEID in the mouse event "which" field +* SDL_SysWMinfo now contains the window HDC +* Added support for Unicode command line options +* Prevent beeping when Alt-key combos are pressed +* SDL_SetTextInputRect() re-positions the OS-rendered IME +* Added a hint SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 to prevent generating SDL_WINDOWEVENT_CLOSE events when Alt-F4 is pressed +* Added a hint SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING to use the old axis and button mapping for XInput devices (deprecated) + +Mac OS X: +* Implemented drag-and-drop support +* Improved joystick hot-plug detection +* The SDL_WINDOWEVENT_EXPOSED window event is triggered in the appropriate situations +* Fixed relative mouse mode when the application loses/regains focus +* Fixed bugs related to transitioning to and from Spaces-aware fullscreen-desktop mode +* Fixed the refresh rate of display modes +* SDL_SysWMInfo is now ARC-compatible +* Added a hint SDL_HINT_MAC_BACKGROUND_APP to prevent forcing the application to become a foreground process + +Linux: +* Enabled building with Mir and Wayland support by default. +* Added IBus IME support +* Added a hint SDL_HINT_IME_INTERNAL_EDITING to control whether IBus should handle text editing internally instead of sending SDL_TEXTEDITING events +* Added a hint SDL_HINT_VIDEO_X11_NET_WM_PING to allow disabling _NET_WM_PING protocol handling in SDL_CreateWindow() +* Added support for multiple audio devices when using Pulseaudio +* Fixed duplicate mouse events when using relative mouse motion + +iOS: +* Added support for iOS 8 +* The SDL_WINDOW_ALLOW_HIGHDPI window flag now enables high-dpi support, and SDL_GL_GetDrawableSize() or SDL_GetRendererOutputSize() gets the window resolution in pixels +* SDL_GetWindowSize() and display mode sizes are in the "DPI-independent points" / "screen coordinates" coordinate space rather than pixels (matches OS X behavior) +* Added native resolution support for the iPhone 6 Plus +* Added support for MFi game controllers +* Added support for the hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK +* Added sRGB OpenGL ES context support on iOS 7+ +* Added support for SDL_DisableScreenSaver(), SDL_EnableScreenSaver() and the hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER +* SDL_SysWMinfo now contains the OpenGL ES framebuffer and color renderbuffer objects used by the window's active GLES view +* Fixed various rotation and orientation issues +* Fixed memory leaks + +Android: +* Added a hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH to prevent mouse events from being registered as touch events +* Added hints SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION and SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION +* Added support for SDL_DisableScreenSaver(), SDL_EnableScreenSaver() and the hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER +* Added support for SDL_ShowMessageBox() and SDL_ShowSimpleMessageBox() + +Raspberry Pi: +* Added support for the Raspberry Pi 2 + + +--------------------------------------------------------------------------- +2.0.3: +--------------------------------------------------------------------------- + +Mac OS X: +* Fixed creating an OpenGL context by default on Mac OS X 10.6 + + +--------------------------------------------------------------------------- +2.0.2: +--------------------------------------------------------------------------- +General: +* Added SDL_GL_ResetAttributes() to reset OpenGL attributes to default values +* Added an API to load a database of game controller mappings from a file: + SDL_GameControllerAddMappingsFromFile(), SDL_GameControllerAddMappingsFromRW() +* Added game controller mappings for the PS4 and OUYA controllers +* Added SDL_GetDefaultAssertionHandler() and SDL_GetAssertionHandler() +* Added SDL_DetachThread() +* Added SDL_HasAVX() to determine if the CPU has AVX features +* Added SDL_vsscanf(), SDL_acos(), and SDL_asin() to the stdlib routines +* EGL can now create/manage OpenGL and OpenGL ES 1.x/2.x contexts, and share + them using SDL_GL_SHARE_WITH_CURRENT_CONTEXT +* Added a field "clicks" to the mouse button event which records whether the event is a single click, double click, etc. +* The screensaver is now disabled by default, and there is a hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER that can change that behavior. +* Added a hint SDL_HINT_MOUSE_RELATIVE_MODE_WARP to specify whether mouse relative mode should be emulated using mouse warping. +* testgl2 does not need to link with libGL anymore +* Added testgles2 test program to demonstrate working with OpenGL ES 2.0 +* Added controllermap test program to visually map a game controller + +Windows: +* Support for OpenGL ES 2.x contexts using either WGL or EGL (natively via + the driver or emulated through ANGLE) +* Added a hint SDL_HINT_VIDEO_WIN_D3DCOMPILER to specify which D3D shader compiler to use for OpenGL ES 2 support through ANGLE +* Added a hint SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT that is useful when creating multiple windows that should share the same OpenGL context. +* Added an event SDL_RENDER_TARGETS_RESET that is sent when D3D9 render targets are reset after the device has been restored. + +Mac OS X: +* Added a hint SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK to control whether Ctrl+click should be treated as a right click on Mac OS X. This is off by default. + +Linux: +* Fixed fullscreen and focused behavior when receiving NotifyGrab events +* Added experimental Wayland and Mir support, disabled by default + +Android: +* Joystick support (minimum SDK version required to build SDL is now 12, + the required runtime version remains at 10, but on such devices joystick + support won't be available). +* Hotplugging support for joysticks +* Added a hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK to control whether the accelerometer should be listed as a 3 axis joystick, which it will by default. + + +--------------------------------------------------------------------------- +2.0.1: +--------------------------------------------------------------------------- + +General: +* Added an API to get common filesystem paths in SDL_filesystem.h: + SDL_GetBasePath(), SDL_GetPrefPath() +* Added an API to do optimized YV12 and IYUV texture updates: + SDL_UpdateYUVTexture() +* Added an API to get the amount of RAM on the system: + SDL_GetSystemRAM() +* Added a macro to perform timestamp comparisons with SDL_GetTicks(): + SDL_TICKS_PASSED() +* Dramatically improved OpenGL ES 2.0 rendering performance +* Added OpenGL attribute SDL_GL_FRAMEBUFFER_SRGB_CAPABLE + +Windows: +* Created a static library configuration for the Visual Studio 2010 project +* Added a hint to create the Direct3D device with support for multi-threading: + SDL_HINT_RENDER_DIRECT3D_THREADSAFE +* Added a function to get the D3D9 adapter index for a display: + SDL_Direct3D9GetAdapterIndex() +* Added a function to get the D3D9 device for a D3D9 renderer: + SDL_RenderGetD3D9Device() +* Fixed building SDL with the mingw32 toolchain (mingw-w64 is preferred) +* Fixed crash when using two XInput controllers at the same time +* Fixed detecting a mixture of XInput and DirectInput controllers +* Fixed clearing a D3D render target larger than the window +* Improved support for format specifiers in SDL_snprintf() + +Mac OS X: +* Added support for retina displays: + Create your window with the SDL_WINDOW_ALLOW_HIGHDPI flag, and then use SDL_GL_GetDrawableSize() to find the actual drawable size. You are responsible for scaling mouse and drawing coordinates appropriately. +* Fixed mouse warping in fullscreen mode +* Right mouse click is emulated by holding the Ctrl key while left clicking + +Linux: +* Fixed float audio support with the PulseAudio driver +* Fixed missing line endpoints in the OpenGL renderer on some drivers +* X11 symbols are no longer defined to avoid collisions when linking statically + +iOS: +* Fixed status bar visibility on iOS 7 +* Flipped the accelerometer Y axis to match expected values + +Android: +IMPORTANT: You MUST get the updated SDLActivity.java to match C code +* Moved EGL initialization to native code +* Fixed the accelerometer axis rotation relative to the device rotation +* Fixed race conditions when handling the EGL context on pause/resume +* Touch devices are available for enumeration immediately after init + +Raspberry Pi: +* Added support for the Raspberry Pi, see README-raspberrypi.txt for details diff --git a/libultraship/libultraship/Lib/SDL/lib/x64/SDL2.lib b/libultraship/libultraship/Lib/SDL/lib/x64/SDL2.lib new file mode 100644 index 0000000000000000000000000000000000000000..6d70cc20f868f3aee54c7cffc4d51587b24fbdb4 GIT binary patch literal 16880106 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%0DE$M)gnCOuZn><()d9 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�G zf@w8CaRAzQZk^o;hrdFE3Exc*$813`9J>cf2|bY(5*P5s#J0dk zn9P-8N$pHSsBuC_hAJCQVaA3lfFXjQ+UIzQu$)vTo#8U*HzHoc;LWqDFQb=#MG0!~Npdv&1n4T-f5v=N2Nfg%D75uxj=sRnIg{UEBA!Qf ziTJG(pJ8b!YT?sA=S)1i&nDj2j5R~+;LYL$F4Ic7ba`QW&!w|G-G#Z@> z;%&Preh*1+KSUgB8nK<|G-8?c=IoxfVs%+p3HBR=)yKcwW%sI zu1l=O^JiI)<)>#S-y)v*trGnn0A55y03x%g>PRmy>e-E0l5(71DkO^b1uM`W+-v!L7ulN>~-L zazH5j4Cnx|WcV2*ZOpb4aQuvtemJtt@<&W3(>T+qSzNw#TAa95iQ95wkQyd$-<>@8 z>1DNNtKgV~59x>WL*c?g&8`(2`K=TEq`p~3llo?b<$SioSRP^Ni>B!lbB>aX#@!NKw%It>+58{aF}#E2bxcwRpx=z zGSO%zm@tA*J0%z%uGBNTDnN0rS3Fp4xRhvtgL>F3lKe|m>1O%~os7n$XCp4H`VQ#b?8FF>#Ap>ujGvC~W%_%#TEY{hP`4Ha zxcu)D@rA_zj_eXBBJAIc`_<+7WADq|!(YSm>+2HiqJMYOdwl3$mQs4xy-P|sFBA1{ zaS?QPd(*ppOr&1-zkGcxv4gMJ`D33RClP-#C)G{w^6U9+GM}5fB*ooBpK?y8J$~&y zl=2u{p5NXk;7_-Mr~CW6hsPcq)=GYE7lXU&r^nv#{-HM*JU!sYIT*R>P#$rYm#D1= zmI&T(UlP1D#$SyX|4w3DU6CMoT%{zbq+lj2rCdMuAD^zsY45RjdwUM=yz}cGJokoZ z_1?pvhN5?U-M=5);Xc3j@BjzE76gr`PKr#{4!@GK@ku<_^_=oc91i~ZbpDWR?i7oZ ze_~4(DL=(#77fmorFM>eGE;&l8apOS37a5$yty0PW1#gf{ouGbcjL~F3^%k6fS4sNq{Q9Yvm>^94l8j?++zdf_6MbTu3Fr?S_#ZW-iSpZg6mNJ zYDW2YC5qqP4L?8h{`u6qz5Hv4DgE)^WuX*qdU8?-2mx?O6XD(G;R7NCB<3oOeD@s@ z1HPX>J|-s3V3%1jEzAA^lYIYaP+8Q^{eKOy>R%^keM+RT2IW$JzC%fdx4rL=cee@g zzMMaO$=Dly>0t|n<{$L#u^8z+t6w~*7u})aq+8tFT_vO;oB>xIb)6a^y20{IJ7jdAgxEIy?qB^IiWO0{ zfrFvX)1~zMuf5xc#PWQN+TpFN2{ut~Fg|z;FTXzA-Ovso#e%E=sshJ(8&bg@KEceh^}%6fDD<+k^T{nzJy@A?W; z3Z|Jak6&rp=wsuK&N)bQf+{MsO9v`UE;&?Rdl;U#Uxt@=sJYt#_IBuqR{UEWzP{Q> z9_5;Fcqt~24^J4MEg4kyo>Ep0&^C)sa=F7wMkTn-eFm=E(bwR9JAdd`OifY=q$9vY zjnmcB!}(=mV980nqQ9HOiv9Y{6V9l-GqtCH3Pk7|==@3t+0>v>T7e2V?(YVDp3*Ys zHsC|QahaTsv7TIEeZz+T_6t1qDti_1P;TcnBE`HzYLG|h8KOOe(`hC!=2f6+?+$JlbGIUU}EOL$!plZ9e(TgzL&)) z;|$OL-M@Ky{F;S}zOVgqc=$|64YuOEHjsEYKOd5-C8=C;TFO%DaQxlgdZ zdxEN=Vv^yx+b%Yhqxu{6$)vH&-6egyyT;h;4e4*9GQRhCU-FOs_1%|;^VIMrYiDGJ zeV9yOCf*h%p#CLx8~^y;r?;Eq7G$c1_Ldzq?M-El$0{9bL7*?BiB42&W+@naJ^zQx zQ4n~pdAi3RuU?as4DKF9Nc`ZBSp*Gd5+7*yjQNvxw_oDir5{I0=+;6KuW2qp2x!5f zRpXo5PkI#SuCOW&+}uo6V4J~Xm1|U`K`$+Bst+MP-KdowdZeYs#EiuRYh@{qtKQ)9 zp?^=EBay~4#{IdUr5*pzq)NZK{%d%P<}Xp=q2OVlaB_6AS;ne#k2$S3#J1pDncQuI zAsxEzRcZg=*x?NE^!fbq5u0kKMD&SRj+)9(=b>_~poOVvsP{hI_Ho8lM{dWS4v%-? zbdXA;GtRgEouA7T68ao=v^e2B-IVH(55d?d-=T z3KsA1c;i!^9&nVS)7h33D{(|wo?{pQ3#DluT!zl3!LIr-|L%QeMT71W^Ht#A#B z+F#UQg)3$gA}^8w5^H}#h*gsX&@X>M-N2`#s7`%CRH;58s#U8i33Vyl@obV&qXZIQ zcXr*sO$!mEMREjbktkjr6J+IP^oxhP^Q+7AfjelhlrH%SM}ExNm;boC#mPU-0t&5k z!u8$VKc3vaEo6MBuXn>Fni2gqc9@0}k3=oi3nZhMv*{ID@bdA_Ek2SKpG*UJ@9$_~ z;p=lhKQo=ZFAmWC2`&WFxh*x-&`q;jQkgCHQEBFYMYs=V)JNLl21rl0I1YSwn*+u& zyVAe8praD(ryy5(XJUYN6k*z1tgMHf3ds1k$HC{pZ1ID_c|H_V_i4iR|Lv*Yn->&8 zm60yszPoUsD6zMgR3&lHQi@c}L4P7T@sH7@*Ts5G5kNic`}yGfzCYv#kYGGvJg_X( zd2Ja0i+K$P{yuUP?;4Y0V`#zrA9n3u3OqlbN~iZnpYg&}8G)Y2VWWJM_I(K_m-XKa zYtU@So9C)vC&BOB`$!8~9{ixxnk7<`4-_BIHd6oHkqt;f9?{U}UOI1e09pwc+A!LLyWGyczE zJ_xm2&YT95bsxsqG8qw+nDW58W$A}y*@uu^#Wy48MoW*BRA%L( z4$B1%JdQ0x1dQr^xt1@9;OFAj^7fFy0*`_FbX=L*G~xZ&%VOl}{CQ?+3qm+R5m!bs}L zDPlv;oK`eWCxEXm`LfkTsu{%bCRbCURWAz3HxiHxB=ZRes`absPSU;L%TF;GM-$}f zASz-zv4yw$i4J{F0( zlMg*-kfkDZu(Tk-20pVq1l@-b3*lk6hp2*XgMS5_`*7_Escjo^T#f+OMX(A9T$HL1 zYy(sUENsB35Y+{h3c+qbyCO(5DCQUhKoUBDRELBwu8tPOMDU?@)z36f3pnjO+aep# zJRB=B<%Od~)=26oCUz6C7a*8X@JtUdjTNngChUVm4zl}0BJ%Mh645UdLc9tXy7B}a z$7f*CL@1daW(!0xFoMAUl7=sXxLM4M#{qu~+%<;)hgb7Cg#^8Pc;q^VYr}9jD~jUu z_z13WZ^QT5@_<0=(Qx#0G@H{r4yViM2sYG!|0q_AVh*3owf|6LCYg-79WI%056R7L z{{Qy&Pxtgc9zHrgDfXx1gXyQ~;qjS;A09FGzWe?p)b9H%{yu&Fba*y8I6l}rIvabs zGa+Er++>>C=Q=RdZ2o`(c%8t zr_n(X(>wU#>E7v~!yiX@E6hvM{InK-=3@!7PP9`5f?_Ya;APdt3|X*w#-o{LYP z4nIwfJbbeEd~~u8<}679&V}*t;&^g)I65AUr<3E;v4W2d&yex)>Dl4<)aP3q>>ZC! z_V>o4PbcF;-`>T+eo>qi&y(k)=l!vlr#PHUo=<#vio*icu!q`w-rJx0_AjDx7sp4V zV()qS>3A}k9w~muqvE(YL5n}1jf-a|Z*g*RczSYndhlF~jwZhTi}d(7ETVQU&JIqC zqv@x;v+?l(oLSBIIxL=_pC?EA&->HjRN+(esrEw^o*s`; zEhl@&hpHc<_w4QC|7YXp{o^ww@AUa#gdThJJUtz$cAZB3cDlcRd~z}xO%IMI#er`( zbd!V0p6_SWZ9eTy4-ck$qtn8-*L45r6n$s3cX)bsF!Jp?-5(vE6bA)0;^BcW*Yv>3 zyMMAj@$CjU{_*WFJ={AunV#;CK27%bPCmJMoF4K&{#%B!`aV25ntYlbObuR?|0}K^pB_ev~T{|n|{*u_vzr^1fBfsr1*5C^FP}gO%6xJA)05jugZ6J za&k01`gF7h0S{IAM*HaZCp7V%P1HD>qT?SO9UY8MMkkouy*#61|Id-?52LeF49Npb zL3T~StvpDthF;=jnGy4A?+IgzVi^A{kA55l) z#qoifAEua;Mtf(Iz0*(QlQWI)tLOMo$vIZ=BQ-w8r$=a+vy<^NDnjF*?M)}DzmLz% zKc9+cHSbNw7;Xojjz&kvM+Nj*uD^|`UXJ%CwEm4WeDdk!XoSi340DC*&l6Kq^2hU; z>_fo4(b+y`Cp}&!s44%C!k2nHIygAf`+?~M<8J@(c<*dVD~7_CdfCU2JULSHz(m#8 zUIqME%dhZH)OehHIz2epKifaX>M&OQbzk6f3%A5|Iu@GKfo;Tj7j(yqwZMG zduBsms=}A6kco)@yQkzS4#y`vS)-ozRsSoFjxnb}#0qbf6KeR2T;4*^{TT3r$=T`n6zk8y z{)9H-yl)0PS-%87-Y;B##CJvh`!=gU-lM(!3cmZvb^tzBCT#Nd##kSGe?Qs_hOsKo zQ851;?H!-!41M`dD&VITaLvWf14nzGlKu8*Z!(=ueUW^=1>m;#Xg=xwbF{xd##YRY zx1;@&qfcYMo*$X>jpJW&-Z?rrWnmoNft1I8i>&IK5&XBvr@pxm?)y+qPW~G`L;a)R zAz#d_`X7&XIwH9GW&!-S3>5c$6yYC5UCzI3r&IYnxpWcfZ%(&v`v==|^;?IUqOU}lcb z6boWv-}F2kO|Va%93SB1Jvnpz?RlDB{{aui*)tBasd*PmkuMB>c{$SamK`w`58ui8 z3GifoagJ?^ke3i|Q5qCaxyQSxJL;D4N)<^J*e?d|^wlKZcn zv)tSWa)oABx%e;DnnJT{iREU|X%nf??19^MDOaJj zJYvCZWXflB7JJw->mt}Lk^1YoVbg~H?eTw0e;pc)X?+B@09GR4Cl|3O~Cw?QLm>;5%pRxefc*P@w%9#;IdXr{^z zEB;!vLJsSP6@M+78RCZ(e;t|#b!euf_^&~uy&*MD)nAKdig;A<*P@wu{ix!vMKja* zQN>?_X1kGeo@k2%V1#DTV)&$d!O(7??*l9)ULPQz4lsrs%h0K1genm zNO_|egAdybiH9(7d2qDI(S4P`0w-)#-Y6yzrKkYeDq#hKbMo=X-bVNe@5>oIaEcd< z=XY>jP!@vpjgD+hl!u-<g?L`f@R)g{cwTQ)4m30;>e+*R zetOj~JodEDEHa1VgkX#blg8WVzs`3f=(AxM3J$T-29K2RjFG@_i2RHYsJM=hScEnR zmceQ~!ds0Sid!u?QzuU9*r8nxKK%9aq3RAt$`8 z87fy-haBWbztHN60yK+5i4+2$QgunD%GDKtDrJkRE@4DhR~WDv#!PA-t`6J1DgmNf z6cU|BY9u<314QK!Bq~q1mRM^dH4H@ZMAw^8AR|(7m61p;hZI#5kf^!~=ZmhqN?7Hb zT76+or2e81)bCvF=p zXX1q6qr9b0irHr4ZHOjMvGAAU7m2+0#cX7Jk!B!Vco~ka9IlZM$K%~Wy-o|4rA&_v4Y&d21p0>v_B&la6d$R1gO9KCT?m?()1P%4v zCGpig_c(_R#7u@Vo{TDX5vdaNn zqda+tq4YR0$+OhFGxPAlhnPnQ)WrB49_c%H=C*>XAmB{G5m9x1&%NQy(9v_hQ#y9H z_nu)R1ke0Y@?!|V?1b2xF=oTqdysA7IParcEF4*I)jDvLch{+6mt-86H~z0jrtvxO z5c`Ya<8dABiAqFc54uDz^}_LC1rHb=Y@Vq7WzD#{CtE5jOei*D67SL&`lZ6Z?B9f;E{Up$iHNb zx>(2=I&d_OSviuSDq@wwFsD^tVqW!>NyEoYfcJNmWmUNo)(pX+d&0N^oWgh?$Z&gR zVBzqbDYzmih%pUEQSdb2udT}ZtIYANIfsG^vREhBVa9}kdBX=*C1V`E>=0w%J2DE# zpH-EB!toue+C6IGm@3PcdYw4Pd+M>6*E zd5Ww;!908}t%^M)5pm|8ew@FedpAcVXj-d6y! zv&x*F>c|3ew{~XbduwI|0z?#oTeyX|q`*&m!bXnSI!`99vr(l(C@ zUVfdU(rOC)F`+;U+n8XzG>WJ@nH*mN3hh!Z>3d zbU0x&&GbrZ%XjipM~?|(O^~ROX-sqcxcKl(snaXhUG8S!?ZF9jC(9Tqw+_m6$$O)g z!HcZM)Vs>^>SE<3uduc;?|^f5zU3vM;4}|;??K*!g~sIHRJFW&Ag|FhV-}ZKUd6kSyqYoOEvRSA4d66f zWqDV`(2w%6J~Za(PpX&KbPMeGu4;L;V8_0L#{BuG<(-O^m%W>zcz@$F?P{?H7_%Hd zFMF@2e)WCkohFtS%ifn^??os1%x~>1uXhZ4Des~Sedg7RtC!c|5}(=AuWEU;x5F@> zxoC{#Rb}r(1wJ$O2Fr_OZyxk3neH?DiY*VDp7l2a_NLGFnYSOdyezD|>W}hXf6ix` zzEr)uvEcl&wrY8;Veb!RK6Bz{mKV$3d(cpmKlhm$dn|8RjP|V$UcG%j)BK3#CB?9} zu)Z9-E;(P%`R`Ffn?#cJP~n8-Sgk25Q7wLEs$Sn{UKjWb;ytX|$+ za2hSHTHcvx-;ZC7Gsms8ywhUXTL^ovUlnJ*TW@)sj=c060R#VC7H67nuUfxh=+9%p z`E;M<#p=(LxAD(7b6x@_RxGjVkMfGaInc=RV##BF{;s*-G-zviRrTkIfAgE;&bPc+ z{ka3=C3p3kuH7v!)_ngxjvuqYnRvD39gb0dl$SloZ>9~aUf$c_{A+U6@}5HV&brxe z+Rv~&G^6MIG82kF4Nm*nmX}wBekacHo6F`^uistZ-1tP*`qAD#OZ?{cm#UZd0XVO` zRkb|Yd)IouIcKBgRb}tLz&Ynr%Zp`iI`nJ$x!(->s%rgGLdHA=&f5K!heMs`_@KPC zhtaS6_CzgKf1$jd;1txgyjb!chP?$%;!W*SEHBpl_Y?{m2Tr5rmNzU$`(A(nc1Ejs zGxW@=^~-{O&x3QQi{;ggVK3!9pB-=Z^r>E6yT0+}h9OnUs|S1A6~>#c<18zVYrOgCZp(|+9+dafL-FS3$E%n34mj7p zShYM(^Vh!~Z%!z+yjb=wg5uYK(`c>b<;SqM3-mkT{djZrrmFR0|62&o8#}7jkMiF5 z4xIhf%exqyd|v>XVTsXS=EL6n8sOBnyjb?W1$*o$(jetn6e|dU;p(2$-TlRm%&Z{^AP*rrspWI~8`sI)5HJ zIbgcYu)J93lOMz0fyDuH_B~bWcRuW00?v0&SziAb_EO&TuGth&Y#ynq0{>&nC}NvtzSd5@A)|iruTTu zi`AbgZ)s72nKY|34?1 z5hDJ@vbPI(J&r=&sH2oO1H3s$A#d?f%3A~8rfTG|-S!@(yu;unuC2QMT0q|E;Pi0w zJo?KhaHhC2T56CweRoX1>ddO-c(3P1t-(Z z^UyCJoN;cROF!B>2b@K2o`<|Qz**b6^XPwO1I~x=;}WZV*`Ln<=Ug|>L*CWks@~r7!O3*8=8d~hbYc^>xO1I{8h&n1uczTt4hSp17+?^f`3 zRwIx0#($Jx&c~07_EQi2`hk=0=DGBvy)(eM$IbJQ_X0R?xOpylwD&WIL;bkKviBf( z@x1YgMeT6OqrJ_*>F4Ho=r;wN8E&3S9_@V;oEO|Y4|yBF`OM98$)ml$I~*isiDmBz zWeKJkeq5@uHw~OAZk~sJ^T2u3&2#BTdrQID;O2SA`w^Vq-8`4PhLG3rV`~HL;1bK; zcHo`waAVnZ@GCc{b=u(;OuwvJml5+B*8Snk4r55Xz#fWM~L_r z%ib%%8&HkBG~~YloE2`KhkjeZ+3Dta*c-nk!PLi(i`wBKuLC$2x_K^n?9crjjtIoR zSoTfrp&PV=7!P)NSdFXc-oWxIEcDVFo`<@O?CpXVSUT<)6-8`2(+Iy43K~k1j z_Ra_IpVi2ty>F4T)n$i=ekX%-hMVWokM?GQbG4i2A#V~mx43yOd9-(t!x3ZgFP6P4 zz*}35JleYxoMzjqw>J%(EH}@kAMG6h&UJ2{hrRcM^SGPml1F=2IUFQqiDmD0@b*+A zkM<^hhU;JaxKuUX27xoi&2#BTduM~Qz|Hfp_f>G#xOpylwD)U=L;bkKve$f$^IiP7 zs2whOJpP^m&LB6>L%$+$X1jSVd9?Q#a9(xuJmhTw=W935C6D&TZMQZcDN8JSPX_M{ zhg+4sncx(;c^>*L1m_ty&!r#jT?@_@H_t=fui(UeQFVLJ-V}#pt&QEj=YyA7jXbt* zJ~#{AJP-X=fV0-k^RRa(IKR4i9`fp!CzurcxWsA?+IykH5hDJ@YTtg~*51SkGWmmMzs*q@t$)4|R2kk<>G{%)R29__u(;UFnXEPLmH_h>cpXm2Sv2i-gm z{Z9A_$1VK0XuG-eqrGY1^m6k&j+gLA)|=aNTzmpdFJWr=0)Ch)dbBaikT2B+gU)!Tao zI0M`~mwvSO25@G(c^>vY1I}_c&n1ucZgx0gEdIr^cQ1H{tC2^08|_RmSK!A*`>BV1 zh2Y%a=DGBvz4O6&#?AAPw-%huZk|gX?cMKis2`VD_SXJ3!8F2;i`wCmM|(SiQ|RV- z=ywM=^W8j`Jlgv*IBVTJ4|zMm+3)7L=|_9pIvgS5Uo3ks1+Q;4^4Pu;zBsgx;kyKLI(}TV-8|%FfYZy(bIGHv>*jgrSNnU+ z2l#POJ6!tF-p=4;x_KV*^1&JB=DFmtKhJSEESF0xd!GaEj?g?A;6A;cDd3-bO!RUc--z_EQi2CV*4q z=DGBvy$iuv?B;pMdmo%FZk|gX?fuo^P(LoQ?5(>O&q?s(qIS6C(cbgHnd0Vo=r<3X zN8LP^Jlb0d&IUKnL*9?z{O;ztYK}$`Z@oj^L#^+*tPVcr*ZM(cbOg{OIO+$g8KM|i2YBNiUvT`zkBi#j z(vS9b1}D?a^N^Ph&Nw&EC6D&baX2iOODubz1MlT(1`!hJLf2-c!OTp>u=DGBvy%WHh z;pTbR`zSbz-8>I@?>ii8ZS3~_47^>{$V-8c;6a@4;>Sh%sfT_U;Pi6yJoFm_&P{Hf zhr9*gJmu!Ol4pndO2yiC3c`p6fzW0FhxSQu; z?<#QCyLm2owD)_5gQP66>^%rx{O>M1T=HmdGjPVac^>-B0cU}m=aNTzUj=8Ko97{K z7dSt=d9Jttlvno;Yl9eze`$3PH^76}>?nC1j*{2qD0x?S@ob!g-eH~lBQeO$W1NJ+ z!$ywp)GyS5$L^~YCW5niY(vHsD~Q=_A*o@>reHfhFeF!jtyX2nFjbM36N zhYucCFuovvLQ0D(TBh_YM6AQ%*CBXPO4owXg@^((&gzta*C*;A{Hy?Qq2< zT?E~uD3A`=V``g8qCaim5;BR&O|eF7lL_rRQ+64rC0u6kyjuUB~rCj1kF};^@*D z*;oo{#ITezJILm#*ks&o?4{=1OUx%*ZJPY7Y%;0 z!Wc%ZsN)-c`hxPo=kNOaZ(na7IlIyQlZ?4r@XP=B;r*^R{wuBDq|WV6*?$=1ZGsOT zHu>qX*L?H-gcBy0uDn0{LNpNysN?&+-D7c`dewgDl&$5rT)#W}6=M#7&u|V$(>cbE z8{A(4XEMlc2L#y-2is*d=A8VAV+OY!MmhKxC}LobPPv$Ye^OdZ>D;Mh|Ep~1-IU9Q zPZ;07eY^hM#|$1dF>eTx=y>hVY1grR+jjjY4jwn5zZ26@Bvsd4tI%jdUX(`F$rB`uevM6QNp<;Rmfvi$4fC9nN-}RC#n-HAm{m?H z2?GmmvlzfN%x0uoqjhSSEe@7swmKMdrI~(aPsOH+v8Il>%;cMIE8efTS<>Up{)+7t zw}Zo_o;lqlm|rTst4J{^=9`K?D(Zlh0?mG__@SbSX<~K>R?{>$@#go6J%a75ID#Jd zf6?NL^T!8*35mxg)u>skcBoEr-Fo$pKcPXx6B{*da?;7Cq%>`IYU*jHH*eAMj8?7N zwEbJV_8rdbcvh#gJD+pzdFNkn;YDfbUAks;yZDmK?w4McmEEIfugkBvvUi`pS6zKg zzrXjtc0f+Gc7D_5<4>+Ln~tbKRgd+&d+{=*F$H+{6Z?Bh?ie7bepXP=s&jS--&e_b8)4an64gGUVI4WV|NlEOpUE>+XVBfPgLnl&!q=^;JF@vHTBHFx;55z95OdkNv5Y_S1QK%J$B^Y<)o6# zS}Lp@eS5>oSWMq&_9uu1epyyIb+rjL?$Vsii6KWo0c+UX%tWCm2b-l#eTtndbrr=N!oPyelodq&_1J~H z!#0xqA@}b{4=qmw`UNt)2OxJ7HC&5-!?sYDm1I((+*16TmX%rutAcm2EB8J88~7{# zRphVS5k#W!SHu4mhH6m1X&I@7Kni}szueWKH<_<&H+S?-%_a5`m}Qha23imM641b} z`EMJbBd8e^*be{ur>5Y4YASXWel2BeGqfp*1-(xh>++o{OJvU7`P9tO=g4=kZ4F3c zzX{snP%X?|6D)K!>dWedl#P&r8hJCb4t9NwT_`Mcgf*^(e9GOmv3nbKZ{u!cI&wVw zM}BDRm#AgfmIgVyNvsRv4V@}8psAJW6#MzJ!1P^Y-2Z4GDBiV7HS?Cq?eWBw+}y5aoGmQ5fMa= z{0YifG+pS(Vfuw~6#(oPft1&e6TNF0*1L)2i(lcm69viBl zKYB^1pkpd<6psG%CI4;Zzx^m5h2h^HEF1E=g@&?weA_ye6^2nUW+fBo`U6W*N2NyU zryXS3F~J`XPH+sEl=4_A{v!%qfkLgiSU!YH2U``~VFKJ|u|d z0qI?qi@{K~o_pC>3*VI;J4h6*YBDqHk^@z`>XBc_LqCCll}HwRMkyR6WuK8#%H1?# z%x+4-w8-uQDO;o9awyWc1sGE7D!CYZ&}UdVetUtiu`60OkV(2KW72h|@Jrf34@|!x4n+lUYUUK}OwZL$#b_5A zjro`pFt$F$7UpD5#X9$5rsdqrW{yXyU^8~H;orkrhDr47@65-pso2h5tj63@X;{pX zxiS)El%TIijRee{gCBzz)|IDwnYB=V-$G~^`ayUmMG-#$vV#oWLZ)WS_o$!`>}cQ|2N-iPC*APOiCzLJ zEX0|j(H~_(*16iw%B7Hm{3vD{i@}_X-uD$`VTR`1%?TKjwC#G~o~KiF9SG$#E>pA} zf|Q48I(mv`2{H?_$$wbITMPDrkZc zF7vsa$05bexoo9xk;isKJF{a_=X?%1kXDG6aL>dtm1CxolN0wuyew>D<+)g9e(hUm zB~Hkgn(Z8oSy2usXgJKw(pAtecxr-!3+iVt?3ROu?LO$~sQt3_)H;d#_pvg5VdY@r zi_GB=6rR5!4vi@X1luEPvKXFa*i(su&yWvuHRo@Nt;5~nSsNv6fpE+TGVR%}$)mq> zP{)28RdHlT!cNmNAG6jup;KO6%H!di(>Fx@PGvbabMkiT854l^Hkq<{*j^u=w9&$q zX6NuQY=jtX%2>wJp^J}nZ_&ccL&QH60r8`JVb+qP4P zbDo5O8!G6{rrfp@-R#HAlE0(V4gD&+WOOd}^iS=TT{10~74>B>yM!kdoX&Xyk0~7| z!W%KgZhRX#I6GtHltbP&sQ>L{djY^^lolGgwKB2%JxKXBtMT6M(|7wqx3>McqQbd^ zNuRzdF5|p=AXKU(}Kp3lu5GQsoW9-;eiKY^8d&pw*jvtiFXG>z$W^)h6c}#x zg+IVo8<*!3!Sk8P!}BH#b6uh@HFf2Z-DlWZh_O}c3-gZ}AsJwi%Iz7w5)2QmdX80XA;mjl*Z2gmeOSHx$wn zwRk&WxC&_~w;EDV?>=*la2ewDW#OIyJGv$J#C8kW=06|qlw~9@0>)buHeVmf*B#hu z;o$~_ldqjCA1{|9`FKA&J^4z?$B*|O!udM8@-4;wWHs)ZuxYI32B7v8dY@X$O|6uvcIP~=Xc=6T7| zN3(Ro9edl}uqu*)o#ji(@QP&Utr-$=tMA3qe&$J1Y z2iRNElmEoN)8j}!IXK2N3$PAt=5aagI|=1M>})EO+X6{ueBcCRdkEMrsi%hnXPNE( zALADYcOme6j&yT;;=R6(@hsvnww7UXLZrXo3+8vhj$rFDk$GIgwZ8uGtk)D^uM0Li z$ZdAwf6I0-t}eE7vAq;O8Q8ua0b+$w*c#vT04vL?KM{{mMi)x$E&z#vY7u^0wyAso z^AcVqkZmfx12da3U0_6)%m+0hLWZ`NOw{Tfsltx}8Rin0lb*Z?*gphY5omAP3&!fZNUGu2K)UH2-9q>- zqBih@lI{FpJ98Rt+P@e7THrM38dV!kYd!*T^`wO+B)sAah^|o83=#d81^sc)`l*W1 z9`$g|A-?z;Q5|FGpfkk+c8t5F*sXzU%%uVLHP&U8V10upndzpluTA`yfs3L#jKHAn9%aLE%TAKJ!TFZoW1t7TdW76+^*j`FDggeAV;{gDP68Wu%6_sU32 z2;N{)#U`peO6vWAggbqQ{hYBD0gIRZ@Uc`RyWm+;T&sj6lWwN@YQ{f|T4CMMgr`xo zF{OcarYB@}kwbg9@7ImH0A|@ib+O3UAfvkwIVQ>WblE=#+s(zy{xB)rZ!t@Dlwuyn z?)#*e@<0}fVPB(Kd4ly1o@uhoMpG95Qec1_>FgvhRfa2Tur^PZ%rCOd+M6#X57L@@ zP0Sq-+-IJX=8x0vUsCf=GqOgcWhQk9S0{C9DsoOu$ng!4e4I}wh^!}q&3yMdSa>S< zSItX(r$kK!<09Rroz%sE;0eBol8M46iE%3eP0bi-D;m66u*Wdd-4Hbu3<~SSx&9Mr zViTNil4Y{ynA|Se?nG6$jNcc3uh_i^_*l{3B;M`&$j>^Z{=W;idqQh7#;o>z>R%DK z1NCN`6*020Tp-Qd4ykZ6C&aauX3Pb4r*JNfW1dCWzDSz&bZm#4b*k1OyJWW1*G0j1 z%r9cPALXZsUS|Xsnmsr;g!4_*QNeM4j@bEK;Bqrk`U9uop)vw~4JMhB%{jg)@yoF% zGE67g`I~)ypUgciq#_>SwkTnOiRK+=T!b5~cCAwLw46pdN0#<_WMOSzB^h(1XHlz@ zMXP`aX3aMjO9~R3n>LB8ku+f8TC3F2?Oa6NPLc{-7^r8i5?$CAY=HkaF~+XYzVNs- z)N8=HMa@NnI>?}9&CU=)qhQDsnupAR_-9a8;aS?AizX&CHYfYu@Fm3m5x5XGgll?| z)HJ!QocE!S2H;#x%jG zZyjmUmjY*?`EbCiGfX(x!F_hc|9FsC7Y`D74B>T7PoKTc!HHw?OvRk*m^uLG0Oa{( zPam&S8UVRpX_c-;lI7Zgr>Z@DyxvGoehNgp&FhHd%TEr^VE7Q)~t9OAc}ZR zGzIIOSmT&i^dr{zl0Z=!3cL~P`DnoDSf2<1%*SiUSy;CQ?+kEi$n#dFlJJR+FqZ42 zlFTT@sHNrc*{RKYuVRlV_Jm@q6?;dqj}+rKNUXeriXB!g5gOStYC5STld4z?#X2i? zzG4h#Z1d(S#-3=g35wmL7`uhlh3#&6&nfniVxK7Xonk*J))>9m<~_wpC7DYV>!Dab z#Re!gRWY=hqss$|J*3#viaoE`D~i3Y*awPjRO|=E_9=EmF&~Dut%DRNRl}qz)=sgG zie0W)AH@bLHbk+T6uU*S`HC%6>~+OfD#l3uwoc0w+pX9SiXBnRhY8f$k?f>unBx^Y zO|h1Wou$}0igi=0yJFWUcCBJJDRzrucPKVjv4x5~s@P)1UQp~q#XeH(3&p-t?0{mw zDOMlHAzN1som7%(p;&9h&Q~l=u^hz)D~3qoj=Vb+dswl@6njyze=GK}Vp|p4qu7s% z)x(@?b#CCKlFX@!HCK$GmM!l*#ri2WK(R@RA^x@GNHPyA_LyQXD)w*1-cjs5#Snek zDffHD4l4$yEvJlzPO64!qS*P0r76}+vEGX1DK<>8+Z8KT>_NpIR&0r4FDmw?VyhL~ zrWj*M*zv(Poot=*Jq?TbaW-l(TrfIVJ;fR*cB*2$EU|gJD0Z=8eHH7c*iDMvqSzgZ z%~fonVvj2Jf?~@RW0-oY^H#<7DE6abe<~J-^CPSCDNd?}IaRSU6+2t8OBB0Iu@Q=m zQS2tgZc%KWV)GSyMzO_;tx;^9VjnBERk1ya{ixXQiv6irBV5(ldO6uiC7HI0bx`aI z#ri6iuhQ%_DRxM)BZ?h|^De7%EhmM#SFD3#7b@08 zu^x(Dq1XV$1}QdOvD+29Pq7CTds4Ay75lehuPOGiVp|p4qu7s%{izu4ML6RKC&`Yz zxFB_~{{}C*sVLz82VQiYQ6v8|UUZj~%VTFc)b-rU{|zF(b#R=cX9ryD@B|f)zYDNS z+=1Z75z2)>3*0i`$p9aYVSM!Z7C<^a(ThVI$oQ-_m-*<1fpnCET`Ug{IAm0Iq=VZW zloA&SJgBv#YG-C%R{_PQ`nUj&bl{fVp%dbotT2 zUbu(gxoy}H1FkT5DEyVpqpl$0x)E`s<8xt%!b9z_3&{TlXFBW3CJuGzU5+yyo=}VX z99%J~b)l=?dv27tmPC8c?L+0mBgFA3$=!o`jq;;&JVDSRQOAZ9sS&F7yLisO!qm954&ZcW1%KIoax~AK(7w^UT|(;B^)?-&g7&2=UF%eF%Ah+29XC0*&>hZt)>U?$gLekn4t_{sPfF`&XFck~j}8tD zWpt2JhdTH|z>g>`?1oWxgoAAd|Ist(2)*p0-7wUj!f~Us)iDf9Dj(zYfZT9qTyNMjYxmyE^`JN0|Q-_-;f`%yu$%W@ed(QBUGnr|xu^ zsbwDs`3u{vQ7EP+OvmD1XXj$^cjojlwq!+mntqM7*A5`h(i)_3U`liQ61-FPA!*H?8k8O$d9`K`_R#%-;KGnaic_ zI}Wx#pq04IMI7wt5Z%Vw9p!9yfgq6LxYTjxjdH1jpS1OnE*MqGn@+r_F_&2<>PpUZ z;wp>-JdV}2k48K>W%jl1dFVg%gJUOUZ=)Y`r9*>y+kxnK<;h8d9`rFvIO$jyv0o_Y zUG7Vyw6NbC>Xly7j@u>=L}B+i^fc>Hhq{uZg3FmM>_>+tsAATp1}FnFsdQEES=*`@ zcCEuiEW-=F^O)bE8$9ahI0uE`>x=1<6Eu1vVNB0x7)<8j2^wB>M-Fmq1E%{O=Wfp9 z^rDlQJM2kUp#F8XeH|xg%;aS}ODv-|oI1@-6TiAq;(NIkD)CH-?HkK~PI{bpG((NA zgPe-#H76c)p)$B*!+#Dwob<(mSE1uaC+=}5^dmU7{Rj}pBYMiwM~*&m)W8=+Nn`(_)kT%s( zQ>D1YXEAQPPcW`@OT;wFGiO~j?OO?|Jab8y*Zu>z#5OWjh% zpo+NEg>XT7w#%iCUw+4*DaF6RtvESxDRR5iO~hsGf8tZuxYmPa+kfg)*SJK}3x`qFtPu+2_DB7p4ajkBqz00R=UNt^-JN|Q@x>x^G zpSm?i=TparuXw5$JRNUwjx{X2TKD_j{i|OcAM~%04DI9rI~_Wn#5{_635@YM)C zqI~GqOO=(uhpxL+!6MNADcDPBk1m3-s;&}~zk^f7>l6QRARAA&!>Txbb*w`O#S-zWyG-<& z9sJxJC)Ke4iiI2EpJs#GudW%|l47j;+lYiFrZ*x)WSDn-FZu5a$DayaDgH->B;8W&nshdYoz%<9mi%dV!i;fbX3AP%|nHl9yGBo0GFh(FWA6fJYo>6F(1S~1dqe8b6UC-ybj(N^nME0mi4cre+wIFj&O<-IwAT% za@=PBo`ChUqfcEu9OjMbn6SimMtr2PD*4p?CZlj)V6-_$?BGbwlR9slFxR(Vd`&nQ z7U8&V%w!oHi;!w4eWOf$?9LZ8TEHcz9_pq^{1Z_=c8`jQYXaw*9F!65W7oJ=AntN; zzTyDO6dCWTkKGX2eogkz!G3feVq#FJnTx7ONv$IB5iP?FFWoJ;r&FLIZk&-wr4T>6r2{M=N}>fdxK-6dyI?n+(Ca@CG9m@%e3B>k(5H+wX3WWc<4b;%s$_ zX!Y1}HO$S&g^xz5Vofs)xM;t-#WRe2+;y@DiyL(9X?FiO_C-7Z3P<)QLDl#us_PhH? zYV~07L@-+V9*kd$T4g11qWnng9T1!XKk-OSNBP}tlbW`UdhC`LOJ)2PO!uvck8+W# z?04557beku^0$eQfih*W)T?EGDzu39yK7v_#61+-?{223I$Qnj*bnxL;6xR?L^y80 zJ6BUhjsk*aySoqTG*t2TVh<|zuwrj0wo0*0ihZoukBaSAEDp1# ztryJZjvYMDw^$>^&QPqaV&^J$p<~Y1O zQtV~LRw%Yju`d++NwEWp@!ZyoMKBAD^=_* z#WpLpMX_HLJEYiga8k26*K$&rn-puQSa-#;6&s@1aK&aSHe0a;iY-!Xsbb3%D^=_* z#WpCmS+VaGV<>LhuNZUA+7a)hl1zQY8Y-5mSPR8ED%M%CD;2v+v7w5MRP1`irYZKA zVoxgeZ^d3y>^;RkRO~0k4k+fw36QmouS#2c8z|OTvCfK}uUM91y%ft;EKjlNiruc* zeTqG(*t3c)QS3Fv-c;;E#XeH(JH>ud><`8GqPMjzgc~~6-g-_d$(*9tsft~sSXafa zRO~9nCM$NmV#SKl0ne7ZOtF_0drPskiqY-P>PNRboA-!fKAi4Ytd^6iVUiVVs@Q3Y zwO8yc#d;~$Td_RFhABp8JFCkLians%LyEnm*eiU$G5}eWqBs zVt*)Bp;!p#kha`imb`=XN7?=z8O5dD{cE!Q zdooc}yKc8`3(dgEGD1DfkjN4xeSMk52;YL}biU$s*{$9WE%~s!eFD67@V z^peXeGK%+a+@0NOf5pnoSy`zq^7Azy-6f&ry*vB5hL+dwoDo`HJM?C^q>Rv;*VYWZ znH`UHozRk1p(S{ZzGN%@GW=UWNK6kcS!t8CnG~=tQmZ5tC)ipLgMzIME$?PlmIwW7 zcfmH3KC_!ap;?{drRX>m-Mh0N#U&y~P3FaKouB!WAkvmY=_vA3(4djs%d%~WK|kE= zmaG(&ot;!-6@<8p_QA*QDqpwI@(_MkRUk`}W6>()cvp(8sm0c@Mb<@;p*L?7W5N1e zSn({<|A+q&WCX)Hc^2DsW_()~iyX^y{3y3)T)13RbsrS>9-4a-<#qFa#M-azUyB-t zwcYAw_&0)Vo8i3-{}=wXRwovT%q(!DpQ(7XIugtKn3Z1!{p+NzyUxsLi|B=`9+>{6 zzocf|%0qECuQVxm1>ZJAd}?~}YR`R{(?_MY@bRHAI#^a}=gg8x2%<6#ztM4BW@a?4 z2;I8+h{Qfw3sD*9_cO6}xfm+L`LDA!|7|{oH2CX1Vj+19YIfzu!0b7`jO}rV6%bC{r#Y^A-o8o1PO?|4VUo}-1 zqtWig*{M9}mBD%%gEtJ?CsCw{Li3-D*0_|Av_w$Iu?EVb3@syx-FhJDZAK zC-9ZRIC+(c;zHTcImqd+!YB<6>WF~T?#Q$)_+ph%1uBbD;m7$d!rZ@T1b ztoho>Hvie!Bu^m~DbL0j$wa=_g~!`aw!F@=&3`uEQlw(U7-6&aCKIpvK4-4P(<&<> zO)&nmB3?%7KZ-E|K8xi0iboS;geA$+LM&vDKr{{%X~UqLEZdX)Pnv0R@0CNTg9{^QN(q9z;Aif!&^N4IK31sP#)c~XRYDta&~iOs;g zTzhLY$;TT!H{;$X3m*YFcVSc;yrG|f8$;xd1lA5eV+Q($qgKoDBR)dQXzp)}_fO}U z{wOHE97?YzIM+s^yDDyZ`Ny9&GB-vu7?{oO6t8D2Qw=3;}j`o06Mgl7qBeihd2+30#j z>?!N8o`N-aMbBaVA=WQp{SMZw?J}&JVEr-HS7D7eW{Y?mZ7bG~VZ9COO;~@1HE)M~ zfpsIaWI5K|vEG68P^`bknmz0rtlz?VC)QtLy$fsJh}w;H6X^XD*1VBK{dl}MfOTu= z!`puLh9y(>Jz z(MctlhKjMKEU$%PJU&{CL*C}?rC6?Fd5Xc%rmJF?C^k+ph61s9Z&B`i~L$PNRTdWvw zQ`&OZD8}2A7Tc;AZ&+H4H!N)#yg6wx-kh`;Z%JCLgJNA2Kd>Yv&$3s)s6vwEl2!8(!GVZGB4W<32W1R5_w@5mawAT<%K;Di^)*&-%j zT#_Bi#MRV65V{xd#aZVrq%w+k_bjRZ_e&9hoYz3TrXRv7=b!{!%$1g0T5;>Up&9!z z8HQReODzPuTgebyV?CG3Ng~v8g~ZXz2(_Fc0rrrXEfM#SxJN?pA+bPW@*(lK6Q!@^ zb57hoh}?@2iCrsF%aI73QiT6F4W6A^4)Gae2`JR1*hyd^ZyOM zPw?Bu>oxzo8O5uz{BLLZf6elLoaO(#+pS-RX1t2(f(zwI6qsIeLuy54F#{a7TD|h8 zKz6GSvs--(C(a)#-U*#zLT_Fcf8df(LCtgEN?gzY{+sqqq<66+5iXkr5}g}v-bWbA zFt-eekKj9MU(3KX)MXNrQ{Ix0XqttkhPi%%L#ad`hR<=?O1kXVhNtL0@EJq1fB_tH z8AEdz9ms!m{Km%|3N5c84&`(ro&)8Pc|Uea1m!V1kQ;9G(^jMw$u2kxhsxlETTn)Y z!XCk)g6-HmglL}w>2i7quBHPKnh|d;!8Ev+4`dk9sJN|VeB%JGNQ8#}fFD#DUI9YE zkMv}P4>tUc;Wo?o(?{SOJGNXLtl`HC9InozQgg9`VJnfrakNE1RAfc@N7jV1GMjY` zrXTKsuBh$~APwbfWz*~hK2yu&D&4*eP=F|*aK<(}`u%1)q5xI{k|dkPT$(bnS{o0lycb{5{vChJiL+jQU^y1^u&fTO47_IM^Z~Zd&~jGGQ8bgI0hIeD zoc{=3M}fn1E;arfr5xEtZ75${&QSyKs2+At>LOb^M}7b&*V*J-GNEA$Yz-qnyr*-Q zX?_1hoy*0b&=Gzezy_gb{A~6RX<>S=gGFC{hMGo5*QK@`yd8r!MdvNp$(-<72MsRk z>}|Q2RnSzSVYoxa^>D`YAIQ+I!#AKA;M5K|(zx~|LdjHMy9VEw3=M=_K=P%&xbS|zZ-IJ(2yh)U3e5$^}m z>Ri67IP5FFAW?(=uB=0G*QYSuwHNjc|1G;@65mFe)|GzkXkO@5$lc=$(c;rG8bUQj zlNDuFS}2X0zQx?%u%Nd&k8)4{hP^fr+;(G1FcqVJeWCn zZI_bxTbU_y@P}3E#@zTQ&89 zrjl^RVE6LrpiM1A%I4*Bu7gs>g^A%5M9Gb(Cva_hmdnHbTCh^FpFtt|L~cAe;c5pC z8aj?&rIIV-u9S` zHeh7aD-jece7C2CaQM&O?I{N@#tkE0lk%%LxSC7+);td{AbZ28onZWDMeqdE>xPl7 zcl24|-vp<$^yD$%7KmCq&EN54Gc2>SOC|>;Z~gHaJrXvU_j+N!BEuNPFDVqDAZ=eCTR$_l5UZ82Oi1z4+8PTKU+LUI`7kbD);MbfL(jz39)B|Ta-}8GfmGJYU3zaVmASv5sMrIUr>ParZu8(#%lba>Pw# zC!z20`y%XfxTLW!Tc6hhBCrn*Fab=Vs$W@68bk1pST}i0} zU91rI6_Xyz>5{w%Tjls6W?jObV4X@8Eg5Mo6C}MaT*wr{;1E10ZT;_I_&Z` z7C$K#sSRm48-9^@k=s8VEYw?^uRIJnDtSFaj1_DRtuWdR!aHBMQCp&kZ_e05pvZiilCkq5ME|=hzpnp z9V|Rp`Ui7-k4L$*(l;O7fyS`y#!J!hlIbCAr;2g?W#83OuT+P@^6;XB?>O@T zurBgMtDKP26NzA;fNuzl>H=N7_%R+26+pTj~64w@D(m} zuCRW`3*mye!8oEZ6Q!0*(U~d)(JQgkmOSk0sbbTam~oO8q&*6Rov8B={ckzkDTa?(*wKi|{wyKpdysww1a-%gZX1WJNr z{LI$?52{#ui!}4?!R_X>s8`HbpfmroI{zWZ+G`{eqmq|H7-EG7oA|zs8uXIsEK!ry zcc*0PEeE>!TGEXP8%>7*)vRpZ*_!Wk$#<^XjL2;AwU|*Mg83d*IhBF^bIn*0?6Ut% zmCUbg@C?yK=qLovOB03A#-*ASz?SMRCC~S<@*dHWrv?8s0Xd(si%AI3%PW+qw!DV{!WI( zL0?1kX6nz^bjm3fap$L*87{fDPS}iVMQ%OG!|7my$k~bOt_MV4j?v-LgL#PWlAH@p zIey{kp>i|ZR^+^MyvSWIb$LW}856wD%)Ud(3UUSxl00m{E3Klk&5Fc36j*v;JFMie z;bA@%{aMN#Cwj2VQ)RnlTw{FeBa#PY3>_yjsryusd6wki^m3|fm-_nREQ!PXVXdGW z6V{sZT;m7jJF<8@>o0lj+{g0m7Y^+C7mqlMY>EiuaY^O}seHe7u+G655-+(+@=`F$ zNplVymGpM%h69F?HSv)Pv11WZCrjCnd)5v4b!7h*u@felQmLDDn1}OY*3Dwc(@4so zeL*SnbEy};s#Fe)dd@=h{>t-8<$9reGj(NsveWL7PWv>xN$>M5_1%KH=#snvjB?VV z?6zm|k&lb;BIWS}a#F?4sIz?0k(U&&$^KfngbqK{=cEw+JP9uYo)iZCM*eykbSd^f zBK!HSQTWOG;DRxehK!pqBu`2i2F?!Q@FNrH$-`ihy;s4H^)fYd8eM`^D8j z@>A>MRO{#vr1lTtr9s>QX$i)Hxnd3_P~hnL8ed-!>M zDfaRTGx~Y`TE*1&CpmcoKvsG9Aw2JE*zGI;4gDMI6e#x!)_hd>FRXb9|2o#v<*;6d;l%A#=<0YCtLPFK z@;26evBoq|M1S~qvHl8cmNOI`=tHcp$NCej*I`XPcpd*a*6d(Au-=LFH(2k+dN7;7lv-e@Fg<`E0>#W%MisdTC2lrN9p<)vho2l4r#a>hlt>)x?PchWEgZ-u$ zAK}|Fa3@GoHB1dB1#fS~PF1X%Vsyi>d9P9ITE%$&%)K?tKNRD`e2ej6zRmltVjn0* zmq5$=T(NzM{i2u;hZM^TIH@Fal45-4$d^a4jDz-tf&5G?+>}SPrI`8Nb@1&9pKjmiiJ5#ZX6zi%O-y5>Le8t8oHc7Du z6?<5*XBAtb7|*k;Jia$%>xGv!7UTVLi}4*Hi`8;caHLSIrDA6(c8+2^pS5|j6&s@1 zaK-3sV0m;lu;uc-A&cFw*h`A>V|SLfQL!?`zENzqVu_fOth|~|3XV65@eLv??;OQ0 zP>i21v3W07Y@A{Y*KPC8RcxMOk1F<0#a1i!j$$7v_K9MgM{T*^D)yUVe<+rKdDHT0 zI4QgdrC4jl_*RkS@vS1O^9aSpD8_KzmUpLO4A*V3#}wo96pO7@jPDIuY>Q&M6yv)@ z+?!+$Dt1`0M9lj(Z%rqaWLhfLMzMj44N?XzLDK=lRXB1nk*sF@Yq1cy-?Nn^PV!tX@w?^2u z6P#3%X{Oleie08yPsMT+8?4w2#bzqTu-Ufm?^lfP?^x`0#okry1I6|!_KRY5Ylicl z;H03lVy7#1nPNQ^8>LvGVzU*Squ2t)7AaP$*jtM6T^(x&zt+Q4lKEM&gNh*nio;8E zQkY8=YpqzOVp)pySBx$Kwu~ahW+*mCv3nGIT(PGVTc+5{ifvKsGsSi(_Pt_wsOi{& zP*097Efs5{*g1+_pjftImn(LyVgnVsS+QFcyGyZq75kTBFDbTCv9}fbMzP(B{i4_* z#f}SwZL8&^l1zKW&QdI0v2Kc8u2>(%hA1{%v8jsPsMte_J)+q2iv3Hm4;0&|*yoDv zP|Q~+Y)8OJB^iF3(e~5h6>F;4X^M4MEL*W_6uVZjv5HMp>|VtlQ0yheUQz55#kMK- zn__<`)))^ft~D%)rdUtKMk-dISczhHDfYZ#|59uPp8MKzOP$m)C(UC{ zn(EDW%t`Z@ljboe&0|iQ$DA~A@9vnB=KlgG&41!F$NhG2w3B9XOSH5sMJ^}JiSkT= z_t}qmX*!Q*d~gxsqa8kQ+9j2C%uDl_mnLq;@lEh!UYar@j(KSw^U@5vVI1?)Jm#e- zUcSe?G>>^{O33G@aOQN(OY@kQCVRm#FU@0KnvUn`*rkf~Q*3}@BNQ8>7~?G2GHy}qA;lh1 z?0LohrPxNr$`sqD*e{Ct;QDCG2so)EdDYBf9TiJcUWQ_W6&tG9c*Q0wwm`8(ian>; zQpGkZ#&;uao$gTV8^w~~=4kb+?WB^->5849SSQ8KRqRs5_==}3BVRGT3}!KgTd-x! zQtV#E9#D)g(pVltA=$i}6#H1Qor>*I>^QhI+Pt-#6hhN0c9LS}Dt4h_Jruh_vGIyc zR_t!Y?o;eB#hz4*&g@o~wTdy!yTush-P-oGV!ISOs2D$fV|j_Vvug9!bW(6`RIH6+ zmnzmnv5|@~PJxv-Td_HcEmDkckXYW^ioL5?nPQ(RM(2C0-w%o%QtXIge2c^K_%?8y#p=QJ(U#l5Ng=$qV$BuH zQjCGuZC&Lm#=z?qyH&ASiruRi1Fu`&tBSp$*gD15E4E*;Ulpqd*GETZCk34qYpz(9 zV!ad_t=L$_N))?Gv4<3UM6s2My{*_r#mW@>MX^JQ;ag>n&c`_^%q5DoQLMXS*@|7O z*g(Z@R_s>A?o#Yt#hy^?X~kYr>=ng6RqS)cb}ROSV)%@gV+Xzo>a^tjp<;I^HdnF5ioKv1oiuH^bkbzXI%y_KB+V?u#*)t&gu`e~|2{4J zQG<+<;RwHOKU8q$Hpc8)itC&1#fLHwc&il2;saSF_0te{D}`S;a3Z_klll~PL2PQq zEQE&VM-Lvr$t}NVpq~;bUQ^P;w{cfS@eTwNTT}caqKJK&QT%IY$sTOKi-7j~vi;@V z{kyX8^@2r^mgO(aKnTy0`kkq7=WPE02Ks83?f;{Ab+=o82+cSIvx*TJ@01x}<5lv| z^2DqXoYooBHS}i2oW$uXi$crmBHe#ZaQdnue7_(YpBBJY60jTQ#Pgc~OAhh71^D^5 z;7bGXb23`3mCSL#)^;tadEze0L)OxCY^2}3)>Kqfq^~Sb6g;$i1K@KqYOIQeGD|Sm zAXAN1-DU;5K>D^qR7Wb18S!Jcgs(J)T~sWHQ>KP_vvrP zp-#F_e=9Dt7!8TQ|J`O?5}#SIDytan+kN^wiQOworH!S*)6e@QbW8I;D=KE$Pi&xD ztVOk=N6y45{k*qBw|<92Xn9g*$?-_A0~oY9D*1-F@zYD0=s!16n*CxX@x2IyR6WQ> zn2YZttV9!k>fb{9<~nsZ_rKOQZK#Ddd&a#cx?S%5ugDgm38gu)Y;9!6Mw>3K?s~Yc}pG{*mL-4#$02 z{(~5b-TfHs9XrctV_>NCl5Q0ncV(4`p%oaO<^EE}*$bVLA=RINCa8^?=lHre9&N$F zcdu;%j=X!FCg2deH_`+cd8jOB=>1pgDPva9k>?CLDeS*e`I%0~tyq&W3xlrWolK0o z?$f_VFvmp91{wHHMT?AcMxh#REn$^&p2;jZ2}#4wbvHU(*4;s;i`^ZEPH_tA>4fy@ zt1%}nS&ONOUGi>zH)S3j=CGNQ`X$^7Ggcb63jY4MzS@L`af*Ks~t`DG$H z2&bTQhlJfgP!&<1&Pa=neE2Oy;pzY{hn|ggw7_-46HeXc2nld;$-n(Ck_#&5Dx7{I~uR%>dPrXWt@J06b{es_FF z-efo#`+otOVFc__*>$km?}`*jq$hq?q)76Y1On!E|1SS8rXqflgcGq|hZEUOWi(qehayI0Z3vfoDJ>KZA9k&_Gk>)P{_ac|GRYb1!5~N-{{Xmcg z@fy4e+f78L`Y1Q{hel$=ab&!^K_c!?|JCM9e^^92!T8Tc9pnV+6~~cP#kh^<3;$1i z%OziBM4~@f8C1J++(zbRG`|j#yKVep6V%*kg7Kft%>V&0V>b?mkV_=PiSZAZKlS@1 znS$}36;g_nN9@M1)xF4+#RqGw<0!Cu5~yRbvxmHNOs3Vv$*{U%8ozX7)S{Q(0W?PdV0RTzxMJc@~CzI2-Uz^=t0FlLcyU~WbO zcS%mc*5!oE3Iy-5Iu*%wi3HHG`b55w(p~m_?Z3nP=A&C_1IXmSGSHa$XClSm4fxtP zgME;73-eO}DFKbpj?LEVPSj>NQMe@qb>i=}M#Gn?<%xRcCAUxT>!qVn1A z%&^TkJAjIXlTTQ#{Wc8u<3h^(%-yC-)c#1=Gk*W&WXZo&%H_9T%7q{Fw=%1J&EiU< z@>Q;@L>U{eV!y2`+jkhGE3AjDBlb7ek&R#Xfa!_)VIJ0v&C?_*PvtskAZ0u&eAbEO z*N@^y>VmfJ!XcPZW+OU8>Vk6tgJvM~XVm`6b#c6u_q>$Hy0GO%#}|r3@?q!aXKis( zE8~ZeN9{PaA?9q4j>P5RNU)*!-WEPbg5@Jz4(iNfd}Sd^Cn@4h$&#g6PLKnp=b&MD z3=B)jz(HfnXb@#{<#sF<{wA5<*yrs5^ci2W`93O7<+glY@+>u(Xv=UvxA~s;onp3| zTE3Z4c`LW+e9607^07^AzK48`%vYwqk8^6c|5R>U8=>)nsQs1OcBIHXJ!*gDw!L5W zzb)mmZNvJWhPY&{@#UpRxsm!|pV};QbG@kjwk~WRHilt05LyWPZJ)OF-7tzDv4i9F zLE$qtQ`pXk9UPAg=z(uRi9G80S9uY;sNZYCPcY*U>!~rey}r}*KZP-#R2s?*FOf5f za6G9Z?BWqHI-V4da2C^Zy<|B@V}B0Ele!-yyKUo1Ez)fpPm0F|E2L69DW1bvxNtT8&w^;q-pas$?!MsLEJ56=;|spu`N zZ^8Nptfynm2i~`0%}7MIVO@mvEUfuh`yW{Ip>{FW49PniYd*Z5gY_p^L$@M6!oCk{ zPLrtrqTjH72u)QEJrvKA$QdW5ptKt#8h5{@G*outUQkJLxeR5;VCxEMo3RNa}jny_$0!^5za%% zORv{2$4xF6bH7;5`b1mZFP5_ku^XdUVW63s=ba(; zkQi5s=jDZ_r{gKt8UH(Lh&giBIEuNTl{4P%^mIJtJL5%~vs1*%#fFH{2bQP1S?o_@ z^nvB&Jt+2;*gIn1h|vd@m&f10o_EJ6mV_JMH0vzZPmI5dJ?}+gmx~699#b%4m6I&v-RBVmdS7J1@@Om3XG4xlgl~^aSgTzi2>m$bf(95e3 zyFrX6Oz-b)Vt0rw5~J~jr{g^dFOS9-&hRTgVvV90+AP*e>|n8Cu@l9(r+axa1O zAU09#VX?==UKM*oY^~UOF`8F+KX`=qdiN6BSFBj9n^<450b=xL>*dk)t(P}ZY?9bC zu{*`)i7gacDfWR_gMxG&jiMOFS*(@VzG9ulx{37=8z44VY`EA6u^Yv15xYZdy4XUo zMPjdty&<+%jHVPmRy3vX@uMk)GkUplwwGA3SU0i3V&{mB5W7^2p0B*TX=1a*=83Hk zTPe0i>?^TWjnd`O(8Al?S?pl39%8-328*2|Hdbt$7(HKkn4n7oGxKbT_37orzLQF5DMd}vf zTlpgXqd*Bv@M6OP#kp=BDGy+O-5MXn4JIK+Y%t*Tql5|v}GetTG(P6`@tSGHr z2Wc~EOF^B^M9xtAa@M|dF8^gq)Ip!Bs5c6L0vg1_T&RwEa4z?iEmTJ(I#XWb1w8Yd zjjU9Hi;_XH&a*-5i_&&1Iko=DNGi-k!v>n%-SnbrlmIa+>epEdsDFhV97Ra^S=S?d zHuS_AZOv!ea&IjYdyC`NqCw@6I++XCp%syCU8KDibzm_&;4)?utFta-3Djk)(NW~A zj%MAOs8<8i3U|lHQ{r8`SGCQ&@UjaY&D! z8PTYq88yfR8M)#V1>XkNGSmC{rc*~rJLHp`9UA$QLUES++gQEMCi=(J z>r8vD7R}F)vCHaIC zg^sgk{X7Y~eSfZm-JX!JdqQ0*P4@_Q{5Zn@K*DZ6TS;{#?4E^$-L(8i;JBPU=dI-S z*3-HYb~hJn7uMw;U+{Az>~4il+GTYl?AV>+rj)Rw&*DtyC`0g#ciZqJyy1^Z*c~Ma zyX+#epMtV`e464Cb`7wDrMJgVTlgrS?=j&ANF52gn;~J>D*tsz*d6s#Bbj3+(*l=B$$t+n;9u7usqn3|^fbAL?2 z?it)cgR((RE8KOh4WEYB5|7%NnF7jtc~FwE$3g25djp4KJlYOD?Gd9ZDt&1ce+vu! zw9gN^jdBUQ6K&g0o0G6R&o;X%%6b%htrh>IJ<4_2o(u^)-X~93d$vy;2=UM1xU1a& zwQ`+dnT5ach>n#-c{{RPu%xjQVDqwB2|M0K#|?Wm`C@Cs*o-zr5_aqp>v`1LKnYOSV6 zE0ZBF^bMXFlqYTrZ11HxyM}uZ#_PVWeBGBhy~Ata;KYn@Y|bCii1gIQk3g$Y`bTI8 zpZIW=I4dt&$9|d7s0{f!PVF>H@aH-SGUV%SwQj$ck)V!z-E`~LM=+(RhCN13VpU?U z4SqFBf6XV?N*BqHF>$@A4@fa^!w%L(46+ z#Uo?xM>Y6Xi%+`H?2PCdcWBP&Ue>h}5^W&<8YikFU$?VObAHC6t0P}`we`PMRtZ`1 zbqy@R2{{*sLu@he+1pyHdJk&~7Z0DO(c&c;_|m>hS)F2Ol64D?g#*V}ru!jZ_g6f$ z%1x|H46_0`ulL)?zl4#Gj{^&Apiakg>P-2%n+uvHzD;oS<3$xe2cCkm)>&C+Si^YW z-qjlBb|JAKS}b2j2?;1(ncYV$Uw3oCp^3Ni@^K!{7;CD~#qxD+E#oVRB0MYPBvotw zotFPa*mKkJbsWAsaCHuw+qxz5QFw7v9^vk`1a+nAZZ235PHey?#a-w1cq~=d$MR)O zE}QJfVm`k6#+sb8zQ$5@Hy4b>)B8>I)s^PhBEI_gqf&KzOA@v%b(-b{a8}w_%`42J zES9R9oc}%EJI(ISeww-Ctjy^)xUp2-#Qb~0`E~NRR2>f?gDlS^%M&Y!9iRVJ=vpUF zJlwysJhT`~AEr30zUTdbw&z*f*F&n#%Z;V#M&*wPcho7jqghsP(DlPfDhgbG9I>fNSd`%lqx^t7^5^L;aeA{4+{bgbwJYnYgXjKGoSc#L2>ciWo`K( z(I{NA*|B-n@@#K)+>G4KtX}n+vWBzyHy3nPcVr+Un-H;Z>`9H^}#u+WCU* z`Gu{IMp2sdRn5@+eG;GMaaAE}HZN;8 z&r{lsw)2!bsHuAJ(*wwcGn5^B7 zmSXd=cI|9C4`A*vrcr zu|;Au_wjTz_wl?m_i;vZA7=?1UY*hK$60H!9mTqd^$_FhH=g%YF`D)`qiK(qcd6JF zV*F+9>8iyjZ|98icAl5=cFrho=Zx}p&M0r^443;6%Zp+zZ|CV~zw7BJZ|95#bj~Pm z=ZwFzol)M-8RhMqQQpoO&M0r^>0T1672~~hPe z-p=z<-p(22?VNQMqr9E79%8-3&K0B3ou|82j6!$LZWW`@owFyzD0JuSc`*vzIeSZt zLU+!-5TnqYvs@fU87mAFx^q?}wwqWtF`D~$x--Nmbm#1MVidY_cC#3T?wr+#Jt?+W zj6!#w?p-mS0i1m)#3O^wzC+8?wrw6n5XM2Hdbt$*d(#ZVvmSX=+4Vq zE=Hj{XY0iH7M-(}QLNB}?wnEHjxn60lK_7^)=>^EY=#4Z#YEq0aI9b(hP9uj+0 z>~*nPv5&=8i#35A07s)RG>c;J?j_bytVE1LcRqfD#LgD06r;SIr@KMyMls6UdA)at zEf9NFjPiD#j`DV1-nU}w#9G16h^K2E#gc)dcFy(^D;Db}Mo~LYcbwR8u@Pcp#KwwE z6T4H4qIO>1!(y+By&*mhcc*r{UY zhz%8+AU08Kir6%<*<$m=C~D{RE*1MqY^@mH=Zn%ciefNb6>BASuvoDeMeV$fqs97) z4G^Qeou?ZvHb!i$*qvf`i!BseB=(WmXJUnT#mwtSMKN60iR~kHsMuj*eZ=~UT`o3C zY>L=4vDsqt#1_NG!Q1ju6stG+{7I5`^(LRNRZ_LENA9z|a-T2D zU0Mc*Vx3CH4lC+VQdKkdlA_(pa_5(hEh}nMT(xKwvW1VD)UBdh)x6?SwYA+2oHy*0 z;;NeBQ7dTN#p)QoR&(By+AAoVt%W=}zruX>wLE{%Gd&romk$!n}&Mt$`* zpY=AM^){boubQ?$thf2BxB0BM`5Xl2v`w2Xz;%2DK=W^?i9OQjAD6S-eY2m#FmJy7c(1gYs(h+ z?|J!>sn^?9ti2e;@;u$aVtvI1hz%8^Se}m8w zjAD7t+KAD2ptJ5`J;hEEqgbA&qgO#MkA4N6Q7q3HU+i%9v>5#jI-{pSPe-vlXM798 z8O8FP<>2R^Gm7OoqgbA^oy6#8-5JI5JRQaIoKY;#8O8FPQ7q3H#qyku6q_tIMU39u zJRQBcd0u*Mb4Jf?&gi+#89lc-OTduQ8QD-okuo~IiqMzK6+6wCAS zD3<4}T8v_O&M21W>FBS`8O8FPtq@x&mW0uyr=wV&r`ttrcd`A%D3<5xdWumj&l%rJ z@$$|T8zVMWj6U2v-6XMDVie2s@+g+)>6VGTC-$LOBN#|}I(l>SymTJnjAD7tD3<4p zVtLMbicvPtS%uj7V!s#T3t^t_PhynKb5zzY@X+(Se`SAM%g@1 zw|x{VG}%07dyDO-bX~=|iybdUu{_WFTQSP!IlEqrvU$$_B1YLfXAg=|HqY5xVwBBu z_L&%E^PHt%NXb}XplqJA9mFV`=d4tWvU$!<5i1wFLX5I`o^Gnx?P3pz%@TV}>`k%n z#Wsi)!jO_B7lu?6ONNeOoy3k4J5g-7*a)#PVq?Yb6uVpOVX?==-Vj?M_KDaUv8FJZ z^fot-V#%@G%$JkNW87$x$Y^%Ofv>@=}+#m*DEPV5h2 zQ^jrnlK|L>Z?|1bAdXS=9oT>fy zpDLhdVtIL^vIO)XMRv(`NtjSUK@XC7k%AuN6YB-^imGu><6kVGXJUDE1oXJiO-xUL z6!dHg{<{S9AfDF(B6{18nq&HT)X{SRz0|#PD2i7{Kre4o0(!}M0X@D;ofrPI1@!2! z!2hyM4gVVi^r$CA0ljItub7|18!-^{CdIq!33D*#+GO|H0M!fV#a4uavGNbMQK=Wu zvtg(g(EILz^RIv$g#r3~0phs^?>3NKu&~Yr9TN_FEE0fF9>@ES{La$(VVR$`qEPfL@2hfQ+&FPZ81EHKWbh^P3jY%z+b(9 z-Zn6P;HB55tQhDZDcg#nMk(u9F)YA_ORoYBjc*Fi5^&M2Vg>>V+B*>d*1SZf$E zIHQ1`=cRz2v(934y6ubtdY+B~dd?`I=Zpe+&M2Vg>|wFT#OP7W)6t`rr=v$LXY{D$ zjDED7HHu>JydXvaJx|9=4^P)#>|n8Cv0h?Fi_y!L=cSh|FOOcfoYBjcvvFb*#O@Zm zUu?G6Jh3HWG{f-n)`-yz!x@b)yj}|EIirA{GYaTAqkx_>3g|hbfSxl7=sBZ+o-+#Q zIirA{GoCD+-6lo>J!cfq^K>-Ga7F<=XEexg)&Qq3XN{tm3+Op(C3djVQ9#f0o+x&z z7zOk^FO4re9R>89(fGm{eQP;;Ozc&$H^kP8trw%oh3DlF-piwap0j<$D4^%8n-~T3 zoDC2gE;d4JqSz#{X<~PZ%@bQFwo>c^u?8?k@Om3XF&EHt)=F$&rRyx#O^hD3m?Iem zhz%ASE;d5!Mll*%c-}k2D4^$Tq1Ym^SH<2CTPwC+j7AmS4+`jcd6dm_wy#(>u^wWS z&GU3a#VDKS>@QtSgU%I0}_YsF}C;jDEOONP#3G_>H>WT1ear=x(L zGYaTAqkx{X5n`8$O%j_d_ORGvVieHx@+hF^>UUh#1y&H`oqZz-bLUFkUN8o1+rOA$>!dsVG1t(sm$8@(P?tE(O@qCsg%)dxq7 zYj$$aae3oQ$Ceb8n}8lyjs*19VyXV83Fys6zu`!uHG3}sz4FZq=p7E(w$AV|P|<>3 zNY+w^YGGPH?*)8=fF8B;5TS_Pi%^K_OHH#n0(y|WgDzc-$yj|x-8_~9ovWp@p+r@& zB{cHZn0_AA#nvEY`B&HuX}DBhsHstRFH=MB@?k|oTv(54dZ;Rr$-Dd#Q=o&w8T9lh zrI(?Rmx7>Px76A%Q6eSw)Fb}!W1PJRzxhYSEsOhr}ToXy;Sy86ESIuIi z8Amxb8y{DvD_`v$v36SDtl2J!Mx`#bHmU^Txvjm?a@#zqfy#k|bsqO>EM#432HinZR@#V8IsUtc3_`49Lv=sEmbyAJ=Be$Uvm zj6H)EVgp75W+JHG6!q|LEt>Ti8&k&FL<^COZC>9zo$P63uXvdmK18f9W029~yucj@ zmEPzn#`|2c0vp$(x28}?y}`aKSoTxQL;1(`3-Q$!4$6E3*{tJiYTq|l>0F@qDIqr) zf`tRQ`q$6nG?ne$1aVg4|FCK?tTkZXS$46U1Au;_$6qoA-8u@xt&b!afAFlRgsYYM zfvgFoK>m*dUa_-vn0Z($Qe&A|i=%q2shGuqth?f48|mIuP@;% zgz;=yVqsv%vYiOg_fTZTYHnW2EKlKI#p@8AgLEZBoAnCF;thJ#S4nE%Vr)S-%10Mf zva-~mYdlgyi91Nnv9P`z*1@i=S7WJ=1p}SVgUnncKot;-Lwa%t65r zMR8;+=AhZf+NyXNU(4UZzd_uAD{RN_i{%RaywqSjMnR^sybQ}3eY(Vg!OKkZt_usA zOP?vf_*EpIO;tN8 z;+3@Q0!(?q!SCZ=->2%zvo9PU-}tkzk%oV{U;Rgra}R4Og``IQ2~!d|0D&xHR#303V16DYQviR zYz4g0P{13N{~#3bn*SsPylsDm0$yt<;CTC(5grWL=7H;xFDGrRfHxWr_H***K>@GRPf@`88pRhk{aFflc~HPx)?oQRR=_*9jso5v zpnx|bpHf8LJ=4MXM+$hOF*V;cnEqo5c(-7Ag>Y8R?%{Xg)vzSIkQilaYYHgea0=lN z+ll$^7jG`{o_LEu**cf0$+a|{q5hFpWTBrZSHN>Atcy3NfX7F9AslVVS^VFu`0X=P zks<{=uBB=uaLu*@almmE7PfJsWtwS>2Sh5fJZlC2K5;_W9U5dk!#;`4D&V;a-()rU zH7l+-Lq4mH0-h@dcF$;Jq;|(fvU2D?;I9p;{L%)g65rmkL0Sl@nDijU4~G7P?b9vK zUDgUZw3u(L*e|ORX>?HvtfLjUbI$L=iKe+y4fZzAX_y<1{uIPcwC}FL!iN3b^31^4 z-IZ0asotfB_)^RCSZEdo;W1vWRrFhjAR?ldk+E8$Uw0+$Uo#)skadHQRC>k73VA2lwi98? zpWYTJVcx0(%zKurkygpeAEoB+MPxKEL+oIwUcD2o|Rrq<9=3z8>iZz?9nrp4f zlw7oeV}-nnEz_w`$ope>2nsg0C$6^wS%E(-d=Xc%@o{3E4b;}Czz@c}M<2pp(Wvyu z#t(R>U<(ya(u<5o+*OvJGn-CN*CCy)!L0K|+vQrA5lbwcH5xK>T^oFc6I48d=5oZ9 z@i;+zOA$vYtT7*vSiJ2rh_{{6piV|teB*(QiV-24VkQK!7T@TCV-vITHc=xLkX$j3 zZySb4SCUQyWY)#GXVyu`)=^p5B)$K~`J>?_o$_8sute7_%GFcaHY7A)M z;VrtzO3qq;6kF?P33zO}z!JE~Q>;tq1#ouwVrd99b}Wn4-G=916vo?iPMpWbkD_Wj zSeeh*s)<$V&W0jfRh>Mpn709WPP07MSe{sdw157IiTm@ihbK%8BldQn;c*${^H6)fNyfXg>bS3VjE86h@ z!omK9<;%lSW?P$7c6?`J{GJ||Sh)0lqa|&$x^|12jY<=P0*vR~$;$Dz--7SE*dg$F%>A`C zCp=ECvoxRD_{9>EhvttCS2o~y^+vv0d^j$@OuTCsMI5ghkXn2)$IGwQV_Pr&82M`f z(`;VV&Q{xT;;_wm6XB^IxcHS8J2z|9C%& zf35I&$zuN=Rl8?#n4pRs&mmN`I~*a^?09~ln%y%97b5%+A=T{8#R8(5-AIHlBjjuE zcOzVZkZN{ZU@H)Qf{p7&8PTGu$^HM5t;!=y8wVVpINVuhiJ*luEbh;NUU6pYIa^8?QFab z+Sxd}O6(dj+SzzI+Sz!zXT+#x=ZtnXo{n}l&iFIJ8L#!6QO(ZTFU6>4=ZtE0p6*1k zQ^lxe=jo_s=jm=0qne#Fs@Zuus@XZC?Ts_q-Z-P}jWgQbI7{FV?2J}8&RUD@DArA^ zhZxoDJnyMuw6k$WI~y;Lb~esvXXA`&cFw3~=ZtE0&ZuVRjB0kysAlJkYIe@3X6Fo- z<`K(_Vy8NJs>8NJsjB0ky`iW7^&KcG0JRQ~SoKelr8P)8ZQO(X7fA%=zeQ;;I z`f*k(#{1&VXi4MgwuoYIn<3U#jMrSAuCo{~Wt{aA8z44VjB0kCj%s#{B?Hy$oKelr z*-SB7+&Eh(wn&T?H=cKe7}e~YQO(ZtQq9g8)$E*g7NeS-vy;Slq;p0!JI_lsJ7@fD z;*4r`&iItU8P)8ZJt0OlJ7+J7y(~rzJJ0*R*cW0{v-7+yaoqHD+eNWt*h8#?*l}Vf ziqUSu^PVGit=M&9e-nF9jCysR_Z2Z7)17@RwoWYI$j+_F&^U_W*eTXtj21VZZh+We zu?b=m#ioc&6PqJ8Uu>D!YhvGvZ4he%ix%%kQ4~uCs?<5_B335WTdZ8{bg@gsD#d6? z5g3SaLG-6&oNnTx^6G_3FGW zH;FwUM!h;OZ@$>mV#~x{6Z=~1JF$FN4tX8PC9V!Mm&Cw71s_3Autf3fq$ek*pP z*ezmrh)ow;BDPd)h1g25Mvc?;ZV|X=qgXO*C)P%+ix@TRJa4(!>0-mgE)=6)o!4=T z*rQ@KV$`eibc@A47F#X01zdf2x~5Sq8Fm!gS*)8_53v))P8FjzotJm17`5q~jT56b zowK{es7>eWF)^ytIeSBl+H}s=h~Z{K#Bi_6V#&}{thpHV>O60Iv0h?Fi}e*7Aa;e= z7%{5Ud3jW+V=Ni&7n>Y%j55v2J1~ zik&KUsn``_lf|ZpJs~z%>@Bf(#B$*r#M@jD#gbubu@+*~rt@_Bi~U;c1hL^_Bg7_( zO%l5e&uG28JEGXXTYawHUb5a^vff@2R$wykgymViy=1+;Nt)D5!9k+lU=jmCo1uDx$$Epy zP;W3^R#` zj4y0B>nTPlIA@fC^Soz@jS(9wHc@Pn7+CP9U6r3}@oaN>HNsLl(&T7Oc1?P+caGv)SF$%yrTO~#* zIA@fC^SrHKkLav*6ibHoVta`lFLsjHnPRkV_ws%(cD>jPv4_N#iqRXH=lwv8R`AZ~ zjm+DZfIXr!dLwhzRBTVNy~WNDJ5%gBu|J4S6}w$*uGmvzFN-Y~TPGG^kLc~&F^Uz2 zoy86oD;A^YG4IFGVtvI1h+Qgnh1jiPQ^lSTn=4i;_O4h1SQmP|jiOjGv=VDAc8D0o z-n?(eh#fE1PwWh_3&buGqu86*d$ZWz#3=UWbvz~ZjM&R!%f-GC`(6x=J)$}aqgXQR zD%MVHf3X9_%Ee9>8zy$4*d(#ZVt0z&E%t)gGO@SC-V;m03em@9%P5u%?Zkd1cA(gy zVyBA@5~J*!mq*z*AJb`K6o7L!Q;Y&|&R!Lx0GzWA#3%sgYztT+GKTAyCUdLpy$HZofQS8mrEfM=fY>n8KusHN|TSc*C*hy>`vF>6$ z#ZD4CO^m{BUfyM56n1lVtr&&foZTZvVK--wi&5gu*_&b%c60W*7+waC7<^nE z+eVCHZ=QEgu_MKf5$h**hS*54E5#`B=H*f1jj?2SKx~%S9I^RgFNiG@qp+Ko_k$RP z-JES1#gburv7N;B6x&;@t5|ojlf+IFyG(4P*sWqy#cIT!6sr|`S1b<}jNaykQ7jpn ziM14?u$!mrBzCOWZ^SMTyGZO0VmFD=Uee2>y(D99FZusax{WXXq;}{67i&9=#;+X8 zLybE!v1CXrLNDI8;V=#~3@)!c4lK1q#kgiHAtFg>EU^R!0Yus`b z%R|-$#rRS@dqqP7R8AV#xKl~t)0s%ZXGV*!Sjab(yN%tlYid^B1XiCw@sw$r@UJZX z$h;n-<~OuDpa_*$^t0-SdZf0eP-IC_BI=oUUrVeE{e1sGT?6ANY(U4?JO z2hK~4`J9o|EQru0A>C#ZUOLV^FPe56#l#Rf<+_F@?*{EYD7k&h3Arvm((#j&o6Xa8 z|I|Fy9m6fPDzOaGQ}oZTvbx2mFseluBknijF#vzZ2i{+=DXKwO1{bk>d9&(A%6p!n+VackpaqUr5 zz`Rz~=GI`BZG)*Oz-LR$1^2j#Sz>O!FHVdmfx|H|o`kfRo9&Df{{^#9GIqe z&|pFKg6rPa9478c*JJ6GU7uglZUNWe^*LA@J7B!Fp_&_xKMQcsvJDM!fSd~jw>qM3 z7`mrXWKD7I!c|@*O3OpqXRv?Ge!F2w;hf^xwGGpo0n_A)1w1m9jLk2_@~A|#bkvhw ziu)9wR(xvlDSb{mb?*CM_)&mYG55#(@*Um0P^#F;it#R!r~8B0Ule;pu_u-8J2Adl z>m}2>kjD;1%**3lA!lbPc9~*pmF^InW<1?diuF^B@2h%wyzAoW?on*EV!RLH>7GQ) z)A0_5$5tuU8o&IV?WtI?Vpk*Pr7RHRTb7=K?hrhN;>>H}di*x2>osu?{Qlk^+nXWe zOZ)zpZ3Xy0R(6}-ph37b_q*Knp;d#6%|{DwA}7M20fPq)8fLBs%(lrY>xXLvzZ0K; zlO{gB?~OV0zw`3$3!QRl?9&@JEcs?F-81bF-U|a02f~?2NmCwy;{3;1{$9v`s1>kJ z-juLME}cm5&c6R0ivAWi?S=Ac4fJTRS6GzzWzI6BJR|%$_e(36N3FQr3@FI>oKC_H-QRP9FzIoos;Zl{+$r%568EkfAl+gy$oCwf6v4Q$Ea_?;^yX4&y zS}S)KWBlj2c|_k@Eyz$y;cN{?A%|Orc6pPazL4%lsWJZZLTV7(gh#}5^4?5oe+jg$ zYtsekuVIh;#c;vK$>0ctaG_a$;o37iYu|6r#qZag9dbsQYnf(X9gQE5cVpPmCcg!~ zzicezu*pr)q*t*shA|O-*Q*reY*5R zHuHSwWgm%*T+|_4Y#EPK#=kab60XmEICpv7j9%lh$T-b1US=7ORmM9oACq!F&MicL z)4o$;XMHV^rv>uTAqEd7vC7#Vx#^uh&KE1Y4MLv1E#Gm8W5O0;7CuQhM~c(N-r%_I z+F07htq!iIT2>jh$ZZXW8hhj{%E&jo&#-fb;CpdXI}lpFqcXO~3Q+hx1($^U>zc7W zb`VBIDOYf-v3jW}Rcq;6=e7$kCic#GDkER^n6$KgV79e`W8!PXy&4U(GGfIqjzwon zUmZ9WZ2KV86|bxGxMz>au9oKkOV2U!^vyEb6psb_%7-H%(9>7Cym&0Q&(jq}2<
      iOT+eL^uH94G0Gzyb0l12zdfL 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

      SCrU= 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�A>{5)puI)&-e}Uz8~xE1Ydk!q5a~Jj_g;A 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≪TJc*P61yuBH?EJ+`y77V>ZteJBB&SCF@ccOh{_q~Je5DBIBBjOe`QjBL?r+># z>~MeK{#wWK)$VV+h68WTaDTV=balGF@b)M1Iw$uCUS=uo&bmjmpKA4f-19GpCF#|K zW6yK|d7rCnVuW1S-@`$o9I~H0@^Eo^Q(s$$QLb(>a{6>@b3w?LqoC8ENb(wf7(-3Qr8Ub_ZTs~LV5RYZD*=SsZ$;L_E<@pUk-?o_TmKn69hOH$)ThT)hjH&CT=Tv4(6zqA8Jb z@v`}PE}pN;G({pQU)o^aQX;F*;d4#0b?N#9k~^MveK5@H^BN=)$#g0o73D`xYxB=U zD`4JM!8K@t52<7{8TI&}&;N7jTwOMk&NVe=BcAZ&3Ykc=D2>jXK-Z$NF4d5VMw(Kh z$jAWM6Zq6TK^KnJMdQh6Qz{;H<<;Cl7s}M-;?Y<#)!>O@`Fui$k45WJ^|AVRS`}+i z#O&#DO#VVPk}iokhK^0Np)Q(fh{oz8o>Z|zEherxXe?EiuTRGsn(`jhmiJFZbZnwc zs7HxxeX>60##5h`=+LoPT|Cy**pP1W6kqdHMaL!@t82{W^U+8|q@;iHqDwW_C87hC`ds=)ed@HrJ4h)n`4G!(X)QNsf*U3ROCuj^^S`p4>N1dvr}u2V+ffc;v}m zJ3XDLkPePe)8A*3urFTxHOQU5+`HI96qC~p1J`2;aK($Il4;@Ll>EvrM;T=%la4p0 zFdeoICwb2CoH0dqkY-GAXL-(;BBpsdW@zQ}k%s#Ed?Zrhd+t z)-z)YCx6bE(mrE~nEvTl);HGSG?C3?_U-@VVXiKbibwD&=v1AY$O&!E z={X@9b(Wa+#7UIhc7Fk-HeR2{8Na^Cn>yNLO(&da%bMzA*=!<~0}f3;s5&l4$`u`s zO*DrSNGu(VB9Pt*mJEj=SE?74I~J%L=|n7&Z)(i<(O!AxhI-1< zj47SnGp1mAsAGkykd9_^(M%>@C-TuZCDg&t$%$neQ3mp;4xA<`RG_S8d7`x01(%aO z9Xn)vEEPp-g^okE%Mamw>`PH(<%CklA{MVpZ;Ii%jI~`(c6CY^D#Aieh(<+3k-&sk#}FY+pzoS&h(;?k zcb-t9U?-b$=vPE>$}J0}oc4<7$$77JR;iR)*1o7CirK2zhx5|9Neicq=VlEYH)Yb4 zTF*9N>g1_YCQO<!|+ zh%7hnJU;&B@XQ5gbI-F49Ac05aF|kTX^a$I1a9kyD)D;&{?=JTqTYFUbl3@>NqbaT zNqo5RZ|#u$T<@Gd9)AO$nP4XDDY@_9cioV3J&x8b1M{%rICf>yTFC|JHN*J`Fz4W59Z+uD z2I!pxy;s4sPLmu5QBCnZ4FUQb%=eCv+`a*Nk8FdvDo0jXm&PPFK0vPn8G1sZ%6dH| zIgX2);`=T}uGckHS?xv1@ji|zeCOi$6D?KNv9lzHU>Nll!1)|7pR`IYsD5z#e#z`A z>wbK=v0j?OcPpH~0dq6g;J_B7$49XboKt0OcdX=g576sDIuF6~>py6h+|J-k@g0Zb zbLUlA=itMQe@)^04~|~~=Dhim6YZ6ueWBhKFhiI?*n;#vh1>36cIfC^?*wq)1@mXc zAsdb1WBTp2u*!ONk<<%HKi0R##Z}hr_;3r#-{;}{9+F#qlDTaU$kWlxp$=qkx=4^2~ipN2#Ntd|5+ zytr?@4D`+c^B2VhmA{`uW`|4A9&imEY`pboNoG$`%{S}f6Y7bt9#+P88zfy8R^@9uROuMSeI{j+N1)Yzk z!1)Ly&hghsj_G15FTaM~*I=&urR0Lnzi-3-`0J{yS-+AT%#3<0FUNsdeZAy@;=2

      `k3T` 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≷io$b`pQrHLV@cty^sl88g{SwJukiY!NTl#K2e$(E0!zJL3a=mj zQQ#J!6rQe2;mI$BwPr*U>e-7>f{tDa`)En3X zd=*qWZ+ic`pzd#-=cVx8>k=zGxlG|1CxvI+g&~|2o^f{tPD;c$DLjk&T;QbejQccj zQh3Hm;aOZMJmaMBjFZAMPNm5>DLmt(@QhP4**?!3_d;XSwbxSKFDSb%4ZEnJGO%)3 z?`Of}5Lm8%-2bL06dXc`D5TWKNZiyf(k z1v9JXvUJ&6%vx70v)=89z{kcaJJaWg}{ z*5+1Mg|#(i(zW}ax4BE)?;c7_wsP5En>*h6$J#3_l+HZZmcDz~F6H0&uoATdb=){0 zHdG{VjiUUaJXW#Qo0FNNqn>uOvZeu4u{{mk(fjuYPr_dYE(WW>C7{~j3OCvNkMMro z!BTh?W2JY3=T*$KftlGAaur1?;>MlmT}AHuo5nQ-?v@bl7lBht-NOAkaDNNj-vg)3 z=`5TiPOhS8ap0B)?mukD7q;7uFQgq`_uO#;}J>oX}&a}<(MuWhez+FML;r9X6h8M5A9Rf;zHTG=sE0>M^8#mWq zMYck?rGfi#;M9`jcwa*gkl_!O*!&s4f~mcIg7)Z zR;f);zOq=6=rQ%H$hxhyRHP6{tf`ovkuho?^4f@*fy#B8=_4I+6FF579fr&5iIZ?y zop36y+&V!s6!K;K975@xE#o|?Ga1jUPj7c+v0BG^a;;LN#I<_te*HjZZK%C2kAo{JZCxg3sceqj95vU)U5zYz`CcnCsw zoV6-mT^2g>Ot-U*b^n#8A9HTXDJj))1TwCCJ`z;bTLY>Nkbgh$Xz*b07*KV$ zPDY)D`)A znidm}bU^nesuiSuxXj=hhszAEX}CV6CNE&1EG}l};>s;%$Mc~1!}&iUlwSYEoP#5!Bq=T`Fct);uL0u4SMKLO;1$IiCg4WaZ443gsEa|s2-7w#cFm{~p%GyE- zYG$=%T}?gfh+LVKIknJ*?3>eN+}ZF)JWfwx;W!nE>lN+C|7rY)3g2MI+rPq$yUee! zglW@#EJatw$?AUp6lyxnhtYA}fNT@&YRB0><@Lv$dW?&ViY8$yDd!FWmHo80UGbA& zCfF2k6vz@cx6_KQf6x052amun)9Wa34oF+SQCTzu(S#Y@rF+&0Eo?N~S{;HOl1E*D_ z->G8y{G9TpcPaAg$E3e1Z$gKxUtiwzHLw?-5NJYctlz8QG))1Rl)ii=I?8P+rD^v^ zB=7ylkmo8^j53`tE=+oD*SP}+R*}%0^7La>X>J;2yng)`W6KitJ7S}(->$x(qUEHj^rMb9 zW?aksNpUu;$pk9R3DmV^K5KZ&=cta~l6l1IpAAv6bxt7rke#M+cE)8I=SR4#V%K|r zip(j9o(th-lFwGfYiuW1_xu$mzuBkHFi7_2f%P3!@$u%F9Vnl;Iwcj3-lz|o>iae*>y5!yqjhMTTSscb7A!FJ1*XQZsR+S)6V8J09h@OG|YG14O3y$Bwdpdf)QvRZ{@nu^)>Bm6`j4+k(e}J9&Qv zI26D1*Kkl~#6jTYU^#dfI0}3K91T7Ljsf2U$AX`L-vgy_#(}bMt3VCsP5`$DCxSbI z`dtl~9s+8ItjXXo@KEqz@Gww)Ge?427I+k>Nr8%24eI_S$MQ>`zC+nCeJYo2G+~^K zB;(YxW!$NO`)S~0=2*Df1NY0o{ULC#1@5!JeHl3Ij%B~0$<3DDg1{{b+`7Q2q*}NF z?%d)QdYAS~^~yJQ!=lMq8x|exH!K>LyJ1nctc_aU;{I%-mZwUa-+Hs{MlA}^!9cjA z#k7%XT+=s;aOLV7&4SNwQmBchL;2oSLgN^It(?A`ECZ(e|5j26E|i+ykE|Mc=p{7E17AJ*~ykg z%2SnT>G3H(^p%tWIj;f-flvvz<25tiH$2dul#g$SwPE7^l@}>cor@u;n z>h}_M>y21EYm@fEJX~*|u=1!ksZ_3Le3^%0gRkUrY>#O97iVmrH^6S|baG|~FJJ#n zLa`U8+VR6bPF8)KF4wq}+!Jx{>)c-@tG-H?Ymlnj@UM~+ziK&gO3RWX_=?mQs}l7G z#*2m9U2gF*K~tESL4q4qG&+VbHKs zcW+?jQ@inU%#Yls&RUo>gdetYe>g7eUTlx!aM>_@9WK)Vr{OxHu55 zn8Gy!TepB(EY>4aaOLWeyI}GsNJ<{0g{1#Ah;2u%9_eJvUgO&8l~8p@g_bBHu}aPb zobPdNmqX2fF3ZcN4{l0UOiZA$w#f zH){5X9^aN6ncv3gcj0Gr1k=M!g)a51uIOQ;rv`AU{@1Y@J<}Il1MUER1n%SglfXyt zOQ$^wPWRVO^!}5;C*V&3p9IhL*Dv+{E5P5uO9TBLyc>K0Yz6-SJ`KJGJ_EiEJ_o)5 zz6!nx%654hq^a!gD+$W4dw&D#*15$a(c8N~?EUo9VuR<7a3}spm z{i=GICtc@Me66XX}YKk~F|CZFqs&x6g|_IQ92A4$Voo<_U1 zGi)vW54*J&qj2bWkRBeyfprA7O3(s<@nhErVC>$Iai#B;I-uZz$`&TTr| zh0b{STHis>Ql8KW7KC!DKMWP|;@{Gb$bCPQ^)_ZQ>-F={ctJt+9nTR-B8ncUUZ3Je zMnIhog}vBQO?ABw5RYZrDL{H`p|}g+0YDlm4+DAu9tG?IcpNYe@B|<^tt3Yopm-7> z$wV*BDS(dgI&12VxU-_v_>|GpPgzEH1JLNBF76@bz}nnMg;V<9Y7f1M@D zLf!zvFlmNsOdF|VILxJe2k{xtIB$AS^4V^DY7vKe9Z4*f-l4k(0lY}QKh7;Mu-m>7 z{T;Ny1=6`b@{;GcIb~-O@3>WE7XW&XTU>UTfKg>5yz!oU5UWbQNPZT+M{!uh?Y5=n zPS8J~XV%`!Q8=&U)94@1AOoJ`@Rb#ByJjigIM&@+7vK&PZ?+W2?D$wzFy%Cl zPx3)AW%lKC@>{&yme^P~7aUk9z{1lkg(Y@z}UZZ z1jb!3J-HkeSDPvtHRY194@+$XF#3k0rAFOGWkFjAtdhW%0jnsm^}wnKY#Xq6fn5Q{ z3uu&G9vE`re$gbPrSMvKU}y#!KE(qXO}R`FSSYZ~f-e@>36VboFwXO6U{A%>>A*NI zbAWLU76ap4$(Gp&Ix`M0r@=)}d4~W?$>yRTv4f8}`{0De;2z=bvHf_ej=r2Y7^4t& zXz-Pg*na9%vNYG$POJcsS3(}OrlpvbgNQ4B^!lG6J1GcBG#FxIA~U{~Z!1KpKe82~ zd(6sXlySo^)8YY5j}-<}e!;lStR&ie1N?|_95QLGMTh8znl%+KOW1?)wqP!S@vEsA zi%0==TjbHoIlBCmNkI!sjE?TlIYqwQ^H6)D9vp9+V;(LqUdF9}k(GC?;K4&b4c}fl_kuM?8Tz>14_ewV$VeW$-Jj({a>Y z650KJK(ftafHVbtTtAY$1x6uSH9Ud13*bq>7Jx*L2RwuL0Kl_=GXT#4{tSq^Oj-hX z9*~Cp3xH%We**3Tyb72Kcn$Co;B`P-80G^h|Xdke(!-0n&z=7l1*4wUK@Z zU>!iRiF$x!Y|emW6Ab}}12zI257-!R5?~X+nSf0J7XW$yE(2^1Nc{?xiyDm+`X6?C z2!pGkXmqEUHb~Ku6pfxkSazkNZC14Hik7Nqw-k+fT9&06;514p8qEz|5ibhAla=Nt@jUE}8wocLNqsEvJNF!gFij?*#l>10J@y7y7h(3^%^0W;tNdMboP$9wZgUl5YsSnlY6bOE7(t9DnK_eeJ zI|N>o5;ZB}MaAeuOEYGg(J(<1l=P&5DGi~3b~JD(F9cE@D5eiYa+spiJ*hXt`Y#SI z6{D9EBJ#B>T3wvNw0_kFyNDzo*&_4JQna~>wp`IxE7~zd zJEdrUDH<(XvA&OrhI_BmsC(wT*ee=!7)-O&G5usotT7w!VM+gnm%&*rj$0&FdEM02 zGO-@K^kqntyma3G#m8K&H=`+A^`@7c7)c|D_YQ0!$(|{h7|+pm1ja`>(u9V-Dhw?B zG{zTD>Svh7AYU5evDhTKftvzoI7 zS-g_;Z|5q?rB!<&7pm36!mdAz;~REvk*Cm1sL3$hK+Q)6DnA*t@g}WE>{}<_yC+}) zKm#CE4aJ=RqX6py#sRtm_68(BApy`2koY_3@h*TQ7pl`E^f;L~@liu~0(0VqKp1V7 zku+*XOr!Ca`H~cEqoQq5v=53#cbjEt7L#Ski(?w?V;9eZTWKfAJ@9HAHJ4FAQ(LoA z3?=X!YN+9zJgg%!NgLX+fU!mUD9jQVx&P1c%lK?WE0J`aI+vTGp9P}ZtRXl)?PEIW?G{UsY5Ug6 zzpg-H@DQbc-B!el;{nH3*=uJ^ThQ-GIn(|z$&!CuO~|^!PWiL!jv}7vA3Ak1OR^RU zGz&)Y?i|%dBc68n57~+gRA#bMjLUd~mqSzdhg1(O0P_KQ0+t4B1xRJ{2J`^*0i?3E z1q=ZU0HhTC0I3csPIl;kyTNuy7*BsOjdH>?gW~I_XzLV>ERy-IDcTK1d!lG`SDDWm zb;oH?m&-J{@fMFRWJ`Y;3VSAxaMkS!N46g$qZ1d|MqzD5iLC(6G>v_6)aIh!7h@{EyB#D>`(7#nL3g-OG_4@$=Av|gZ5XBv#(>kOSKKB=QV z@|1;L(jZEw?C`X#8TwQTX*Nl=DDCoV&usL3n@h-b%A)Ti`zs|l@%?ll6mO-+)hsPH zL}P=bvSu{MZZIS&e+VEo^iV)*+&uuPP!WLCBS!*Kp`rmh1I7SSoy7u@VN#q7va~Wt z!g#5KX>>oBMjbfQ`YPH=MO&+A=N0XeqTNCtrdz-VxL zj@U92wuTQ4P(vX1-f0_6MQ(-bi6}noEsV3FnV}HV=>%CxqG`5lyP+S8yV>v`VCG?A z;C~rPcb_5-aQiZa^m``%OhRPdFloX2FjZgcrjLhH?`j1GHr;x_*kD^Kted(zUSZOR z%ODFG500G=F1kJ&zlNff0pZ>?Aht)3sBn+?;2v%~(ihR*@{V>@n^+7a!Q$+JYPs?GeBX*6H&Tehtls%hmHcR<6 zDQWiRT5Eh;Jo6XN$bF!$J*UtzN^?RdABRm;qq#;$UAr`iFxmlD!KF9)2&+|j=A|_ zH}W4;m0Gm48vHN4Xx|F-)k>jFsIF+uoCUp8K&KK!C+)`3 ze%gLUeMDEc9mtX9mi)%k<$7W^x8&CkizGL7<@4upY9!Ckd%7HOv-5a~e3ha@A~8FF zNrS?iUpjbR@?p5_oz~AJE~iuRcrIW1cFDu&E|6Q76OSs`4vUj^X%If;J#MhCUIDy% zo7}>69EykXh#VvD)L8|IQl={-9dhrM{IY&i$HbhpZ?}HaD#+{`$RqJ`R5#ee03X>( ztYJJfS7!kCw-UGO;apRhOFk|#hZ8P5$945Z0a5rO#^>tmnLT#DHTr55aicXP6R!e@ zyFq;kcdyiWkwIB%U4ij=`qcYBhkaU#^WT_{x(mKa(_B2iQWO}U#a|m3pTO?|j3sEg zkGIFrHtlgDjf0BsqT$VX{6&d`7xfo6>y(id51R|yAh zz;Sr^4^KN5+=sqSooQEI`e(ZWVw*0_z0k7~ylV4;7(-{_H`vS!U9a4!mv)l9aBRq7 z<&ak>h=GE6<%zQ^=4enT-mP7^;oYQ!2M!sCUrPJ_mA!Q0X7cTi}uC$`1yVMbi;*##!$Po5J>2WhHT*M1uZKQJ^^3|v}-GtvM*cm~ZB%+hgHUg)uKbrvw zr|0LawgS;0Xh+FmT%}j8*BJ#AwkUdkP-@hva0yphz=CL5QcDKB7-vMSw_k zh#4t$emr#XK4sHiEucX)K%|VEm*PS8nNeH~vQu;-<%8_>DIj@{G|@|;JO)i`z)FB+ z0T1beD8)SxuL?+yM-hN@?|TB0dl3cL7cd5J5MTlz4XOsf1%QcwO94qA`HTYq>9!99 zB$F5ncpY#E;3L4HfS&+I0>a9*F@WSki~}qUNb=PHw*b-rybX|cZEOdmWyBOfn$q6~ zNM`UGU>x9jz+^zm$27nRfGYrh0HiK|D&RiA8Gr`>e*!!Y_%q-=z&U^~0OtX|0bB_9 z8E_e(9qMx}U|v8!0A7uT~CO#fy39~`t;EjDbHL6{vk=Mk0 zG;7DSUlnbIqHR*NZHjh7(e5Z3JsPq;dNgExv`L(4jTDW#9;VUkEc5-SXtNY;iJ~o6 zv}`CN%jVEA8?A_<6<4%riuRMD{i0~p%W}Fq6fH&3=-I$teC6zon=838G+hV>!pUwV z`H}bV(?)C=Ngy#7Mse&cu#TrE1ZzaZLqa)vsd5)FxZ3@AaMYJXON_)l)5gEkq!gr< zo-X?g&4vZJe!*ubFc(u8@Xk{^f%Tg21mYm$dK{M+Smvq<7$$y#4(y_PA}7qrBj zo`;6fMG8i#*m)!$5--|Gc0C306%6FU+5;OB=2*e@0-S#;^MISNRk*myOA-TAW z{id)33VW$AOJL9Nn~Y*K$S|#03^W^Dqc%xLoN+K3<9K3|-q0u+Pm3@tin2h^L|)#5Mj$eWxDuF5U^zbX`34)f07|<)yf< zUX>yKPlmXiUOU9E`tpl969Kv()R)sUA&=Zx7KN`)_b3&xB;enGG_86IumRu=KzG2q zfGq$Y0r~>B_Q?fuK-5?z6P8D_!e*x;5)$I0Y3s#BYF&&0{8@w>iHAk zS-{VLR{`-lQqp}ubHKNNmVh~s|7?I{Pga0cK<^2=op(~5RQ(NYzSdP3%-bqUt@y`lvwS}#S5RkVSMHdN7QtYLlBidf%bMO&t5 zeC&yE@aXFvcB0dgk4X#0Jd^u;<+nSRBm85{JJ_Z#NVed%zKjCVPjz(B2|L@6ZQabe-AxiN2flF+? z0TG`jOpK;i;+Zuf18W;F8n2?z6E*!zbqnO}(Hj*!4HAq@@d}EgOg%mPT2~-9ai+cd zo`75%ZwOa8re33yu627Uqh27%C@HGPTyE|>UNI7qaE0L%~4OI`GuBUX&@ToEV^hmcF^#)eNV_TLQO6B%d2 zFR2XQnG?(SUpIVL(9?~9^p=(bh?E_E%;D_N*!CRsApB&YI(dp;4*Yn!6Q2=<@licF z0FqHx03@TPcy++ifHeTi1Ck6~C*!5-G{?!R` z<;WxjH+(x^OyOX=3ihVjt!-Kir;B3Arj@mKXo_3%9=o+3WovuR^tMRxwrFavOY|%4 zne1?xqO7`x6~Yg z{f(O9qflZoEL&=0L30rpHEPvRWfV~y6dw^{cvUKO3;rAYO*C@l}2|Wyw zUr4pSgpv~>QwyM_9_;rMzGd%H)VC+bU>_jQ1*G|s#j#xEk;fN0Oir?-jTRXBzhnk>_(Bupc3ooPQP8o8ECTc~I|6>X2AolvwhibiE**_Vn23)X40 zEXL{9RkQ|*MzcID+fmW%(W;o1U&p97@-Ayl-*myGcO#@iPm=HS8FPAI7TemyTQyhx@tM91Hwn7$ks^xpHI9TENBj|~^}1QD$C&3&EN(n# zQiq1VI~yOEEe$ZnI>NT7cM^-jjN{c@z;u4EDcy08$?2j3zeMMHwy#CCWYQ@+A< zj~=_Nq0FoDmxnpi=x_CB<65t4{Y6f5OP}PIb|vA@cqZo%nfG*gn}}WcxxJGQdC@W; zQ=u%s=a+q74tgcqUh$b&`wC&O>hdv6@nf$jKty(bPf!z%_jS_7HC z-vQIw$RK?RXAp`;3mZ*wS1@^RT<-fc4V~ta82+sFmtNL1)hUU2yplbxSc^=M-*W5W zI?vF9-s7rLWgr{-J(I1y#`$P&hepwcd}t(;_CHeaIy5SXdQ}8bN-ipI92qyPA1>(> z@r2=-e01FKK_GtdvmTYwU;mUKwH7^>BerZo8d@U1sgSNL)E0y;R9OvKDE5pz$BlKO zlB$@|g9om;;u9G+Mx5T2)|N-ujBxLeW|Svl2O=rpr0#3T&uI zBLWy}i3OG)GsfVg@FSU-VX0A>(aDljjBk*!k=KLo`&!^3A@a6qj%RJj*MJ`Tcz5KE?BSVCpb znO=7YvZuxr7LPX#;se#E>(e}ljH@rF%tvSz+Dd#xevR2jjJ9rhd@w(qA`)q9?g;C0 z#$)dWtY&{PE2q2<`NA@-#Y?YXsE`Ra=eU`88lHW+P`sAw6qPr`hda#y= zMmvn@Jquq@s7mmjMLIL9FTUVK?4vz-8gMD}8pq3tG%y&JGJ4>Dt1}TJ+4@t!hWI_w z>8Ih@ko{itj4M=ZM6MYXL$?pTiGE34$KnFmSmEJi> zdIE^bOnL`c9*~x790AF5st8CovkD-78hXp58i3UR>jKsUYz|lpuoWQQS4ipt=nP1n z5Bk)k0e}qv#{#+l&H(fPTn5+-kj8{IfSUk)0k;DN0PY4vKb>?8uoEE7`a^dTEo27* zUIq*SyakA~gvWXSID4#wvB%1^2-H5)$OC6uKSi6OXwwyKzoH#hv_BN>qN0(X%KF|a z8u_VAv(_;it*WBcP&8UdVm>!Ti&3?+ZbhRzOIPus1VuZiXbHH&vgDXD z-v~t;qi8hJFdx-8^Zlu4e<|8sMWYdh`Oxj_vX(lgZ(P&;YrBzMkRS23NZR(ad#En% zKhxY6LGw)3U9sVZkpg+MCG1MV|KgWlGhI!*4W~_Pg8SlUFMZs{$)D;kCr@pNH|=6^ zO@8H>JSzop%r{tE)01iCC=q!3y<|i-=uG<4d!vrrlsI}7x5&dx#&VC*c^ z1(pl9%o39g(wPYWmQ&EaSG4{Ln+vRixJr+bi;*o$4CxZvruaT8ngwn>yGg}?u|!!# zqb9&K4@C=Cm~>_)fs)agp$?I*Q-h(=j6<3;(>75$GZ|fs{9sKL?Cr#uRT%g%5f2n` zIz6@yw4%e)ugkcjmU+Jije;}@F-K^qFGg-J_!88q;DtTS3cFx@F)LpeBR4(1XB=5m z95LC6{I3V3(-JcN{%z!?(U%rzl<09OF|0<%?opbjTYv5(-s66Yhpg*Cs@UNHnFIQ zQxx>e*jE3qmou;I-9sKtq+^8~aAyR+SYOtw59|uuLQ6DM`Lxv*7#4v+>j;cb2I#7; z#sRx6uF~Q!Umc{bE(FF)g49KlUt=jcs%MC;M7A=%#P}QN)REE6J^=Td19xPJQN4m= z0-MH%V{e?kCis=54fzozmR^FT4J&l&ws>R17Kh>5YSUn-wA|;2#Q=PXGbX_h91|L@ zkr?^x999T1cZjybCM*MfQ_urapI2FkCGfJOkRl7pC>0FJB>W~KDdSIC(-Vd9&s3jA z4~*2y@cPMov?eROf@Ou1#jWrbVpe??&BQt(JLzU(<+paJ%=m_G$3_?6t4=H7mxp4<^b z6{8LTuK^E#3U2c7?0k%y@R!v4LVzd41dfvE4c8XfNJQCZxhCb;UYGx!ss*FXVSnd!a6k-gEf(E$-AltihMAeb5POXqo!42z=ri zIYWF*0-v}>y(5KFrHq;c)td}dm((OsWbv>~^l~ssg5?1rr#S*rQ>X~o5U?_!n|_^4 zwv94b!uS{frp4)3ZNzC;Oq-%;)MYYloub`Sv`3280`$VsbnyZ(^J=MS`w>8{&)`0PjvoMZVGotb!;F+r6m)%Ntj@1<=sNEg%fo zbumnl55>b2)o1$lLAw-NWoRE$!DWdbbvswS);_%S{UmG8iH)}_D6AQf1dzpDEb2E4hSVl z9stBgJty&X(BoYIEkO?k%m!!x%nnF?IPnhz%mGL?LUGDE#i>2}sP;^l4GzwgG?Hf8 zB1QXE(atK`1w|_X`(%Bkb<9TlQPIeHS>HNE+o)*Np5;mmT*!1y886XMm6>)&lat2c zV!EelOZYUh1v&z|Bw7~LYWnuH29(wr+7s0=CDsJLu&=eJ_PsFZ$VTNG9~3^GuD$;QYR3)6{LU>j71tAJ!<*8s`g zxeize@D3o^+~0uZ0B-=+0K5rUOTX?6cpGu52jVANX{Bt1FdMOHf@u@W|Zc(_=3hyD2c!tiL3OG z$VN6@U8P&`3_p6f%Xt1Z`E+!B0e(wNnwxiQaF};wNPKX-{Ky2;6Y&KP@`|W;YA=Xwuxq1Ix;}US z>O%IzrYxDp3wr7%>!S~r&=$gKSda0?GD{M){d*rQ_f$}6+L(#bP|rG6D8mz0DehUH zBYsh*5uiGIiXZtu$MK`E7bZ&exE~POv;%--@&^IonQ4~*@eH9I21Lu$jsTK}e-zL| zzwW8W$xWi`0f5H=sd6p=Qa5`Mup1!h3k5t0NPD|Z0n*eP(P?Uj;==*Y0Zs%w5BLKh z>7ge9(z5`N_^D~NR85O8{?-T6dg@pCTOUjtt!Td}*`qi!{c;(DBc|$MvD{lIADQ;R`(&xnOuIl8)WsAuZ+*p zbwQ&*?aSY!)whd@%4qlUB~j{GP1zzFyY#ZF3)>T^Wd4UWEi$y4`W2cv6TK^0ny(Q% z<&!Lp`UbKR3iolx2tEKLOM3!H7WNNddBEp@r1%9OmG3nm-C=K35sHC z;8{qki+fC~uhgSC2!8%&orc4zOnQ}MT4Y)M(pa%L%$8*f7^Ty%;gtcZhra=-Z+ins zS$hlU2KWWAB_RB8@ySPuQy=vXFck13V1$01<_~TlPIXHBWPy`$C)ffB<35II)WeEwk&|5Xo(dw+H2t?XD7Ue zl+j)jt@O!7X_RRTD3)3&Xu6YwERb3sTV*|9_XUmI7q&`ifrmkH%V2>WL8I&b_|Y;u z2i*eOC4}o6HJiu7`wvO%-aS12Yo=65h^CoR3lXOmR6EnA7J94}ru4NAENw6?nZ@8K ztxDW+&ajvPeF_{660?aMaDS4hY`+6iKd=q31mJE!%54fD?aJH(NVz=@NIuRNK$`Q~ z4@mVwak3)XQNvb57+Vq3$cmUo*3Gm5inc=0$n9pnD~gt?Xr3-d4Xr$q-7J&cE%Ci> zgQZ*LlzoU>C%aoCp7_+mZj+mt-6nT4j|M4;H|#dMn|s)8b~7K5YUhR@v0&q|n{BeY zE#Z4=rRy;HQSifWY1*w1jmBxlVR&MtIU;(+oIaqIzB{1n`_x? znmd7@)uexVmDftbx@=)Iu|BVy`uMX{j~9xfpf+$gVl~$=LAGuZ~7EiFX^N;G8s(i^;3F@OV-8L^m1L0PFiD>!Ia*PLa&+89V#o?0e@6? zh%w52w@eZhj3j0#3C2hwER#fMBZ;4s1Y;!8lO=2{HJjR2noUi%HhNHyVWyH|jHKd( zR4H*^X#l4e0yxlB=A-+{7~NNvAg%@Y$zV!%AJ(n2NWCEH+R~@MdKcj8eqDlqDZR9F z7VRxVNt+u<%~B<0j8YoTxiKoKl%T83MR=tYeHMW~&-xj8d7MCZYFC z#y0u0l35Pl3|{Jkb;z;tIS9D zmNB}wEJ0i|@RPxm?)9vj?(P4ioAlBHkPN1DZ_#x#kIXZOdQQ{lp7TsP|CUM>XL^}k zLa%WTW$eJuQ#HsKrLzBDCFUy$#z^95CJE`bQRWsX3C2j`G)v^P)N&efYB~L^Qb80a z%@CxpP)RXHQWu0&sbZE|F??+_TWzAHNzq+pUb?G{(HO^4U4gAN>dj5*zry-80O;5L zC;g;*e-`?0==#Zi(&wFGoTK!m;JlOG+ga$or|X6y1S%~B5OuxjQ((QMlQyo)V5&}@ z2))7wif13_vSbHbr0x=9lnNXl)hA;nP4{(Z^Rf)TC@IEB>OD&tjihxYJK$m^!5B$s za1_z^8%cN@Ni0zkjFCikmMDgu!eIrqVgUuTVzu$D-m`_D7EH~5I&TUePaIB_riWjZ z7RE@6Eo)(~Fpd~q>7O2!Dhb9&BCn7z?vq?~Zo0~Rbl({x>tzX7V7>5@!IbX8tlOwh za@E=YT{r2)oT>_@beH%>-K4i<7P`xFEgIcDdTf(nnW{y`s4O_ACBywTmRPPN7$XTM zmJr?nykXrB`bj1NxI#%WMpAV%r4wo-u~JDeMiLE8rZdM#YL${=jHKLI%09bhABGQD z2Uu(NHEmN#s0aPi!)hhT7)g2x$x?Z+LS(Q)Kgi>plp;%FUa};{s2^l0;(Cgo45swA zX8qKAK))R8{+oW%OgDJh8xkimzW<$vi zxJK0^W0Xn|=Y%{#y%wbeU1dJX17lR5EJ0i}DIkL>-QD$4rg;nhO*iS4PgJDel zH7NB`4KjE7+;g5u=N3|^2UB|ExdwAsYB~I}rCJ1;`x3KDp#q$tL`RDX<-J+c((HsB|NDg8K!3N61>0ZXj_yoGEy7QtBRYx-G=bZ?i+ z0Zr-0$yTHvSB>>rDsCzx%TZdamvrVZvPV;T$1A;HR<-ywy<8up6EE1RU`p>4p_iX} za%eVw{Cw9+$zWbY-6h7T1UN^FN~u4$6SI_{tIS8`V~p+}oXaXgbmV!`j3li8Rbsc2V2mVkvjmUrPNaT3 z{nJB=l3{k+ukwg_CA=+F7+6ID@psUPBZH_T&b1XqzBk_~LlR{pOymaC7nM@rHV7XjB}=XX>TNPK$Vg)Do5i?5{X6<2bBb4B;k=sBEm@G zkdk1GBwDgWerqj1X0Y>PhCDw;mi#sO`HvQ_WH_v(86#=mf0bTrBz;6lGe*+wS=z*i zwq7O*cvML;Mv`4Jl{4B%;+T?Pj3h!>!pI+{B}EyID+$I(B0@+QKdDLyy2^ZHV~mlF zu>^4qGb*_$-7%~ioD`&9vX`{<(^6o)r1M4=dTEeI-}^XF0(v;1O34_NV}Ma9DSfnG z@t@BMW zrwUW~p8ActN$;gB@;y`NHl774V-F?RB?$6`gh-W^&LsEjSG9TT2#^~;|1abM` zCxa>7i!+tyq;(oai)^`_$L zZC!$ZDZPg?m9mJD#A8)T#)KVZDy5X5tIS8GWQnH|g!4h3?dE)J=LPWTE@cH|i$6^Rv+X=o@vDUgJ^SRDD1HM%|?M zKoR#G^qi)h$ zHVfSazfm{ot(S%FV&ABn^rjupW4b>n{f)XwZ`UmH?f8wlNpD;hx~qMoZqhp<3*Fe1 zk-bR4|qAp5LgO^!CU? zcicDXCcSj*kPN2s-RB#1lirD0=pOWqx=Ak`izI`od=J-kGmq@2$m?Y8^xiD{u%t6T zd}0|)=^ZQdn%QL2Y(lc9S_WD8%DJ`xDF%qCOIQ-6#u%kGiE~8H5A^7dASLK3^O0xG z7l<~GUfQE7gQAjwX?hD_joAkcTLid$#)J=Nx^P|0}7E^U{L)XpqCi}qjeI?6L zZ^(Th=}gK(?>(W{c#X27yfuK>vZwdRj8UKagmYrlBTEUo%6yau#;8YT3F0zdn>VHV zWx7&Iy;Ov>^wUycy`=LLelnQS`<_dQ3Nqd!?Jh+CZBoswXTBuZpTqrQ=Zy^>&zB+6z=BiTp-o1ye_Fh&xU zGD);FlE|wh7$XTMmN1&lq*u^n$fqP2BZ<11BuYtkKx%L7zc5A;4Ozmdu6h|sV3Uh3 z!5B%nvqZG57X3#qEn( zPpo<NJ0-ywNyM{+Q8|_vNnks)ZZV9J1U_Ry^=2gDVI)ypNiaqd zLo!KBHIgWyBp4%!k(ng$lAa1Bl>}oXF`gxISYT~EuUcCVRx((JQ&NnP)D)HyYZJLN zJG?_>7tecuJdGqvDM`jia)yvBMSc7&-Zw@9Qi^PydCArp%MXmDh^wfPb(+#YhxLP# zg4BzQ=-O~u$0#k{`*91yf1z4_%r-8C7b=s9f7vgOQb2HIgW+Bp4%!6d_TnaCWUQ(z8K&a^I(v zq`F~#vIWKpD@o!q-q~R)jf0$q@P;gLqGy@}<$xvVUNA=Ku>|QIi=PapbRTEkU@_K9 z_ky|8r@(qi=W3}`ai*6!tMn2h>86mLCoSh(i=@+d1;SK*FABZJ{gCngk8_rMjD1Y;!efF*?Qm$ol_4ke%mMvtLp3GE7)j+9QpWw2l%T83 zM{R^LY9lN`T*kX@P3bPmy1_|7>P04WZRt~By`;04QLk)DuLGBqMz4P6n&ohzUMs^u z{I9M`${3|oKCPq?Y#LI6t}-8$lrbtPOAuEmelnQST_s&frCus&TKZ`zuwK#`EtM+H z^fEQMq(=Q}X(I_IRZ7OF9L}5*IJx-^c;^^>I0Y$1NEXTV|3l_7I0!NMDRGlJI4TlDV{! zVdb@w0p+xkwaeoDm=aq0o&zVBL2m|7kkVvhEJGtWW5s~6G;syt zCxfYU25>qwmcO(VdV_R!$^}c1#W6=1Y;yIk0q=vH0$A(spfH1g0%M*2p_Mc7$d30Tw)qi zUs~g2gfI$sui%c_{m^O{|eS$&_*k`-%iUDmRqx}4XsE^%a9h? zGixAwX3PN?r$y;ZGrD`G(ptx9;cN_{AL(gGPozU>B2bPg{CirIPFZv2r2nSU+N7t& zTv9Jt3UgE4GDazL8AxZNEcEUWdW~l)jc1*b)g5GvQrXKA8N8waxFW*@CB+y?9cC$O zeB}D9r4w=9lk9+#lmufWaWYfRjQ8qKRuYVn#2;xAXW8nT8Kv=ql3{KO>3=ta8yFL7Dzn&!EpV! zAdg@}ux5x)4A&B3yBqoj<4cdNV;v%b*pEY4WSB@K zI4sN|IHo`132{-u{S(p>33T)JZqp&qzo}odX083*C_$ac3q|Ya5S^Gnc|;B!4A34Q z9MdD*!O5YjLph_I1~%&$(9Ey3n|EN-Hmw5?5&Av6{C&OMIt8}#cXRh{7U>M#UzCBXc4i7ffe78F0W8 zs-Npb(4&Imk>Bu`*u)+Y4&5PDF03EtJVQmrh9|^SFyQ{g#l^-O96}>dP?0Lvm`FwQ zis^%!6sF%_t!ZpxR2WHhM?uopFD0(|%1k*_D3?&dAu<8AC=_In)GM4z5*=&^jQ~ST z_o&EF17$(CrtVR}JrW!e;=)5CyGO!K*k(zqAvV@Q6ttSwCN4atg|{jOE`~?qzQqeG z2!+zf9{6%;7~M|TJyj#wV469B9-0^rvo?t9x^=NJIhISPND{Ch1FAAwYcI~u|Nom< zFlt&aB;{PcUno&*j6(uUK;9dla6@pEyiAq!|F9l7t^X}&#I4ugzm=n!LqMzpzAfwE z6B~sypxd{q;*bz7?oD6^uht%Dx$WC|w{mNZ;z#wbX4I@by;^vB_<9AR5mM{((9$yb zACiTain_${>JeIWWK3XR@jpVS_YXI)<%tvi5~JztcE^eh90KBDlrTk+KL|xeCq_FY z;3Au5Ji3qI7>DTKe(HjT2&u;ZjH;Q-v}z*_4hhl0QRs_x-A0MZ)}eoTz^Lt2f&GRD zqeep^N=6=tGl988`sW`UD^f9fpqhgnV#52vh{TuTMd@4kxw!|nYSziUjhml`QFZ%x zwf6Gy>f9`_P3yqsZJM_85A<&1@2>?X8e(OejN-#!9fG6qt%Pp+ z$WRC4hMPq@Br&k_H{HZoBE}J2XOAe9$=?u<-a|9OBRS#~V+ijN9^Xf6;T`Da=N{P1 zzgA$)z|h!eoa7oA5*Za~=x=UmuVN%D<-yYjBK9hZD;^=pni)+i?3Xci;wLd z85M4V1D_I%j|@pPglp(DF&g)Xaz{UFe3+jon-RgyUT+gOU=ol^`?W~ zv_TixM0`RQpYW*Im@XdS3B3%lab3_Q)vQ{xnp3r!PF>nZCL{(&HSN-`ZtX69@H)|N ziR;zk!a_8g)q|G~u6BOTt7C)BJ8o@JWoCowQ|F(XasI{FnvaSuxU{9!iH{auYvKdP zU9m1UG`wqI!Ffx2EpI$+p?l+bKOHN3r}wM%A=^_rUO8N5{Eu4y<)`m$xRmf$WB*|> zU8grZ+H2^@3D?GyNJuGPe&f9#ik+QstJ}dA!RKlX|0(xht$%cgifX$mB}Z8Km{-@U zhJ+`2XPLc`PZlbhT&D>?P_(som4z1(tp%gx1ko`mKqZfmyRd3^U07ejp< zqr+}&DA#%X;)Qh^{?Mdi{@i&Fw0)g#g+troZAP`Pb-=q`yBbUGY#(%X_jfZLzh8NC z*Pw$zfkBm9k3N>){^8}YoTs;LINEmmY>PIHN)||(dM(1M@zAa*+KLLZV@kPqk1G_| zrrPw@WiPJjl+WqVmU1b5t$rHzcG>TZf4kv0{iRdtyn%lo{U*zkJMFP~Q}IL~K+pVNu6@vqO+yOYz+ zGym)Mt$xqh>6eQkepfo)sg~nMn@^9YZ(cODg!fDL?~4u_5wYo7uOH42%vo&f@o`Ds zQEOfH?S8o9ezr1QXVv-CVp56e7nXiL*maM2)1Cj!`P07jZNHEzE&C+9Mc+PBF7=mX z+0NIgIp^HC8&2IVEGN~A@4BMc>PmxWO}hH2>W_untnBsOxy>h+<{y4LNBdD$bG;^4 zYv%Ff`=+!ENp3ZG&&svbtM+rnP@ua#G6i=682YORO9@uyVVCyIRND`P#PHVc+je-uRbo zdtDmY=Fmvzrx*Tt+4Jtrq{_DW?_Dmr@RM0?i|Rw;i(XpbQq}BaquF~_v}>J^=>GQe z*tHQ0fA71aT&EY^ei=QYZkdff{(tRtvzlaK-f!&qz7O+_xwvi7uSL(ixOlXA-B};) ztB<>rt*-l+2Mtg4AN)Mk>Qmjv9ft2rsoi<=iTK}(58TlE_ih7D)xC1+($K-(z2BC! zfApkrmrZ#u_I7>I^+|}s=Fs!YYaHzIlWpYWBi-FvTGtD)5MN- z_H>^;|Ki*)_TRZA?C*ZNw!v=SI``dO;t!4A`N+w3X8Ff1#hX`*bn7z2W#{If*SwDz z5?lJs#2E+j_BnIu_}cqx7xzu{zEQYVr*_e0ng&#JUhRMOT%DvV#}4G%)8z6WsYziI zqtE28KQC^wS&^YJVf}KKbD4L3dhK^NhtxROBxhiciO);F8b2ZEQBt3&4>qI}Y%(I| z#jz&t7VW$F@0+o6z5U13A4gmK;_coxsn*qkUB<5czC-)A?-x%xZNK(%?K0?xl2{$7*@-g`4^YJzv?POI$?Sgab? zrTBxWy64|Jj-FktsQVv3e9m>V)1|BP7xevcbxdfr90v0~Hv%v03HkFauX3mghoEHG;L4;x*UcfEPc{KwxWwe-1qWBb@;HAgga>oO68z;>1C9f4}MHAGe@s!jG{B2cLL3ckY)n{c8=X?)%ugqhX)_(IW+a zY5aI=X~!~ahffUNS>Cy5&&$0Ujm$r*T*dMIqU*2R6dT{rIm!O1!=x4+Zf}YET&sM_ z*cGdLo0X66>0ZP3NXX@-B`)8+w$J=fq3exGFZZzR_uYX&tLycCzMS2)_2aHn*1Ihj zF|h)2C^@SJ8_?UX)z%DrxwbUl;Tl=Ki$OphG|I`TQVvMBZOLE7sdsJ$BZu zWA(1js8s!K$>Y~w&$rJXZT_sQSFddgdNg)PvA+~iD0%Yb+h;?%Jc=3qq~xd96Q9@e zZna_frelvDJzF=#(CPadE4p33GEH8$`{-MA`}PliPR}{_$<`ZfJNvHt;$ExH;-D2B z&&=}t;(B&tNE5?x?+4f4ncYu)^8U}$^Os~RJfO`FXYM_`SmDfz=t0MNhu!|IMYH=( z)1MY^`SI7}mhNxX#{8V8`Gm-|Ew1JIz1frN-&gA4oa9?&^6VLQ7dvEqd|(iB(k#jnA2!P`J2RNB>Xv8;>sc z>_O4hANtMCVQ62YbhF7}la@ZXTkO{8)8B79H@e4$N-Gc6dpxaFO0B+DZ%&Qszj~}@ zce+8l#)hciU&>B>_0+>X_s+vx3rt;+<8g;|OUfReHm}KxM>Bt(F=pam$300dEh`mT z6sa=1%N89vTGh-`!E0Zs7H*?AY?|GnQN@QrV-K{u6ZUre(jB2g?3xxo898nA zq3`^UtvvU+PIOYeU8n7?JGWZ6@cV_8yBF*ExoUg!fz|vb)hp)oalw&3hJ| zFMOUgzt{7*)93As96hV!l$mG7dkq=2KA`Z2yZL@jD7k)W1H1RNw?)p~Lsmwe%dfPFk*Af5!GWpH1Hf!;a&N0xewp{kR$22Rp*f0HJ|3aUw=g73C@FIV``qXT)WIS)m;ixaJ^^Zml+OcV(<>)`G*4Fs!+_m#3|GxdV zziv3A{K=Td6_y)XOtW0&+oE$wezq(i)SvId~wCn>wTAHclmzDh}dHf+a2|{kM*f}@Wr#= z-ln+uS6%Sc@^RV8?;nT*BP2IgywPH}CiQQ$a&g;e)xFluv6Xfn-`KF8RTb|O zH`kTw*>#^~pEZZ>CmlWDrv=PdTPIs;+~RgGea?^h{OnEc!LP~&cGz8X|Dd|ri-$LC z-sPXofvsj~ugavF$1lAaGk8^_HHXeRkG!2${&NAfbMGx}b4cc|Msu??XwMEQ{S~sy_KN{&sXnT zeoujGWvli2t;lw>&d+wrxV>3($I@|qKT7=ru1^Zhx4&0t#(4c^UCMf&`{UYo4U&dG zbK7!FUf(&|@=Zw1#mnXOh$j=5?&|9Nz1jGD9W1RPCLO*$qfxaUH>|5IeYJ9Mz4q}* zZwg=ZKJw3*>d~$i+WXgCe4i{xiYj65^xMl(TY3+;5`Dn&OQXxbKiu}+=t-?h4oW$&vPyoB zIU9qozFRY`$k9A0Cy#jAAMSJf=QI6}J|5k)%+-K<{z11L4_9cL-STmR7LykF49xam zQ{8(->?@usdAx3n$Ayze+C?S)xhn49)JeR%c`Qb=V zNS~sy*S~}`|K-O+m1Z<9Jh}YG$nmvum+4aTci)=77F+mesFXJ!6g|0mwV~d!JzlW# zp4xI>$@=nsTNrYTY`k@CHF>`q7He~(*X+uJrTn7@F-e;~445GKYve26|8QIP@QiWE zA5|k_+s79_ub0=451F(-8r~?L`s$KE?$^>_2tfKGQRwuiB(-{y&E9! zZ?5Erz9rYTn<(Xz9=2z^p z6{_B7YGM81)wr$K=H-*}b^I3GT~v7V(P<$MOKrEbi%lPLz1?)~*b$%k_B|lAn zl{z=}f{b5(?bq*_xyLyf-+jDwRfoHaI>~sk*5e&q231k=_U_R|qmtTq$m^XfCLE2J zQP)Ps2ggiIv02${n2h&m(tUl7>WzMs@qd1+G~vg0kFv}7nuJo8N#~mWB;%t(j%=Nh zzt1xn53?*>q{aO2ReomlTfaS5tD7px>XW@ri8@ ztVvea$N&8*xBcj-YV!Kz3f)@OuXAsw>!^$ON)?>GfB9cQb=Ix9;*o7mY_r-Up6_n> z=s~qL_uVagnmn8Gv;8V7j~5@V-K@6a`jU%J!^;hQ`)Om-_q%?*k$76hEw=m}>X_p4&?1 zl<@{fs^@bolG;kfQ=G=7*PYz}W9IA|x{oURplg2jO+WUReq=ff}eLp<0jF@LR zdBV{o=N=QB>;LR==~iM*{~k+vO_ctW^lye8dNuL+?oWQ^dx{+U)Z}!C^k?pbRkbf@ zT_#DkuT4+vb40ZLt768uOut&CA!ozBw{e%(i=G@gZfkh^_wxEFhrREjmOB0+;~V-6 zzuC3wggcVITK$;QBRd2t{h`i39((h=Za&Fh>Cw6(3Gom5#J*pXr$%JnZL&WM>3QhS zNBLF{9p+d5t>w(Ev3HgP9NqiyL&56Z>aFcGy1m8tIoBJ%I{ol?M*rf-j$hj)ybl;4 z)0g!p(~C~Y=Tok6bcl>ME?42=)yUQFB!6gZ?^`*7^Ociv=?}nZtVeaX1==OzEj(JNjKX#cF!*luUKUEej~#`wEsM{X?BDGuvej~Y zTDGByQ)>c8!gacOTAPX;t8-)Lg}7glQ$#)K|fKX>%(6LE_V{2={z zRX&S=CHIHiC@=jJ`8*}BciL2_ZjLi!vZYo%yUDKdr6%%uEbpQRvBNK2+c)&lwtR(a zo$&8D#lKs(n$`CoNcrjUEVn=NB>q0^@!7`Ds9TI7 zbDvfX$JN}sC5(h`_rZ-4VqUU zCjHrkMV)-_uHUYeZ@eVWI*+Y0H&iNl{L06H2ik8NGOOawn)AJ$#C*>2y49aviSNy7 zPL4S%{oTU;x9{6p44f_X%l<{)|Ix2UuZf>MxI=24sg|34=Lfdget1xov5|I?U;2|l z{eL=kJ2|>ci6xz~=MEcQeD0JnYCzjDc_KQ`M)*k(>1DEaP^gaAODij zeYam-vwU&+XWM8UTP^9B{ip2NU1}dMw!E6-_-Rw8<|)*2O6_?E*Um^DnwtNvQ`a6Y zAMPfUD-@e}|K(bjIs22`pEqgW?W4#1xY*Ly0zH?mO?v$P<~qLRAkppyT` z*p`<%U>GV;Ng|G zTz}Y%zsDVa`v|;olAKy5*_)14f_s!;3v?Zg^qKyNkYUv0?pP6Z@R~V%23=?7zLJ?V3m5N^N*x z*Q*a+x#OrW4{x#PndX-*s<>os^7`smw;%Jx#ufK%elBU>jD35*JU)5f)2&h`@9#YD ziGOR8kKNMj(Nmk=P`|xq!idq;?;dl}UsDUGwmYS+q+!{0D`#b1x@Bik_13RnS<(0R zykWySoxbk7^CvIwgEcc-lM_VZ5P7TNH?g-1QnaPLbyR=(3Mx%I@%y%qa+7XR|gng(Cb{bJv? zuN%F6+LnSrUtd>$pe8(b@b~BL{viE^LBXHG8>T*V%)T|f*FRZ2a`D?^$Dc9n$4>t= zy(Ve@QO8}B+~(t-ikJ02?$$Z$%C{H)d(A5|O8Tw(xaE*lFLnQD(7<2EuK#M?gX=#o ze(k2wPru*x(qFE-{LypUzc=fR6&Jq!U7Lm19o=HWYd@Xy)WCi@m+#6La_X1IPFS6u zddZ$aKhC?Yckz_{s(**@>;InRWiQqr7CdkOFHa6libd;s_U?T{AUKyJ)2l0bR+izT zjRQ`kXIV|Gv~D_Gw}@A4CI#V2KhM^)41TU}awmE!95R!FdDl9Z^hqFoyQ((l%E?yh zE&Sgg&=W5}=u}B}w4zH=5HC+f*LJsz+UUG;d!b%Z@JrY`m-EBB09;Tkbntyr5HAZy z^a*#oU2f|jJ1K~dRdp^b#b565>foh{NkOaz)G0n`NIT3ic)7}s7cnLUM}m%XDKq|} zsaFTCi3Cg(_Q-xc`Sta7evq9M#0NDgoko^UW5Rq0d(2O$>wj>qFAzk2urx`*-ywV) zyuuAGL5ID&p79dlq#)k#N0(v#8k}nDz-709nF1Nc_P`Auq7Qqw4qToKm`d1Vxngfr zePrw4WyeXu@4-vyG_iD=IT+l-UsZ>Hx7s>b8fbSgQsru9=`<${{>TT``15CfmgLf`S6@I5Eb=|y*MfO22=@MdkgPcS~{%>gFoHU z6<+-?H0>5!2QOrX`hl)C3|`^Z+S0)X+$05WfIYUrox4ATyR*FcIe{=`5LW%Ujiu9; zFnEIn_Wn8hwnS|mymUJ$__Rx>t)&CQ05Jap47%?B>zjI8r#)fnpbph|Z)fS8M3`Q% z2dTh+k1zhi*6Bc)zhRGk6}OWtos%J&6jVBsu6_xs8x`H-6k8I;1?-j1$(Bw>!dw7* z9Qni7=P$8!IuXWQKOHTd&V<2nf$de?>V!vZol^<(A!Jka!_JmY7s9*;dz=$i^=|A_ z&!-XQCznnaO9y*jQV?$?#CHGo!Zg@>>*sXBya-{{f4W*a-3XHddz^ogm;L*yt<#+_ z=el&dSvoxkgAZ}VnP|q*ec=`S6YbTLFq^>WOn8M`4@(DIJSjLAFnDW4)21V!>AX5P zI+KFkp-`8=E8KcnI(;CT6r|F@t1G8$c;D9POBnq1U93ag`dB*sAZm2lH@Fz4DsO)J z6UMF6&(cXIOg`+f|D15v?-20n3?R(?5XPArw`5CaAViabSZ>VozM3lvZJj}cc^h<8 zyAQNv6jG=I0E;w1BW0UxO{3A%yu9_Sm0$Z_FHJ>tJgq1&hEz&GSPn zouP!m8*s4f{l-4j#@4~vG%2_oba2MUZK$OK(h1PP8g!jdIP_mrlge$s`Q+G_0St*WSLs&QBI$jszW5Kbe+JHev7&~@x3JBw_pL|OPh7;&?f<4yHoW8qXw{?mLgTn>KAZ~@04iv+cp9w!*{*tXTf-vs< z47YS}F`g704SOutS1y|#A zl%<0!4OmC9&e*@_Leqhel$M#zMLikHt2YXjiu)j;^Y)fZ6VZMSr*5R97{#jw`Odw1J7^(SZyrl!v z1bAW2v0Pt7xFkM=!6fR{nMjy(A*|XxYUz{`W*h8r{gYSw z(bKk08DYjkxm3HCS~@Yp;E@G$(c`HT|FU%^5$1RR;IRO=n58orqDetqC8Ewnd(MGL z0$;h;b6Am%IesC#^^$2%*gEGC2J2bPtL2u?RKn2A0IyEj+$`PJ zsUXZqm(Em62Zj^m=Umw1_iK+2rq#*uC zY9n}+zH6vYd%+guxHyYJQ$$>C7Wc zChW0IuR8Bj$UTUP`niNKAqcDfJkQd(lrY_4kL+I0rQB%i%qL7905H$EU25rE2GOJ- zu8kYRtFZ^R_>8a12?O_92in6c+%B_pu7IfXxe^K#n6|q7Ry#je5~iuETvu2+R}p3a z>``al(_am5k+)kK0*yB95Vs>}<&s#rt5N4)J=XOiyPQv^T z_6_0huGjkavUMPfkY}6^)w<Ws|XW;J(jCW z*83H<&NGDh5CE#ZR#`gF66Q+SV;{ROfAVX#4z5O$g6{G4tfjM>Fr8qJ`8l)A+wc-! zx%=VsggFhus@+#xI`FX#yz*fW6IfvNlvJO2<3++?epI<$uyocCW-RQnZ+zc$h)=m* zB21YpKWi+VmkEQbDI6E$U)|Q#F4rrB!Q+m~&&!t1TEa|(J@$=XU)l4Ct@A2j@VKnn zeXXUljxd-Gu)upGqp#aK>j{IkgkHFkQ&x`Y**}VCAi!fQP`gzmR*+>|bpSjKcTwv?G zO&ILes$3f_op%Ux0_-st|Gm5Tep}~V!gKd)_3I`0wY3fNo%abd#g(7Umd*!+!M=>;iafabYg-486iGptDD}Mh zfu*yBFiEh-t!G*{SbU+PyZ?Ly?~{Vi(Y4MNOXp+4B+d^i$nSGMwsbxvObYCAelD-N z?SFQDwh{)9@7OtM|!1>HKISvp@3rX}pLR;CSl<|wHNVcYAHObiN{tI_~7{&gfw4K$UsQ^_8Uq-32hG zK;@hWub!P({)(;h4PlOi5!@SI;r6wqvjd_@!Pj69u)y$RpYs`C-x6j$6kLt39hS~_ zgc*!`_&aBPKKzF@Zjq^!ys#3ogWC}o_}^)IzJMo3G9*m zSyd8z2=MA)izfw-hcF&t>6`IzgRlILDZaQTlRJLwYJV~!kh+Ps=a=*boLPD0@&j`*6pV8%Wa+C z34`t46kg%B$I|%&qDeue^UC+H&#-m=B#c|<4@(C=27t~Tu*ZIQ>>E=;w$9&#IT9uo zm7l*XoxOyq;j%y7{fSgtXCGlIc?h14usc*E5&B*4@^@Zz|>Yo{cS?V+e!2 z5p^anc)z2qbF8IvjHQDQeoPA1g9g^m6$`)EWb5FWv83SNuvg=&iKT--HE8OmaLEmA zY@Oo>b0zFm{WP<5niJ+~$P2dnmYcJB**YxNEj>^dbL>^8f)jL6JhZB1U3J3v~)TXrWQ1CTtu(j=~F+a66P-0t9hfdrPGBl zRjf08Z3|eIK}htU(+D#S_G(;ov2?l;W-9Ca@Jn-_`S5hYVBb(WT`iq%gt?n_F1i2x z4R(II6Xr_Tt8#U-bb1g5)1evzSKiv;EL*21VchNB!_w(R7C z4cY-Pxb?Dh`VaZzbXrefH#}w@K)pI=5aw^F=hFa#+h9v)2w`erkDs01pM9-Qe$FHe zt~X8~l|W#Kr8AT;D7)|oCSc;au4-H5i?&W0Veor%rITvugb9-l8aV%a`rVm}ZJl(&U@yWxhFjRu zi4bNPq+xz$zc3%BA_$3cWe^6BUn)NlODB^s1Aqyzz%%bY{+_LqMHpOlsD7Af>0}c| zjf)GT=RIue;7{wqwS2Hw^G3F%lS>$wl&QVeeboaN!VnVW$|DTc(ov9tTdt*p-*_ek zi=E^^!`{EbhZ3(&0bx#qy((8e=^*J;W(EQssAk~DQ>;ja6&YhiVpas#QqHE7=c|DB zy2XmzZ$(yFk=Lxq7AvyDiogKnP2~sI*3PCPxayJ-JRZvk&ag6qeN;xyvLfeMk(pNH zYAb@rRH^)=6?xf;yl+MRXGL~fk>hY+(57m`{KTz_L@Z3H6`5&87IEbKfYN!2BlSA+ z7DomL73K?$4AGHaIZ~)uO<*3!ty)L$>;P^hI--8Ya+HotU`(lwT+ER%IQ5|`j zBb7R`i6i56?`*O7)e{lS*6Bd2mCS4SconXMyb9Qj8_F5$==9l3`iSLw(aj@+&z zpK+wMj{L@v<~q{&a3_b?=tu{ST&g33IWkX2hI6D{P_l|sVSzmGFPL089PjPD-RPN3B5VBZfPUpxB9m(RzF`6}rBR6Wye2z5MnEN<# zy~e!4kw0|gGmf;;tiL$2M`K#z2PfD%2UVWCa^zu+8Oo8bbOe9?8n=}?f=cFaeO#$rz2fC@|ccfa^z$knaGio zbmU@=4AGHA92ux1D>#y=BO5u=Lq~q#NQ#ae(KtX`s*aq*kzP77h$CHeWCTZs>d1K< z>8B%CaHNlpEaOPBj;!TKSVz9#$Y34W%aMqVH08xsHyt@$Ex&Xmog-az>zu=pCp2aT zN4jdvbsYIkV;$cjv|BJ-`tZB}Ht z6U5ZnTwz6)Sdmp6iRc#G%#pB;?BhtLjvSAtvS3RMs-7^6BSUrM9FC;u$VD8f z)j7PLBaL+AA&wlQBQJ8KjgD;MNMjxOnj=5z$bOFO(vjADdTxh~^x#Ojj)XZ$jN`~VIx>|bTXbYLN8Zzsg&f(eBad>VPf+!QS2z;Wm=8E|lE(bN zktP~LH$y|Yx@k;%b=py523nCkD>B}SR9lhxR%D?SS!zX|v?8xskxf=)n-%%ViqJ_S zD7%?|nzf|2uEUvQKNz*12twoN7@pmv~n8$I7ltJ zN0d9BQ=$B5ov0P5RFOW4HC{yq!wcGm!=7|> zBwt0ea;}Q>Q=!=^qVtU3sgX_}RU30uM3?<46;U#Q+f^jFFTBF7HT*d`z3DyPrS2{1 zHCAMvis(|bQ*F^l>D;R@I&!$e=oZ|oFnty4LLE_c*jlmr41_e??u0)l&&s~7#;7)( zVPTHZ7*!pORYb|ar$1KKk%zU8%Hhj8qP+I&h|2TbDx$3DXX<6U_fuXP6I2n^q=74x zj;_ONt;o$fqTHJ+oj$57EL0d>uD?`7yU$V)-N#xg9nHE`V^sfXVqqGpNFPNzpjdrX zja{Z9dZZ*NmLdf@D@`Zb;s19ejBb1*7?g+IY_6w~{Wq(RUFwd`v2-esqBGMn;{U{=s zX}k)F(MG=8IKFqr9qB7&L5v*Q{=qjJ26U?0Qp01XE7e5r_Fo)?J-=J{a} z!Th`~BIv%?9qET&c$PC2{-?I+hhC{7f?gv<1idDU2-eR9?uhOiT6q8}!|%7kJ^S1f zsNJzmF+%Rt?pL}a)b6*qBh>EqxFgi=%S8mswNgY>yK65RgC7eFmJ6@-GZ-w_4iUjj z|0E)q={+KXncgQNm}#7Qv@*5(ks^Y5jzJw740`<`BIt$R-5CsebrTWv!gIbF(+}s> z@gjn4dZCD5*>4dMEc;_3g86w}L@+vU`ni--xKYB*$0#RyrJ=+Xb5j3X_ zb4nN;!FqC7_zJf${5cVI1i?Cxk%)?5mTBt-d&1~Q7ibTPU}ezu1neoI3K8h4F#33U zvWjR{M-}OVy$-i$;g58v_hMv?ifGK6R%ERei6~{ApRkJP<5#MVDEFZ%qFIf!GS)9{ z$G{)ukVYIv+Nek$6>6*_N(je>WEHE3f&|W15hW8Cry{y1bXAf5sxiJ+5#8>es)$zp zOhpta@Scij%w`qotD2{estv8&L}OHqbyFB!t4j&f)AzR2yGb?Rn0yRx^t*!fUkfx@p&#<%YF|S%eW@V~Ev)y)rJ{RBl+mF^e$5 zYpn2U)Z^xrhIP#GSSN5-Dq@7!IAS%0G;HOI8wOe$R##>bMtI@3rb$87H`e~s=t0AZ zFpDt4>ullm{O508VOUXS5k`2OBfOgJkIXl$*~}u0@WPdf>GRk(3U!~qomqqtUK51Z z@`^KO8`dk#B8>1VvAn9a*SE|fjPN>Fcoj}vxyP^?kX@rS%eW@rJ99#ncM#GpGRr0DrONzc$H}u_Ne6xI`cYvj`)+Duvfg_Y7TTSlgII7~xeVyoTl8IKi+Qw#6EPE13`@ysC+% z+UxR@myI^8-pnG5@WM|frVc;Z{O%uyHI7+?5nksLOC3}C%(-&l7~Ni%FpDt4t44UO zTkzjF!@8GQgb`k~!VBl9sP=l9S%eW@b;1kBvSEG8EW!w{ddsU)dmW93HP{Fvyrv7U z7w-9SlVSB{7GZ?f49!B-fq!j!XT0_*W)@+D7hYv!+Uthbo||e|wag-n@R~&|)#v{_ zVd#&BbrZ7)BfKsUUTto9HrcRNGK(<6>q6mmR?g2)7}kf(B8>35NO-mQ=7k1^^#`*E zBfMr4OZEASdj0agVYR}OAFvTdcwH>K?&z~*m|+cM7GZ?f9Ac?HkNt4CZm+S-B8>2w zE4(^iy=snO&0!W{gx5UFD_?spV-{hA*Cm#hVZF^P!U(TREw5bdwVPRl5nl6!*HzzM z)xfaYw0CNrFv9CH%|gUo7u@>hZ0(i8EW!w{%QXv+m94++_^x41VisY9*A>LVg$1%+ z%3dBatOd*>jPSZrcuimS?hM0vnpuPqURMdPyC>arq+xx|EW!vcygts1%;TDxYe+BGm9|7 z>qgB&^(AwIr_9m)uyqHF!97lh5neZG7WSwsKmVnLVGZqooIrpu!s}*YsdC}G;XFMC z(Gxr1J`f;`@VZ5K?K|tfuwh-%fk*+u2(N{fm-D0%#6QX`!U(TL!t1_|`(A8Vo0&xz z;dLvqcxnzz-}l>muA)BxfMtI#$ELDg7b{>97bM4iK zS%eW@cL=XtuP*LtSjEgDjPSaXSZaJ-)9(0(4Xch>gb`kM39ojI|F_1lZegx6x> z)g^!9F2j1BS%eW@ON3YVb?y2Y))&kojPSZUffqeY8ET#|!s{O4b=M0U;A{B9sg>ZW z{8OA4gb`l%5=*rg_W5fxD}z~t5nlHRuirP0?Pyq~%p#2NT55UC(_V9!MHu0AzvX3E zcQcDH!fTmkVaYqcGp@69=M=tsiCKgZUJqy%&KuvaiMUwXm_-=j^`KR*dv&??Gm9|7 z>mlJa_QA3VhSjbk<`cfZL5%QvShFx4%jMj0iSN#27GZ?fBbtTfdgrZA8MtD6byt>?U)m+1B#U}^}BfM4+OC6UB z!m~;ZYXGwdBfOpxUf17tToc0@%`CzQua(47V;Se(3w1x7&Md+Rucw7q-;9ax8`eT* z5k`2eB9@waN8bM32*X;*EW!w{XN1=mf3ECqSRXKpFv9Cu;q~{M{aYE<9%d0ncs(b) z%KmEPs*UEIu@46Vgb`k=iKW_W+w$b8#;YH*2qV0n7ha{e&Hmf4ikU?i;q`)MVP1ag z-C?kE*DAiNWfozC*Nd8!1i033fBcwXEn*g7gx4Bksqr=AgWZQ4)^p4vjPQC%c$Xq&Md+Rua||_(JTJ`(XiBQKZFrpuL!RTrfphoSe;JAItc^_BfQoUOSM;{y{Fx0 zSXs;>jPQC@c-8Mpf6=fim_-=jwN7~bbL!j{hIIq82qV1K3$NYNt8Xx@raqL@vj`)+Ue_$_8!v48tIn|gVHRP8*9Ky#v0VM+v=xTc4!yo)0HTwbMHu0=NqC)jWbi)2I-6O95nh`uFXu@J=rxyF zgb`lv3$KCA3)UFc1I!|f@cO{=a_;6vuZ_$ijPUwUc-1c2eu`mz$1K7KuPv6>!@9j1 z;FqGX5k`1@B)l3w|JI|1)t*^|5ndl#UN38}!OS9z@cKk}rOqEU(6Giai!j3LQ_E|= z_L|8o!U(Ue!mBVf^9I9O%q+qPug{33=8cg%25&X2wag-n@cLYMWtQi`4=o+;RCwS! zW)VhseIdO5UiHHg!#d`4hfWybwM}>(H|vj{hSiT*gb`lbiKXVKrH?l4YFOi#MHu1r zrSN*_(YHGo)*NOLMtFTitRuPnIF|3$wXuv@gb`l<6JFI{zS_yKHZY4Y!s~0{h2I4@ zce|tc_sk-U@cKr0wSH=2Bf~ldFXe!ZFv4qx@WRiP&K>%Q?!zp?2(NFY*KH~18P?g% zB8>3*PP0%QKNC4m#ld&;nMD}k^}S}{v2y$T1OFJ-Qf3iGcsR4*-0lCoYFN)Oi!j3LH{peK zxKNktQ)UrHczG9t;q{mB!nKX_lpZY4Q_Lca@cLVL zrEXgDt6_b}EW!w{y~I+-lpo&t`#!_^gIR1lOnCkDev@+yYdW(CBfJi` zyqqW7qx0>|B8>1lLU_IUziC$*)*5CJMtC(OmYO&4bBgmcHuU>IPzjS0iG%+pDv#!;Z`%jPN>2c%8TE=Ul@IF^e$5tFiFH^HJ@z*E!50 zjPSyz`j~Q+opt2(hIJvc2qV0XA(omq8eDd56T`ZlS%eW@#|p0thmRR&SgV;u7~$1~ zSWTgRapiF3lO+QT>r-YCMtC(9Uf*r08gE#8nMD}k)r?r~_8Ow=unk{^OBmsWPt-7V zIC|pry@oZIS%eW@&55PzaPh3gw;9%0W)VhswGdwSoVI43Va;L|VT4yp;nk;W!RLl` z2eSwxyjlsbTbJI^!LVLn7GZ=}>jYk(Gm9|7>v-WcbKxfqjMsi<5k`2mN#NCqOzzBkjql#%mt42qV1O5zE~V2kL%!AF~J} zyxI$|Rk6J@4C^&!5k`2OB+7O1#mBWWtnZjb7~$1Hc=g{l@C(Cg%oke|MtGepyx#A* zc7$Q|VisY9*D1p5l#{ZaGpu4}5k`1*OyD(xS%eW@orG6m?)e`XuREDV7~$2KSU5-F zcKX)z6MN|PdYM^-5niVXuc^P?ve&S_WfozCR~KTr`$mfPI=a7;1HuTe(}Y*ISn&&n z)tgy_5nf%1rRJzFFMe*TVHGorFv9C};dR8hTW1*7OlA>Acy%L|n&&rMe^>*I!x7d_#LwdBfRhqA~VkiPXE2su#V)b> z5Jq?nOyD($S%eW@gM`0% zEW!w{lmuP{%p#2N3JI^y7aTR;c%9EI!U(U_1YWl=i!j0~O?WN2_uCJQ*R#wbjPMF4 z@Y>2O!U(T);nld|))$P|er6FyctsL;br|Hd7h!}~hVaU5GxJ*G6=oJ;gjZ$)uSv`z zjPS}5Ubj}gzQ=f7#Vo=Iuj~X~%b7(O;guu2wr*+pvhjM4S%eW@xe2^>Gm9|7D^Gas zuDq_+c(okt)I4E?SAGJoLChkI@G1~qN3@?^ZoJNB7GZ=}VFIs7GZ?f2;p_yhlRHrukV;e7~xf%!0V_poSG+$@ER$+dNpY?+<5h1 z7GZ?fs03a`%p#2N8ZEr?TT~A-UbW03jPM$hz-tk+2qV143a^QmZC`A>Rx^t*!fRXt zug{r97~yr6@M<@^zJu{Pz%0TDud@?)oifB}FTx0~bA(s3f!{oCydumZjPM$tz-tP# z2qU~E2(OE8yljH;x`tVV5nd$;ydGy3VT9MY!fW=#^`9B9&CDW<@QNnz`kh&X5ndC8 zSMKBERvE9>XF4@c7~xf#!0QZV5k`2G39rHD-gCO~8qX}k2(MTIuer=3jPRNyyawL$ zu&Zw@WfozC*W?6VuQQ7cuR=2(PKcQlGzmdS&TW!y3UX!U(Sl;Wc%_^}iTaJ+lZSyehR9mf__|7d+TYfBw3S zS%eW@Rl@7c{S})HYc;b7BfP4Kr9OXk8F$>BhV?142qV0v39rkx?d)w>|1gU%!s~qD zbxotS+YPJTFsHo;BfM&aSCd6EU0x~7B8>2=P2d$}7GZ=}o$yNCpY^E8;ib$XjPR;Y z;I)idgb`lTh1ao1_rJz?ZD1B*gx8D&UOSmZ7~wTjcpW%D`6uJmIK`=X!U(Tf3A}nR zi!j3L0^v3Ly^AZ1R}r%aBfKt5;8n{k!U(U6gx6uM@BX!U(UMgxC2G?R&tm7BY)4!s}+u!jj{??L&3Bo?{kagx4*ag=d!V zK3~K7gjs|UUJHq(>Tvyk_s0zDFJ=)&cr6lM-QM5wonajxcG``r8P*TXB8>1_EWB`hg|%0cbf@MCBfORfukDXFzRj@uF^e$5>u%wN zbvRgijb;{Mgx5X7YjoBncNo?M%p#2Nx>tB%xgy$YF|!CGyzUcT3vM5NtYN*#EW!w{ zrIuGW?X{Izgb`l%3$M=G#y@9R|1yg(!fToE!a8(*(Ft3sUBqcG!U(Sigx6J1MPD*O%lU;VEYZEpB8>2QM0o9b zao)9t^$N2HBfK6Z)`?DK1-icY@K)#7zA&(jS%eW@%Y_$SD`HsxF^e$5>oH=f`LO-{ zX`dQay9_4_gb`kk3$H)Exg}^=!h($?DyPRl+R72(KrFSL@>AcNx}P zW)VhstzIy-=A`7 zmQ(YD5ne9}ukUw0_CLeQVHRP8*BZ+!ti39kMHu1rlJLTN%?xV^vj`)+Ubehawb#4M zB8>2QMR+Y(xvbK#{$&w{cJ@#z9=NRp^idlpaUat$U zv7gS|XIPt=MHu0=fmp|b59Y92`zxjx)=$hLjPQCxc#Zq6bhcqN%E4R*0)!D>Z|ZWP z*VFxag$?UeW)Vhsy(PSwUsLz0VTGAR7~!>%SVvM$;K>d5b$hjquETSgMHu1rw(y!g zYw)**brG`&BfQ=rmO6e-`XY0=Vcp6s!U(T-h1Z2MOEV4YX=V{dc)dp~b^N;V=Bg6I z+RQA%2(L}TYg)f)%M9yhW)VhsZ6+4>4ctaOyZP0|x(*xXI#I$1ulI%5w=>6FVpyj# zi!j3L17fN6!ufEA_6jkJFv9CY;dRA~+KGlWfmwtRUR#KTYa8r`Wfx57U|1J2i!j3L zBjNRQm$7#m)*Z|ujPUxHSgLO{$js_(SgV;u7~%Da@Ty&TL?^@ggjs|UUY`<6^^LLb zG&#kv{$dtkgx6N#75?$kF^1JD&uL}C2(QnC*VM(GJ~OOjW)VhseJ;F~{d>}fhBcB| zgb`j}5X;>+ign+pWfozC*EZpW*UuZ))yyJ{@Y-&9ovpp@VHRP8*O$Tz`=MdI!YslF zudghxaoTG;vj`)+{wKU}ZDUyQgKxAEMtFU#SqQ-Uq`GRa4$LBq@cKrxaHQa~BMd8- zS%eW@JBXz|J5+vlMdPovS3R=`BfP#9UeC;V;cCOWfmwtRUf&T*^$lDfeyY75VHRP8 z*Z0C}bLy^h3~N2J2qV09YL=?Q&$QPU%p#2N`a!d>4si`&SbLd87~%D!W+|`tv{#D) zjKR~=5hJ{Q(k%4CXZIOae`XOzcle+! z5`1&)Q+u3W0mgUNF^e$5>sQUfa&1oe?Qg?+lv#ukUcV7b&Ao5kdHqv{wSifL5nj86 z*NLy6`ix=iU>0G7*B)Z2xp(N62T~0ysSryC_kSTqc>ONC=Dn4^*|1J#7GZ?fADV@# zXRbQ>$0oYHQkX>;;q|9xVIAW2*oHNMS%eW@e-TU7;gs7~K4(}LF^e$5>u=#z^!Ua; zhIJRS2qV1q5=+(Lxa%K(*RWn>7GZ?fKH+s!<5OA~*5}M3jPUx0SgOzCdc*mZZLHCM znMD}k^{?>4>y{1cI%+i!j3LKjAfDS5A&$O=T8ggx3LL zsXD~#mJRDhW)Vhs;X=q0cYx zf6O9`@Jh10a`orR_QRc;CyekqOnBir2g6EZ7GZ?f;l%3Thz5T9GUtqzx?C}45k`0& zA-pCmYBj~ME@Kv9gjYji;rPPs;pn5k4%FqkpIL+vUPlTqe4d_Rt!EZtgjXYCsrJHS zWm{dYubD*{;dPYo+P?4W62m%dgp+T=2(QM%3-22}Tzhq57GZ?f(ZUO#2Wwc_%p#2N zI!1V5xu$BbN@fv8cpWRewr^^EreQ5&7GZ=J{`RjkQn2JbmTphV)?P0$i!j2gsb;~8 z06vS`uzp|`VT4yRVs!upvVN)>I?b?J7DEU&!U!+?r3y2a&kTLO(Xi5(MHu1LoLFj} z@3Selr(snyi!j2gh45-xfA|=~x{Fza5ne5c)f93MF9Mq$xu(Xj-eeYGgjXx!b?k2s zzGPT`GK(<6t2MDYu-7wPch?(M$B__*jWELNc;Qw2YUFprDqttf7wIef{if3tF!Q0^zO`ghIKl#2qU~s68zux?-$VT4y#VyQll{jj0#hfgt!Fv9C};f3GB z8rFx*B8>3DU-vQdJbqs8sJ;GR7GZ=}cg=zqfw9-#Fx0SGjiKfW5Jq_QAeJiEj~~o? zp_%p?z%0TDub#r|!(quqhIJOR2qV0D2`{X}Y(2haGm9|7tGDoK4bNsVth<>-7~$1N zcqPpoGJcgV*DK5-jPU9!ysmnCcGR$TFpDsOp5_N$0{w`EV;L5}o~_YXCqS4$&xy6Q z3eaEVP(=fQlDaA73PhMd&l+QvOssYcpLl=$<;Jx+dm*NQU=1MF5zP8wWncI{ROL0D zS%{IWfy8RftX{9aa;#yU%`C)7)*xaX&aBk7A6{Wtmop17k~NrEjhJ=b?+?QDaw><5 znS~h1I)hlSnb9+ zVZ=z*P-5X6h1--}!@n@B(ab`OWDO%$GlvwYoVj3wVO_v1#7I^Ou})ytSs$PAkzw7> zEW}7wh*+mH>-6)7{m-zrFbgq~l}apip6#hdd29FYkYeVWlt& zF_IM~R$I>D(WCBu*RW+|7GfkTLad|NtNNG2;PbfZ8(Wx# z7|F^YR%d24I{dRqhLv=-6Gn_=WfH3wvs(YL%++4Qn1vY0$`W1$%jbM&yrwe?F_M){ ztbyz`t>q)o{Z+Z1WENs1D~DK3m^J>RsplEiPG%uSvT}*lmRUEoTluD89es`yMvP?T z5lhV*&pxygRwgQkDa=BQWaSe}wQ_@<|665PqnU*m$tob$$(+O07xkNHSPPhi7|ALm zR!3&lKQw2ZVZFvI#7I^Vv05_g#;yxC8rHweLX2b$Csrl1wni_9L$s=muH&6BVkB#X zU|l(~*(HV*Wfo#2tC(1-A5OYsA$%TJUUx7HF_JZsSQVVZ`{o@p#<1W=HfTePWQ`(L zPiAd7YWF*a)p&vvMvP>QCKgv#V91&YYYi)%S%{IWF~m~+@Y{`hJ}|7=%tDN0jU|@K z;dSA_X2V*}EW}9GIAR64T+V;04tFpMF_Lu_u~eV`Y)QNQ#_MlpAx5&!CYDm~^UKBO z8dj4M#~U${b&g;?@l~hC467rv5F=URiKSK!{hRdq*RTdM3o(*4L9iYP*7q^2LS`XG zvPy^r6E1CYR!w%XCNm2$l69`|dM2;OYU8z(S%{IWs9>FzHlxn4USJktBx@qEia3W) zU;O%9!}@?(h>@&PV)1E$z?935fU5^p>oqyo5krh*l@aSW_F6D()%S*##Vo`~R*YC` zW*aqnw5vx|F$*!0HHlcNA3nPpPQd6K-p4G&NY-RxwdWl6{t@rdQ{`ICEW}9G6k@3( zQOmAZ0Y$NXW)@;3tDIQv*z2MJP2r%VSY4t{7%`G{9BB{FT--aoL7@w$syh>@&HVyQW5McK7;4Qmav5F=Stf)(Br zdDyUiVisZ~tD0DlE!zG%Z{}{pYCF-1B1W>N5$hyo-SgqZ6^50?EW}9G`NTSfS=s-M zf7!4uVHRQ}tA@)6#A?i}iSs{ktpUa|3o(*4gIH>O{X5{Q?#636 zvk)U$Gl`|zYv#O@f`;`dvk)U$vxwE4bNK$dFYYm{ub71x$-018kS*GteW*(d!#cLi zi6Ta_E+keev)=ABb(vvhF$*!0brG>nW7dS%s(v-BOPGZi$(l{9Zp=zvvInE3*(IS(g$EcC__7CwGeRdW%_z zk*xW|Qse8x2eV!^tnJJ~jAUI#tj_E;+~5F=Sv5vviiQv09c`gHRKvk)U$ zR}%{kKeTlox(E({s`q})EW}9GHN;Y%=-ag^`pvNRGYc`2wSZX1v)9?7lu%q+w>v5Pr^aH(@0=^Vy7(^u`dR&n4L&X|Rm27!`E6?OHs zF&>4aQx=<8Ke-cqhj2aVs80$k2mkdfoiep{Kz|C{K$y8|7--NP;4>z>AiZ!*ammE$ z>blyxn&`AZ`l$T;ajy5p>3JoU(Ta-d(vlI8)Vu(`FZH~yiFpE(YGN@1pB$@;RZTbV z&#$ensWWdYW0kcr`Mz}8ERkMWJ>8`Tgwo1s1^^kah*gRAW%V+>bV`j#2a0)LURND8 z@1k|p<>nm#yYfXAMT2WeG0g{=~%F5`7 zsJo&gRizcxwXve=@~S#Fg|aXrGp)G3W>T~?mQhn(X#_K%FK~hhhO4Wl$7<>nfwE&# zp#TN-m7~kcV%6z2av)x zBPK}6Snbrh>S->XNakvZn~V)#s|sp~k14MztDeE+?5eWZOd}56Pb4QM$4Si&hl^^e zCzV&oLOH^&K5cBBf#CrBqq3huwL0MJbOYBx#QG;xL?^o%Ko@pod7W=wJ#mfCE_JuD z4yQ-!TyvAojtpybQFU#()mgZXtR&4UF2BI9R^x=zs%y$%M9NgHm0w;}URhr$Q+2j| zQw=vdGZEJ>RdbzO#mY?6>7)^{+VTr<`1z!zR?L7gURX7<+I74ro>D!-+i$X9GV;bo zM9XWfU_NFOD%1<6qWi=lcXib@7F_2(qrRe|wiM=2IRiNI*1S4u8hm%gVuzAAB3A02 z$+c@{O?0A9b>+rpO{|XAl*LKTuZES1Ow&ytC+x4NS^kQsH8ED^tzw;fVqwut5u~C_ z)4a5r^2t-`s$#XS0j-ICiJDnBEm~S$=UTLAnw6qCFw;fxNNh5xld`L()z@WIm)5&7 zq7!`%%-YQ-P4lwK>qbInGjr(I$?1X4#$xy98RvW<^)^_ zV*Rb*XiAHRTiQ>%>truLNpIr8ezq)dfm=M ztWJ$pZ^x{Q)LuD-@eF?j=* z1ROlvK-0sABEyJGhjpJPQ=pOs3vUDBKw5P*d{S_g6$SHQ)I=x4iqpLigLrXy<+O^J zUuu4=4myw1t4Ei|W*8qQg(n8TB*;i!bXLrje}@9`IK7q@_#}=33M#ni&T46^6+8B$8Q;11s%4kylQd+MVS1` zCs%m~qE|G6lSo>$bn4_9{4A3|kC1TmiX}usKGR~Q)s-=?vHYZl?~3au7SF1!i@82J z;%7IX@aX!AsnFkj4;`Ea-C^`p*kxDM)mVhr6_BZF#8^cRp;Y1S+F@F#w2#f+c``~hdV}nbGnp50~P3)wOkmb}#L50Zc(?5<2p*gC^EbniQ*{ z968g0!(#}=-3{oD^HITv08=`AoR3yu2c$s~D2mq9LL1VlDfc-gTo{lEY1aVX3Ma2bdE95slI9koW|;e zXSksnow=2goTEl3{A?YKpX{O&7kiP#^rm=8*jxQcu9VU#Fj;i!OIaa7SDKSa|1^i! zF9FX#&EfS=!1GUYc*zNP{%NjCfrj9t*FoANE=r2&^UC7%u58*k7%9X9#GDG28g{ZT z-F-&bS3m%q`s_{h2^GU00^&4(LWrZ%=in*{A-=_NPf1oUHaYfz`4`Ox=wCn|prhyv zgoM`a5t9(;C^|zVA<$7g1fXvv>hA)4JA_H~C0pMZ_=?ylDdstZ_%)?JM9R1hB7PEf zvVSiyAF;VG-tO%J__w+X;NRLVfPX8y0RFA(0(dIHT4MXwMLd)gvsdzdVsTL(F>4** zD;5tW#hgPmH>v9zAld)oqMTaSGfrHbQ~3wSd0O!xdU~kF#W{M;VGhQAT%41?gX0`M z=kRxMy@TUijRC7Skv&(>baICaoCF}3ls9L-QVBqQQr>U!{5pt*@e{JX_48A*K`trx zO5N)EK8bOt=6gg}4%~DXz-f190*eE28Yv;fQE`rK2~`q8+qTK4e*AQI<@xEmE6*?8Rd`)D>O-_O1I0r)neg-gUzNldcVXgrxeF8z zx4Rmr*ye6u5ZnFrxy#?#Y07~kIJ!8kge1&asc=p@Ft z3Z?7DTxH=mXSh;bWL+cHbsR2@1R$4`&Ig@+abNV|l1c#bmGWNY;VWf<+){9!*BRIL zfbu4}Xx6LI#c}jacF}e1nA2umxTKqY&@0tn8ZSOcAUQ)a^=ZK%?)%(>RLCK z%D8m=Qe9+SbYHSxsvlXMtWPZBgYpxjGsKCNybza+E-zuQ%Hj_UFT^FIOYX%uy-yqg zybza+&W-mfAiox}FfJjT9}DD@Aq(RY(m4_r82M#K0(|ET32}1bnJ^^8QSmG3AV78C@@4j8Av* zLR>PsZp1}ketD4qmxOh-n2T+vxrpNXEo%__rMmm5U%I=4`lY*jr(e3eYxjUk1uZUk{^Nm08U2qgy9EqGLjJD zsOZmY@l_H+WO1y!?POu>WKU6SfTtifz*7tx;3()q*Z^4sXjQ&sE6&$Q@X0+6CZ14& z<~2$ZB&Fa3nSJM=tXhAFlmWAY$@oL0jQ3tePewdLz2~bQ7i>#AN3M9^AajQO zKrSiYoBdoF^G}xo&P@?~qoCxW$viLR_d8C@5q2V6PzrnpEjfc5+YcHCr#?M&Kn*>RIyRR+VK>)Bmb?x-&q?$>e_N&YNXvM=3r z^Qo(4jjKD|Es*$5RJYVYkS4+WZwZe{f$=_DT- z-BHK4r}|Juay&ZS#Tt+7B)X{XYi95Q5_ePEX-<#qO&^i$RQH5or#f6`Qm|7UZoE`i zhJ9|Xbrsex)tza-ba%G>(%l*NOLu48FWr^-xVHeiiVz>;&PaTeJ3H}Fj+S#YiH~x$ z4u*0S5JtB%Ww`I+brsG(T?r((+gE8Mf+!id=fYVJI9X9Q04s@j$u7FPfBMjUlU;Oi zp@R?KKb-{<-gnGpNQ`mi1nS#!_n7MzV^@VF#!111_cTk*#89UXItNe4Kw_}d6%P^Y zC_4w%LsULQu%ql8bPrMa5W$WzpIbV#+Bih8qs-?74^8a85G%BOHxH2zO&8(r{YH zAK_>?-+TBYoO~ogaD~QysDPS^;y!i2eQL<}=>x7t^-p&-s(V6rKa;?v5f`Fl;y%7W ziNpse2{?Adf2e^|sdxotT#R}6Z%Rr@I8@R*tss;YE-1_?%*zWQGh;+*ek5&FMn+^r zNoqJ8$%~9g9hqHN5DG9MIWM)SuplopG$~q98`I&mtWb7(PElG;P9#)$ zDjc1i9w|&8kv%#x!eG)uP&fHmnc<>PN~ds!5{picmRI1T-V8D~l${yQ$;r%t+(TJ4 zA|-h`J|!1&O%D;$gm7-CC?~ftH#1xq8aV~(M8W8J7631Ys-c`m%ivYimGS&gQBi(+ zc3N)4WV|FbFRyS+NpW~YBvMeE>MjJ-P+EEk<>W&~y#8#hY84(}U22Hwq4W&s9I1H)K&+Ys&r++SrclFs65dz}RWdDBT0TkB z(lSC>8Ch9r>4g~~XKr%xRaXr|%4voE8k|`WO3P2pEi6h86;6v)WkS_EH4Igag^86z zABQs1uqv%~^Rn|YvU2ir(?ZUf!9yg%v=GV5OV2MX%-6&ywuG`LC(c8x%oyf}ap{i)5>9~Cg3Nv7mNly#S(9k|<>8at={M@3@6dg;>3#WxM(lWC{mE~0> z2AiB!6v@sgD$1m|!AFWh8TqLh;S4yI;h_+golcK)-8=_lBOCs5Qu?JNkE|&-UPW1H zscGTD+)!n7rrRq$HR-~k`pd_O(JgT@Puh2~9{j*YG1po)rP_(|zjH@*0-I0upaBddNH9R0I zoJYw*x2S+qYh^HD;j?00V*_T-!u&`T$n8`ghm84+jU z=o~T2aW$ikrRBW7h++e4W+W{X$$}MBek2lthvPX5C6&t=aBQruhXZBQ$Y^FbJ5-nn zeG(=)8k35oJB@36Rl;aCL|7%{6r|^ei(pQT)j3CeT4>h76#=-sfJFy1w=;27nW+Pg ztcAI7kjVlfEsuRl>0aDx$NmNIfhGf{4_GHoGI~X!JUE1uakJDgSIT58Z#2D$T@ zQ?)wGYv~2q*||k&+0=CEK&-f~mZOj%!o-zb7%9rkh~EObpWy*sGn2Dn0?*HZ&RhzQ zsIAlSL6Q7|NI?lrct4exfB!*!2P5I!qslH{8%TbqoXE zcar?{TEGu6l>%nQQU`ZN9K9t_;1`w!0^{I!198LO5%bfV+b|Fq|41P4#R`H2@b{Da z@^>!8cdQHqB2POwtWQ6^f1$jkfGK&#!Qroi`RUyXfd!ws_Qo4;=${vu%R`4V2hb_D$Sm3I}yKmRfi zxbZ7^0ozgV=U3jh!RQabto@o`g!9wGe$*MwU7Md?3(y+~xZE8M5Pw#O`(~FgCXwDNptlWh zOMXnOhvjYXlTvd2_p3kD3nA`j2ZR08FMn9x1&nc!{^k7_5+4NI(q9}@y#9iE+Zl5( zy?ucD6MnA|w|IKJA+7Ikfxtxg!wrh%+rAwjp#m@qb`vZRufMc{1}EVW20p-@big@^Oq0&MexI?U*nIT!iIZ4y*D6X7hqPM?BJRL&ab?0 zKz!6G!9cr?4i5W)pWaBA?<)bbwzGq45l3${#IHIv7}ySfxZ&PU59hy~fLV1~V!eBT zKf7x%(EfA>7w>q~0uuTHCZoH9i&x$X(EAoJBYHSE-23G(9rVrt%sssvT)g937VvNA z9SnQ|f4D(&`|9EN2=oaC=J$1Q@#eogfPD{`{{0*r?)~!jA|wn0%)b5(E?#?_4E$G< zp})W%Zn*c;!-QRc*)_ny#hYJn9CjTT45YvxZt?W6yxD+xXOM%7Hy><*^7GALg$!W8fui@!Gcs;07Op-k3wwD*@cpgXrPBbJZd0-43{A2hqdw zt~*4%jez_35cK{yM7{lhYm|QQ_UOVGr!{yS`HZ(-fE#iUJsfZ20CT<<=c9K$VD9wd zJmVL~+iJkP}m102e(3y*Y=dcRk?l zJcu5R55T!fe?8W)$jR8!l7w4ll4=^`+aXxxa0OkcR&PVT4 z!0hzmeDoUT1Ov_CPqdpyuLC6Z0nBhO&PT5rFc*4p9z9%#-Od>F#Vy|WSO&Ni2hr;U z{PzH}$BXmHU$b2J+yj5O>3-_TAGYrhz~p*yK6>SVsrTYMdRX3@8H2vK#VhaKfP3^H zdRX2!0kg}C^T}W1ykMX;{NWa_yr`E9m~md5kKPQxTF= z&ZCF(%U;I7OWNYq-!b{YKpXhOEna!?cs`IZ1cY5Yy%fOZ9)e!^A?lqExY-BM!}`1P z5cM7f+_MMK!}{9-n4MmnPkS^hfcXIaaEn)eCqh~uz~p;zK6+CDGsBDXv@e!-Az+qy zaXxzM0P~&~=h4IU&V!6<;DJz3Ybw|oKOC00W-&o^W+c9 zyBIK!d2v2^8v*mN7gvMdwL0a(eM|WJgE1-^Y8ndl^x*LP+)=~5^jE3`xjwMU`XPvF7EUN$$YOiI{aj~hSq=ZT2D#5LIF0lf| zz`lO+1;~zJ`M`;o1ycui*3dkGtMkKb4J`DHLUCE= z(3+u%^A1W}7oOWz8Lp4C#v@HJ>kQ2kJSa~jS(RvO3fEX=ntaqj$<=e_Hk(mE9! z2cY#lDTp`tCg2=R>q$U1ZL$fG57#!-N84H&YMbk#)_I!ElZI@z>W0RuXj^lAyh--; zCzIUhZG|;!fjd2iX2ssUWJ7gRTU9t=O@)Z}OVDGcS595Dxn)jUw6U?Fv8|!GsjZ>9 zEzyAT!6uG|#(9$0it@*kT$E=2lf552h6JKGrx?K#HZF7o`E!+o4am zxZNSLWi}+jmo%fIgcD88jnTGnB+?j7CQVF&>8Xu(&qkaR@dP%-AWN$n>ab5Qii?bz2uv8AS| z5lLWdonRRlGn|AHUoT-eTv?fvL@_T$*wWl5MB0)~jm=e(%}RDdqOCUC5>ZKQR&ydkjp>%h z;_k3B$P~A3F_ox>OvCw_NCGuP^$l&2<^*<;QD(S)p42$BxdtF`Sg6hBX4$<1-4IO2 z&iW$TSymmXjMqon^l2lV6WB4_APr9O#fRsM*M)1MTDM>mCD_uE!tKc4YMI7CHs|_2|x4`qcaV=&7>?Mo(d@)BJ(3i z?O_Vfq(yZJSq0AaO`d{-@u2*(*e)>Xop^W=<>o}GK2mb*!c;mJJaVT`cIk8)Ch1$9 zLRYLEzN|Wfl}>Gp)>C08!s!2ShykAsmf)SzT6Aa`=pyRSL)rD#CFWd{iq1oeNj6v3 zp~xkCwlbB5#fN5;Mw3j08&TbayUK7c^X2wwWu8nCA#6J;3d@HV;%RcZGA=SQdSCJ@ z#q3J2$^;!(BHGv#M|Ho@2)No;fG0@(f`e+*LXwCI!=DKH>Kk>i(NF1;zio!)B;gWY z37#C#MuO7*S^yiu$+iwsN_-eyt+wZC#cb;h_C2Z?8V?e_F8za~gN7ZWA!_U}qCvX{ z{hwQTvqn&aXpe)6NHj)yUbH%#Y!cJRQG+zkRC1EO$?;3U3^AM(SCcQ7UHRP|fTt{G zNLRqfiyAxZ$SXp-EN1HrD55Gns0^N%)Jd_K9gVi~;lpVQw#r8xWVkB%s}76RX+U7+ zAV@J^>&pzKUl(p_^YGAAQasoB@~BGh$LVN|>wP)1Tf9e-ZZS^iH~7kc0S^F^=NtZ=iQI+TszLMPiV7xwov0AvPDO?q!Dr*ZT6C7r{6{}Mv3w`COa&3u6 zTX{+s7L1#@$wX$fFS8kZHDPRqW01;*j5O4R(LXmd#@S87gyVqUSJxMO-mihVlUUbW z+Z31Bxg}6X>P+&Lke%I*6uYrnPS;!bZ;EggmQ#ae zv*0wp4lo(6OW;U<+dQ0TY~=h2&UYuN^xgU5SR?KKo)A`Jm-brd%PrQ3sxLUzjUl&g zmBQ@Azr&Z=htH$mpwv+2uNHrkG-GFcLd`B@QdWqwicr?iic}$M_X_B#Mz* zJb~drn>G-dqA0oSHsI8pxqt9$1KBAxNA5lGl1y{-;5=VZ{;aMfIYoD=uYh6WqQ`#{ z3#Zq-%vXqsg=TVv@6_7)zO32d)>SCk!1hw1Mw8mB^R>-Vb=E_1_97Q3MtuBo5xhhmgb zht%E~G7qf!@+W=SFxr+uzc;X%rs$qJ1XqF+2lZ9+5JRVxJnhTmHauKe0?z3sxS#uS z+L3fkDV$|ko;fHBqNmz$#4s$m!LQh|Yh$_ZypyBL?%8@cQq*-f?#evJ#G_>Ja3tvJ z7{=spyb4Kansv5g);Pivg?_auJ5gF#HEtSenm&ut${k^jmA(F{!-<(lvDccC?ld}9 z_U;S)B-xb>y|}Bv(g32luI8{@HNF@Lg_p@vxnIbc_-ip@-}vvuW@$smVw?NCU(w`dWuhsDQ3l$09G{?z zCL3y7U|>5_Q%8W|Ave1b7z@Xo{IDmzxuO!m zWiL7P(UE({z~Qtzt*Oy^)MPMCEvT}HET*}v5l8Nl6^9ewWRx}yrVPAoP-zL5T&Fy{ zeC4`w&oMXb=A@+IETOGwuR4?rw|2;q;wYH)KRcWh#&D@a8|KEamJ4+Sm22wg#U?&? z>_40`Xo}aV#c#*FHL_}rtk3_avRul+8Qy)tSDF(6SweRAjm`qooxZF-i9n??D=f~m z=v}_-PROlcdsW7ny#C@Lc#`oNUSub2)9H72fA4V0QIBNxYKGpS;1s5lWs}$ViSuWd zm^d}+b>En1R{uQ`9*yPHsJ*_DwCWv3l6Ro$#Oe)SSvn&QE>hCxw7YlT`hrhK8o@=D zHE0|%fZ(+-xx>le+ot(-5Xt67tQTY88BT;NYoC@O4cLc^E6 zJ>2}1h|i7IO1%|hY`XEzvwXbIHs1Mu-sRQ_T6i$a8_P6vqLFgzMD0Jq*MIsfLom{p zVCD=H!l*2Qa3l7(G?z;RN66+Y#vkJZjKLckxqf=~%o!?q^j67pdrzM+Qzh>`Cvzm$ zihFKjO{EB@x6T}wH+<(BZ=E?V@35O&XO7DozG1_y^Ty>p7yXR!);Z(yhOZO0&KH+= z*v(y_vd!fU->`KY%7vThaJB`xCV8on&3N0MD&8(nTk!i?Ii}6pnYy^>?andneKvkl zob-2Rnf9N4&N=58e|Mf~e|W3%B)>b;Z2wsfyF1ggcR7C6WTczy?p)LUGp3jE&vMkr zC+ht=CYc%@X0=r712%lwm@*N;jY2l(TZx_(oqgQ3Sf{SMbIpX@>KjaJV_XaaGsVi@ zbC_Vc2c`r;eSnl%PCL;HLCy8Jf~mFMI$2W$(|KdY9&K8?reb}U5^|F@=8~ZfWRr!) z<&r^~l&4EtD49zJX<1~!3CA4c7dI(BM_O<~OD-9tWs{Z6${}Oh%pt4JAp=!7hwPdh zGPbrHvXAAEfl5i6YDytka&8V8<7QVx)>W2hFg>q%-i+)#Ax<`Lso`_tUw(B}SzfZe z5xWkVbQ zV`Lb?ZIM{~wJm0sQQnY%;TNuT3DOImK7w3qwj@WkEr|P{RE+dMMX&LPRbNe9(d-y)N% z)1;L2s-oWHD8`OGpwC`Xv=~RlrPsLJT=qaHcY({rw_d4lH{U_jH2c;x&m&3I!}=($ z3*?s2dTf=pCTUOAD?6Uz!YyHnRhu$~71p@%QgYVs!0`LjhmDk(3MoZx@x4hRhG9w>P)q$diIPmEu1sR zibF4{x;elwBb&hqLNA}X89YJQ@pppI%cE`%cMvv%6U1V*p6X_B2XXeTm+zSP5>#i=5l%g(tr6?(UaUD1n>HWhSstw1$VnZ=nTC1TldB9w&eYGNcfkyt*Q zgzQM@YG6b-k?0vtL{=oSB{-4j9Zo`4B&qprana}2 zu>N5fD#;agvF28hl!sM<5iW75Smss{r-BZ6*t0lQq;uJwe7(lQuINPw@|78M7&UCg za3Yk1!>C~^hm(*UiR}8})UZ{$AOwJ)6CtpV3 z?5i>tS}~!69iG)VFMu&4zKbEYI{mEx?R4#5*U*eD*}M$B5~eLjjngF}cLZfUUN4zc zHCJ+hv#v&#x{oIX_m|pclsy3`rb}I1&Qew3E^?eNYG{i_YN9w;H>!AR`!a zx|pTsxp~drI~jYc4TbI#PGp(_rYUYFncq^!U1(fMjxko_gvhc=m>_00Pno$sA_D{7 zJ|ZNhsl8X0n?P*dibM0N@w?4TgWYCMyO_DMV2oL1=9)lZ)0Tqm6vS6H_bP9_?@`%9 zWt{LbRFWbes_7moiMtQg452y=As&GctqSChHhA<IxF)rLFWq z$Rk(-U_6=oBoC%JKa|UW@0RGzqOnHotJJj(XCT1KB|w{3s$y2$RL#Wp0@-ezZRWS} z*c_H8b?v6W1ulWI|N7q(XqIjoqu8LRstnf&hY3Ln@ZSreN@YTpeC$!ei6%_`GYwa{ z(jbNZKMeuGs-o&+HVDhE7%V)gLRn$qh|y99~qrhIu-|;behHN&?v_G0T@~rJcFPi8Ue4%O>`eEB6Ln$=q>dDj7a{j5!Jw zb}Cr%!6FS_&yU8U;Y6EkRK{wQ$tzWD-YZcGLbAvxeh^{5wp-`xHCcv2_0Nr+Hmk)% zWU&sT;k{=mnAx@vDcmd}!>5v+!#t!?pTdwYlj%BoH-Rj7O#iUKHOcna_S*( z9I(h|t5r!DtKH?u0cj#GJ4xnkbph!O*5PVyXc4`FcuB24(udQvk!x6fkxn5jfO8;3 zx>d|(+M5V<#Z_A#NXU#Lp^m2^l*+?{lCu6L)v^X;N_)HZr|77N7L&~@cIY3JaEXNZ zq_;N7S|%zY&w20=Bc=hwnmqy5tXlc0gV_d^P}wjS8nYG?blBk|OJ+yNVqX<7_Nf7U zRf%si#QWDLqNd5*Te73QyOW>2tnb8E`ubCnynI=#X-Z%rRjBeVvmd_01bAFc3OyhGwme1M7=fW(X zbBxbLSw6FjPeqo`xyC1)*?DdUd zeZX+e@%klD37ZopQFUHlG$m7C>b+iM#CWYaiPukr zPSBaq==DQPY2Yxpq}KY(a1fmzjx+_;oI@bJdZKooNp?#v zNxZ%}DUFd~wC4CHYT?bXExqUFc;oO_w9ypRyd3}O#_!S`zZu5wvK+se#&3R(-`U3R z@*KZ&jNcVGezS~UTaMqk#&1E6U%ByX&+$9Y_$|!wD>Fsck>iI2z&KU|ChLst^b&*< z>ZSyks-{LR_L3wTT9NVG(ZPbb((8%3fy+q3wMo+ymUs!Or_VHAUD;k|8?URfz0NUS zOS8RZ8L#eauXBypvTUz%<*2l)v%O}Ru==vSoZRTo_EOtY zn8_)x7i|5i=BB8r00Ulcd{ii5{I2o(;ml;S(P1mRemKquf<@F2K z;FySEyw>Z951=-f^k3)oLoy88^;urHJ;j7~gVztIBV5V9(d$_aYt;z7$?I3gY_oMr z+Uut-D1vIV`a=z=Oj70H8T)Q<>@jvkFkIbcFpuZZgpJ>ibNnie-%oP< zs*K-HbNn1dF_h!y#ARcSU$v<=PvrQ`MP;y?_NE+P)qC11W^=ATF6e=2W18X5aws@t zGRA%{jK%2qco`un41<8D3McKl5a5oR>PAh2u5 zOF0A$RZZAHWjCMS=J;!MYx3@QITW$zT-<{vO4;<1yS!AjRZWexriH(p<(Z7dU8Am7 zvV75d8-4R?mS0VC+ywcW*RRnNbpd9qcOTx!l;AC^^;b7HE{v&yE+P7rc=c7hy~ zYepI7O}K0mwKLxvMeHZQs$RUQS$3_+QXwgQ^1-2mozU3ODpEUbsd^ciOAvBc*Ir)6 z#jf?DQ%EUNvnlN@2eLO|rY+C429tfUjqF`<`D3L;7CbJqLr6qXAM`q>y>UV=cC|N6 zaB+&%Qe?wY+j}OsPn6V>>3-C5moN6}*y3#lwan)e8Joclf$PL)*|FCVN1IglUfSo} z!bw~%hXLxDnph$~46%EOlB@9)F3~>(z0b-hx6K@|TLzb{8+n3J%TYHl>kDnw70T6E zD?%)}phh-{2hP8XSiI`Dl zMv+z4R}Y`n4w*~HWS3R*L$S|jlLdGN%Pl$Nlhy7+^YO}oW?s=vUWVCjSDb8KyXrfa zzRKYU^6``_`Fu;q=2Lg^*vq7b$G2Q;o_HM(Q5qiV#xru_r*8KdzV1+qlgk^sVY!^D zGg~uyqj(5LyZo3Z4Aon6a+#C!>Z{sxEoT?iHca~LEXm47o5e42HcM76a(e4TI}{Zm zMS<$e{Kl|NY6JIq)Y){-L1kZBw$IaST2pfzrr}G6nM_V^0uIXQl+Z<**;_(~!EBcj zTMI+?mXf~!Ht`uaAud6(wTr|E z9Gyj31Ebd`j$^!Jm5mMI2qNjBWyP*S;9{uj%_>gNdZJTC;9wX^nE(96Jlcn0Ukry9}tv#DurzE;eB+P|xVixL2ERJ+ZqJs32*cU*^=sj-Bv2XIB@vTmRu{O|KWO%%l z1>JUOw6Q_-3MUImDG~Qj>MRf{4u?r44b4M^#Cs^DN_#2zEfVzG>`zDAadMf!+>OLN z%>G-HF4SB~RX8_BW^pxRk`cw$8sm2@SkEZYwiXzwQW3fQSjcFKqfVh0!Zr8G{-YH~ z9@RW^d4|9Di6L?}quEZUqoC!=4em4}4M)30=CpM+*LkdBjSI+B95#_hWkj?o%GSxTGks9dhY+BXZDflj=4fxJw?Y&ESG=383xhJm8Z%Z7e>kDMB zb<5J~p1x)6sp`&lO04c~zp}C`)i1%bmGJndxgIo!Jp(w){UGuSD0%&Tf?+$xqC(S;$V@^q0c6 z)&eoc9C0SQvPH5erhpaEzqS*sLLSlyxMqKw8aGg7W$VGAz;D ziX#Ouj|$|&QV092l=^^EF(|_#J<`{OJc}aiXzc@lBH6misg8C(xxyqwy|>&+7ha%WD2u@Uyy29+Su7Y(4E2p zX@PuQ%T7a!>PqEyR(SBHQQX zSwSbDDY8PP-k2g}EW?#j)XXgI2WI7|Lxn``uIyPUwORbxwAcXUxE$B!3gk8olDnFC zboszCtW7|VA>SK2d%MvN`m1{SVvG9f2bOjAb#+8K7k4f1?3b#0668gsPB3&H6+kMx zdON#8kxaSU7eg;*NhEP0a1(5Uf?_g5jp}X5QipjYtYvAq17Y@?rpXq^Ll!MdMN@d& zEvrCCJne9^vWhB-GdkIY9&2B|s9Ti135Y6**I+P9I{W&1`b4P`%U#mMnmy7miV9>N z66x*4B{ow1vg;8m{$I7aZ|v+yiMmHa6Hy85woauwCE1*gh2mM#*R!m>mNl3fp8Dz( zC)wftUWhPprEiD$)^zqP>rC~nvc0IaY-KBDgAWTbCIO+=ik$4+jc@A(Z(-TpCf2>M zPpV$TQHj-RJox3uKDG$$ryA_>=$xPN7;L_m}rT z(XstrjrUejkD@v$S=tqoKoefnN>BGSvUlCi1nDZy5MNJ6=M&}x$eApZc22Un*ty7- z8H2vTw+N)ta*>HOVNU0&Wj%|ev*w4FT9(?(@#Xy~bjLB^>lx^^#W0n$$k-j?x-4oQ8q{o7eT!*CAuFqT2A0EENp|$8a$%F^N8;F5 z_pb7fH+o~{Jk|3wA#GTA721zzLg{9q-k2G%%V6I%^r3H*=6Q(_Uoz0yw@PTG2C~kH z0m6!(FBB?cVx8^1rpi&Ha=FHIgJQTfwlBZ36P9{`*vf1%3kR-*Vue-aM2S`~bK+`* zRI7qw5mH?@V@gL14{979BS8n<*S-u=XvAcdJ8RNAb}`d#lQb}5JU{H{=1LeB(i@4% z!5iJ2ilOr2Xz=htG~&a3eeJ6hnx)ERA*RFb8k_kQ;LfH_7^{RdpBee-Dz07KC^|_T zQ=^T)GvR--_*V{ebuaQQLOWksj4TC2#!{UJwZu4<3A;?R1!gX-la{4T=r=mM5e+EN z2$X5p@`k>yE4!A9x*nYsZ)O52r5%oFIkqr6!MOE2FG;iAacczMPLH6;aOtE;;jy{w6c^%m$70S-nnJsRk%zWnn$9{$a`k;iTM z$NM**{sB)$5P$r){`|d5Q|89M2Rp!KFzkADN z$fsWl{+OA2zWCgSCKVie?53xymZdh}lhX*GDA04uY2W>G^3}~x95>?J$6js4x0Ejv ze8-X%U%PtVAD>PgvtnrD9d#F4)~5yE_2IjAb)3KZvUgtl#nM|objLN8^*h1ez4E9H zGd|KV^RX=xlAE^IAoZu@QGRg#ludU(FeUN%*{6Q3<^Fe|&aV@Eb$!Q&UY+~a=|}WV z+I7=8@BY-Xwh4ag`%lgKpuPCVM?e0P^;aGB+}|->nol{e-`)SnmS@L(@Xx}+%XXe| z9u)J%g73KD_VoGxTp#|wsd+2U-aM`h@f7?Cw=deX`mIaWesF%x|9$hp(eL3?$jk>k z{N0IfE$;)IJ;JgOg!L!z@I$(ZzMd=5yh^I^N!$LCsVmE8O`G3}iqf;9zhn-^aPy~^ z&5tkd=pI+}v!|a~HoqUHdFP_}D`5H1bU1U#;e3|2OG{!agWm6IU#|H6 z+gS9c`r5m@uGG>F^>JW#Ec&1%|I0WGbo8a>cVNT}*oIN?l7Bxh`cr6`9si4XENkbO z;C~?rc?xauzmR0|rgK?G@2a-`|5B!|c?PtsRBh6dRmhTGSF- z^F~Q56Ha9I$1*RzQ?Z2RL1-=eUSJE>tSrIXvwR!8zO*d#=*r^VkZx6^59Ec`ZG|hA zsY=vlE-Q&-lH((x?^kpKQ2Z zv~FkW_|S<~IQ0GP2cBF!rC@P*_O^li#e)T?!+Gm=4*V%oHDS%W)(v?FhMs#jc1PWY zNmURt@Y6jLAx8uj!I2{`^!);eqpVSj!&9~&hP>@6LBY^E=AkD+8J(U?tVE@z(N4@~ zKpNr{jXOOPnVt-iGo^qL$dj}L5$V@;TJqNn81iD7r=*0UGlypGv|oORj6%YcPb`CyjAiDRmdDm?F1cb;7=B;I6SQ6h z*@NQR2iMoc^#NQDiz|r#Z{nE?o2DX5ffS=Yu{9HZo-IRuN`c7iGG+%c|GBhtRZ~y6 zyLU-DG{l9)_hK$MVD;-6YHEl$LSqB7tiJ{L&X%u!lSG4D90*uN2!nh_LjtG00~SmY z*adCvBG{{FCJNiJV3;U!-Vw3mz+{Ul)QZZoR$}%_DXBF=J3ml`5yq#XvyTdl#VkDi z0#;i5t_ zyf16-Un*gDKzgg7#>#sa-n-;I=px4$ewBDHfHyU$g^Okx!Vs zlC0znKNM8@|c`* zA^D2LZ7JMS<(+*|xVXy|H;3IMm&q#=@`r@nos?s&ON&|gD?emeQ&2mX;TeyI-B1Z5 zp??Lo1MQ<2WmQ~U1`I2CL%^=&6M-!UmKC=l;HkLmj@TJ}RidF}u|4gBa|WKfG`>#P z2;^IuZLSIMTtH+{x&jd6taKFcazKvh+5nS)DADvXKvabE)qsltS;C6}**RSa$U20q zNZ$sC98KR1h>D!P53n2X{{WW*ZUpQF+ydAK_$$DEz!w2ifV%((0QUl31ITo(1pEi! zwSdJ)%k_ZA0Nwyt0(cW3yQwtbY``^u7XhvXtOWcRU<=^QfUFGb0a;520TDL~bt{dy zS+@WpOzRVXw*uY<_({M|0X_(b@n-sKfS&<;81S=zKLGq3;7OfWd7t zxUB~Fyutn2;PxBb+Xk11yj5{#E~{{lF}M#I+=mVBRD+8cT+HC+8r*z?yUF0z7~FjZ z_n^Uj$KW0{xF-y5i^08YaDOzoHx2Ip8C*B|PL;M^?JBe?nv<>J*4Tz`l&<{OfdjGC zZ>$G-Jo8@WH<8SHb?dedl*Be1jS{tD8;&H{E$-EuNfvHvyX^8!wS(U%9l~2}$2WH% z8>8#~GBCl1XU`Mxj14|g`Y>o?neXl5>$&b7LFoiX!k^5Zw?dy$M5u zMa;M*!nt)_ni0k?wjo*+8;sr)8SMNj^FQRt|ACXjnP+m7I7THgv~D6KgfqWFL}N}w zL+g(Mnvt!0*u)hPBng6f7{NUT4)#cyb*zpvcZMHhdwWO!5fHtyKatb@yam5NBr7o@>z_ zS-YrJg0QMAi#jLB;hc3Bo}e`k|7!%d050X*377I+2iL{oOAW7lKWTiw3Rj)@QtK<< zM~p8fWUZg$30fy0El-Jy8u@8)Jq_2V#Z?FiVUZHTe-&;5uFc}R2(C|w>r2M!(W)qflc3rt7Wh`~YdoLymCR&$cDQytX zI2w@fz|f+vqfJi$%+NNhVra@c2S#KUtj*8jc??e=Fv2D5k6~w|mmk;BeM#jCu{FT6Hl-R|`HKT8^XIrSe^m3~d%vThMZKX4- z6Toqxz@>J|>PSfmRN#eUSMFm{OpBK(pCX8K#4!Wh;vV+!Ny%wGS}Nq@YLAk*5Ia7w zd??{jPdmQkbNk)~Ulv)ZL~>zouhdyu!?biQ>)k*eq!gkRO|rfr#o3K4eM$VHz)p1y zTf3yfFtaeu!Ea^$hpjy8Ux71nGHtq5XLJBpJjP62{fChS`HS(48=041G`f0ZQGPL8 zQ-CQPIdV*}U@XQ^EP_)&&Lw0%c~*V#v@B8iAAJlwv+x`{x?$wl{Lsk4F-K3Oh)KhV zm;uqFA^H~(>3+V1pzgx+MLb7pzt5r68ctC|H`-73uf%p(9J;}V=Kw`kb2xFxUYAwM zo;c(TBW(zU(;DemAcugY=D~Q+(L6=)*ai=33-Lfc7fVZ4{EjA|2sT0`Lh6WY_(O#& zF5U$Xw#~2)>cI?@zeCIrL4b7id{n~i8WODklyxjrd~^=E+RPm*oW)`oQ!9@#xEFQ zrP&)S0Xzw?3-BDk2LUezTng9%*bRt9Lu)zUM*({PzW{hO;FkgW0Dla44d5RER{)Mg z7^?uM16~VARd*dAM~~|OuLHap@DafEfR6zV0c6ND;#YIC2xnpL4#^sP`e7PQw{D+gR3;SYJ*#BaF{F5VcckNA2qnI z8{9(%_fv!8m{G-#`KaQ@oK!d{GL0LdU4_;}gFD{fn8%7YZg9;8H_za1Fu2tQ_eF!d z*Wfl8+*X5o-r#<1aF3v@RJf06SE04T;C^9n`wZ?agDZf6rFh3^SE024OwY*W;#rtRMhXI{uWxf_Lu@!Y#Hj5JP+IDl!+L_y46UT_N9UhVBrW`QEUT<9sM|)6TKZRO+~g?HoMY58V~=Y zg{H!q0zF5bB__C|&73sm$ke2@P{cu@jGZH;ul|W}_lPv2c zP>w=p`rk|xG7Sv@Pg2<>RRFELRPvNUmBlQUf&E(m2Q}&_JW$W_I|Ukrxo{dFV}3ed zDc~7^GXT#7ya2EaumW&8AT`jVc$5aBs}Kg8jqA~_LhCw%yUE}lG&s&4D&8#y_oTu7 z#^8Q$aQ`$o>LCO-MGkhFdVZviglQL`7#Fh-NTi#JDe< z`2$*0B$jzSmU%Clc?Zj41EoHbCNqaH&L(fTEqq1W<(F-WVRq&42s4!hY?5>37{+!od7U36CDpw!daikkO-|R_90%O zwU?nq$1=?YwU`E2S&PwrZwyOO(;3HDCWg3gPnFho(y{>Q_jBi7=Z)Tzonx00IBgF-coV3xVKdFY1og+ zfz7c@L*is>0Xo|761pYCObwH^0Eq-x1PO@q^_a6zu?(%f5#gM7c}Z$jEhaA#9Neqn z{CODHr!K?)#K0BgB13J*w0P#{oZN_s?ApveOqktxVO?e`!UM@AcrGre3_aSkI=^cD zcqmL_!@^v-C9*pIK>WZ^-Rz%TzhmzaKSFJ@SdXHae}-58nUyrvp+ZU^19zsdzIsD} zHPFCRb0T7HZDva*hDB1;4McNp=+XJ>^S4AW>V~S8_(U?hNt{W5NX3|eub+Qgz6osa z1Y4BIaB&Zr#w0r_S8D*jZTgq$BibaK`$`C-Y+mo`}!has8`t(_vI6 z!kMQ-kA6nVarMi8`^13*sA6lSEa5;&;(t?VczvQbmZ?re)>mAuV60EUL_gtRYzdPg zR5hB4kW_@E0vucbGF{3jhT05j;i{0`ea#%&^KE2lblri_+Il!*nbv}tFR^$c8?Fnm zf_6$pL`I(->j=!wyXg$p*4oUFr^2oq8aSGvp%p@M1dFw>Jn!{%{ zK|8D)3Wq+sb#Fej1H)SPQfTc?l;4FyOE5Ft3<@kM`U2?NDl^c!o73tF5+`LwvW=)f)}XdQryT})8Iyj5J^ zg@hl8>o3MN9md!v1@}$36z@;rx?gZ3p(#HjuH)fS3*#S!ONILdxE>JSZ@~2fas3Rg z?}_UbxKylOhfB%ZZ(O5B*zzXA^_*}_gX=ruYJrRDG-##Z`ii)~DrVU4fVm*c47(jT z8bKJWi17g@em-W{;Td43$!r2GoYO>5*NADD*J{M`T|C?hGNi!G z*=nZ>V%dl@Fye2)^L;$o=9$+Nn<%^-OiWb5FbPo%-eT|;%e2T4@V5QvHP<+ZnThiXIcM_ZgdYX)r>1_>+I0s3+ z0?$wJ4Cb9~J(eHCZi33<2z*Z#n!XW}Ag^R3Uu=2(?bmcJ(h|A9pan6Yd5wkH;K?Z2 zdOQ!|VGgula^`rH9fql9nvbc&c0Oh1k%+T919)JK1z84af@&dlvoGqGyqOCxP7-pf zu;%XI?h6Tmru5aq9hY}jmk264?RUEnlJY)M-nsTS&-KniX_I%J2dONs0OzeDuOP_x zFy8N$_jmKh;+@qOE4}y~7yM1$R^i!(x0?l56f8wVRT24QSQ`!?BH}!%rshbw`p1jo zS(MGltYz|kGqzxyB$8wBJ%J<`*E<_Bx`dx8r2>E{r{4qC%knx8YRW^5vb~ zlBEgIadJ~tm9GA_p5FGW2Rg;C7JerfKkSxllSpGDMccwv$}RC_ReDi!ZZYm#AFXi# z>ms&j>lJGQW`HLeIeG+QWC=N^#$Of@S77OZt%%d*wunYd9IH(=utJvg&Jb^oUY?c^ z)SivFsbWDH&2W2ykP9^{=LVs^O}{%8@;C@rC8gtrYHgxS zg`p59;y3};;rKZnxYdZnR1dwVsM{d>O zL?5e%-tA$k&51fL%+7{@PjUz0A8*A(|}35b2~^g;Aa3^0l%%^e+r1vLwYmd ze83%mmjlvPqI@>1g?OhPUJQ6L;8MUSU^gJQZ}b3Cx%2~4E2jXdC06qnXemK1oa1G##fa?LdP2(28eB{w50FMB?6_870p9iEGL9d-Y z74S~L8Gv^Ia&q&FfD1LA%V(d)JJrnnfU5u>0Neoh6~Ipdeie{C%EN%a1%wTdX4yOf z$fdSN0lCojeZVsSe*kz6;Ew^%1KbF>8gL8XJ%CRFeiiU3z;6RS1NbArX8|_>?f`re z@Oi-J0e=n1V+Jn*9);HTJHRP`zXzNK_y@q#0sjPeKH#4LsdDxJRssG65Ou@a2gug@ zcfgMUz6ba@z<&UK3Gf3zq|rJ6h_qRGDCegEM*u>$1xqIVSHJ?mw*f~3;<1hbECLJx zvTqv)h^Yo^0$?5BhX5}HoCLTO5H#tPfRh1f$FM$e`hnJzntq_G(CRce?qX9oHdsZs z%HZxZxCaf6)|H~;^nv2#q=Uk}VsL*oxcvslElP@Rs&*AxoD@|!PKqjd*cPR6oK9A_ z&l%ho3~sZ*Z8NxC2KSo5aoSUb!P>0kRT&%?p%pG^aIFT{VQ^O(T))AsFt{}aceBBL z+TdU8B(#I3+bXQ(M|QbLX0Zz+h|wMx?R9B_)HsMT0BH?*=Di$<%Nn zhS4}CSyH77uv56AZBrfm)R3niE;b@(Z@}+Rtl6`|w6@0MxfV|etpWL|;fS1f$Mr1s zyf6+at3e4(TD1Z#lb*`dq@ zY63i!;n*t-&b06et^jbcfj-K>o=g2`R@nmW1%3a;`(7|O+O(~dIiyOFgbNH#mlO$?7^Er<;+V6F*)D-% z$-x2O8v=Gt7Z<1Tu5fma78f%|6wb~$ELs|z$|09I#>m@0*6)3IM&XHQd^ z8I8B#kQ%Ro8ZSnTmw?7AYum(LwbNSmX z&tLZ~Km@3G+0x8}(QwL-O?-I8!$A#aq-@3WEyUecJZ0ji{uMZGt#~Sc$x%EpAX9kU zn>*OZ70#u291Z0to&|V?qS2t4%4OKh-;3wEKkO~Ao? z>Mz2idStMF{NU0FnrBWyrWmvMV>3^j3|VS(b7)-}?$xj0UueTe@n7%kUAFokcnPLD zLyyLbxOK#OewUg2=VEbaZ4Fvu;kr{?=fO23 zE>0+XN?cdK^)qpC2g<|Z`V?IEi|g}neNkLLF}NV!-^9b6SMe-;&cPYgI3e|n`W-@_ zJ6m0~w$rz5xev-t5i73@@*L~YPlcZ>^L|v}tZHfeS znDui4@>Av2@K>j#I7p>ULo+l6SB}~y;RJXnd-F%DmBw+hq+ zRJX>7Nfq=_64i0yZ}%$UVs?9H2=4a4^|(WXlJ`rI=!s)V02eE^2vtHdp$<}ykpz7U z1wTr5bSlZbGelT8wm3^j7%JPN6b)V8j*K(%?0 z-Oqjys%^k<;K%yB53m%^>5^6~tf4PqU5^4XqpJbW1H`B=&BCe&q!p9|q$S$~xESy< zz-s}4lL^8r09gbJ0BLJ30{jIaXwxqNUJ3Xr;1WP8Kuq7H{|*R?H~l`~Qoww~X&K;A zfaoXXoLC=VDc+IbG|LN#OfyZ_1BL-_0Oa(`T0pA%^?=-&HVC*B5Y~E{>n67Wa!=Z4 z00#j-3&`?b0musYIY6$JejJb!jTu1O4pe>YJ&0wY)r0?Zjkfx=t5Ecp!rf_bT((oV zuN&Oc2DiiDers^M3=X!E<_&6BA?_@(aoi($4`>T5YC^h3TNfA{n}Wh!VsNz36^<4< zU4>T0;BGazuN&M$2KSu7{nFrGHn=|;To8Ixg;Ahgm{c*i2?qCu!R<3Ry~E8t;X&(u zWjOO&rZo} z=AR1>6uYImqvH{sAnqZxSC~LaHALO`xusGo0FaX1|WP3v&+ zF_1zH!E+am{`TuAP8E7~6sHP(jejRWy*)(;lEUD08dF>WI32`z&>koBJiNgULS6*x z%p=$%Z2x{>0jM2Xd*rQXRpKa9%{f3RxM=MWxuPv6nfw%OFWin??_5TOBE)}ZKE>|H zpo)}cWLE^GZp{|rQ_!Wrx`4*d$NP;)H5aeg>r;z65mmQ*2#dwt;?&|5c+J-0G2o!9 z{_}x_5@_eGdthPbp_=(nbar03XFlAs7wiHOcpnd0$qP*G$?)TTKxWDVfENLN z8E_8ZgMbZyUjt-4$3%muM)2w32VH7zUg4nJWy-KnvPa=o85~rv_>LAMPw^rwjYBA! zm)(itebV55WpKYSxVH`N9|kuPHCFM`gj8XiYH(*7T#LbRNTTT2O(@=v8QixF?mGs@ z1FeegC4<`x9iedBw5t#&7qMCHl7c;m94<0Z^SzE%VMmdzRmPAMKbBGxs-pUdR*4Ms zc6W8)W)?k#dU$&}#-MmEEk-P5NtHF*7Mcb1k}0F*iWFUAN}CGV8|ixKtxTDmCmN?xy{3=jWvgovSfoYpyG>QpdRvnK=c! zA=`>=tzzP>O#W8`1LHAZD*0+bYLs~G9ib>Pb1+WYp0eNchzx_B%Ql?|PFC9>?xp3Y zJ?TPR^!*z1;Myd(tMDJq48F7??hw}}@PDJYn8;6x3r*76CNAcL!Uf@a6VIRUd?c$o z`W|q!TnTB3s-IMx>b}mysWUXv#|zs%kmSCLW4wM3NTE^1o{2hD2wE=f&z*`c1|c@W zO&ggzpgYH@CI0#F<5K^@?PC9{6Vx;cE8Y&382QiivEs4k+bkHI(H&u>>3jo_dGI$t z_Q?AIrvPH9C4Cy;+kj^Sz6V$V_z%E(zz+bEfd2xdr5hM&r56F_0WJr`9Fol81_5uv z`$)ibfCYdX01E*>1vnb;Gk`||augc^ybrJl@GF40Lpc2qAZ{I$2EsB{4TLUr#zWy2 z<6YtUv}-iB2-&!g8r;VW?wQk-g#**=33`p8PJr|7qUtgk{RjR&%g#NzUrpLwDzf9v&#=Xj%O( z#A40}25J?=khuC$X`ew5n~P;ylX z%CVKX614iqG_nX;`D+!*+KVEf^9?{2;a>phkG(!=7WF!GJELHqNAc! zMMqbm+IiO)z%297rmcBQg*aI3;-H^6*x2B(>%;4Kt<0(q^MT{Vvue`S2>l(Wn4wB5a<>&PSuZuz1}hHt~h#Drv6{pZ_0K3ht0&rJ(GFfFs*!+Cvfp z^^a*~h8~UQ5rwi!v?`wr$a--SAanG5K-P5!MLahNOoQ4xL_<)nVLA)qym^c{z-an#KSjR-7Xq|HW#*cwOeQ+Bk?g)YA< zrD7()r+#j~h2nRK%kMwwWsdS_DaNH(CcBl^V)(_yB?w%-FVuaIXt0$!QUuI1*3>b0 zy7BP05t@j}eFBg*bQ9ocz#V|3+X7e&xD}8Za64cL;FEx-0X_{_2KaNp*?`XivP{U& z8um>*s)o^}G@Qaw!zmm!oWfDVDcolbj=E0aSf>;n4Qz$`xxqbWa4}@JqN~*|EYP8P zjdNKysgbh!waHb@J_iBWwh5EWA9dIqZ#9dx<6{vAw@th~+JDwVIZB5O+x{_LEXq-M zA{vP~^E91j08;6o*`#S_o&(5{$Sgp1LNfrF9=@}P{tu5TBD$3Qpm4Mw6z&^_?qP%T zWN8uRm2$K64iINw&f?C}K5yTEEY&Ty5uXAZ#^C#3W$J#!?NC{Iz*1QX-6mNI%_dn| z0LUyo0+3mXC1%M|zB5a|ibrKBU4_;ngIl6qg}C~{rel^Wx(b<1$b`!9m zQb%n_1a^bMS~EH?Q&o0gXt1gbE1EK(p9u6OJkEU0ckq^7iOYb4eIt{wyf0AwL|5Vy z97_*ls)obvF~Y_fS+~LMOxUhd&%iPct1y02Tp`0c5Xx zB;fIY*l8?7Y3!CvPsRJOfTsdt&!m*fm*G~WLYJ!O3df4BaDCdPhO!E`&ETFkbeQ!i z-x?_`0YV>OU9-7-(~)?429Hx77b52_%(9M-5ehYkeamhR>O@p+&x+2zN?f%fpI_0Y zGEWR~x=Zd3%F2JW=BNg-xU|D(99xW%v-xq|h44F_m75>FhTrM3c=d>yocjVYl_gw` z`1|}YCgyOc0$zG@uCD`=HMpJw7&RWYV@SG$p<}E_$MRQnc1#@Q$NFIZn18Gr?6*oa z@{{>iItVxJ)RF!Q7ez^#{}eb?=5(ntS2&ir!mZV=(OjO>INCLe?m>gwY;dd*ikI6m z6dku8D4frNQ3)D!Jo6^!2IIICA@h3ed4Yk`;@Cn_i-)$*5#dZl(RtyOJQa#99~pI2 z_k>I(kk_Yex{bkgnx-C#RCa!5AkkwfSzdEbQ$8i6^~Od z*CV#&S@rT$px`i`y)e(esGrsox?U=+?9?cfsMIKG2x>$wm3lSAv8WXn79XsJmI_Bb zB&gEt@Tsv}IGil<)m~Vq2J>=nTfSXy7z6hGO4%vn&8g8JGBx@#U874xvieuxxOI(Y z-SgIHwt(CkU18|#8XYrqPR!0Lz7|;i_+2yBaP~x`w0|rI)^F;%^EI*?7CTeZ3&;rs z?37P;0Hy%10=yoO<#q$$>3~1Nqv}0fg%(FC3b#PJ3dIIgxL$+%grQ?B6fdoPMaNd5 zaE}|@kik(qD!Ls8_g8~sDi!a)3@#64q;PAs3vJNg?lQQ046Z`%rCjqySv>P%<{$bp z%HzB7aD6j$2CCgAS7<2NQ=|8iOUX zj!7MiX7%-@D-TJ;3(8+WcrjcIkl=3nxx5x(L2YIiZ$_9}o7qzfWJ&163S9e5Erxww z&&D!;ugm;BocS9MSYH##98&8B>TI{(h;VF8=7}4hzEbQP%lEjRWqS{1DCXz=DRRWi~c<>Ck?!u!^ zW!H#r#Q0ufd^_P%R~mL3Uydmh?=5iE3Gb(k?>)x%VYm|F`+eg}J+F9w30G2le`|bM ztCVjLt~dF>k-bLt0%|Nr`WO#c-}KsC34C4(-v;dJ?Z#L9dY7~-mCD(z6d2s!CK!u% z^(&Su>UtooSP+{76Jh(~eV%72A@oGk~M_QTMP6YzeN;I;*h zhn@-J>B4gxo=5P!h{w6okC%bDj#Do|EYz8^ z@TZD%k_2^ZC&^|g6QTU)tj@EaonoHPl7oHu~4xb?Tv-nsLfblW*WaE zz1}q@lB~vT9Zn>X1{FzW@m27iDJ1<8L0(XAXUjOONP3d4j!k!gJR&R$g@qTZ+bpHl zLTMCt(zKBq6?<1oRA?ZaEKK+7cbjR1FmO&^@~=%Za5a9aFnm%NcrspvQhu*O0{9HxPePiW1!Se! z0m!=W9AFvX^MI_hzXyB}a2Md$0AB`t1d#lgBePxwWS>C!O#fqel$}PG+NGj!UD{Xe zQc*beYKrb#+BI4>B`e%d4DJa-_rAd$Fu2hOU&#w;S0N{jG!D~7I*ew6<5p%B#wvrm z!QciBZiB(yYj9sSxSa;~D}#I2;QncFW6*vXm> zma@k2w5XED)1pcquTEDuo|9I%Ck^fygL~cJ{%UalFt~pi+(ZmUmAvD%tI#SpxbqF} zGK1rV6)Id_v8Z@^4DJ&K$6I0*9j~HPboUt?PhTtCR)gaSY=!%^!SP~0g?rcFg0Nc@ zj+gz>RmhXl8aGC}3V9iP3vMinW!}K7NAK!u3l5+z)n(p{^9rHg;Ht9Ft&<^i^|fQ@ z5xR9eUc#$a30dgYk?KwRy^9>v>rkN|zI;UA_|Omc93l5I=?j;5C(@c564t=ASck@X znKgibYYH+L5?2?@E*Rjf<5BK=+y{Xq}-tYFugX^l}9pX;hylJ+QG-w^+g++aXR8z zTn;77u?@{n*cWcWjr+>f`HM_G?jz4s1qY)~V@_c(x+7CHW-$5-=BGqw%<6JRC$#Qk z2nJWR;X-m;XNJqoUtnerHt&iIMqd-kBQm(t0i^im7e_78ncKO?HLUlqB8D%>{Z`E8 z+RVEWDO?LxR}P7xN25cyUM}<~qKxQ>A6}jSPTZO1&9*b1IS^g<+Q2CcomX9D3eGDW zn25YWqP9snYL<8Rd=fEcIuMg+rg{uw63(<>1cUqHoAfPL@KSt3h?RZgq{Ip{B@!*h z$;8Lrk%jo!PK-}BH19^NcOwpAL<(^jjH1#%g%{-HTf&T2on$*5wHZ}RnXSARpJljb z5PeOp}I zAAFCvcyEN_t%vIyg2Pr4i#V%6C3R=7`LP_Q+`FjM%U4aVsd$<%YHK5|)~hWqC`Ky0>Y9NV_2ad$6c?;JGv~0&%%e zKIDxV;|^RQB_CO~M-wK4Ej5}L0zc`~lPJhp?dDONvw>k6XaG9*RWU^Nsocmn0)tN) z?Gqr)&P#j$Gxju_Q%1{>lOL13{&7H-RmqOaff)+zKhG^e(?ujldRRcmuShbt74Mu9 z!fC0%I^Y~JSBjW2_;5&}?w-=cI77V3;pLEXj8IwpRp9Kh8i(As;{GBj3HuO|lQX<{mAOz1`jHalm3CLOd z0M@Ub)9=3mdfKMV!T=pyuK{)e{t1xw`RjoE*wH@#?*M!Qkj>&RfKLPd4e%8}TuYs%)%_+QZ!P*e z;QN5@0G^0^h9#Sx2KWKsbijWB#sKdHWM9Jc^O`umbFB3Y9yQjYORdT(+!F1p4k;_# zN`t#YyGBc2rg(p7a2$0h+;0r-_XhX6!Tr_X#vl(>7)9DuDDw&m$C0y=$39KrxHh72 zJO`j~JXET1pD?&j863+`(fz{UUNgAe1{XwrDmosFQu59b!bSya~?+BEE!X2qyxF+4;I9^h8EK5aqhQaNEy`XTfX_q=|tuCLDbJoqV4c(>R z#%;>zg7A$h3`=0XzK3xFJ{bx*FuRU1E!_ck6eM`LrF2NWY{!eb*A|YuO78&{jt5F_ zQ;u(xrj;XA+6z3sg|t5$I`v)tdowik+5M5wsoO$Re?_X?@9A7x_(X9I}Bly#O#U} ziQS73UP1_$#UzB#S?^y{v_CZe{r#aU-eUxx4NZNYJWnW|o#c51JUhWtRSTY>#i6tI z3C}+8>?hBb(A0h5&{WBa--BW9uXiKMto@ zb|8lgC0;fSM(=dL^S<6PgFwi0-x-XqA@|=wy~X46ufgce^!W#Twi+J{8E?f122b7H zgV79zGlS8)d2e;}E4;Qk`gNh?{nTZ=v>E^AR0s;0j+%!5QtPJLm2j$EEvMQQb*f!; zr>Y7K7FEqdQ+3s!s#*g-7{&&InwcsH6(Ph>F)s7H*-D+Y=7x-wnzrVK+pQa?thwP% z>&D|V(VKXgbXjd?liZ%dB{RKR5u;+g)Ec;>pP z@yx52Z~8bWsIP<8r=XKQE3W&Di#?CRvF}l?-x}9njB6B{x$>QCTpa0qN#wELS1!)4 zP-6wH5zts1jRm1;tPkY9`P34>=98JJYn;22aENili`q`dqmXS+w0ya za?lac$zp8QA@`N2kwF@kZxnGo!5-~!8@)4{IX3tSSoWXG>&_a%*hcF~5}yDrR}B{@ zAXoiP5?fiV^xLK#DLBy%%ML$Y$Le0@IZ;L)H2V%`q*4Ys9H}U4d~w(E_U<;sUo89z zNatC~FoTg<{*}|^+d-VHU5$r@LLHwFI_VDeqehhsbk-Mpo9T$W8-cp9J_5oVUGOB0CL{RjGVA@Hrh>cX=Qf zGZ=FMM=9yR$0FcX3H%}iJ`x|1Ep!DgSzjixJOu%VCGc2YGtL$L2`inxo%M|9|%0J1~l>4IiD&ZbBMt0tiTr5ClaqA%HX? z8#a)@20{l#Lr5W!5JCz~$|4}(5^_vS4yZINAe|t{rBI`Q>{JD02{_Rx*z!i^VF_ePD57=2gI)N}9;T6| z$4tiAsUjJY!6@g`r?4NnPREQQeGo4eaEdlT<_+dCB3E*uxHqPbY%~vH3fTJ`*Ik$v z^5UwDF)c(al!;b0V_L{I-aajC283;m*p(9VXHFlJ6dy|r=U1#6a{35F@NxRbIv;LY zm=2#AH@qKLwF81b2&Z=X$CyigriC$c%M$e$PB3h9Pl67_#XSZZjA8w3Gk*uY3>5X< z?*qlUzkfLB8BkH>FvDP}c7TotjR2hh>IBUL#TvN35EOlgpV=D?$|{JFv3Phd7PJ!g zaiB9m8-V&j@s3viY0yTXeEkH9lh}o70?G=4bvS=t(3YUAEEr3R*G;qrWxIu0lAp!1 zEhu+$I)HK|rXwh8Hb&fjHb<9&E(1*gW$o?;`Y`gFsQewQSHPpo2kMfcik&g64pxfDQ-k4>|(W2RagT80Z+#F`#2X z3qi4K;;#ao0O|+53Um=@F(~IAlR+N?EdhNEv=sCZ=oHW|LCZi-fldW&iYi$Sinwbt zK{->r7IZV{JWx&$=7a76y$@l-O+wyHjDC6}ClTdla@$VLvGBCxx-hNPi=c8`2N9i4tSaC9x?A z6DU7QJl8>)xlzbc?NvxN`Mk@>t zMe2Mw;imH~RM^7`V=0jOUQ*br3S)mQ{Xh-Y`Pw00C5GCeV|^5clC5JC6;`OQxeD_u zY`wxZD2!!E`mtAGUn%Tch5f3qKNWU9%9oUFrQ7gsUxf`+7~hjD`L0kH-&HKJ6}ka9W*OZmz2^|f!0pcTE@sMaLMyL8xO-UE!j=Q;$jy=la6MH>5Bt& z{sy4gpgi)0CRKD_Xj1(b;~ody#N%eeL3`jH8|eN%pd&$L0uD;QF@{yl!02;o?UMq*3+n98WQE zYRH`mSrHz@^SEw}Z|!77;u57aO+`Iq=Z05lV%tYJo97N2i?KIVG#30%YDp+qBXMyT zrACPH@o9S240jC$*Ryz0MWl9xn8;Y)0ooASjfsu9$3))(LXI!uBFfa(1fyOi zk#Q!A-)1mAx|$?pp)ht&5<94{ZxnVyVf9ebBww6vi`AMctcAk3Ln!&~RT#Rw zj@a-&;0x?xI}t0Mo~)VzEWr<|jsX`7-f&#pg_Fjpd;eFD#>a`$%|0zoX!Gj# z4vhtb4+XMzB*Es;_cB=XuOXkvN>_kS36`k55(fhK@r@F^Y)`vw#yKZ9#P$T(O<6W_}XEvWAIE1{BhzUK611$ ztHh66e5(#Oi?T}6Pc+nRNhi>~3M>IHC(7+Ly@Xv}irx$IF(vpaLy`*(Y#LnRRjc-j zGz`%Qey6~F;Elp{7cOpPOA}O)&iPIOE+MfqixJ|tqtoI`NUa@N40;QB8Y1|;0%mX4 zN64^$St#@*;XbrKVs9sFOo3R$ku|ESI={L`enFra7_fm4!{Y<;Z6sSzfQ@RDB;4eW ztg6CZXEovi2&+->ez`cW%g*R2sZ0DaJx}6dtR55yKg}-RPw+Qr17QDvCW5xaz)*Dm zpp20Nv>T`s)CbxKbQ~zoYx)a7F{|?zfnuKLp9N}vY!wUOZ zVZSSk6-~;rqDfi3bNL`_&oZt;_AvY&C3~8zN?%|&zWF$!#N+?_Oif~D@9j15nZ4ht zsTbI`=;-Maksv!A9`re^sOI=l?{e}H5_?Tqhj0XUIc4Btmopg`4|zxvR8#)9cOzVh zL^rw=p0^0?PPmjH%ji|YeG0k<76EogrmP$mjsveWMS^!+SYG+=gz-VV<1M`5DjkdS zWkR|9DhDg684md%t5Lr?>Y)fCb=EH)AThfsdF~_~!b!M>IT$xNwUhU@_b{vii(!~Q zCvmxPai~V~2x=OW?=jH&ppSz#1lvuKlDoy1sgCALKIEms(K!X)1v3VTRlk1A}d z!roBWeucfOFm`ZK-;WAo2PZM)xgHh_XLalXg>_a~s=^R|oewFX%i6j`e6f`2%!Q34 z{YgQ5Pxu%iJYXAV3=u__IYhqDPgFtxY!Q>h zftS5m1}?skPMV-PnyY{Qv5q$(7!xzum-W*UF;D6Y&w~3i?)LGm)c88NR46#iHIk0# z@#G6eIXl_|PNRY(836-j>C{b~6@>F8RuKAz4}|N!8OsJxIC7_>yrh?L)b>IuobkMIrnXbgi_aH7=#%YTc8!Qql z(_LdVzix{YHB$23uds&|AEsftzGk{jtf+PL28`K7v>a=3ZlUHB?w5YV5#=pdDu~a- zL!D=tRCwUi4qWDw+5_QF@H;eof&=U9pq$A{6I6Qs^*c0TMS0+SB33ApqnqKVbeZB_ zzM-6>m#|ZNPB-LJTlEBcKmFbm57$n!17&8SixT{tP8i<(Kb=l+iH*gOLDnbeVhALj zSegjXFic05LYBHwI(QtVhUtJ7$u`0sjk>`9VIG zx<_!yQb(KI3y@fe?kZ24Noq91oy%!ikPvXJ$BRlA9X++&@ht?k?JRrSaGAxG zRVTQ(UI2_H2^ZhODUB$uqszR=m}Xcx2#Kofv<0Br)=5fm+)hEEy#lR)t)Ly_fdCS;b=CbL{(%yNmn zpxffaQGbbXNk06`MBV|nnYQP8naDKzU@z#5NL{aPFjH2(48(pggmv5OD*oSlnFx=y zoPGJ+SX0yU4hKEhy)e&0x07>$NrzVy`P~r@}@#3_gyKC7&N&Y*1p4>y*q1xyY|W#0KXvidvFen`#o3^sNl;4vT{)2`vtnxG2pN_%$#b z?+vJMbvoQ(BbMZI*;T8@{N51TU z5|=g$wwHwsgMIy=7>4!wfbuoi@H#*6y{<5pNpwHl&JTHc%RX?i+u8}rqaD)7Hr6;R zcJ3CSiCBOi3LUH$oIWhWT>n8_p-0B-EklBk%!MRdN=k0RKm~=STqhNS zZ*7ZX70yg-z(sA8mZrY&&wiB5818b0#|g{|j2PDAq9g||(lk>05aMjqEO8!){q{`Z zp6cj}0Oe~Dn%mJ_i1Ikp5#bhr1T~{yD;}fe1LgUMBAORr5%E@XKkDk;k+s zbGzW-u7mu(&ZFY~I&epVKgJ%!*&-MeYan9b6hSVBeT5Kf>F5B@DEuo%Oy)Bo+^%Gb z@^O?TaK@>?7s?0RsggyFpQW@on*L!=07gEG!tvN?-fBsLnR}5;L7_ecR$~W+a|1pu zV(g@_5zi&BZkibuOnT&_A{9XFjrc4ep^dm-@fnRc)7svMvkOQ9YHpR17cV>z`!o_o zpv|^^jff*8U|2^^f~MeFq2oA4;%8Z32HFuc0LuP<6=*Ifj*Ne-<9?_@_n6{i+DMG4Bl*5m*fE7MEhJy8Zj0rfnU3+?rIfu~VIGBXjY`U1rLY=>%~seF zg)LXuqY8UMVOXru^}V97qYC>{VJ8*#i^9^-XUMQzrrTo03vMKa9ezC?6BS>f!g``# zk$io1Tdd}29IZ7j#Mg30#b}MY!9F5^nV>hPw4sdPa-yd)Y|*ft5SXKRtk%3bMr&Re ztu-H2Pix*SN^9P=$x%3pevOpoATFsv+Nj}2fl2@4;eQr~_|105Ym_x8gX=$VM z?*gkU^jtPJ3~Py$mNrUr>B*@%ux{O;YitTRpXHBk4ueVwX`_S_IRJ?$9BS?vM@?;8&dJOle`Ja)>uiA%UWu}=}(jTHB<@cr!jQX zcPU}_MTUra?<2cz!s+fMW6Ru|B-wHdc2Ks_G7qGU{^3pVz#RA#L!+PKPsSdNuBewA zB?<{!YQuaAiZGLR0taV?{^|iMn)4 z334T&Au&ui-AkozuvkN4Pd6#YRF`_Gv*S7R)+)W$)T>LcObhDdp=`s13-2vTZwABrrcHXvO1?-Bku z@CM&_IV`ePNE`F`AsMmtn&B#kBz0nvl!T%M>=lBW)}ZQZIELIfve-gZB#$4JM^XFw~Fz)L1WsG)dVFS(mOElUBe3cGuKaHV*F_&_TxwIw0 zCN+?Yvjf9~^NV9$#vCaMKQ#C!=9u&c{?hzAzvvHV9)=0$*LK}6$z$kcDobw0UD}w+ zG7i+q8Khyt>D?vt%26lA${6uB#+a*dS2PEX`_$tNNLLmp@~J}DUfklQ++9>&%kQ9Bx>#T`#gicCV z$;Z@^Hueotf_i5{)-d68eW`mN{|cF31!0R z<|8L&3v1|QG)(_ZAEaLDq?}>G>BS)?=p9`?rF`1V@+9#-%Ow4^sUy93pZ3(Z z^*dgaRFPj*RaBUipEPu|&zDrCKOtby-2BS?sYTUAl}R1iS9M4#tx75_pMfVr3&kg` zbY)3}(~7FfJ5(o?ZY0@OTjoz+IzMH;ImH38rQuVZHNoDz!lZ%)FNqnOVR2iQ*&74|MJv*tesHz%| z?p2pgLt^PC1+vQvi)O)VYvNUjU{%#rR7|U^E-K{HwBm_c`6^1T{^8PJOvwi%^&}^# zTbZ?EwDZneKWq5dB@2HWd}qby6S}S}xNJ4>0lg=Tt}3dmnvhdeHm!Vux2S4L^|Xo! zNW89{yLL(G(luqmn9{16{IUTPX7%VcVMI|`QGQjCaPLx4I7y3rV%{V3y1cvg{^PR; zUiJ8qPA{BJyZO9jn@inkhgXgn@?xW+b_pprHS&HiBH_^d#}5pQ-gbP`(TJw$)sOk_ zK6upk=@o+-fBn>z&pzGj;CcP;ys_!2Uaur~-M0Mt@7iv=>dwCP?yBe9^Zw-H-urI; z=;6eux<%aPh}K{Ivb>!b$66bN8inzuocq-Df&{(06cJ#Y-dN{VQ+S zw`j`zhmLI8vG}nakCdc#oAS|==u7UeSv}~hl@E>H^uU767d#j_wa?`Vqt+dN?Yg_y z-m>h-KdsAGbT8huxBGQZ-~Ym$%kP`Cp?=(gAG$tvddP{&P0f0q_rubUAL{q`FZFNe z^4PlBt-3zCr0bWzd;2vRer>(hA3XEzzMKxfW?boA_I%mhU&Xw6@!qa`KltUYhU?RZ zwwc}Wt2N24iNh*)=Kb7t%(bIm9sl6e7oG3y7}Ms|vxo1y_4?axKUH~r@Sk&z_Wh~F z+i%_2_4z?sbljXbp6eV@@8I*rH@`QxUH^TL%-#3X&vCch_4caW^KZ(n-*$P-(s%c` z7C+qV!MD2iIvsudf`!%bS9>?!{YYSW?R&l<-4@-nXz6!PH81K=_CkZN|N6Q9$DYHt zISThB4*d0sxv3A;UblbP{>JaFn-EO;|$Ml@G>cjmjR&V*w8^(RBl?z&D zzW8}u=Vg;mcKrG7UsDG&9eTX&pO+rp-R93YA|7FCdai0gD=(%vlgE7sgKG`VxtN!bw z`dqnr(X_WFe7bSp^j*oj=M;YQ?10AG-6K3m!jH{d(h= zWzj3g^?tGcH?>c9zPsTQqn_;gQ{g=4_s?E3<(cPy4aEHS#ip}Xeb8n6!QxLlJWzA; zr8ZB^I2C!`u+MX!xh%c@qP5%HuXdU=YFU$y?(Y9y$Ff(R&ihYn_qP4spLx~Mqp!_7 zolqQq(SO0e-#sz1(S>(>7x`v`3$N{bN9G{M&(BY~VRGDyiI=p$>*jiG%bsuW`r5S3A6I;E z=!Fk=T>Mgt>u(&|X6}|JFS}^d3s+@+{BonOcRadi%O%5aTKD>r-S=-c@}p_WRaflj z^=NYN{hVj7a7im`KRLhA+JS#lW_Sx06}l?Qt5`N{dfn2$EiS+S{YM*4vxh40<+%lIZwFODo*IPB9)?j198 z<@B!c8ykGs?ZAHDg4p+7?a=x20nW}Fjx25e;oDOKH!SGYaz*!52Xl+3j&!SbO zc>UuOTfcLv--elco4pwLsLkY`URiYW+l{XtobuyO9Y6iseelQne_rs=52q(ByZF}q zn{uareRRmTo%+4m-m&7pmp%OccM)x>`W>$KUdMV{H{LcU^OLI^K7HZWS2uB7S%2)L ztN!S(EowP7;nlIFw|v)k+l<&(4)(tE?;|Is+|>W`te)4rcA&-jPu^|Ru-&RZhF;q9 z#KJWxBTG&h1A_E|X;Uk@looETaXI)FRHv3+T$EqkB_(B*=J4ytjA>QIklQ zLO%aDqlj8C{=y=%Wt2t`rb}Vbq?*aeBWb6k(=qB=+O4KbbaHnxK%BqL=P6r1)=3Uo@>fxZy>F|SB3^)5B5BSK(ZdY^r=uT!8PZ$F&$~WUPfNiw&Z4J9h@Mu0$JkydS{Z+P zs2-LYrz6)AuT~*?+6bNr_@&wS%sul$^(4W?>DXe?(?3 zh`zRb+wRVxdJt8FCkYHjzVo?LdwIS{@UX;E&!YnerH1OcSnwP(7Cjo-e^*EC6*1(Sv9}510K|rVlmx8_7wH)^@&&;7La!dtsyL9HQq^ zpiT!DIat#U?EDN3Td*Fc9@=Ne^!O`Gyx2=P9Xv+BmXRhcL{E31;K48Rbl3}T)`W(qhv4C+I9oKD?jd?E z1L|~)!7sxT9XL@Os)tK0vi&jiTo$6Im*BY%zwk~g+xsFSL5J|TK87d%<`MV4v*UH3M!EjT=E4V(^^XQN%cJVZ}_ z!Q;a(rK2|RZFs?Y(ghEXe;Dc0KSYm5@LYgjO1tU}M&n1DHGMJ!4`CEVVLTyv1_++B z*He~0884%r4hYecDR{WxOTVT*(Hxl*9G-!a2MNfUPm?M1(8g4iCQ0PD8Fx)HkYs~J zA*>MMjtjcD8o*`gy&6~aYvn#&b(Qb#%{gv*jN9);jpLt*+Wghy#;+ACzR zj&xT@o{qFrNVSf%Pza7Z3DZX*59!DS3fZb7mnj4XtAuH#5WWMKrk6tS9w=ejC?ris z(iCDWi=VF$ygf;n^Av*jAPEzvkd-v`6su(4qQwYNM+|UeAQh7RZkwRvLNCiTWbs@-x5ag8*gm0~v#t7lZA;^D2kkcVZ z0}d*LG4yl@L3)KCV?vOs5M-5(T&hyzaUDrj$POKG0+HGBzK%o+B-uBVou)9H1w?5; zy0Sl}NyH@(cACOqpb&(x=a*6(4bX5*VV7dRV@Ehb69~IeVc4e#B$Xo%8U{=t>_&xQ zKWLX?Pc5a;wF*OKfv7MuHj*br41t@^=u7aV86nIx5EToK z^aPI~gwh*~a8xOHx*8F?Gz4KNqO>lv3iGS;VTBol3*!V~$I;DJ=g*e&F9N^lc`A4` zEK(~e_VrE&dpzd;@-??UY)UoJJ5<4A^DA3O8RLl2&+p$R=Zt{0%XBHhWAkgUkTU$5 zopIMVQ>s9h5DP_Al;E-X#j%GOuNk+uxWSZqMwb#iHorK+ zw5Oq*Q`4{abt%DP^J}QhujT*Af5ViDVKIRbJT||E0d?Xiyfp2+SMHYcQ{MN~r38=7 zuUxpA@!Ec*$=#;ZXkAM1*!&tUqzu0vSpWVna?D1*rt4CI$L1Hu6sBL}-kA z&94bIzdV0s-(pJb)1?HD&9AF$ez6?NxeWdKS(g$#Hova6`8BWe{tHa0W^9;Y1dq+H zJfKbo+bFhdp2%a@nNodqDZyj&Yod@c+Ni~!-1NICHA$BeJT|}B1j}}Ver@hq^&eAe znJy)GY<^9$`L(F&Gu5Wlle(1PvH4XXr1ZqnQWq?{OwMxwYln0x!DI8Q(B@a)_tyN! zl=@MZ57U@S`BiN5>+jY_el(>z>r#Tp=GSB)#de-) zc<|z8y-g{fE+u$uewEn#T6T2zVpD3WE+u$uewEt%dhz(S&rPWtbt%DP^XnR$U$ZmU zH87<%>QaKo=GPRPU(-|nc-oZOr%MSQn_p!%zXsR)>jqQmM_o$r*!-F*q?lh!!&^7* ze%_R77zYSO@Ywt+2Wqxax23LIXG*2%Qi8|k*EAtz_*EFY?s8KK=kkRSJT|{7Y<_(| z{QF{4sz#R*JT||kE5E3gZLeIz=iP0(l;E-XRS8!!UN7H!VxK9sS(g$#HovNb6yrtH zpXpM9$L3cxTur}Lz45{nQ_5KQ6FfG*YJ`+g=HLCIrn@QCnvD>Q;Ia8N z1E}fO*LU?g-<0a7O9>vEUo(Z2;aB#H!y1@USL;%O$L7~8n_r*q?Yz*Gny*U<9-CjY zZGO!g)jG+Px?7hLJT|}P*!)_(RO?_$y{bzI9-Cj++WacHp^qiyKhdQGkIk>SHoqQi zvdXC3tLpEf7+M zUuhlYU{I(Jr#Tp=GQ`-U$N86?=_|F)};iG&9Cch zeie;)}iHt6pS*B@I8(r38=7uf;-&8AGWBZw&q0^y{=PC3tLp zEm2aiXjc}Eik55LyldTnzw*n=PMcrX12yxjOY^|pQF+wL``+Uin*$L80KLdqx`uiSoqD^seUE+u$ueyz0mb=lwFbvC80(4_>A&97B9 zzecZpq}Y_2p-TxKn_o8xDI>o=+0cE8DRr|hC3tLp-E8yg#)+-lm{L#bQi8|k*DXSd z?L5uW0R_KwQZ2x4T}trS{8|lOv&^s9^w3mO>MLDJ@YwviRY*nCBN&cF<(fI~&gfEt z$L7~AIBQvH7(|NEu~=ewkAFx|HCt z`E`eo(w(&zvhHXs_qOQQLLC-7Hoxw)`E{uA)-+Sz|`HJno`GgDZyj&Yn_m4$zNQJQ`T)Yr5Ypxf)PA6zwQQV=GXk{Jy)1g zU3DqJWAp1CA;qB3ub!uGyTOziqe}@Mn_u?|DI>p%C+zyfl$xVU2_BnY_X(+H_@(Lp zZL1S<50Q6w>r#Tp=GXmjHRIKAllwkXYO5|Kcx-+>Af)>87uVOlvL7|2zR;xvkIkA z&96t46fD|r^SZnksoIU1x|HCt`L$k2F*ORWh+b(*-Kk3n9-Ci}3Mr$^FE~Bp4O42f zE+u$uem!RMtNojvR8#7xE+u$uemyRvj5J*KR9+8L%GC&tFoMVC*9M?w*?6Vzr&vrk z#!(%0DZ!(4sWewppAb^#Q6Do2^X4DGj%EQ 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%0Ad@YigXaG0%R{ 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

      JEn!#xEr?K9o`L4bU%bWl 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 Mu02JTXNSf@x2VhDkwPyDE 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
      ~BN7OBRqR*=SPkY2U>$rdJ-7ztFGqRG< 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

      U5?Y?j3i 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 V0RnLhoNDlK1_yyozh@M?t>JL$99#%8bCZU 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�h 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 {GJsOGb#(ov;dmje86O;~Fj=5A+eH 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

    3. Tr!%Ft6k`0mlBkI9$olDko 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

      VMnb29){1j4n0+3g=3V5nZW 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%0Dowyb~|0ft% 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

      N+1$n)7GH{XQpRa+p^|mv1MFo(w!Ot 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

      )pqlgTA?xPnPMm9Tzmrc)nO%AEh1u#a5NKu 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%0DW+&!(lxM4k^Q-kXD+-@s6RF~c%po8bN#!6Ic? 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

      ZsbFWKZ7~M!Vv0DAfY|ngL!~b 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

      hc4uiaBG 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

      =;D|dTJ2-^)W>8xOQpJ}&JAHUy`g^=7O0x#{2+ zC8tevI9ED{krRXdxg}5HksxpX$`&{0iuAd)b|NyIM@Gb0>nI)l0CEAF$;=7k8uAj2 zav6s6v;sbUBSo(fZaQAaK?H-;BJ%c>o%PCee3of)Z~~iKo^0A!kCX-NrtjS+yzF;} zq+e80Ad3h;D06095YZLhPnPFzdBCR6LI*c@_BI`kWNbz)NQX)#c-b}hN8w^ktaBwa zs4){;+YtAb>)mIk@0#|*`&IKvK)={bloK{>CM7Wvt&bR>Xj$~ye z0$kOot&_gR)g2>edJEnaj8Bp z1l|Z;{Xt&N_)JLU#Zih)=vu|Mh7m?qazThq7G+D8GK=;aKv8gNK19-H*UXz$Hh{8q zs@f)wb1{_M;HlLbX^M!%$wZRWN!;-?!wtQ%Q&fRyG#8~1Q8k%Q)RKHycqb~!&< z-Qg|D-Tgzst0B(7G;cy>B#5Z?EGiQ%VyWkfIpa>OW$9*A4k3o(`*Cx&L=PzUuROPo zf-2(|rsYtj%jz7p6&{BzX&%0jr$jR4amQ~=l?*zr0$kG8k+9(UnL_lSqb^&mhyr<$ zFvfJ6VbfhAmzlS~tT{)b3XZft;r*Z700o;RvohRSWNdOCO%?kQQ$i&-1(DJU?HXlR z_0V5j7x~B4ADm;U+Il0UbOj%@P$7w4M_d;Ttqvj+>O0yOK^L?SxMCT%c|3>DPMc5b zRZ}gtHh(8RY)3LphsB#`+73CLc*dDg8LR5f^h|-(HWKSq6hM49#^#cq#Rgb4vK5S1 z5vn{Tt@6V$>1{)AZ-x1h8SO3*PDaJyAgMC9ksV)=th9>t%#}M_u{ERUSwF6fDJAMQ z-czp4P4*r^6xpm9w7@-y(VM?{jofZ!evF*g_~rN^^I=l32-0b?tW|&IgWXk>_s7b= z>QIvWx>FN67+E689dvc}S>D?FDJhpI<%wmhk~mg)3Ux0i4eDxjza71+)IBAYlM&#D zu(*-Fcaul9%tYzY;9*1}hx>Cae5X;b@9{DxO7gF%F#n=Zr!v@1*-%{$vdkf@KW6Pv zuF>*6D!;FHuXp-8xOQ>gg^k9VUYQapdFN3>g8=Uz+B>^Z=SH+U$Uy`xDqOQP&Xkfp zYnS1*uruFGRKWa;jsA(uC$_Y+oz(QS-t6w5qNOu7^Cu1PM=c1dVT7l7N>|)BVwYF* zXV7<2Jo&z9)Jz95o){mW{I_!Ei}C; z0Rk2M)^Y|7!EZ(q)9->EpFdnWeM0sbuIcR~v8>@*L>pYmS0A=?xN(tnr@LS!Qh!l4 zPuY83?;kve`0=z?u-%d1Y(0ku+aS26-ZHfmRRXeJO7rKPcY?z`gv;eO^@=o#PeW9E z3x*5>OMiSgLa@=SondtFVjM`y8s5?|&p2HJz^bMG1fai7Ej!m*gns0o+S(hqx`$Uy z6k>XQ=}gN*3{GuYmM}9rJM)7{9iVAB%-br{%P_0mqjVyFGFEXm94ZA>D;MSHPx<`$ zyKISSec3KAE0oPEnnT~tB#f}2{UM#@WIZXUX4)G^QA_3pN*kjFpHmbgi$_kFe@gb_4`o89L2JatKbnH2bps-d6P;jatTT&}jsj4z!+Xon zIo3I(8D-*II`alN#tn5w1rDbWS}pa*&M8l2tg1(@F=SC-lgdG63fmRfjpLZk`RcLR zYjV<^6%tKnue~oU&pr>>!+U{;IE-{5DrCTe;nkD{caW<9j)$r%6jj~Td0DYhJkC!q zLwE@K40e1}pLt-By~5|!ZU-{86#{TAl+tn@5-<;}eT`ULZMer#GlJgarr(eTp5c$- zuaDd2L*2%?CIiGH5R`|*ny%y+M(|}NA|#E%4hJHW4{FHL6vqPWVr}!zvQ0J58)Ae> zqfiOZxtzS|U>DUxN~Houroa?4q*?AB?TQ_LD|^ZMk@bNR+hnc7S*)t|A^e~+Wh63P zny{nI1_D(r=E&Ibi^=mm;+=RDHc{Ux9r{|qhfHeJhp&}6Wjg-43@NWcf%M7q>*;s) z4FHf3FP`XY#b#u`8wGPsPsiYvQe4q=vMSyS;0B_H*kW?^E2E1nrksa%iV?E#_~oc! zH-&c_6<@{Z#wS`>=UX30Ac)Fci#+#~kDKXVOhA(%rRfwu-ERbo~dNflg?(UErZV66cQf;o2Q5{z6&b{9p+GU;u#Vi!`=gpO;=@;*m?bpsI zK3*XN0gD}ch!ct2O2$wfPCryV0rp3Kmyo~0zLY_s2kx%v( z-3pvCk*=C-wK}@Pr2J&c``RN^_h1puVEp8stOm!T-0gDfo*vj8jE+4*{)piXecuDS zwNF)mQ++@3CJv*lc)shtS>#&N&PyRz5mgaZ)%M;#_))&ymay>t{bY+b+4gWK9-F#A zsxTH$D$6%7rxtbVULx^kzNeeK$+<4E#|^cYJkMOY`Vv#!`jVodkuEwl3{m7nE+%L| z+?4rR7v)e*ihVb=Noj(bqUsjLgLxC+%Dg;PA)b1C4k}{Kb zj9C`zm;hi1z^psyDrU>e{r3Jz$aFQ|o~;*je&Jl2qmQV4PpR&nP{nh*dOwHf(Oa97 zJAy(%eMCHSH)J!b?T5efW5~N&5;$(*tJ>;VqXJCDbg`8X}gt)L!I2$^AFQ|46dga z)9_6+6Stf{Sbt(ZOnJZY1K@-eq=&^u-cpaLN{{)W4ec0H@~gcB#2C0cUNHO|KTxnN zAI;>|rWf-FZ74FUh6cJxxrCpV2qdM>i|tBs(m{IXBD+FZXNyP)H3PMxa07#hLEvLo zwY&X>PFmcr!~DfH#PBc)K!O4~3;Ao6W`xCsuW^#%g9keFX{pUD= zJ*|=nUb~~!s`K3+E-0>#fck(fmj3Vq)JeSUM`-^G=;6h;Ht2IF7dWpx%YWF+ZYkNiRUG=ekkDK$` z_zD>Vg+NMKIvs*WF01iQGT_DC78C8J9%53jJUXk`(ZW{P*q-2N=(f7TRYAY_j8RPe zS4BADK(4sR!$m|Z9ZJRx#2}hm8^hEN>NfYw`Pupo?<^EhB950U(d;oN$usS!N5E&G=<Fnjc9V)ait0GVVFTEe zJj0JLDw0)=Bl^l_F)Calq9|>|3VNwngJgg|?l$Iw( zP!-a#on%-67Q+cuJjFePH!lF_$Q^1cLyrt4x{|$t=R*@fcvxxVRT-7m`+3A^{iRN? zA7tbLW0iT8nkS%>OEp-vuKdP{CoN=MAk-tvG4tw*5goA4 zZz^wrDkGmD(Qi%$R83in| zp&T;p!NFuR;^Cq>x)G7utjUw-LRrBo2L@idmXO$72`3IITELsWW@p}Dri3J}K;TMW z=0LnILEcDNR{*1y@yV*mcmf@g8(M1co5-&Tf2D{#!>Uk8Q&^NN{G<7t-h1}w)wxS4 z$6r*r*KpbvaMUUDD4}+fs{YArEmtKfH=>bm8-9O};*q<@)B3J8V4Wfv7qx=On5ISe zCg+loAWe6^YK;@dD7ro9OZuxH+|{8T!e+)a~+dm6@gV zbKJgRT+pq{htHf9r)_z{tkRlwnVCs4eb-zO6>fj zApYRfq=H|KLK52g*q(&&OPc)J9b|acQ#d28LTtcHX)1%XtEeK=ARqps4x;TQ?iL^g zW*zOsb63C31%Rnx65o~#z(l$i>N4R2-q3mZan&lL=OB^a z2U%)7e3DhA4C0wN<)@$5_2L%M1*IE(%V+eOjN9%LlnRc&!ecpBJR8;k&95Nlu)2hf zl-6Xc7+_+aBdT=7@D_p52mtk`E-bGe|m>&>hIh;bCPbb09LV^=0%J z9JWJ(GI+8F*zn-VI)AVCyJAHuh(86qjTozsLq?>K#QV7UMj>QO%W1rvqg1uFo+&y> z{(5<9@7CFWQKrc_)XAzp2y;K4FYDDJzVDWEqA?NRKZP26HJNNakJxd)r@|YMbJT^I zKPoG<^UBG&uxei;Fr!q64)5rt(H;G!S!bg|o_+Ah%YP( zQlV*(b*|w#vzO-rgDHpSLW7RJuP+)rVyeD;5UR!DF$Fc=Z>_dS*j62w%oeMfe5s1k ze-N?_V}@qL>*zKRST|JQXOy{GtsTUA}M`2yp9IVIK_U9{~m z>IYAqr z))}v`u^sE}*2^U@ltOHj@;6&-O?A&`NGEFKBkL7K2iuD3&|bT$r7}xKRZ%+7=Or_t z;9)w&3@+|Q0Yk+H4FUsTAs-vjl1AiRwoDh-2?n`+3hm%IeP{g?*{+s)!%{5 z@$zO(7wcmCCMWcMy%gZnd$b}sv)AM&b^W-WKMj?@=mU2(=3NZZG z78#@;anSS>9ka@IPtz$~3-SriPtv13WJOu<{+?71R5G-Kd3+Jp3sc`S;HH69v-Pry z3N!<0wWUwUUMm(-cPboA7~S;!$uo|5aM?CW4;192Rdb|DuU1d92d2A=Y9sU}FNjnX zZXw;wF00*rUv7N@HSN$iyg+xt@KbxF*OH!+I5vAln4nCb&b!4)T+hyv7lX>7!q8K@ zGtZ|f%oACT=Jah5GV`&r;wjkx)Ke_Z_H7D7BX||_((wDv9E%`yB`IacCL=YmN5=B2=K_pxh1p?8i$W8D? zeQ)oPMtb+s%of0DY*Omq8XHU zzR<)$J{ZSwDuVE(`8o$(9s=*lS1>|YFD*4oL8@y~Z0*h5X?)PyVz<#S#Yt?Sv`orN zlD6DA-RRbef%#T|!L@Q$`YeVP>!68rm^ikBVIf8ILpX9fb6W)mRT|jGfb|VSiRO;< z@#lN{69RTBL#OuljngUC%Pm;%=c9pCBpoo~uqMrI6wF%WQA`H5XZO>D+t%URoX$_9 zL|O2F3BRH^N;$gmG&3)tsQxf_5hv~Bpw-sf(=ua+)9*9i@L_b$I9KgNr^`jIG3>4C zH~5EOc)mq#26KUI-rNv5F!{}R(y!zfS~Z69a2%JDnWD)m@Bq5d1TG8etz z4!F%+UP_2w_VRqf0){FzayyaOI&U^b%*xQ|z@;-=V21Ef;W(0_xy0*~GLR!YJekWD zGRNP6g2hyNfMZU1yDALrAi?R__HovQc>n=?zVv#X#U>LsvASa>tsbY{QQdNyo!pOaA+{=Z!|^1xwkL)Z;???MAE8vHl}u$- znTe1n%*T%ttaEDbPGIbI+6#^DiIkui!Pbs-c;zNGW36bc*RM*=mDRrZW$BhogO`o; z>{2ky!L6aMqE?HYWUEDFN)uOFSu;~7KC(Qlur|pOOnF-nnTb5_bBo$y1Gt zxKHi53;#i2-$W!KGi=`v}V3a2(YcDilQ*S<8A1%SOX5AW@ z&ap*l(_wKA_ua5%Y?zS3CW%wUn;Xs96;XX#WiBO5A9MF;-S0bWQ;`|lCQgnB7|o1{ zdq_cWG=i$qCPW6Q5rm1M5T=Wf!U+XV{lQj2eg(IXtzfby-(-t3(Z$FIe@aFUp{Cr{ zm^Kp;BDuq@cl8DLNMH_I?PQAzv(r#E9xGT~ER$FUz(jVuPyu1qHL(x~5I@y~=h9|N zS+Gu}-cYdt@qW*@+Z`DnZsb2J7Fpbu_Dbn!NekJdzD2lwa1saY`QLzV(T)elhxp3? zpFrb008uCrVIdZlmm9F-onuUb$>O+<(#EKvFr<>Kmui{%H`KbYgc|uH6>r+CJl?=* zZH*-|mP)w0)D}CIf=kA;+2aHZ@0vC?#j|>pE4LOU51lcVn@%E_tSgoa1YKx#fEHaXsm9J^@Zo0PQ%!P^S;nXyioZ2vPq3m#ZQyDO|_9C2}*cKogup@ zVFp_4A3Y&b`-ei#FpJ5UN&_~xhU);zT57H#Ab#mc7vDNA%lFo{xR#~@Y0m-POE2_B zOHwl+^Hf4RrG#NQQ$N+j>CbUWeFjpGjkvlhEAB7hHWCptqhr&w_d8Px5MGiMa*HY zE|#ZmvzXX%C{i?TF$MroOL=)i+GbBp<*S+R(zp0AI> zcmItMgRu8EHvKo_mKYK6BF%S^h>O>%en_T)LB(fGXJlNu2Jd?djrn*So0tC7l#O4!9NqO2_9D%$3; z6lPo0&_U7&al*PJ9nX?-(2O>xviO&6)eHQM3swg$P1f}r%sI#IWI6``r;_oNb_tWk zhMx0mfc7F?6O6z&9PAK8NC@wY1$PK=ZK~g2uNCPVfk5GvM>X3pvxK)|wzWl&n!i0f zz{o$40YsH}_SD&lMe-?}rpl+F|)0Q0St4knJP zYaXYPh_)E@>ur|iyCl<1@C;hPCN!zS?ZzM>LgBECSd@lX2QUi>GoCSy#f^AKEu{1@ zk3%AC#N8wi>p)3{v0BDBeO^|siYnqZ`N1Z*aE~i zmIXg(-q2}#M9q4L8_`MLS{^dO%vdFa4=wQ$K8L`Fp1?5*tw9e?NjXXpR_chpRJ3$w zniQh@W+<0%#f@rv7svMz=>R0jgf>PJwez>X@!&4ZGJ>;b&D^Q_;tv^7Pdg@0)p1?{ z&Q@x5x*1%F=_Bg~_hP0_4#OB&*R?&TiQ%%s2WIHt!`g;tqCQn*wM0;6bc?J*Sv$DG zd$?3&wo6CYD?l+}RSVK??Td3)Iv)3L8I%#Zr=T(| zwYp4%g=VjLqDeP?1OaSjaTX*n+9nfqkC}GFg12m$vNS+cZJxixm8ngO$?DmVmgj?- z8cT9!68hh>s=TibUmHTf>B&H z)OH~EW$tN~A#H{pxMDU#4S}dH(&^>xmDqBTkpfXtbvh@Tmeo!JU|?{jQdb>aD)|EE zyt`C@(Vt=2Xl=mD$x9(hC6V&7=41(&S}%GEMg&J1{pY(aaYH4awQFV1NWRHNU$DL$ zLX6!ha8nc3GFI1l*B?j6WfOc=Mn$_aeDlY#=9#it7VLsx%W*OTx^w&uu?q|aqE$ov6>^R zaAsUZ-C2%v2<4Dr>lWQC0F`2hU5ZA251Tb5>9O8uP{7e*2k{-GmaxbfeuZt2M3&B= zZxN;lF(S(psiY7lS2{Ncm7#drY;B6x7_Ic8I?$b?%+y&NX6z!Z(ds09zNyR*(~eo` z4Dp;OiiS8RDz+Zgvr}QIS8+OQrb@Z$fcfPmon`~qfrDwD3yreY#04&?F7B*eJxeI0 znMrgnWuB7o{(4%k@6hH{n=xvdpak@!GV-V3no^g4n~`*xo!BKm-ssAk9I`Crsh0bi z$!wm7J5p*^Gs>!T6Zfl8%$(D}?fk0R8FUdWPscC}9S{J@8>iPc)-|~}PzKrUW9x%? zI=#=VG-O7wu8eaF)~t-mEr1V?`L;l28?=wp5GX~fkeLGCY6^mdGjKf7ut43Y=c+we zIhNr_i2w-4o9zrPzxkqN(jK&Q8rK4M&tj4cXI~o41uSBno{nvT3DAJgi4l$R|An@5cXp$`q*#_qP1nl8w? z7l6M$UQWzTS->(0B5Nrh`6FuKYMvfW7BMy_j1|p>_%=KXY|!-iZgWapm^X!3hV+t) z?IrjD@znCi%vqP zNVe?pfc>y_VBj`EVz42{UMiOhs!X)bVyb6ufEge7hWc0*AOoQr4fye_vfNo8tkV(Z z>0`DT1L`P?XeMcnK@-y=#biztv)+WMtYCc#XCDK~Stl(g_$XDeNv6?t3!t*B!mA%% zBQUELzuSi-fjL&6mO?Ss(*?IyPl$vU4S+n$S%QP$+#dP~+$BhE{(1yP#^Zn|vH>9PTTh07F{Z6P&pR%s!C&;}Lh3s7+nDZ71q;to=% zC@k2BLzG|HT|{nXqXt{s<86abDGBGQOOhyq&e zu{hc2tTp=Gvx542$1T$iWvoC?NjFds^CjoimYh)1rpa{poh7GW6wBP8N~`bIJsYSr z9@7FRoB0V_D~HVt((j7(!sKm&fV2JC1{o@g(4*g09^+vFe{^`Kf1 z(Go&aFr2c4Q}`1BR!Y$+tKCe#$yVnCT|dm;LByyBVa_ESPc(oRT07p%1qhlLru^a4 zhus6GD1yHO4yhG6?#K}AWX5A-3mLXiFGLSthYYsnK|-JPLC&?(Yxp7KztwsvHeFx%b3UTg^wvGkszLR1mCo1N%`B(K<- z?Iq6?{AG=;_m^WE4uWFR@-Zn=pDhLcBa{sdo;DdB^4@!_!)5FtQ8YRUCMMo39*kVv(X?S)aiKbVC)IbPHM5c#v!lxDEXS<40lzzGkccjsM#G_aNu`rOxz~7*b zG(4?lh3Ylq)J1WU7!I%*mwl~fLnNuodBdNIdsk+ei{eRZO1vQtJMO>g46s_LL#SvO zs|BMq&6i_rgKNqz=$8o>q2MNQqyd(R!WfxJrBKSO@>FNJi`4-l;Q_%WTvk<13LX4I ziX2lq`^xta7&VACjl=i=8$KCM4B3hTC%6ts+uO70hSqEzoy~H+Y*Vm_Wd( zDi#ObE-j=6BeF&6J#?*2&NC|v+wpgr(c=R)4fbe3*lA%Vjz!G*b!hEv8Rc2%;3M14 z72H&I5c6U8IRGPs4R*c&! zP>qesojZ?P1`sTV`F(ZJU9KZCnevg7tpk%TcKj5 z!VRLV&2-nquvq*o$r}#Aa+_CzFuZ+wu|o&JNusDX)^Hvz^_i8sjlhZ=fjF^exVf0` z;~3uJw9Sog z=x_)Ar3j=C8@O#$n;H}>B<%%@@^;s*L`#k9#eQSWLMuNl;53;M{b*GBg)>cCe9N%v zHxUqORtrvbZ0m%{`Wg!_?M1| zt1H;?Yw4d1iq_T?EwcvAGF@NHvX@>lmQvAr#-?5nrv>uqwj`B)a*bU!J*4v*RXvR; z6!MB5w2)Qh4|Jo$)UY9u&=7+Y&Bf8iE1NhLtxgACO$^#>^?4)Vub^$69Z??q!xSuT zK`4tLy8Bk3;nsg5ED2;nQ9jcjQKnI?r?_DJG}Ju#*p}#?l5W=;WGs*nhrN)3$S>8` zX+WV9mBmwt=oT`IGWa`?6|?c=rg9c>v?&;;cC`6tmH4d zQu&r*RKJ?1)gcXS!``Zl$nQc2)J|d#);{8}ViAVGWr_6w5;z-o_z&i`HYtG( z8)jBmLlBCv*7T7qW_u?g3`Tnl5;BIf9&B77NT_Blr0K+Bu6onx+VIvLZ*um#^_i&D zso~RV^-?2lEK-yJ%dnT_=MuhD&0+T-*p|!{b1A`e8E1&US#F9`&nz;eyD`neaud@n zijHG05?mZr>EU0N7RafM*kLJt!2ae9-r;v)hmLBCF`^;^Mvj}(Gn6vq(fwhYUh#ru zUtmULGMzYPnpsBmmn+^gBWB_4t7fg}ue_z<5_Q#Xlp~z6IvE-piFMg1QgSVN>Ycv>+?-PxcS+LgRcYX0_7k2f7HG2^X~(*qUa#6}lHWBgu2f*I%o#Rt%H76# zz1vXl+)Ev5d<+Z@|H-==X3Ux@S+c`7;nhDjOL!f(*lo35p5H z;(ijd;M9G&=pVZ=V_TJW8DSB3oYVcL1=4da6-=%0PYX{a^cD8T_(gT8*~M&^qAhp^Clr{a zCd~?_nKkr{yhGh<Hl_pIZltpv$5aH+t{KxdZ5 zm4e0c6#0~@CH2d1)C+gmw}PTSBh#*TsT2xEQATVp3 zpz2Wbd<}nj&sLTjc*&3ox&tNsLv}qS zNi;-tpT1@`d`zyIOjzV7RW-O>=c?*q3?lb%>px^!J@o1f3)37Vu5;bZ6jb7G>*!G( zoaod2VQz!OatMRFdPQaXxMSlvfw*DtwHnMbjsEFQ_aqtn2n6I~BTr!mF|TThIJPAT z;@Y}lx86eP*%{{)SJH(u*pACbt7%iz!qRbVRBE2+)~z8winaj0iQtOx$u=I}Ml5x0? z&2x%$ThumIhZl)R57tJ1A8rC z%vq||#!FnGLMPI8lg1L=3(#Y|z7{@f!Q71sg+TJ0KHU<0MlFns;*tl<+nb9PJXOJV zbtxdM_KaIeTYM}Al@~Yy#eM{7SQr;;oY~zMWXDxy5vRg57n^;pDATTLG}MhQ^}dfL zXl4%%qDVg1qNBampg?w@`qE3*jldtdt#H_k!(km7+05%+_6CQtW~^J3nG&O79n;4e zt=6Db@8;Lr9QA)D?L>YYl!*%`;I*kmD^45Ala8hENTn2(Z-0rphvX8GIYe>q&PwET zwpu{f93B(f=;%M9%r*P1hW+SRUxi&A^yqdF4@Z*Eps#wp{U3 zVH1fy=vju9gqm&lusgBUT(`jM8m)^b?kz)>ftn2@xl$ymAkifkjMb(G=5mT0GAsR- zY-L5!1uC_I>DU@7koUB-;F;>uR*}XM`2%hA*WB##oxqi^-6t3iTuukoKY{&WwER;_ zvDgYlx@)JojNtT?385fV$T!Ev9}dlLPv8c>bSui`mNra0+!IYON?cR(Z(JXal^+~y zN!z1s{Uci9j45!}o~|)%7IbE%Vw)gXl!|S7ty$7)5tD4z`DV*AbjO_2wPX}iw>DKg zY@7{5wOXoTOjA>~0*262?xNztP#vrj?Hr5g)?o?4D_#0-I=ZB&QeRt7pSovLc-;oC zp*z_@@uE^diBN^Go7_!NDU_JWA`-O@=Vlcbjp6tNevh_cY0r&{a;0Tey>6Hd1AuZ^W2PM*O>hvb<}TW?dq)^|xp&gv0K zJyAxc6&90a7J@ay!1qnqLPaWbG zVa2>&n%i<@rDo=&$_<)kw06z2Xgj4s6*LzMZNwAUT+WI}9@a+oRz=X5s`pkcJtg%c zdrQHj>o|{j%z9g)XRATS%nVjoT*Sqmry4Uj!p?0H`_6(QMuE-CXm1ftf}lfN;e~B4 zh3*|{EYX=?nVUyFpl4E|jaeBhQiPI)%!r_GY*&$+%SsNy!Y$oA(WJ9*wL9O~98+fO zIAv>%T~?=?{Y3=wTA0&rL+C5m#;iBCIz-+~g!4nw(3s&%lHjTsqKSnTo`wvAsjz0+ zWjGuX7-@PqV-RsfVS~|FmV?gW-8>GaH*iUmBvq_cz@27pi)Z~q_b#UWiMU2HCh6@^ z>~17vYIg0PG-h|u!4eB&ZiP=d{v&02qq_BW555qZ+Be`aHyeW}#=gu7{b8g?vTpX< z(fKKvGXytj2A)1+rH;8TnwUI$!&pcXbFi=6;o#hjmCQ)CmADYiSd$yw9_{%K&(^b+ z!Fko`BO;X3ScC&_v^;hphi3`FxmD)gb~N4K>dRb4+|iL4Ydt&67$lr=&T27@l06d8 z6ZTMAtYYTYriE;I7sz%+qfeJw+YCvq;+&2~xSVNk#mVppXx2{NQ&o!{pQN?FpIFZ# z(j1P*>Zf73Ve)7{I9OT3A$ylXI*&9?$V&?*nlOf2EtEss@7*D1YT9P>IncD&YW4|J zhrc2G(&HH0m=}u=v-toN5^D6fdi`QSI!12Oqz)Fn#_HXrm{-l2H8CL;izK3CbvodN zOHdu-EGRVXq*l<%>ZvfR`)1}%>AEmdK8=2Hsb|)gii8$A1fj9c+TFQTUt3HG!CjuS z$Y51Ge+mmobP7qz_^(>1DT2j)#V>A}Xs}QYMb61?XJGN#xGIcfuQXN==OZFwowQLU z>S!j{BB@2CsWOa>!tg=cUl!pdU&llP9@M3Q6C<&PF@}XR+$FNy$xcVOHn5`GUZIP4 z+-4@uYj1VBQ;in%&JgwJiRln|)g>`&?5E_r$DCqdqOJD(ppZUPb?|!{bGa^7DL{%) z&{tMfq3a9^wpCQd{u5k#`d?n3)bW^;ocF3MG}}nusv^zQu}DGEqysx6))cqSwes!W zX&l;i3g$|_3zKI9ETeJ5R&)^^3|-n;wjkx@X|`CGF7*&_79y?1y#dvJV+idR6l7(Q zjZiBnbU2+Nxxle!6hEX4^N( zn!=ZiZ_^5yZSCLF)i(q?DPje!3yew|XDdV4IzOOe;m63stPWbpO!VLuk72T6=$W2l+NLEq=;d<&PW%GP0q^b!UO}v~1VLk1`E+MyIY(2oD?UFr{)T&N8#FW$!I!RH|Yt*yFa|$%h zgAd!*U8%}1W$%I6P)`|3v~c#kyH5xfHnX0@xhaiCn;c?=_7eS*a_yBnOY)Rmp$fx<)kL-#3sgsff3i5^ONh(p_d+diqtc2|M4|)t6 zgZ^r#+k7R*6duO(;SD~Pu26&XaQ1LHxPW`89#ROZ z2rsjx9E_4aV@qZm!8Z09EgzajNq>c$xTVg_lH6_?!=<_mt1UA@l-^SF4W+LveVj6S zOGDC!wwcCl+h$9P9b#~}nOmPe?k8MQ=7NS+waOf@6sy)!oWnYlIMy$5o-^HyLS}s| z9>-jEl9$+=&u|%%5_m6b+}4HO7F4QWN1XK`jcJ>p#)OjNG=#+acsN9EUk%YY-EMX2 zOQTH+A(2zq^Caz7bIc~%HhQS;)YH^*W2u8<0If!+$}pV5cP>^4>Y8;#h4|d5pNyUm z%fOdV0qQ!hu=PJ@53Wv^{9x_WzSJ$+D`rLfEojRj*E5LRF%Q}a+(+v;t1FDSIiICA zaWhiZ>cqrENvCn_PSi)%aL_iheiE4!k9p}B+Xdxbs%{*dP6tP&Sc+zvM~DD7DIWvv zPm46lCkfcaRxeU`h!@-t$`)JSTw%~<#-=4m!_kc0M?T?*=rvnkeOTj=bo0B zJAdR!8C3gcTi9x6BtwFBykKR9HP;%J;8D!VI2zknS0aBntGP-udVFz_@-Y~zGUp4F zo4Gb8g0gKEU7po4us9W*7})nCnwzUve~lz^Rwbuz#*F65=G)!IBI1g>963vOQ_fNh zdN(ZaW@!K-QELbrY3uR3NsX8!nouPN)BvZy%t2=l!Cf?*6xN!3t6RZQW2fHhZ>&nN zCtY?e!{9wxG-z@hf$D1Kbhvb}NI&tM}{w+_Fqsy;JS z2#1N*+0I~tU4mOa)_v`npw7quYbKqM>~w}ZT_En6MOluS)mj`=tD`pN+!qrFgx|D# z6g6nub1K@V)^~Nxj5wKNiC0pFZXq4;B#m)Dl`teXl2@Ri)@+S6nOhlNC$bC`BIEg) zjQI{DL{foP6I=*a zn=9=i{rXkRn9XG#hepYZmnT2tr-UfegSSec0wn)q6?CVH}smA*CT6)8$V90fFbbiK87mdxJA-yq?3fH?Ug!*G|hW4Y} zIlvJCgEgSn9m0(>7oVPZ_l~&Fx9it84xZ?Wv+*5$B3jKwm^6;Xo>N}GES}|zMwEqi z9=4QGrUWH2@L4KVg*7X8d!$kro9#^(ryBFQSlm5RayFfeDPBZj9ybeWqUuDPjS=Ip zX2Ecsc5h&_p?V zCXzo^w+{Jp5RfNBoL_RknQWp2rJ%i*We%C!VqTTOTk_c;p3XMdoAc4ScPPbNWm@yo zwXI29gr?5Id(a_l1JsI%13fM7hfveldnnEni8Y${HDr`^fqa_Y_O9N2%$B*Btif7o zy~vGmGBM~M@sCUID9%`d2TmUyWac4r8#07VF#3V}6}n=*v9cF0mN6g3;U7xTWbDX@ zA?j4UCLSi%p>xD=GL7H(qDwDMZ6q=$dnATMJJ?#J?(mamVuXDRX6^33jA{v|uwg>J9s?GBJTCdc zV|o)}ZIwyh=z65vv@Su}ke>GQ7???^IV3GKTsAA4*vr<@LD1bLc<|-PG@0lrGGjf< zJalC$%g5wPc8)eM%_J24lF_a28x>*ebS8#b^+&Tre6ZFiEIR*ds^4F)i2(`cj?gcT z>mP4oeHYH;hDchdw+4vmz)?Hi3qdgy!Yd`3v>x3UD~88U*;(0(kv9ih2@(oRBa2n+ zZlHB|XNZ5C^y_pT;gYwdD_bKnU~)y5)G)oh21=D%th1SUH8CpD%$Ay^&U>pBV{d$T z496_erAk?(E0zV~um*o)rXev_LMQ(C z>pUOoi+o|J%9yL#xNAW7)JO*M$<0^}2`^@4g)@t-0o|=2`J5EmAbBCShh7NdlEGy! zv9Cq4cNRB}LlOIZaR`^(uaZSIg;6Qj2R(K2j9HemxCSz4tuPW5x?~D{MCa+Yj?`TT zd2_Z}FyqEn@Q(HpsoS@Oh_}D`7<%r(3VYD7AS-kw_2@HI(9@FcI312=qrJMb5Dv# zDcn=SV2ipi%?(kcO@^G)$T_zPQm%GdOaC8ilCbUN^`8*g_Lc_r4xhHc9=2fiZ<*r? zndk2SwpOG&>6WJDj0Tr1;40_#N&sLf%+K55CbB@t=-;&M>=0QtY`xni$wMe@p~_w4t`)!FqeIN3C7YfZZp3$BJFUQ;w(n6 z@Sd=J9{AJTN?>UHs%FmS;w=*}b*5=(?q%t&RBbDlriIJej6~q@oq|3CM+Nq{IfGy= z{to0jRROpuA<875aji%lN_W+mYac?kYzkCVx?wF~D?ZUVu}Kz2#n>C05)gKLa~DJtOKFo ze=X8Kl*q>Chn5adtm7K`pzuyLvHo75Ee{qPv&+3rgE-`#lq4Jmu_I#5EfdA?cUWPw zLF{d*WgWcJdOIoU?h!(9$vXaOO) zfNUh!y^6(g3`FgdZEWVSv`#RP>Vc#x=_xmynXG|I;FV<=rHl!(-T`6G=U{&k9%eK7 zY!;%ML#d?EUQkmA&^xm+qysyjK4ib2pcvrv70PcgTgE{*D@DqSXclNjhn~* zyq@q`$sq7ywS^7uRQ(iaEKf63&{K7*U17Qvh$fCpAhZLpxP}WkQiUzxa|qap4lV~8Z?xd(@1A8W7aQv+)l#8F)#)jT z@MEWYECeqar?RmD%YsNuw8*6_7n7VBtb+jpcAKeN^#G4 z*jIzQr{G}jSx^!*;P0T*YekDeZxuwJ2~SwP*z~7BC!>CmDhv1S(m}x3|7&UMQ0l@{ zuV%AfY}Q$-FrR`xV%|DsZDnThO7|y3HAIYAEW}RmXv{&CbXj?^J`@j~Od$e8aa4Y{ zK|e!bj)uS(voOYo8|+e{z&J>+uS++Z?AZETlwwq4I0MM{6eTqfdCzG({mx>i#m)z} zvJv=Mm7WMrF_T#9J725Are9R+Y=d)#bu`hOVKq#ecgt&BbkjRsOBLD!+80X$jW@UJ zuCNb1I=;?n8+)lJFHuft2#-X2{eInt?`uG&~xYqV{adR)C# z8cQ6A=R99CEbCKnR*#=;*Vk|fA6;1CHjNUUnNi)_41#oN*pOB4Uipm8LZ=aLv=~@P zmVqx&0g!^`I$hv3l%V?ROg9gE$bF^J?=~ASD4cSi=wO$$@^un2MAAa0%(Cj%n&(Na z+t@IhDsZD})u6om+^V-J`@m+fr>lkdHe2)9ELx-nR=y@sO1K;Qq+V%b5d&+zqNqw^ zoo?hy4em*o>(D{Xt`-QxB(AK)feRMaOR#dPt|CQXTSXRxG}>=MzuS09(cWg%WLvKE zRXa9p%!;C1@AYt(%u--ASZI2l8=OWb)MEX zAvD%%QU#HlRUvS}{#O<4*XcU-a9sYXi}hB$>pNx1B6cYQOLS7mfptD(qha<|z^y-| zdmP7)X7w*PNvK&pK53^=y!w*V&u)xj>QnC34#h@ga_@3!0rjl@7pacWQ_UodNC@7HYf#q2hKQ65MbH3H$C094-(qYOm7LI6!X_zr;z`oh!WOa-C(pvF zgB}hxjK*3T%QKT{YVX1QKyO*>$<8LLx>*6C&a7igvD73Pu;8)EKxMPch?XeHDdJK) z%v^cVa^pnRO)0Jo*AzxB)D)tunXKjxiR723gjjYqq;d#bFm3e5DJ<-!&dAJ$WtKAo zQV}B6f|&%o+Sz%82?Lg+LvFDon{ix`yb5I;ziBc9n=%UGTz+G&l=kb&oeI&y7SY2K z%p7H_-)PnvTVSp{Z9hhaqAcr*wh=mm+2335w0kzoQBx+E$720SO>P(JWT%*wP0R%- z8L){{(arEq%h+WVD}9z?klT#ea-&O&?%*-BOFvW3_4@U-bqltlzXMZTJ@NbLdiSJt z8ZC0lsfOCH*xPIPJ5@uA1q|dpY(1ytB}BhS4>s>7w{TJ>W7>v=s$a{1c!;d-S?agSU9n8F2z6t& zxq}0NF$#|jU9D9-T=hadrFLa#AsZL4vTMgY0=r8R-KnG*jlvOKCvXrmzZY`tE?`J; z%;faQyar3tNn2ke5O&YQrNG-t6Z8|>jkd?rzKsd2{&Wx?$CFw!ADLwlbw$s;G-uAH z6xRp_lNRaGoE#Y+fss7c!IF*IJC7g?xb9$Pb~?5})JLvk z2RoT*l(13hlzr!lW{PM}HCpS9uA7)v)l#argFDzPBudwdmBt!wzeqLD6%DfwLg{5& zwZBv2M;*Xy*@es_qfwZU(!?kqdtsrflusPW&1^m<9>9olSCiR3&Ro0GP#?B5?*ZGLIJ-Y*#s&#nz`tD4tVk zo9R3T*dxvUD&hcJh_Xyy1PqOSXKW*%P*fQ$9VReTo9##oAA*E~ZHFgoxRi}DzbtEr zd3wOHHhWDCj%xY6!lqg8I5!IWnIkl3vNT!|E0ZPRwtC%* zy0(@J;c)74b+nY3g_(4%PFGlQZWxOb6-7iXSmQtuKv^XnAO@u^uFeUKLuOqo?HL4_ z$TOAc&N!>@Mf;?bvE(|lVrZ=wT3$3G?R_n=yZ=3vqhb@=<+8?p3(05j7&yg-$Rkd811h`QCtQwy%L;{EHuA+5`;E1Py!)WRrHo=3^`sZp0eAs6 zMaUG%R+sXHm^(Rb6bSj?758SVUfoujvB}j&154kt*q9njx-(XMvbnxKJlW9NsPosm zcH$3gUtR~7rMcC(i))%sBW%WjFp$#4lXOIeKlxN?Sdm!6$-3_DSK1~pTbguf_bm1m z$TK2E%0{b)Poskfb3_o(Xqh~;#+$h2*2%VxHdgDWV6tr#+X*NwSRSXbJ35J~S&oJt zN|jWZiwzB>ok6d0WVO*~mFsl7I<`DoW=1ZiiZaCv0(X5Im~nWuIJx|BlgHr3PdC~i zqY(S}wm4>9O*T3!-TL|}c2zZ2u%NV2CM$P(yyZNJ&PLlvmwka-&U?YMtM&XB+Q607 z1~JQmTjF6bV;3O?`z5>4hYNK5Xw4HN5s`IL%!0FR0!RiyrDvP;4v#EtDUU$ zS>|RdhuyFlMRYVK3W<^1+yXW9ZP0igLea^VimguL4QQ1m4%844ZbU$5IK13^Lqo$b5baelfejP`}&Z9LpbJ z@nL;AY8gG^%vI{oDlO4KA+=;+bA}|WE>)RY*{rEqc;X;gn2CMFz)L{hkzqzk&_=8_ z^E3Id!wwf4ax$ZFhF?a^iq&~I#5`YloE%(caKf+;6Q>(7rgGE%hD*pVovP!~j3u8- z3jA;a?Yng0LSu96ue3X~vY9^x%Y>Xr!L;1WRcd%mn^`*b zvtMfi>}BeFN;Gl8=-kb5GvqF@x45M&Dz4H{oKSRo6rvVIzTyICqm;d;pDU#DGtmc;{UjYOB?!)DCB z;i_{F^NJ{ZW8M<&lTr>>Ct1d&>h4Y8z6INyLzPXX7H2KZPH=h#3sJ^iVX;wKiTWfd zH>nQOIne@h+lU+W58#(NhRC{RqgqQb5ooQGeCU$}_&0ask|YNQx1fh9J?h`TGzs@s2B;$dC~T?61X&ub)gCgWX9Zl2{V zo+@0lG0w1VX2k(x0)@L*M+wzd|fW&8**k6Pjg07~1T)L~B)NdU%247$1!6W`ZiAO;fy~mEpvc z#ayztR^=nVc_T=8CTlKqhzWhF*&Z9v>1Z_9Mm`H?`bu~zIx;9VY{7?Ao|!B$aeOiO zzuo9H_~OMin=O;zu2fl)Cho?hTMr{hRB75gc2e|v)TizWlA40s{NSV}pig!ry zXDu9E8@ZLjGT^GS53KpJ-DV;8$klMtBfL23xW;OO?qLsezIpUdMaDf{P0g-(%4?U2 zl_c?_O#K_9&VmSv&d@E%%u>akCF{|$3TtExRg&vSisYn`#+U{4W2d{>7Zw3kteClD68)Nej8Ox)Rs|`IN;5H~ zCb#uuLX|rY<4#htsEq*k4u=fm7%q2Ucc`V|u8D(t*m918VzDZ9w~tHf?6YVcGq1#C z2)pQ425F~7hL)App}I!ho`DZz910eXuXCU88XSI73#B5*IFR=fvTj*S*+9!BUKS(o zzlaLH;_jy`Q!N-Jz)EXijDzXZ?QjIFd8Bh@ArG0pxqXQI5G=EQ{G$YIWss;hNe zRhD9TCrjuz>HZvnn{S_m^QcbqMA(p3dC2K-K}+8cF<|J+FE@%<+S0$9q_HDh{E%t& zaYh-ryRw02>k3uLhB$Dvo=IJ3@F7%%&YP*3@m#|R8u_nq>bqZmNZ=uwD060NU^LHg z&6_-%sTVbPw29{N+BBh1#dDNlg>#&PsMPZJptTFdvqdg%v^>hM-R>cf z?02^jd$HVYGy?Fo##*n@kNl=nx`G#{7kjNnJNVt}ckzGdH_laWw)@M$o91GteX0f^ zh*|I!>Vdtg!JF96$wr^{SG~A{wK@dD7Tdi(g^d=+xmnfK&Y-naL{w$Bp+GnRXAYc# zFGRiLjo_vPdHR?sDSxKfGrgax_f4-y2mL;_Gffr8^JScc(GwCUqoQ-Q8g>NMCO~8r zi6Gvfc`#)c)g_hUWeMSq5-cxs0Cf6M4tUk>U)ZD~kGX(j2`g_6m35 zfFImco~z{XqC7uG@7ffLiZFoSl?nZ^Y1rZYnn)PEqH9 zq3b+2L{3rXFgde#rc%J!yHn>B#NC~xp*pV;_zWGR^A5pCI`0syr1Oe;_imuQ!{r@< zi8ancu(8f7nd-=7v8DzI8r786NxoMEN~Q=j_TG?85qb6*QbZn8iUBcr@7pHC#CuW6 zo=7F(9HtagW5Ri&jS(pZ#43X|4Dlw^REjl|^lS9&nF9zzA>s@$Q)ZPSnz%bc7L_Kb zZ%#9jGny|-P?csPsY)|(h)NUrqMV@8OkASU3`7}gb#Pk0RC-}_k9xltfB*b_dk*d06@2y_ z+<)-Eo_+iG-xj>1r#-uOA3S()*RIAuBH&;G=-PCRhUrreh=$noda zr7jk4Pc_7^Ty75@UUQrJCI8*AGk5D!W)RA27Lx6kWXT+Ol;Ga8kJ4bIl z0rySl^ZwAYdb~SV{_w42BB~eo_t)|Ff!F48_1B4)SK^;L2(B9iycF-R`&j{_zVFz1 z#~pFFYmxXo54fiSuHXT;6L2s0fI9@Zbx*io_kg3W__7Ba(dEfMhp*6w=|VT#-LTeH zuW#Oz%iRFD($9-GMCV;Q%P+q*2KQ>b-|_lf?x*obpG)v(g6rV@wg+>$0siQt;bQ&v zB&2;)!Z0AdO!!@g_nUqJb>WXbK-XCBGx7ch08>hVyA^N?fO&Na9ErnEOBg)z$JE|u zBjt5~dw)uK*8}dOfcZ)a+*<+nO~5?x20Y-i4S%M3iJu<_%->45%@(*Fc>isJc_aSt zvC)sp+X0woNjO(|w*e+E;cVqmy@vra?*Uf>OfvEqKB$d%~UaguBlZ?mf;lAbx_iazOZEwp(KGylKC)`b*a0fl%COqL5JmHo-;ZB+0V*c1! zQ0_j!eNMt|#c%ds#r*R9O}X5Kznshc$gc=eUxt6~*a^RUth{NwzwlRcxjFpN=R*9M z%4?y#Uj)pyhZ&6hyQcDf7;rxhm=FD$fFu8ysk|Hs_L}%Pi$xiF$wV z-MQS%Zwt7q@Qw3{tz(F`k;WL zcA3g+;{CIKHwZQL9fO+oY0#4%>EAQWs{MUf_ zi$4}{)W4>BsXwm#lU(ldKNWB`{MLbA4KSblgn-k08mpJ&_oaUZp82F3ZWVCVPvvsI z`)N1aYXCR-nOyF(pLN6SC;a|Am;1TT2{>Cjo(H(E0Os<)5OA9RV(r)uI^PDElV1>U zHafo+Hl_iJBr!@U}C7ypl3?q~km4Yvfie*w&qzj4Fe z0l41<%zyl?fV0u%4S+lR70~AI1f14uF}fTA+)KX-I)BYwUJh_y0nAsvF5oo(or$im z5m;3cY2n03~&vP@?Pax-Z{Yif=7Ap z^(^m0fP37dysvwf_s@X)kCgJL->>~fKzDkw^~a5X+aqCZ{Xyl;dY1Q6z^$Z|w;ko( z>sj6dfO}&~dDo!4_W|aUaX172eG@R>jl;$GkL-{q{{zNC{Lx3##ZX=WFn7k`V&zeL zI}(Nq#FwofcbtL&Vb+3|0$Py z4*uw)=@P?_+B*rDBXKxGc>}=Q6NihHN9}!!grR!rV{7lP0q#91dgaY%>(Wpz`WA~?jwNtW(pj&W79w9atH879~*uIR|L$DdBD96 zFdz4T`vPDt{hwT|v)=0gGw%V{1k6JoaPJ1pS5x2)0j=)>X3rCD{0Oc9m>)}lBR+T? zU_O)rw;OPu2F#}a<*t|d<0`-uJ>XsjnAfGiQ9Iram@lQkQN2$9=Ei?X$M1H)tfjzF zz4rj-10Han0L<2Jx$7nRT??3E3LN#v%K&q~2i!w|c{~MfKg#ag5BRv`JP(*b3LMpYKVUwR0{23|eGV`q-=SLF z_1*}WV<~XdziWVbC$fO#SXj_TbC=gRHmV8O>FN7I10Ck2k$`+C59 zA_b1>{Tsks^*yT9UN4pR9Kh5);0Azsrw80e0Q21xxEG?{OaC|YF8=7_qRYzw^STr` z>W{Yr=5r}<)W6>V%vIl~TJ7~xdCvjNF%P&kz&w-!NAM3x<2Lr&oBL$A?{SaWjnF2@UZQ8UccL0C%ap6}4%)kTge!#pp1&;8095CPY zfV*__rreA0=faQ5yAv??c)-0LFdz4T`vPDtx*)yYrvqj>1&-)k2h8g|;NAh4FL}T{ z0hk-NxbdTUZwJhp2i!e?d9MfD5p44*}-m9&ld(%%%&|@w*BzFY$WF#C1*A@7+ zuEYkK+=U~*dIe)xEaQxc>fzeNe5sUsihRE*H-`85v9Ut6S{pCS6bs|I>t)(zPMawl zDO73;g-W$JJ5wthEmr5M8sq{7nJtYcK~xP}L@D{{LTzkzW};Lao5R*dfz?({o2$%M z=ctC_L~$%XN7anYPM2qA3Nv%H>0-57oSDo$S7zD9SqeuBwQ8X>f%8%(fl#3$vdtBz z3$yccxu;3s3mJHRrkbB9)aGVu`O(?RT<#i~x?NyaD2$_+(b?I#+*6VAQ=rzS+-PxT zygFAw&9$jQ9?h%fcFDxe;Y6ZbnXsHLRM9&k`vqZ$!qK@(zBXSeF;-OimT+<@KQlR> zpDgIqt>M)9YN0X%(&^M~;nZ@zT0Jsb8P^qG7*3tf*UH7Cg;G^#-X2RHn=Q>&m_-P! zi^8e1)!Z{=Yj%X+6GAnhJ2RKNL8f0EPM7p3%#6+AK$FR8?m7u|Nf@d;iw+-~ojqJE zT8=jZZF+1!&Q%w=I1BB@HaJe)wMx;$Iv*cnckDCH+>)U(73v!gFAfE86M zM#6yQxr%@T$IhVxH7%|PLmeHj)MhKi$>NOWjVr_HBhzgi) ze0GevLm_fi7@#;)oGa!_wTWV>zQ4bRIX7M^d2ca9CpDX09kO>!v1nvfsPXgW|-ik3$xm`_(q3->KrVN5x(~RY3W@n(n zOU0KII2R>umWdOUVqs>ybWG>EKqjF7<}1`yB+x`T%C$u%N(m8Uy$MYBj%$f9^r3N6 zoQs6hn8w1Fvk*^FAzNi3x{cJ0l(0=Ec#RWv3Cy zc2#5n3XVY}0MVWRE|LHw^tFk~?6g+>l)6KvqNyU0b;Ff1@5M5eMiZ77%5sT(3B`*c zQop`by&jt?Oy^-5i0Us>uZs{N)!fVF%kkOiJd~9p&rbQeG%H43mLRHfL=~cXMrKsy zT_MwD(@C&ChHPMi>O71HHl?_*H}l&&=L?l%upG)oIZQ)rh2E$1%{h@yV|Q(KqE^b& z*f51*QHTn`Tp(ds9m6P4!wa(u0c?o@u%MB2QsP#b2vtxiRHu0Sr}x|Rdx!{zg@P{b zLRDOTrZ$sbC{7Z>#F~_CyG(?>t=47=a~OdS>oPBriQt{FJi2C_hX%^FBS<05k}s7C zu(#$a$9M!Jh>HUVkr$&&Z8~2rqZE>Qg1IDIIYa5HFAcJ@NELWwr%acHQeX)&ztj86 z!-Y-3j+(6;n_y#(?Zfv21Y*|c;_+HCX|fSpl(T*P;x$;d%GZ8 zC>g1F78;r%392zIMY9QSk|;_Pc!v^I!T%AXSSf!D=6!9S>@G?UQ%olB$A`O<(!(T^ z>3a?wIH1$RG?VE_7X3;2!$ec*2ZQWkqRHe#_^^mk_Au3C`rbXe>A&2KX#Mv9vgPj0 zmt1j`mYIp!%5;9NMr^?i34>LVU?5c-?D8vQbzrT>xo9PpFF4aPs{bz*Old)Ixi(1|4?E$jK0da->L1 zo*Bm^S^*y&MKD!e#N>Q&oGC^9Mii~#L{p6AmyBHYWQEA$^2*vuci-L`oJBRX27@7l z`jU|@)19C|$x36T*~7u+wV6)8xh!uw#`F{|3WLqJyGFq00Xhe+~xB|kC8s8K4W50O-yty-C#g!NZt0VEJi4k93h z@#37W920~{Vg=#_+{nnMyqG9Nl2Q2V1p5Sw;AFDJe;-iT(sP)c4TYKcX*QbZ&^1@^z8V2slcj*USA+z2ZBw;JEd%qDRAjw4ly>x#vUbXl?h|BV=$$w zJng0T+vI!9&ho+A3+3DS8Ja?mpzvP@EOfwFZEUI{6`X-%wdv{@JP1&aJUiE~ zuG!9D6e_hO*g| zd-3e3bVbozqJ|j~`$^|2vn4Q2eiY2G7X=XTW+(7;{%CC!0)3=74tLWnGS3!go^kYN zZ7x5_%AcyZ&cAAkF=mTYiz&)2^(oZ9F|Bpo-fe|yf9nBgg5k-_C|D7?E6>h#~mtoHkuCq@l=3OIht51U`$ik-Wg5fLP>Q|p_OPFFeN82rBtIS z7>bB`W2HjA!gFGRnTx_4riG$~;<#`W5Wsu_U>d7s#WK8kWIq$gLK37nGcVReDE&wx zy<9@F%6>GF%+6@t_+yFmJv!|riL|{s?WKvdeLC%UB5l7;ds!mwfKL0r5@`o@S}l=w zn@)RqBJGe)t0&TK*J&pbX}fjTEhf@vJen1YctrO`6ad~NtibVVndZplC`fr03x2wS zm1rV(qi`q2)2bGQ)hNKko_#v08Bf~JqW?=gc8<-`;>KtmRwFah+!StU7?+bL!u%ES z+y`{QC*w&6by6#ybem3Eizgk@N$q%2p!GVjq`iUGTaPCNTJNrS(q3IxH=Yy_OkA{} z$C`<~!f`~@5SK0JBrJfA(JF~j4ufc+Q-xAlr=5zXVKHD{E6CH)G_0x8qL?c6Oe}S7 zwye44Y&0!DNv>s;@s-iUc}yX6`+p>whGyt&KN?G#EsNy>BEXMD(_rm|n*Za`#0i+) zy3n79rcD#sl-jvFnkEbnXiqi#++#{-&8tedHwppyp!JqKuPYJS_a)MW{N$_qckkAC zyfF%ur-?lzLwD0JM$=&!R|%;uwq4k9RkS4mX!ekE2ER;dEQ{Ax6@a5S9wu4p3q72QSi zKO)S#4T-yRH_O!Dj;78{VQLK9wi*!VCJFhTC?qCaMNE$aI5mj>P81I7WwfMujI3UE zBN9&UHN#ZrM;S~N^+*&9?II%sJ%@=sc?YPd_a$K1N)bS+p!X+$sG!jbd7o54A4tG( zK>|n-^MeVXx%{ZMUw$`{Itm{%=DeszG1KoQVDdWcLy5Feo%Z{Qv@xCb2Z^*mqkK4# z7U1%cMB0RAn~x^ajzU_LCV4cGDn??Zi$0c2FJSJ2HFPDfA5TD($m5|3cr1|&j|c>( zqKW;735fhOB$K#T^VuIIV8%yF0T_ib5Dz_`0K@7fX3zQ3C@fDBWP ziB(Q&=%-B}@Bz_em6o3g<})UksHOf{6G(o1Tn{&YZUTS~fXiA2yHHJ^GeK#SUP<`p zO;B=XpkV$Y0Yhf}G@Jg4`2RftBO0ZuzVsVt>hY01rOaQ@ynaAp>s^yCbfY~vu zvTE-Ct305mrL66qFGrzDV{Cmwio~)FJ%p|)c{b&`k4mUW&mKzP6^Y6QGjWy zjvUd=zbKl7u!(??c0|)4!ejF#wtEySUL1o!Fe8l4U`};OG(8VbC#K`@;VMObX##+K z6Ds+#L^6$un$s^&B*RH|BroFxsRwr^Aej1UpcqLctI!E0_E#hz5I=c%I$t?l)#7wz z6lRo%e#FyM*?v|fJ;??ID_kjvtD-RE@&+$dj}*!8tp=Q{qdU zB=0ss<~E5^Nx|rMoB3TO@@|WOBW0uEwhK6VM?pJO-sZb=ck^4}^5Z$hh44^g-KTT9 z(WPMP>H3-G8W#U3%WK)EFph{MUUGpCUzlX{ep61rrzHXU!NpP9<{%9&drl%1NJ$q2 zNwh>pA;~Oal(r>ED^8O~r8tMKL`W&O>0N-xaZn^W2(c&BPI|XVy+i!MPWf&#zr$(? z3;%BQ7z0-;HVHwO2z6- zBvl2+1wJ8y!eUJTg>YX?M`^)VRDeaBAW_D5QiK!<5M{>VO^_}gC!j&$+j$-!9tH#& zF*`k38bwqX#ZObn_xLQ9wQI1Y+0YNrCjp$$Km7=OrI~5oNVl+34DYv8?yELdOwOc`!BX)i8>NBOPT?(8k zHux0AlVl~w8G)+}3k)u55|OeLlEpFpG{h04+P1)un4$4z6SjmXRqa^dRH6=APqm7{ zrNW~S!97LpY!LO)R*#uE(!8@(?7Enp!CnM(t>*8ihM`65Ri!|BKsAWH8dUDn!jP;C z;gS_W0@%%gfl{&C)5Cy8skQ?aqVbl>dqx;cs09k&(Td}`a5^q8)(9y9*%byrR~|h! z4zoch7aFvwlIz1TVjB;_+$Lc;DE;)zFof8>gNX|UAEhpy6$O}vlWwk7o`rct`!Eom zwg8o>+I~Y6nDzqINU>6o4!{&o+-L$r90slVi&2hzNz{OwtdOELx_h2&1*`~5UX^&W z6%aI>F3)L(dyW+l&UUz=l-~FOD;%j`1W(CXHZ|wDVOU8-ERjv<;pBM{fPH1TQBC*8 zE#Y*;s`LIm*=@QvD6WudyEP0LB3VPMwZ z6v&U2d=6_Qh&>UAgd{5Mno}dl-Y`6~JM0Ne3X3z?FNpA2h^^AU`@*2*`O#9bItAUU zRlj1i{b4vc#U$$>fK;0LKp3)GEzKXLO#-8|u8u~NiAzm77=hwt3Es>`Momzrg1#*R zJyV>Rz^=r^Fs0=AP#F5)engwYbd~XKWJyu|5g6K3p&94)aBhej;Wl0qi&2#G1;+F} zI{yzE(?tY5<$s|ueV@+%B4fG;*{1wIWK0(^*OdOl#`J@_{5y>4x9Rk}F9_0rW5)EnP9Ha>kLvV-F?~#@PZ-lhgbCp{X-p67%qe5~gx2FlV>+UFl%jvJ8DNhF zIBW(GOM`@B$qcX$mecl;KCJ6zyN|%xe(qBFyUH&xE!sY^fH?(kc%&Ucm}G4qxgT5U zOXcxm0a5`k_QiO01?GZtXV)7rueOg|j{*lMV9!C6cr9MgOp)w&73M4FhE(~_U`Eof zuaIfYppT>M;&_v;UM;rQ2mJ!>eqHP{p1WkRha{d)!+fz+hLd8PvD$-5Fi{gR(nm0V z+dgsvg()|KC`SP;_`Vi5w*i4LB>h_U;GS*D@%5w_|QO5ETz&;bG%wxS{ z5-zCiBim6k(L)A(Ph%bIXM_`O?AGwVwIW~@+)|i3`ay}RDpUv-q zI^u&6VwWuZz+#5X4gY!3%9({i31%!~v@G)ra56^4HU^lY+ea=|mC6dK z%czqH2kv76x>~j=OwQ*itbhtoKwVD(1wlNpD50T~t^mW4Y3a%5&4O&Md6Bfkd$o#=F0u-j2PT1DG{MZ~=fNGF#26x0C( zPHhuop`{N0Pi`t!vnQdttG>+9<{)PQj!r!^&17whfC&QgQGVvyG zU*LBX>5O+Y$dZGMaVPI&3F90>)?j^Z=fHbJ=37GUDW0Cimef?34iI}%AYcj7UaV`V z%l-^C7U$b1+t>rg!b^PkztK48hJZh$I8XuT&0M$Fd}RY_h1A0j$({*`JNL4VFMjw1eiM%n~oVPO^KW-RpE&WC#P= zo>JrShXm-ORFiBA_6adov@L^3E_T{XwCXE8)(v|YTj;*9{$QU0aU_xLG;Ve8f+J}J zrY$bm{3L_gNl6g|pEN-vdS9s57m5hx;Hf#Ows)Xg(VFS%B#X))6T^)K9A}~}=AGL| zXwwRzEyk*u(6*Ivx|^JEWF3XTmnuA<)cVgzrHBSmNHz-w#iNH9Hxcj6f$Pse<_n3C zbY6l89wLt~%{viOLz`y7D4`ZkVh&KwQ}Bo2cN4o)=a5<#TAhUJ8e)EB90=h*f+@-N zkxSxIG1nO^uCCXYCZOvY-C}#W!+iLgvVB4bR0*Un2sw#_!i{jIT|zN^!EO0hE{M85 z7*&X%PXZ!MvUsF*!y-lzT+=K{#O;(hqa8laJA{v9V67?$lCuX0X=iHW$Ym%guJ9$9jcK#Br8U>aib%Q$0*b)*2+D zFGoG4@)!*Q%mrkJ<#Ff-#&t>_Aug`sP=q-)^{7yo6mZ><_kfkdDv+U)c@rLY>rYEU z7L-Lu*2qFs!xt9Fo4^`}I*GjLR7j)S?R0rSC(eF@P#>@}c;;I;Dtdv|9D(jqoA`i#;Ycd#A;Ktu5RD*D*5t${7&g*Eh92o(8n{Dkks~+Nu?uxzAs$Yr z8I}(sXqcKLMYIY69W9nYa@3X`AR$SN*g_hYgB^e%y{?oxjhH2AMv!FD)+UsP4q}6g zNJ_$1UYLc!bOV09AlV)am$3cyq=Ibc2^6EuDCSHuzrY^t4)hZhdKZ2l;c=6G?V>7J zKaoCv393*Hi1!649%5r+l0I)t1zywvPhz~F7{fz2wU&liIzx!WvW=F93>A$sY1}sh zWinOx{EAs##bgz55cI_BG6LMm=>qbx`XpT&JE;UsqaHsDOiWWYHYbV3v>;CSA8wpo z>nt&OPc%mHflzoXeE(Pf2CLj$n@u`_oU?WQN_a((e+ zW2sa>+ZpsZp+j91ANfd^@yrUN4_4c0o=3-70ISeR7Hn9N+|V!v)OZ}DUf)j=L6uF` z*BTg`)l`HC{e@>lvF31uQsY#k#ikpb?1NfxV#*AxKdyl)rxFbX5}KqKj);Mm>i!`> z!f(NQo25adji6WFgifc48pamlKss=ON*!(X*XrxD-6br5lZ@X3lF-ar=yhU2=*p-u zUS-pgNlilx?OBF4GVWI984-&h2^|xOm@=wdxZ@v`9j{max#M5U(kY~jM-_^N0F5wR zWR*cgxC=#>MA@Vbh$b{CX49RhPWV$xl}9IpK4mA3QxYnN7>6X7M?AuM30c`FVY`Z^ znB29IIVKqsw9yk-QHThmMV$N{#dI_(b7!jB#99*T2-*=G-4Be7lJj)n)btz#2D)D;a3QPIt8@?uwN-Gs=v5jX>8K2PpYL|-XM@h3Ve&$IvmH!h?;?s1>4MPM zOOv*rlS7yG1PH}{h$Wc_FXyH-G?0i!&{xANGY-{77Fz^Dn`}gTQiVbfQYTX62PiyQ znjOVPPaK<9m_h&pNL6J%`6TvEQ~T%y07m90^&Hz$JOZHkIboWR%w9>%NQNVn4)Oe3 zMd4U(!=?aMk))Lr4-sAI3@cPmhiYL}U(lPlWgT!lun^GC0*L3IbfT3s6No!rD>AD{ zBF3+VcVvh_8oz}y%9|(q{QLjHqEP@4fHT z2mkW3x$peQ$FI2OOfL76{J!&==f3Cb)vtW)qfgy>+xx$AWIHaWSO=@A3ym# z9GLzuphIa3zHq>1x!YOk*4K7T;E2oKuA9#sI{2L9@<@qYhnxN0@jbhb7u$=i!BPW{ zICOK*?YsByxpnvP9;UX9rQ^MRx87>5v~OMYIj*xQOCpYJw3nK7nQv$;28-SP@x=~2 z&E0+t=KX4RJjhF(Jy);4gvN+`8^azH#4PoEl%(m|>E)qxggw=XAIa(vF<%br+AT$tJal&X_fxH@mnY`C`sq!_2(1 zQ7)7H2vm7yC$oT$fq5-x8dm)e)o3yv?KSU&&MUR{O)e~v?KT1^Us*>Jn_kqpZb#= zdBQOQ{QvVqG`t;un_%?OiZMOy!uLLYx*6Z2{6q~X@Y5lDPw~?o_&&@}^m~S%%J{yM zpN`^tj-OtR?<4%Qitm^3(>lIi#!qMP{c?V~8{dok^i%j==BL-=Rusd1{g*sx}!u~wmxn|jqh z-TbN-0eMKttFM5)GIfrmDmQii@f&tc-TQcd>)-Rwa}Zi|?Bn;#RPoOPr5kon-9LWA zZUIC;CAdfrb4Q8S)=5ntI^y%`y`TIydz+`Gbl+_r^1* zcj{bmXYf)y0X-^j@UAI=+0;40mr$9y_rv|t-Dj@J^$)!2jHqiWsB6kt7qUHe$2F*k z@}Ik#E0tvperM`cAG`TcSeLAVwz5JXC9?&gpa>v>X|@HSM?$%6!7(xdZVL+rDZDMr z@G}fo!S5sdbPP|T6k^)v@w*?z(-J@ZB%V(2)6e6H?gHL|n^X{e#ZT|iPangRsDr4o z$f;z^)%l6+fZf!#k(W{Vugz68cZ% zzkfY-@An5^o;nBUeP6s?0iho|9HvN1KipCEA}NILBL%vee@#KBXFfN=S55Q z>!%`~NbTcHDSQh!68kpe|8hLtg1;>+XH9`}pur$~Da>Q1>qI z(=~V^WVXX0B(&oe_(5^mET=;4BbtX$C2~B6-@O1&f*fObTH|*mJP9I@j(i2btK*6E znh2VH@$9iGc7GnOiDMqnt=uy}6oR;O`L$E$?x!yPKK&m2uSYLHMnP#QME5@a<5ygM z-8k_B%fR;^zxVN<_?M}3ckJ|qWr^E*`6GAS_$ZSkl<%Wdtf1*UeKH=V* zy8kEN4_ZKT3`X`nPO4-#@oeoIc$wSxnf&_+a_Zb43E*=A_}phN-+95*xldj`l4G5A zc`RS-C-sCN_8~mo$h|j@r{`(=0ztox6wdd)50_iHk137hgHX zZ6_X%F$kF?Wq$eqP2@P0be1UIS-?wl0e4ypFcoTgCo3Wyd_@x7M+wW9awSi}Q-z`fv=LIx4UYBoX!8Hg6KYHwP5 z@4dIuT1C|?Ra#25My;Z%s{Wt%Ip?nDB%bU0``^57KIeY!`~5k4-uv9+(c*fCOD+rl zvm6Pz=5c&!i6-543_Itt{AbI0%f9+uGOrg+sK4ermsM_r&v!TS*7ManylZIp=XdC~ z@KDnWE|c4F{*jM=E4HxtMVEbbERkP)@u0^@8~)hv%&vbVopYJ(wYHMOR|TqAf*pU{ z9)I3t+4tn%-kS$JKC6+h;imI0Q&)3-X7@h17U=Aav9)J&eXGEd_QRdeyDZ3MS$fK0 z#oktBzl!g_^McE!p%lKa7X+Af!!zH`~y4C%XO!03PGR~Z?grT47i zPRHjwZ{WZ9uMz7O-Oby3tj+y^m6iLtr;iGnS+K*MemgdlzZ>MTKKko;uVvpoKyTqw@UPAmAQHMXq)>U8=ute+3~!~y7iQQQD4pq zeO~-Z#Vg;rtUr$U%v*7%O`h=)MSt^N*I-S_Tz7M}9WuAo^qDnNJQvh_(D!B2KBI3= zy*TN5hnd045BY?RzwoHdN8abAM)*z&I<#&|uU3m&NP#klf%4n^t5W+Oo}J%#qW`$K zmo45l`q?w_c*U|Ab9;oWm{4V2;*F|>T2CKw>uq#o@Z_I`VG{(g+j^_bm(^Ajswa+$h_@~5xQ=CL-{9+?@3oB1yfT0gH>?4w3s zSnAqbXOg|zr!@aZ+FXyaxgKqEeelH9u3dEgAF{d5EOa@n*p2%BE6b!!OIY97 z*<8EZTvxWa{>bLKip_OZo9k*e*VS#VYuH>X{rff1bGMJgXf)S5j0I>=)jr&C*~yhu z{`}_X=9Y9PHhEw@KXVVQ|ilOiYozY2&D*^a1kQQnc*U%4GtLGprW&Vo70(mrH;ZzbVDx zOJAhSNmDy7mv*G%M_#(_?m~gF^d&zY)7np2OW{JU;x0rU&F$$zkMCSuFnWO}Ay(!| z0ZUUCEGOY`rgbV@V+w&|KxKZ7=>v{wM9X0bK}7$ga{zSWKzy+yT|SbrLif^Q$wb&+ zk;I(kACmBjc9_k?Oz$m8ctyLHX4WK0@y^8jgm#_G#F`K7Vwg#D1`GB4nMg-m1BYo^ zKDKxTmy@Nhs!I?qTK!UWnX2xTsynOduBp18RNZ}5hn(epI8xlWzlbH*VFIYEYEa2* zqO2Iu7_|%y>Xm}%OhzpJd|n8r&}#}dy~7Z`D4mXMu@K4R$R>5gnF|Gx-^HX3ck{4y zfX1vKdWySwh{KB{B`N*Tz*r=MNQe9Wbk3*Z!jJbCN%ru#hNTmGKkYTNiNCrYd$8w7$6KS%7B<4ITNtPwKiX;_&%W9IaypCi`lIuw# z{Wg+BQN%g{FN$zESthEwslw%CIjHK6sJaKL?y;()>LKhQ_qe^H6khH}N#Sy0D`+$! z9r;Hl!Dwk=(lwtcZTjA$3qI+jwKNA&#-_B-<3GXM)qhG(+&yXSK>z)xAR=VNyO95c zPehB@n`Wrh^@|k#llVdnUw@di(0w{MBada0h&WpRh%ZfNX(21zm(~DCcJQBc71E#7 zCw<&K-_oiDT{fZ9gU+gSx{5GO@TP|ONIEUgv5N6^aZjL&SRhn;)b1ZiS5}Mex5R=8ahWZD5poKp5_T#dVn&RN4qz1s ztxyx@YDliW%+-cmmFVOPN8U`=ldgevq@`I3A=AZ^3+;iUWk0!mnCmpTs?q6axk3N= z{QC~MsC^|JcAjj-aHYwGV&rJ4O0JKYPN~8TNYloq3b!U5QmrP*#ct$a2d~0xW!QYD zLVX1t6|H@#dogw@g=tBt6?=7vn)2wr)Q$PLL=v_rm?h^_}^NZ0igqTVQyRCr5?dL!}*71>?T&@16OSX|E*6&w(OvNM>CO*v_EAgHZLeZ(v@T(lGRBTAqjtrk;H;(agvcF z>yaEyvJAPDzKEX;B)`YX<*I0+pZ6RvYrb?&OpL)D?= zah$)Z3)FNY|M-S3MD-P|M)Fmw;%y5bUGO7;6sL zr4!vMO{XJ!Zr6;}K(r9Nv#mm|a_p`L{cpBS9;E1iz)85Cmd$euiLTqs>b zmyc~{aZqf1nA3>i?xk!)EURK-hE zeRic=uoz-BT0~7QAZW)3gzMVkx`e3d0XElb#Wmh;)4KHWLJNU-=b`Yx@~2SHvDIS9 zL|SYkiMqX=B-)f6BpZ<2NfM*gT_od3Qd^NZnB)PH!$}?_NgUcd-jcb8myZ0d{ ze42k%(C;f=d1w)mf*>AGpmgP@Q!6>!3GZoBa!~ehV9qnojXCKbD>-ss!pck`Dl_=C zg4NQO{nR6aQeQtOp=a9EVdNnzK;qRttA*YPqdi~nyG$>a_6RjQN;4!CEqadLioH=y z+hoV2#V02*U|$`uFahvRI_(2JC@v{Yyi)1q(ou(jx2|NYBw;I(6j-)(N(A1DW8PJz zJB2O2E+NE(n;%wIw3RCxNkzLT6>UTb5f8B{5r-DRMGM;X3L81 zeB$Y=?m6GsBN?pys;<`lgFZQ#8c!*JZhwYCmKqnJ7P#`^HYS{YwtY= zy2&3`v6}*sMnt90O7p3A-G9ob?ydzZSPJew6F7ysko^>5%e(XSPf?dP`>Un})ADN% z_9hhk@2LOila85h98>cOGY?NF;TzMB4M17Y5J;Wh`T;iYltv#5KZ+7mg)+sFbpy5N z%8^PV?}8oa+X}pSb7YU>_*3B)qyvjShos)^K`zdXBv*fCufKYC2)QueaikA%)At(K z-BIM~%v@8*m51G>#!oy@ysYYOkc<2Ff?Q~79WAfvKYzAN)lB$H({nKpM!|eWXKAwD z#HPWap%wAT4#}l%aI*GhaiENT$Fgb@{; z5XX3hi9sC<9XY9^ZpD5|Nzcjk+nAy`@*n{GZHM%;q{OABC-6qlg)X;1N7DrO>!SL* zk%k3>Xp+&LwKwQ^G0^Wvge4>&P>)uYDddztv)y!TbxL zaeOt_+J&=g=^wRrg{e`Bq#L|l`c;~WEYZ{VhtvVfkZcw%}919*^y)ql6^^j zOmZa22$E>lqDd|#8A}p55Jz%1$=)RQlk7wC7|FgQ(SZa1BT3kOMlyxuTasxcX&PY} zL=t5g;Xp&1KxLjcv~W3DK2~+n!sTSytm?L_x-V7T*QyQ!18(nus{4ri;=1a>YAy#&sE)gRacxs#JQ-MJbZX%nCtL12-mTdRS#NN82JyfB(3Afe@fBK^ezD-?^!ZQ zkt<;I-;U{@c#Y0*%t;?zsDEnzR>~u3BGwEypNtcw_0YgtZ&o8w$STWR^62_0h=15zZC@zfV zBAMa%j7ix7vH(0kG)B1}UfL>Lo#e^MbbAyz~N zW1$Xog@A@wML?lM*W(D!TNJh~ zohj51$VW6O=={>4pyRTIuS3SYXs;-$UgdR-+){%Hq02d!~aUI57T$ich5IL@+F`M8nS9NHjI2Vl+ z$5FV2?z*a@ToyV<;c~KI>5y}2y+UwjsJc0-ZkeiErRuh+x?QU7D^-V@!^3hz)!kBc z>I+h0ZjYILyL%K=8ouRZf)q`urO=kbz4oGGHb`E3JDTy6f z#pWZF;-st1bmho}?02M!#78oD*lSTJ+Vr7R`j1wRzfISkxk5-+klm#gjE!VaqFdUG zWa1fuKkiuOMi=a0O+=@(sFXCNfe^!)!qlZZ5M-na4fjf0ER#sSf0ecDCqc@kQs`bC{IjCuL^S8KU>0nm?%b#5vQlfIz^U#}@03yU6r z->rW!JD%>z3WsQ=Nq0+q#)5psm`xeUQcj3>Es;*VoKztfQZWyE$b=r!k(yzJ(Slqx znGR)#mlJ<-HDo%ZrYCbnsdxL5s}a*BlZ*R-#;6X{eL^l?W=Dy;c`TF2Rg2x7DemUM zl#cnPbzHMa)54}yVs?a*fR1Z9qQnkSDw7A;6v~QJD6v?A@#R)Z3XCha(HL_Y$sg&u zkKICwc3K%p?xPBZLi;CK9Ktceh?UrxB&i3n(0C=YJjuBv8<3nw z(vu{OUNSL;T0j!qMI>Q+DamOhsnN=uPjUrG#Cavjnk4alCoj2hIkCkxu0yJE-C7m5 zQPp8)$zJ#C;6FMeoQm>42Pov0bZ2UH=>5G&Do7n7XkvPf6}H~fMZr(6OGTHhJ5uSb zf038nNk5D|GQ6a2HB#q%ctWvJ|H$Y!^u&T}7o3CP5t*m{O%$qia-r8hyAxUi6{zYIrJb zoQ74SqT7mX?@OZ>Z0yTM5!xD0VK%)9qOc&7Y4}XNzLhFhEB5nXDh^TfiF#TIR72gc(6@@Q@`N{J+m?y&=AH>i>EM5a*+ z3p7S9uB3x^eB^?1?ME6MYe#cOn8fz5%OreB8dfSdZXt17%JfNXE z8+|kA6K_Q<9z}gGqXk3?R!{Bbh?7ElK1n?4SZ* z34m7sxcKOU>k`CWC(C#hH(AxqRdowh9VRE7`?ab=9&;U*(zqWq=@L4cZV6p~RfiJE zabr~7cvYvq&T+!4q?J{!3EpLuMVbkt`K$Bj%Pmw#=(TS&ne`}Uj_fxgXvFxt&)lWd zf?cFZ4QvG6qB2G%vFsNRtc+_T`;XYQ zenjs?%_>FAQl$bfpRS50B#q@0V_}2`=II$2H?QmX{dG*>P?`{SbV4}RQEp>?v7RJ4 zmJKA)xosp_iR31di05XKC>4QfsesGL(p%M`EOFf+RX0@CeXHuut2!l(kCUdkO*iCA zI)t-1ojc?-R=OeYgyhsXiwjls>D1d;)o-h?_5dkdi1_%SQfX=djV(_hn(%aI3pihq z{ci|ZN=UQ_u8hb38B@HNNO5==V(pilk&1oDdHv<@we;0-5f7xf6Um-J|8)*aCgMhm z?W_hLBZ;o-6iLcP%W0BGb6nRUd4eRmG+ZM+aNkp0BTq1(<24m7CpM_#I)sGl(B*O6 zr>gFTs=KA?lsuv332A6hm2|jYiR3Cba;1AQux&TV~3UpSYs)j;p z={3nlB>y4VlH^;Gfh4JnW_E!f8BNlGWFL~bNFu57l0*-Xk7OoEXOg2x79=@|WD$~R z-HVY#Qqyu!<|dLQNbVt7lH^w;%aFWEvMkA;NR}gchhznke~@$|`IuxSlCMb8;&mow zo7G4bCJ8>u7!8tHn^T`KynMsu#C~eSbtutXmmysF*a9`zO;B}HR2=5noQnd+afehL zLeF()Row+uM?J0JQr{|Y<5e9^g@g`y^Nh|Nbo$z~Yo$ns17nrVZp=ylq&j5trI@T* zIAd#8iYf|!lkWssElMX^F~z=(^mL&K41XY%RV#*3h=-1XFry4&_USJ4Ur^q_IhQ2j zvOwfjcXIQ*g3HN*aV6JbjKOuN{#^I1s#DTzEooZWq#4yhcAyTde1DoHrzfSU-7QsQ zt-D3{imn~c_ll^)$0ViEN@WcZYExbYDsCtJl)CE4(EK05iFC?I674k(TGz;g{Fx*y z-z14_`Gq9nbC+aIlCA0F=>``s<6MU_&UF)2+*DO}P}Ln#bxK;IF4>OYc{9r2LR$CU zwB%zK_8k>Gp-3b1%J?OMeoHP!>P1M+k3y{3<)d?GN>EBVW}O%QYF?D3WLJjrMx(r< zIA&?|{Y4v(5s<_Pu`(nQA?5=kly84Jl>=#leAADM==V*TxKBS_Vs8V`?{!$d(a-tV zyQlQ~IX2p+A5F6SYfo67e{eamcU!p*!Qi?~;mSwrv5Ib$s#~Y(j;p#;s_uJLcTLq* zr7&|pux`%%Q1TvYb^$i^$c>mdTq9NE&XOI6Zh#yn=Jn$Ng`HJ zB+HSEC5d_)OefEGxSZ(Go1z;kTu!uRujo*NIc|fh+oI~usJe5i?z*bGsp^p1!e8NX zV&gLOIa$?tj16!go~!YX9a;4`Jl})qvseFHju$qQs*Hd$90*)#p^oPp{{cr>N?k< zu5%sgI@h7Da~*l|7a!xg`QTzGU23mYgzt#kwl$u zLlSk~ha~z6Uy@bDHPRQ?XbXJlt)b)Sg4PV9?MTsKM8Z4|D2c=wE1ak89O zb(dA$Emilcs>8dM++Gvm(%OPYgtC2!A7eNiIq2Nw#+>votG2-A<9DVCg#-1W{M{|A zy?s;}Lk4`P4`WrV_wa+Gkh1@Cu426n2H-`A6<+ApJUoOy5Qs1GSwD9DgYpaa9+5;k zJQn$vKyIFYaM71i=s(wC_RMwjRo!A$hq(*K!6%MW>L%L$W;S&*nRK|{kIoft^p71< z9t0%Cr>QS;yxgJ4bwoOx@oamfE=LSj-en@GG7kunb zri!v>;aGGo%Iu7@c+%it2%Yb#1=>j1RUNdtGJ4spn?~jFJ|-Pl>TN|47({1Q%_EFg zV>oR@?8>gW@zON;%SqSxJnIoU@!rpIN(L7?Q8YM~5o{I^m9+?)i692iO$d)Vkkud> zW2mKcD#ucCpe!LWvxSl#?`0xS=wS()BMv0#O4lhQ(Qc-btVePXNpF%vNcxk^AlZ)O zXp&*#8fEAcx{fFLDaipOhm#yd61d4EN03DR<9Y$fkt9*JI?~C@7F?gvI|ocm7IIZ&!_T|wc>$6i$8y4k9Z9$X2W(so=U z8@A;f^%V1z;dG+j^Fu1<9n-1pz>6DvsZ2Ky#yS})HcS__0YoGzt7$0vH5dw`H7}PS ztJUJluJh5*i9hpGR?C)CFc#4{pU%>B?xpknWlq;tFJ(sgKg7+p44tDqM10SaM6fTC zbR~J2qzB3GNur!yA?ZmH_kBtJK(Z~#>m;$}b%P|@pPxwfBKb2(l%-!tCXxJ=B+9^D zl4$LJCy6w^M-pYI5uLmY!R2I$Qgvv>xNe-PL*LGIU#L2iNUnRT>RzZiCC~8!j_o7a zQiQ@$l+KNmxcrdvJTyHKuNP*q7;d{%gf|{xhu-K(9vsm-C2nAPTvAL%L<+Y6cs|7& znue8E;eF%#^vxO{N#W*)wi5Lv`B8+<_xJMItVH2`L2AUb_BN zvE(P`_7yIzPxB{@kIgs%Z6^*i?3>(}lm2Cs?_nwNeP{=PRQvg#lNt~{NJIUHT`C80 zz0%XISWt{-+X9(pUm?Aw=h-WxOFYN`C9dLP$sC zcMg(e>BKQZq&lbF4BeDQ|k9e zq_O=Cg+8CRx{(=nNcl`3J&qOoQ`xQKS{~!+yOpv){3hHu64x>pur%`5%D(^0+I$pJ ze*AyTRQ!S*g$Y5TaRv7GfC{+@??bHYhZfp+)m}cX5&5`Qxb;wb! zn=V}W*hq!z_Ncl8!sTRXK?#7n`S1)~aFu+_K^ogRH`){BSnH;^vdG6YzRvQ&b8c;V zrHw;rUkIAGXSpK#|6!hGTuU|hm31B=4Q%ULfXJhEB9Ab}<9P%ZpC@zOCv?qq7;$mk zdR2!tO|B~|Tw42yI%nH&>g&~(_vQySC;xytg~_ce1Ha!YP>i(CQSb9>+x|r1PH#bhCls_W!v(Rp!hv7Gg!n@g@su9@p?tqBi21>sW}) zwyDcRJ}(#fjBysvXSjIZ$#v*Exeg;GuA8RncBnekN{;(c)%~pM22d(-Zklju<>57< zY}Y>Yn>yq-fyHq(X&IG~xsq*^cQOKeXcUf6hxv4O zmJg`Cw)L_C>2Q>%b9?sr(0KrL4<^R56{u$MN1waNSV=nnr{RXyo_Qj0;y_rDZWx0# z5V{>A-FA}9PrAJ%F{V5~5^*|25_5*$bn^6sif)OLvS?Pg%u6j8< zNMRVaCer}Mfvp^IS01`gb7|699jz9}Ho)`GRB#vBQyJU^2F+Ck zJ}QH|z@T|H7zkA;57h<*P7?2L^H6aY7-KYsh)0Ny5w9}13yg`J;p}K}Zcy0b{AaEK zAhf2GSB`!vi@U&@&RI_MO@s#dElx8zYpg;ciTA~L=(r24&p8WewwyyTQ&f%wmBC$L zEMz)2_><;j$w_|UP*}L)SgMJ_Rg_$u1=KS-l_M+r)M8R7spPUlv5T>W76$HuU)(Ni z;@36Gk(FH<6(Q$zr2{2TIcR-Gqz!i=rqmYLFi?Y)gI00`gS)_>T42LKm!cf?$-&c~ zyTI7b7;ZUpP)Z_>cqGpc+~qjLle>_noB`BTI+Y_U+ef%<0a5J27tMdo2W}TOtLjoR zE4wFnEKvtUi7u=JgCyqlJeJ&rczmnHGA$RwDh%A^IK+~>5KGPg%9l>%$jUaYa*%&Y zc~R^lmYV;X58N(nj!}%NNF#?FWKYsAWd)`G{9yATgrM*)M?z+4umdb|cMRVXB} z&c#{W1s1KgfTc@KeT-2?IfJ{vc)%D4Ey_Jw<#HBhw$lqa>7b220(>I)PQE@VQG@wv z2|}Nbl`gonUdffN%D9I{zr7>{$9R!Li~UM^d$ryj&#)yT$&y97G(`~ zXy>U2u^AMP1`Ed!l@FK3m(#(9Uyu8baWzi|xITbST^?Gp;VK`l58yZE{E;djE{$KA zt}4AR{+-fOdegpl1Y_Yq`Q`C|OS2>AhfO*NJCq#E&N$T$Tpw-+EdZezS$IBI?ZBnksZLi_ z- zEQv(Z7H`7NX4MW{nw`pYWo$QW?5HWk!?R7b1D9r}23=J%q>+uCF3GfEffgvF_fFLo zT$(L8owBl}1q`f`9OcQuW$Ud7WIF3rY!`vzW= zS-yX%^5N3>u5@Lr3%WK{6lKKWD>}LVaA|xwk8JsE(tA^Uh{VEiOtk}-W=AeFS=&Ly zLU>N9cHq+N$mxN18za1Ecjl1jeze_1D(9b8`EY6cYIIda&J#Z5VChlc2XCa)7bMg; zomFkYrP-3}xNV&3`zWb{IGtDRz@^!-pEkzwc1g7Zmu9CXT~&W?+=LwwD1_;XY6~vS zRxP@!VcwS79$r)J!KK-=Uyj6QgouT3-B9horP-0&W|rpdQ|YJoG*U~;=tMswqXRZ> z(#gv-T$&C0`Q{hiHY%kLJ%(d;ZmV|S`Y=1*eUnqtMVY*-+JQ^6Be(Ik<;X9bwgJc1 z(kwjpR6B5KcI>CIU$}2fUp5&)`aD$az@^!d+fz9_K2%4NQ`lFUSePEGw&40OTi(fu z1L&(Lv`acqZ_EvNzQLv0GLug1+XlV^S(sj^cHq+N*smvk;Q`bP)C;9AG^Io{Td!1G zaDAAqu2F;HQgyceQEkDc*|MMRqW=1Yd&SXG9rEz4Y6~vSRztd~Z>IkGg$F0cr^a>KAr0Ocm=kN2o8zp5)c~J*()%h zJKvceam}ULflIUFO81O?oMOj6G|Vr;uXA7^3rAj+50}PwBffFGXW$10wDk`o2(yu2 zwE>rALyimUmwY<;g-3J>^9uIy3iXL->lNBI5POQ!+ghp}xIWO1H|_1+xf8R4H-&lH z!ll`f^C^q)_yu|exAhHG;#N$x1(#+^?w_)-XI+amv!S#W*yhDOI(DurmLPD9X@~SPkG+U<9if!)e+fhj?H`Nwgnk~8C%p#7w zaiJ|;L)$3!+*NyUY4+qcU9;EKtBY@^h){!_Dykj0G&_~ZBR4~PAnbTk0cAV2M|k;q z^DrA!zU3*5dCD93?R>HseHIJzB}Ekm|YlXBjGUG&{eVFq1u2;vmuYE zbz$J~2<}AwARP5o8*phhvKd4AbV6ECJYWEP`i-_I$8c%<_ok(Yhhn3tY6C9KhAY`O zrlo#9#`ZO4VZhUCUYFp~_;Q_;`26uS`GdG%4W8S9OS9uf_l#|yWJev_(QnR$4Y)KL z@_0(J!NWq95Eft64qTcYSGs3R6WzFjC5ac~`>TAoK7`+u@$n8bPYbv-zMGU5w*J@i zA_%h)tlEIl#aD9l4CSFQ7x~n$e`XC!> zIC`lz;L>c!W!*Mkc=7TQc@wGHf$PKVAV4UmF{&N7G&^#6&pJFPEwIyDwFB4xV21(( zJMpR=xIWwtN)7BJsCMA`AMA+mB&&Ad`fxiaJqS;VY6q_W!Hx(|x@re5&5qoM+UA#d zA&bI-@C;Gyz@^zKMfXa`{Z}}4OQ&0m`-#eh%PzN@o;zIS!ey7+UC$k-0vkSA1;lbjo-?Tu$kY> zRW4i_w>*X0_^gbL-;{9sCenSxdzH$EOXFuBb{22n#Cn{+R^`K`@!iO_alE7Wuf&}N zfrVj%Y6C9KMmA$mUHY+LFdOv66*1O;OS9pYbvWn&M`~JB628HtJulm)+JH;5QI2es zk;_16RN?>wf2YcaOXFwLHgp=89)-seEc|;^E?gS7B;7AA``w8){bs!VDi1D=mrdEB z_nv8eix%9F_lHz2TpBmKvJ*8pEjc-@Z|4Cb%tur{TpHh%?i>36%?%U9J!1mD;AAQn_$x+-%y309v9>i;v>@^sUN;OXFsf-hL_Z z{1fYl?>UtVm&VPeu6d`^(qEz|Vc=g>`EYT57fZ2XYln2~I(Fn=?dA`--Lu}bn8sM& z@^04C>{jqY8a3z{8b{k?rN&{u`+Btp#70{N{QYvS+pv$0Y-zOmTw;+!56C1t9(UYa zZ0ER@OXmDBGU!2EqjTpD1};qb=2DMcExruzndh5@xtfk`d9mOx5A%0CdTmMY!|Bz7 zZ+v#C!q@kE4}Vi_=lPen=bv|c(qhAs)HP*-N{5eIF*$#$m)oa2zBvEHod3>U_-M)6 z+0*{3d2&zaoP6`AMz5=XYxI`mp3bh7u3kIxU$sKV2hKUY`^+DIJli@vt@-+LKje06 z)Ar_~&K}*vhZcM0`zT;Uj|SsT6rZ#I(!HTQryad^=unp>{_9xw+Z##ebh0o&QvqDFvKeaKHXWPr0?jVHzPY;wS>>;m9R17 zv%NJ=eYt+)>!14GnX>*+jN`@V*FQXcRz3AZw}ut}49~Z@!Mt3jA`|YvIJT*1zQLO< zzZ~q8=h@i&Cx2Wr(e?Vjm3D8r^t5n{$J~>BTJ)+pY}Ck4r&-gwwY%M={=_BEYr4mL zxBaij{x2VY`snAU4qYeRc6{Bj$>P9;opLO{6}UdA$33S-$4BR%)v(o%es24ge_gq3 z%+xpKJm2|N8MbZY*sp4CPTgN(<*e{#FT57~wrABA=Ld~0eP8Q*o}*11!k!jO86E#| zNTb~|+}nNf{pMdHXO2Br>+`}j^CrAqesgHPN4cxl?swXC^1QY8JsX{D7JffI|c&!(Sa z2F1>6(6rCdm1o1sz8=xH<@h7cC;#o3v(X}lJ)^%#d*W;v*7l3(1wXA`t@3Z5cDwiY z@vdv1tmt_1^YF@k7e=?8;XU8sX!<9-iMnf9I-sx;Hs}flM;>{=Dc2TX!N(um&Zj+by(0NeNjq8_M92!0BxXigrx#^xe`c54B-N(OnIG35<>CEa&H;;YczAV?% zj?1rooSZs!*Drru4=TH}NZCgn%B???+_poxJKvr=_@aD;zO7^5^eBEO zXYMbHRJa|wYG%aWkJd!BY@6QgbdQ7WYp?6rB6#lTKUZf|UhwqI;U6!|$|&qn@Lajh zrvnz&ZBQe*>68UM&+hsz=wQ1B|Mf3E*7?Hq=SQ4+j@)(XabuS$Des=eUU3;U@7|k; z`5Att_uYCJJ=~#k`FC7$+_ujzsmWSucJzKJL^O-NVkE<73(y#d+|23VvV(0!2J*FN$mTD<}YEb8> zRd)*RX)$a3+uSEh)#(=fnNOZ;HEX>|dONGjwQsNYs~zU~^x?R6wYqj`l3Z@ui1NPs zZs)5tzR%OD&lkT8EOL26#n*Li{n~MaCD-|rO*cM#x^X~ef2X%kWAh!J@FIHlq2E60 zlmE*{3cuanqxD+Vo%LzckmuJ&k2%~mhtG~T$0n3GHs{&gdk^MMZ8_oN*q(ph>)*M^ zjo<&6omlPJ(3?|ZiX7`7({Sg-n?H9y_I%-xA0Dh;{d(??jq2~5)aY^3^p94~`1R(_ zu1a{0{1<-x*@3lJlph7% zTQKQx!k<$uuUg-@-mvq0CA?#*#y1^u%AxdzeJ#43{-NVIzlC+uSJ%CH=8ND$-+eW4 zq+_EBQyV>6ve;em?@I2#neC2NXxh}br+eU~%Rl>G-QxT7_ol@ad*xSk%T*wDRJk{i z!(He6&}nYev^KuUTW?0}4*z9v+RUeWCsx~^^JTr3Gp%1=J#p;dtMNngcP{+y$g^52 z=Dr=j?VB<8s^7Wa*uVP42W$4;TyZB~mmU4jxQSzdnj%Eh7 zs}%mj$SyPQdpdpRP_}+h)dIKEtF`-g^XeC6ir)S6?~ni58@RT9$Tvg3iU=S7!-F0E^HhX)lad^AYG0^(rcB96* zZ>($bWqjwk@g1tpv+gap{Y=+=2kZZK{PxAx-F%zZh`YRd%)WotEQ3yB}`X%UO8DgXANphUfb2i-98&qOLeUEAX&W zc%iAoTZHdCv_HH+WaX#BMwOUR@w?2_JuY>BZ}NIp>CiHj_7yog=iRI6XR2Oq@W;s9 zUWI2a&0PJnYo`qbemOh%=!S&)&i(pL`RvAnv30Bc96ztZkShm|&1~PI(|_X&Z{F4M zzO_&1?Xk|@uLE3`oojW)r{^B=zewmPVbotrVeFDdPzHIgE(dUXKE_}Fue!r1Dekfn}=C?WX zZAyrBo1dKH==tjoOH+b+wQ1eA#Iu7tW*k3KCffg2;~o{x{IF_^!@F5cJG-4O_4l{C zFRd#5SU+eF#6Z>P{M+sl_$rI7)_ud&NyZ=+DLHxMMdtA!6 zyG+?OYtF+zUO_i>IH8)J93eOlyF<)DA3jvjV)(~4g7!T(it&tLrazuxiPEKhPg z8}GDl_vYqLeI9NZH-6cM@8*`h5?BAHU)#4GJ8@X8a*GdK8eOnb@herPyXS0adO0v+wE?j4=!6bWZ%m56~k^dDmm`^eSg*) zQfupo>)XbRsFdV*Dsy(4`|66ddN&)^;G6q3UTyVuUhVj4nP;U^9d7wvJY4$8+zd-t z?(SYI?&P|CFy(ZqwzXplH?7fPt9MN60u6@sDEnqt@n!dR#NUj`)#~4`B5JQ0xO8~> zR_C0DjxD_L%krALa)o8S>o{mm>n4pFEZP3oi8G1&RxNz~u;1O^e#!IG3y*qj62cnp zs2;d}Ro7PM3hZd!Wq4YAtGQjjd)|HE$~*2aE0nI}{&>(0=O2$fZuq)k)n=BvJ!kfs zJ}%Swr_UM$ac|kXtozSrR7oPVu+)xDWvgURI^eYK)!o;em?hv~80Kn8|6yIz;F}ciOVjkD zt3n3NaJs@QRl`i9D_2!hoBeE&F6m&_t!v3ugw953yR7o*<6y;_ zB#!3wpN!R5-hu^;k(HY?4pz)4adgWpPp=>-ehm;TV2mu5*7&g}JEksO8>_LfHiQEh zBP%ay9IQwM9JdB1(EA;VUsnYS7$eJxG#cyT$Kxhytb&3LjFFX(u^Q8V935UQ*0I_O z7BJkINumQ?@%+-KYJOx3Q%gj9yi;C=13=Y<+6epCQ(0BK! z@QDbrUsiC8EBU8q6(F^PbqxK7#Z$dD1Zk`@!mk1rTUJ5FN*1gk)wb8yShobLAZO`H z3#%Je%+_&ijP%i!mY0GBj4@uQ!46ie10Xj3Rq|2|R^n9-iARTv6vD!!b+A^X|G

      r|;ZkY(@WEfJm2nA-~%HUF6&5h+9q$NldA{3Z`E5l1=1B_q|&`uRW zY6GFb3|tuj9q4Ssv~4W}DfXM-BOxJy8MrbAI?(w+1$0?&lN zCv^O`80n5xB5>KcdR;;Y1!myN{8HH>R1_C)1*8HH3e3Qj#iatz3}D^YDs6{UCqjW4 zxUvK~(7mXO({2@{P7w;sz!iAUfQsx6j9~GTu*5=2?ACu>FauZCKnL2(@yPFit$npM z!Vn6~z!f+Hp?fxGYC|VT^&=FRfvabi>S`~aSc}#`3WW?<2o#usD{z}b?|ki#=79&k zdWHfB1!mw1xOfBV>PY#}J8=Z5V1xoQa0Si^RAg|EfHm__jvi7y2nA-~$^qy=cSKs# zXuy=bdWM*{!AC+u0yA*s2y~!pidQWIu$ixvC_;f5xB@mbpuqbOu-sg7f$>V&BNUi{ zEATvniX07$V6EWC0WbYZ7`2Cm$I4s>Te^*jQ&;9osM8-xNgaOHlf{DBdygqNdKkjg?RFauW}KnFTwvxZkU zKx!SKzzke@UMgQ;1S{KeBOg*Uz;zQWFauX!KnI$=ExYD%kg`W8FauZKmkJ!g5-3Bv z2dO560++&-572>*<@J2nA-~Dj4XXBHsrI zP?jvVXOP09{I3gU;3@>@Ku6{6#vMLL2_O`hfvXpn>S|qUf{})haz`jI16QG!N*)-& z>X^7q1*sf_0yA(G26Uhqm4934E2PE{3e3RO%S-hD7{N;C@&hgfS7!iBs>>!4n1L(c zHWyfzBVK#Gs*zc!eGt5-k=6&ZZyV8y?V`k$>~Ms?Xl0yA(G0d$}%Z0RWY z{mH9mSc_0#2CgD6l|C?nmHR?10aE{{E}KYT2Ckxj4)pFO89kQ{QbN@KDKG<9;29p8 z^A+v<7LamBC@=$8F_+2)7{S7~aVmjSCqjW4xQYcj&`%x>^{b+(ah70HHF zB0_-~xJtQHs=x@={5N|-NPR&lFauYqKnJ=b`lBu32q^+!c7X+E;3^I1K-bD{f%P#+ zsUj4ZfvfaOr3s8+ee2E{hEzC0ff=~U06Ngs!KfQa98&EF1!mwX^HN{+VGb}+UFauY> zNfTHXcxC`Ax2X9DQY#1rX5i`#(1E^Fk;Ab%0x5Au@R5*^zzkfK0v+f*EZ>0J|Lm_Q zgaR{gRd%V|fe|c|Ua3=PU1JCZX5i{A(1Et0iZ6p8q;4~TkA#E-X5gwE=sLAy8)csRxkKK`1Z-SJglVn)9TgjUkW%=OkEQ2Cm)%9q79v z#=p}3=NvVUP+$hGYAzLULvva7dkHJhx(HeR>w+1$0&a7GbzPlBTR1Z6A*F;+UC(Tr~k5XltCu$zen53PdO{16R$L>S{)5ui#HZ zss*9I3|zHbs;m8#y_?eqsWXHEGjR3cQds~aSer+kz)Qc{h5~H=b-@f=eFQqtJ==Ih zpai5m5DLt|RqLfH1xB#QTiN0vRf$kw2CmwG4s=w~ogeQ)iijOp2vi&J53bsQ4s-{L zc4EB$sbql>tg87*N=OwV6qtdlPM`x_EAO%e<3MT(p}-7WbzLeOU<7NB z!_gX21RVc$!3b+D~N2Nfy zG%}<%5DLt|6)^39XXp)#U==xF=R%5(^RkHqX5gwH=s-&2pQsh2>=6pgz}2Tqr3{Q< z1yMbagj54Uff=|O06Ng`EFph#5{A?kLV+2$8oX3jSG~`zagQKH#|10|3e3RO5YU0% zSI!%p0h8|P__9MNFauY^m+ES63<<_eFF_IUp36fveA#>gwFfWgO2Bsd9t@ zGjKI^sjiNcAQC2aNNph$n1L(cv<^H&U0?)D$)NENQVhKRb-@f=%>W(fj%dy7gCC@x zA{3Z`tJzEC42)o5n?5UqR1QLc8MyiabfCGxFI_?lsb2^MX5eb>Qh5R+Sl{+e@*s7O z@4qgXfvb6-1Kq)PXq9b4$^oIk3|xJ^R4;)MEX`pfW=MTNC@=$8-+&JEd&|dy9RG6$ zzz6m?SYQUO7Jv@){V1J_I(KMYItT@3;OaX}S+;3jCV&B`7=-!`d<|ENKnMDs!+yoN z2ehtkgaR{g1)L@Tl@5$xSvZu$Lkdsezb=@8t0kZVUCmdVlae82jZk0)u6|xBSzrXq zQ&aghqzVuU%)r$$(1B)@S4e*pq&_1Qn1QQbm&y?s!OFeuVGJqa`4J)v& zt7F*=E9yI>bP)>7z}4!das@`Pm=xWCFR#wn=?L|IRNZA@)o9a)@q^3a?(VLOdvRST zZl#ps#obDAcNTYdclX71ad&t32Y54+|GbmQhn4jDojb`%?&KU;mKv*`IcxM;G)Ap9 z&Z#QuJ`^=pJ!e(Y`714JT6d11Dp?VCEj3oXaMtK~SbRow=T;zNRfM9(s+X(=I)9~Q z#nRgTss=z&W7R8Xjb16?Q&pOy>Le63R=qYVf3EZ=R3#|t{LopbvC6sNJ;!iY-O1He zHG`tYs<*5fIe(?)Sf=GCRZWMY#;SMD8vWhQ*LNdp~M-N>%5esIlrhtKLu*`rY!J^Jz=CtEsW-2P@}< z;APl?TXl4-_E6MV^*?8g&HyWargx6EyvqxrsIlrND>)k1W4H30hu5H}vFaDAX3k$} zSyH*^T^%brrW0zc`t7XId&;VFE4!8ml6*s^`9_@7=s; z%~ef>qQyJ?iW;k;v2rdCUcTf`>YU(mHM7CLcU0AfqQ99A+%g+E#|s;W6q)L0dlm2>j( z(rQO|=fKF3e+)&9RqxuSJbj@ma}L*<|ff&y3v(iW;jDunKiw z)b}e==~+6~Mks2mO2|s)`D~lEUsm-SiW;jDv2vy}UjEtAe}$@=e(qXotV+zP1Jv9j zvnQzf8;TmMlCY93yq3Cau&NtS)L502l^nwgG3PsnU5~Zj8y^C621!P}EqJot5lYq$ADN zsLJjfPgXLJ^0Ar@ zb#}`d=gD8@s0dZv)zny(pOrj)`49e)M^zIjYOE^2Dga{@{`B^-s!dSTSXGc!Fw~Q} zZ6m3A3q_4pf3lLJ5x?2-tg7+RZ%n6`SHU>sQLs&ja9{16~$O1BW!anHF=lQJKqV= zLXB0$S;;Y+bu{3ps_IbGSXIJ|)&EW@=dF{m#z9eIRY_KI41=G(s-S8+6g5_rVkL9$ zm-^jTt9k@Qja8*t$-Lpe>uEGqN%3OTSXG9VJUO(OTRys~+ECP3RhAXr7+>{z=Lf19 z2StrlQ9*msO32qQewOCDudfY$%B2~kosIlrVR&w^foc3$4s@qW1SXGQPoK(YOJcuY5`QfqoqAFTUb@9Kk9^@5_tsz$8j7`|y4CxNQtP}Eq}nAK#ARi@sQ&8lMI0;0yMCamT_wH^@A zTU8JgHC8ocH5KZ^_5RIO?T4bqs%EU@s$BiP^IKJk>$@*TjaAKAUBy^QH;pWzstpu1 zRt2yc3f2C>wp6O_K~ZB>3swW6cGg;aOjVu+?rLhR3S{Mc(ZEZYBKJL?i3UJXV^vF5 zfl!+|vH%r~_-#HdK|!`Da?Fv8oj-xu-OL_QttC$_x+$MU7R#td_Yi z>f74${Y_N|ps2B`H7hxLv)^r!Lsc3)8c<_Z8&+~Hcc}UMtg6;f)L7M))p=}T{n(2x ztJ(!cjaBVfZG$Qk{!<)Pc^bQ`sj;d(s~J#-$IpJHY6cWFR&`({Gr-d=)1In&2Strl z9a;6qSiWg~YgCnK;;yE~st{H(&nGw?*jd$BC~BB^&E;CtGcn08Q{m{ z@W)k^Z|1%jHCAfs8i`VWd4t9r7+Eyox2UAL>M z!aFl6E!0@mivI^zx_xW-yIhjJ$dnjtG>Sx9}yS8ivRiy*m7o*0i{;V)v`eHRM+fvmaC~B-4 zz^XU4a7OTq*{XIzQDfCWR?dmeOIWU|4^>5I;jX2|szIz|tax`1-&0iqiW;jzSveOl zFYhLfY@=!-6g5^2W>p*N@$C8ORb7Un#;Pz@rJ>T+`R+M4V&cuG#;PH#LZDXe?(0nX za&8oZqQcP;WpHrBK`w^S{IqQvV}8z6m9dq(ni{Jnu$lw4HbWE7eYp`7HC9bzg-!AOtW$isjjcbFcEu0RB+aST&y&P90yw3==({vIj#^W7PsywJ_F)=v$-f79N74 z#;S#^CPL-|43 z&8qJGw&yw&HC8QU)f4-b>EtVC7iHea(B555jaAE7t%Hj8Bl0&@9igbPYB{U_KN?l$ zEm3tIiW;j{u|L;GzV4X?C5R+HCC-- zCFjPYTlJhzpz)sIh7jt7bUzv0{8qrDF|%qQm*lH`E_zvQ)AUOR&q~S5%tP%RV$&Wv1&W3p%`m@$lwL4K0;Ar z)ecs*pxz(J=J`&~52q(JR_$cvoJPFd$h$40j@1{68mo4(k|&1&`A$0%kDP~Fp{TKH zH!Hcmx-XkhO4Um!YOLDBO75_M(Y?oHCF9oC9~+! zY4q#YvR|{HsIh9l8Ef5`lciNXfTG5#1FU2QX!)w5bMDDl8JxM17HX_I$ZDYbW8bpt z=XR-T4MmMrhgiv#vd?d%=l-%4XMU7QQSmEvTZAmwEhN|-2 z+!v$9s-vt*W2~=n{ST=c14WHh$5_ex6{}JEEUI=wQDfC{R`T8Q^a@7@s|t??C2FiX z!Ag!s!*jU?sA>d7jaC1!s)79~e|gk-RjZ+>vFao%xl&flPgPRYT_|d-I>k!f<#(6T zOjebkhr0>XSaq7!RBU0V#s$}^@`s|vsxz#dx0aW14T6`eS_4ImRcBd+LiIbF)boBt z#@k4ZRsXVbE)QPv&)i;2$MT1w#;X5V$)|v6We=uMH4};&tIn~)A@=#6Z}g0H35pu4 z&YQ8iM$6+oNy@dHvX{Hv)L3`h8PIRHj)Tp|JnQ#lG#;PlrD_ipHCA0?6$mx^-$Bmvr;L@}`4mhGHCA0`C09zWo`akh5ETeTja4^T$@{fx zUB3^i7C}*C)lF8T-A(bGXuf8as&7!#Sapk)yvsoeN7PhR4G$F5Saq9~Y+;Wtr=2-a z_G>5+r*FtdRY#$yvFahK0E`vk^`FiQ$XHSPyQ`_O z>JclMH%=w-^E{=LhoZ)+$E+}|_zGvdwo1nu3q_4pPmG#BJ$eaMm!PPz>ZwuX`tEji zMfNMDb1$QX8mpeMYU2LbcOZ2+=Q~4Dt)Qr}>N%?hP@QgVUZZLO6g5`8U?peN(@7b2 zsJaG4ja4sMmBm;qeixgnDjpt`sIlr5t3asN2}U~?jqFz$C~B;F%_;yYW#upFR1Jcn z#;P~0NBf0*uwEu7kTbq^`NM+>I*AeNWS99V?@%i{)VE)s;{i%N_kdu@*7q6 zp{TLy8!MRss(q?6LsiPb?uJui)pw)zWN5NWRWKAaR{dZl=X^-ov@un!hoZ)+{~48X ze9;K1UO`b~)lZ|&-;T+JyFb~(+`m&})h||Z4F7$)F};q}7K$3HezOX2U({FUR;zNV zmOxQsmGiI8?=qFAl#x+-7FTr-iW;lJv68DYT*17{RAn0CZUQw{g=ZyO_&deb>#ABo zQDapERx%$>xKln@)gmZrtcqyHy4xY^HdWW5sIe*%t3VvXZU3~(q$=@HcQrLuMP?=Q z#?e&KSE{NDMU7QaSjh}fzkJ3iszyUmV^vgEGTUsu+RgKPxF3odtD>=zxwqcR9!)L0dRmE0?TSMBLMnK-L> zISECLRWVrwpz|-A?4ha%!`;=?SQX2ttP$@fP*oa=8mnR(Ri$^W!Kwy8QDapcR<*H( zCD%s0q-r-5HCDxCH6E(ttONN}y@R60s(7sAjLP2n)@M}}Mz}9VjaBhk$r&|Zd4|ZU z`a)4-RRUIBv4xYnM0l)f8x%EGC1e!@)oH>>=N9d(;^ik4HC82J6@V_@iqgGR6(8xY zrpBtotYl`pFuSs|i_R)u`a)4-RT5UXBz&)9d;hf6{ZQ0cm6Vk{Z=8SL$8$H2E)+FZC1)k?a;^ktlc?GaMU7P{SUHzHFFWJyTcPSL6g5_* zWF>c^ch$Fep69FJ!yGkMrD7#V{?XeF-*v2EP}EqJnw88p2{W|zJOiA9qQ`aRcTqZaewUFQ+Bg+dvR9rQWuIEtJ1NWjBelE1EH#>Ls4T@dRC2~ zN}lQNd>87h;^h?-HCAO{)f3&;=gU1R%UE|cHCAP0CGS`43DpD$u__a*+8FD8 z|H|o9t%jn;s?4kcp~`13^hDJ?C~B~zhNs@_6TV^v;Oax@b9)mfq{^91+BsIe*^E15S=HmaUeRck0}tjf za8~iM28tT13b67+H~4v(BC4K2QDap>RyCkDZGHPjRg#JBYHFsqz67HC9z*Rn6T2-|`LK z@4nJcbyrhkRV7w(_TKIN#(8RWR`F5~iW;jbvyyqf!t}bH``2tJYOJclN}f_)WbV>l z$GQSVja5}yRlzn5DHI{5swC6g)zny3jg_49f0keLN>x=TYOJcxsw~Dz*rUZWRsEo- zv8o2E?og8sjohbdB@{JQ)np}4L>0$1@SIU^p{TK{mQk}?Jj zICkX>=ah6-@e&F}ja9W-$&B6n+(&2T6txeE8msEC^2e(;c=W?FW50o-#wveS0Z;=E zy?v)+W%}D)O^sD`jjGzP`AJnRp{TK{9;*%*>t@}O7gQ~TqQ`Rd_PpGOOC~B-~#Ht?D?T3qUs9Fp~ja7|V z$$mY{-!Q$Zn^4qP)r3_5#@cWwjq?J|Dqd2}bpK9`RZUr~LAM~u^Af5WLs4T@Ggif+ zMs5unt!h6MHC8oeC3lC~GnPBwk~yn*c@9O5RROF5(JdU7?uV+>__#@pRV`S_d>FOs zv9qe0LQ!K?AS;>Yudj~inE_@&QDaq0R<*H(4I=OKT$MMVsIe-DmCW-cN7B)DR`C*V zw)=N#tZK!|8Gx5Y9alTAFRB3)HC6?)a!zz!E-c9XTh%%!YOHF_O70HZug7o>r?ZNe z?@-iO)rM67y2&%MMORgPj=P!~tJ<=XBVT4$bkCirFBCOawPPjc;oMJAJ;!i26g5`0 zXVm~(7%SeHhq{GNps2B`1FI%buO0-}P?dJByP6uSIj((lKG*o~k}TQDaqiR&rIA{I)Ee zsyy@E*P_O%9<1b?pS-rZ=V-KsqQSXILo9t%8{Tvcl*YOLzZO3uThrz3l=uh~%4Sk;e} zJa2p{`1yg3^#F<*tNOEQge@FY>5Wr5t9VJi(EU3#Rt;b!`_(L0mKCb%K~ZDXKvr_( z_&lR!5Gk>J$_;R)w;XvE~k~9Ys~dEzR`BeS6*j-JH zRl`^XKy6%oVVSDoP}Ep8oRu>P@>06b_Is)hLs4VZ2v&0ByS1E^MOD-#?rTwF)ks!> z7%Nk;yyI0>f}+N%QLNfQmA^c>f~w(A)L1o|l{203vNcZCRjN)vQDfB@R=uIhq}g{~ z75%^VXraccv8=+}AN#(anVVWwBPeRD8pleuaK?iNi&U+EqQANzK; zzwtrU1So2(n#n2vs(kDa&t2~r6g5`OVigQEc;YPQnsQe05@DtLcWSJf%}TZ~Vy=ac zRQW+sW7Qm1HSp?zBbEGhoZ)+d8|5MtaoYB4^#CKiW;lt z8};%*oUf`1IWrF})L6BEm26?#5BUnI>IX%QRSQ`K@N4>fqq9D*py~h=HC8QR)fK8^ z*)Ky>{e+^%s>Q72?2UCJdOKC+obNhlp~k8utmH}w*f=SbsxeU1ShbXuoKcOh?sOhK zoK?IWgQCW&WvtquyWKYZc2$wrxT~qLYB?);BD&UMpz|G+vx=8WP}Eqpg4JYnIZuW^ zp(+fD8mm^al6SdO!P9kAU4x>=s#UCu9AL)9=SYOGqzN4v!ShbE7K3e!Pe(CHy^f{||`3Xgh zRqI*RLf5BXEYHl=$hp7JLXA}$SjpKt@cQRFI@UxeYOLDGN}d6}{+Ic-s;f}cShb0j zoQE?noc0`zbnD$Mq{gbvtR}iY_FX7bc#)131VxQiTUf~%HMGlwtg3cFQDfCsR&orJ zTram*75{J0oUNe7s%@;~jEZtMc@b5AZg4l88mqRms)GIM^CWgNRqdguv1$jaK&bsk zicVEE4~iPAcCwOtO4Zj7rmMOIMU7RvSOsFNnR}OdR08J?NDDPq?PeuUMA>c~@SGcU zps2BG4=ZP9cnJ#al~%WKJ`^=p?PVo1z?b(QW~urDMU7SaSjo}Iy)tS`RarK<_{uYlUQ^6D1G+w8s=HC7#B zCHItO#luFcY63-#RfmoGx7>=Is%Ah@W7QE>_>kcH_hDks`*jhD8mo@73c%3_YWVD| zj#XfbyP6uSj2RHfE6C+Zgd zf}+N%e^|-A@_#!@d(Qb>Tiq9<#;TL7WZu|!^|a^tuq_ldR-IxcvuL?&$(&QtS;fmd zC~B-a&8il;=F>0(j%Sw)X>ehk7RaJ+g#;Si= zb;lMyNIBZ`UFAe5YOMN?)e5LFt=5dyv93ZY_ps2Cx0xP+eBNd!HO4WHNYOK1*svgGb`!LjVRi@bCuBOJSORQ!*>tRMyWG{( zSas8kwf@RZ=dS9k;>8b&8mn%x@<;dK{qfAIrb1C;)ooT)pr)RhJ5ALoC~B;_!zuu3 z)8PFPRsDpb#;UuloJo+EjoB|azw+X&;-%B2{ytsIlrfD|x@7XPdiJ)g35mta`z!8unz>;YOZM0h#x?tEsW- zC9B?0V=sCCZ0E*M)L8Y3RRgFKg_5n(EnEskja9E%H4_!(p>sH$RlMARqQtSX^P z8&b@<`-n=h-(5|ORc~3z(Fj<3%yZ7yfTG5#cdX>DH}!u-bLm)NP}ErUo|PQKJu%BC zQ1uXs8mm6A3c!A)o8G&Ns$2)$)znz^k<|>SBTfFksHy`LHCBCMC3m9sw}*K?wH;2A zxn#}eKB{&@QDfD2R?fo{FNa!te^uId$X!c~RXD#;WkF#zSSz5n+p}{72l? z)L0dPmCU`JqK{6fY6KKDRz+kb@7ImkiEpbq0Y!~fkyv%d7GCyG*k4sd=i4({sIe+C ztI_U{eZjTrduHsaP}Eozg;gNbVgI9^d*wVRYOIRNY9Q38M!Q0F3vWVEV^uU(@-CV+i)@6V#;O>s#$v1$3mRqA zv3^2PV^vI6vR^N@c>k-hzmB^vMvYam%vjU5t;?fh&4QxFs@SZYTOBVCeztC<>J=0< zR>ff@TR3yoiC(I5pKxD`8mr>68ji7&m-2T`f9KNWr56-6R>fl__mtjcyk2@wcRwZC1`}N@N5zlPX7K$3H60(vR;8M)BA9buvP}EqJ$c%OP z?5awtBA;}(kQ%EJvvLj`FY|kJ@jPSKfTG5#B&_7@9g=sb^HEHW{6r{ftV+tN1I8LW zW1MHdZbDIGRWepGW1oMqc&3h(=9K$l)L50ARTYfYDSn}Os#-x&V^s=P@-Bx?3M!{+ z1{5_`rDQb~V=XU|a*3*YP}EqJij{NVc=?{I)IL>(PrGZWu_`qyIeT;No7YrTCn##H zO2euN#tLis%=3x<1Qaz^rDY}8SC26>J)h_!o^fA{8mrQ=3d2~-ZY>|JTj&o(jaBK5 z8do*sovKAp)L4~)l^ppRNiRBYxSWS?p{TJcBP%(hI?dcxSXITd?uJuiRVG&5v0wW; zK6Jiyk+H@?QDaqRqkbN`8Aa6vC~Bor6KkoO4n>Vs*;&bza;@FBHL5N`QDapORvj=_%)Vvft4j5syP6uS za7@b3eD&Ye#7D-enrt8%fD_ba$vtkSBsK~ZB>ZdP)o+`qfmPt{K-YOKn`Dir&b zduy`Bs*0R*S5sqEURKUD&C97SM?9a2MnF+xRX$d=pcdTE{7uK&2}O-n`B^y+YP@XQ zdAX3PH&E1ARe+VuHY@tJT&t?sdH1!bv8o^|IS;2yO8Y|9G$?AU`jeHM^V{B*9jfXw z6g5^AVkI-c;)olalS|HxxEI_lq{gbkW~@><9+p$p7K$3HiWucrdh`laOQ5K+ivA1? z{eK6ao8s@8H|{`DV^uL$&eX}v+KP>5=~(G5x@)PisyHjTDx0J%wnJ49C~B-K!KxX? zIy&}uH&y$gsIjUfE4fmhM68=w)&HQVv8og+IS>2HnA=@d;Y;o&P-9hTR%5Y+SLcuD zrD`Y?HCB~jC9_TLry=cCU4^2?sb@8? zR#jou0Ar;;_|)^Mtuz!hR#j!y6Y6;XBKdTzzEIRyRgIN=qK|m@hvzfwVJK>>s?N%J zDCFgE(dN#Ri5&S@*W9(#SXF~nZ>V%@{GIRCM1??6V^vL7@;v|hP3h07c0f^MRV`L> zCrX)c#v)bUp{TLyFIIB){+u+wwW=J~-3_P4s@kk%zcS8GbXQe(C~B;#!zu(v<3`UA z=do0d#y%)&tnz0iN8?`pZl19s+;Crv8msEEk{KYylj*f}tnyIQSXGZzAhxh(p4bai z&4QxFs`{)-L-l=H=(VbAP}Eq}fK?dO_A8ACsfu#bT}_Qu4Oz)CY#Hs%V^#H_sIjUM ztCARN-I@D4Rn3N?#;V4w8bJ-q^E9fe<51LC)r3_AsGk?&C07;xmb;o7tD3S3fSTvO zE4He9P}Eq}%#2n1MAMO~IzdrmRdZG{A1-|n;JKFPLs4T@04uqFJ=|KdfR6PNiW;k0 zu#z*X@W7-gRnhMapoJQ%0$IuPVfp2u&Nstyr3{3k#;TUA8n`d&tM}hl=S>i`8HyUK zf>=412QPnx8*xith0UR;v8pwz zV5liu_svx`28tT1+OTQ@b$(0k{;EzvQDaqGR(l94&ZCE@zEIRy)q#~frIg8bXpXAgP}Eq}k(JD%GY4Kzq3S0T zHCBbNaxN-fvZX%bxjU4+=dPv3s!psXLq%-<p<@~2Xw47_ubXhSk;x4+`r!R9^v_P6ADF*Ro%>3ckT@j)Ui%NQDaqiR&q2B z-$?5@^4T7^TS$#nJy>Ls*q`f9#8}zJX_~0Z`OfHI!9Z zsK*Vx|MlWZC~B-4#>x*W=+v!ax`kJusIh7|t13_zZ%p?*IYfTyuBOJS5v)o>E&Gr* zpN>@+iW;j%vXcFp74gwWRjr_?v1$~n+8C?U*M-h086N*O1&SK0MzfOpSI^pe`>6T{ ziW;lNu#%(kyI$0-s=_~W2c^cUv8?1gd|16hYE=cGsIh7stJ2t$*8kk{JXN-bqQVO3tV=&(9oJwHAsRtERGQg0cQyQzf3N8&K3( zHH}qKsCJ__Mpu={x!cl0jaAcGjdXwP%UWsgN>!zysIlsARz0CguUxlT)nq7YteU|} zK1n_Azo4b68&K3(HIr3$j8*Yo?fI(GIN$uxLXB0kSj};N?E9EJb2U|Mps2BGHY?de z|G16zsX78hja744$rfH;@BW$W?$FU*xqqj|s=2J>=_}LB7&UdQzo4kGY91@u!e-H; z*HtwJiW;ltv#Nok5%|7nc2)mDQDfBtR*tdE>^Oo_ke=Kv84WGFJUD)~HrbzN=adMU7RWFPMU7RvSPg`_(tdb*Ra2p;v1&J~=}^H{+mu&z7m6CI_OMz8 zHE&pzbDbT~XCcC~BuVel3#a&B{Rfkw@fa-i}zU-YOFfO zsuuPu(%?qUWFRxZ6)0+~I?ie|)U&i#Q>cph&0S56RVP@Dh04&qPh(Zhp{TLyA67E6 zRli->xvXUiH$hQj)k#+JejPYHe66bYP}Ep;ij{N9^0Ixy!{@3RICpkhsIlraD`&HK z`86u3^X-Ie;T$MxtUAL=o>H1j?&2J6QFoxIvFa?VMi}e(V>7rs-8emW7T<9C9#FCJ6G@= zjROC3S5srv1y%u2F&B<4ren2$qQAGK=nh@T7>UTTs+k zb(vKYY+=RT>&vPt`O{rZja64z1wx(AQo6sYzEIRyb(K|Ds7}#V{HJOs6g5^|W3>co zV5x?6RQZ0ntEsW-I;-ALu_C1|sH!;>HCEkVH4kdyx*gqAt%Rb+s++8Wp+-%eH&9ii z-|lK^th&WY=BP@ITCGx50g4){ZnKhWc~tJ$o^xX+6g5`eVHJQa%pFq1xqju0x(P*% zRd-p*Y~z>qvggPr^M&JAqsFRxtmHW=Zr6+XbgX7j)L3<&RRwI}v)O+vRrNO%HC8=f zaDx(h{(RZm$tkFC6H?dtun{E~)u_lp{mozp{TLy1FKM| zGha&NQZ*Zj8mm6ClDqkmiwR4rdIm*}Ri9YNjQy>4jfkppMRNCx8mm6Dk~6C8y1{Q% z^@gIxsxPdZsgsv*|89$~YAqBsR()k9*K)q*r8cVi3Pp`o-&h4=teH{&c6L$TuRM|6 z{i4RI@2vcx*7l#~ynv_>C~B$YOMOrO5U$BS8J?OH4};&t9;HG6d{}( zji~WsBvSPNiW;lJv6AcSQPrcKIVwd|cfY8yDm*KBzb?Go>A6x`Kv82=1Xl9&^(Dc0 z?`K#jYOIRLO728QK8?*pg}YpYqQeQCP{7-m0<9CaRhRMU7QaS;-t#>F;uzRNaH3#;RznWD9d=d9_GY{OIm}QDaqf zR>N^LwzY}onMJEZQDfB~to)!hbvnCC$C?L4ja4yN1w%zoQ0T0xvryDn6_b^mhnI%* ziKQy`AMSopV^u6OR;$!;Jjbvu6g5`GW+hkUyL>k`>sZsFsIe*zE7`&%E9Y|I?&fVM zYOIRO$`40l$i^b9QPm!b8mkhsl5;** z&qtm+>@Fy3tV+U4p7f3#dt6P&`UpjhRY_UN(^ul6H~&&qIF`F#)L4~_mCS5;>%7>Z zsx1^XRwZX8Gr**DO`Qu==BTAm)L4~*RV^ID!!7C0R}^&xiW;j@vT`2Bc^O=Hz+zP~ zW4rrBja8{w$=utff6dmaDnU_WRccl;+gymfwY;h^P}EqJhSgAPVTR<<(x|!#MU7Qy zS;^eny-R)1C*K@#-2I})s&uSm3ooVlNpfNR%Kx&`_;8+fah~c#CYz0QDaqBR&u5I7pU)yDM!8_6g5_5V-<)kjFWlT zEmd8hsIe+LE4fmZMcf}()dnbPtjfVkj>bPPj(L9d_AwMSR^?gFfmd~`^zq%J zL5)?pScPD}2DcyP`KG-)6g5`mW;GgWiGPP2I@V4oYOKn`Di|uydH;8+VkB_4kQ%G< zvXV~$)4!d*uBsXoHCE*_W3BG<=(Vb$P}EqJpOwt>@n-Ihr0OUXHC7d1H4yvNp+^nR zG5iHZja3C%$$6M*{_d7KR@H>=(V)hvKUtNWi@&_oP2vO|Fy|P}EpegjE34+NF6ss$e2_zo@aQC@Vjx&O3q+>sVc(sIjUT zt01W8%|kuE;s_F|xja8*s1z`&_T#Gne)fOmftSZgQdC1`9f7J%}QuP6f8mr2%lB;sYur0+^ zWlG}i7d2LuWhHa(nQ7NNS4uDxHCB}~>R81C8FZ}aP}ErE$4Z`3PDIL(T-7lsYOE^H zN{+^pqJ!_M`T|9bRTWstY?I*mUgx5bb3R*A_h?XKRYg`Ziw^p+e3hy|C~B;##7efX z)$Dv{RV|02#;VG!WbTcz>OdD&*P*DfstPMP51(cmu|ieOWbS@ZV^vjFwQ)wx-co0% zs@71{SXGUc+$(<^3h%iS&4r@Is_LxddA{qwQ=V_6Z$MFFRSi~t*uv&T+MduY%#hsO zFKVo+$x8O?`;Z@=drBQBYOJcoN}g@5=Brv##~KAija7fKl5Z;NRo?758mFMBv8pyJ zIir^KtLbd4oQL64xcfzoRdra&ejPfvAxu>TC~BBEKwDWxa`VK{nRrOibz!ts=Z1F_L`ZJ|_G^nwvff+09gX$kt zwS%I@s)lB)lZDPW50eM%3D`e^i=MCQDapT zR`Qgx;CEmCCeD44dQj9@)s)q6jFsq5f6sRg6QHQEsu?ReH-@KKHb=Mc4iq(3HD}co zV=daA-*YEQliJ-cYOD%iC09zaY(D1;5;>zX5ja98!`C$tO zCG8NTYAqBsRt2+?Eey`_c9E)^P}Eq}nw4D3fxcpXs$!&d_lp{<+OP`57G7%nD!Qu5 zP}Eq}mX$nn` z+`E6~&RMETr*n@6HCASRN)fgyhtO_xz{LiF~Rh@>S#;Q)N!Z6nJlHNZr zC1!ee3#qZHGb{PT@hV2>TpgYyI<5;)t!~xD;G=}?tG+|tFk5(HCFXtH3M7NsQw4fuUAfm zqQdmSs#>&&QvGb@XV+BD` zV^tqkG6Q_b|H1RLJOPRttNOC?!&u8phWx2x9e|?7s(!47LeUI zO2!)hHr268XL64QHC7E^CHIsHXX;*36$V9(RRdX7!WLfoxU`k3f1s$bY7i^AFGtM3 zW`n99P}Eoz%1UONaNTAfQdKdtyI<5;HJFv`*YW=*c%C;VK~ZB>m{IY9E~nG6u0l~` z)eu(W<&0|mzM!hqS==q8#;T#LWZoFrzIaAe-Jz(lY8Wf|baQQLm1L?mKv84Wa8`0O z#&!)GqUs?OHCByaCGYad=V9?wWzXvF7d2LmWF_Ze<*73Vs%i>Fja8#q1>qR3-`dT& zQOH#}ABq~QMzfM9*o^;t*rn?a=@2gw@MU7SCS%pHqot1HoZsBbxYOI>TYB*Gn^4U+T%8}jOFKVos z$Vz6m>Hakrs~P}Bja8G3I+!<-=lxm-MU7RHS;=R;&WArG(6R17QDfBOUW!iu7 z%%bUXxcfzoRa04YfSUE`#2X!}2^2L}O=BhZ%Ga6yx~^&g6g5^&XVn>F%?-TrQ`J2v zYOMO3m2=>DnVq}nU#c?aboYxIt7fp0{VKGio#*@cu29riHIvmujP>8~P0p7wa(!)s zqQNvzo@ZlJ}bFW>hH;RKvhL3YOGqoswj?pn|3ul zzv9yiiW;jHvXajZ^BdONrDH9GqQJBwydf`v1;^uLW z1~pbKVI@an`l>x+RW*d7#;T>P{4iGKCMlfLM9z&-P}EqpjFsHKdbDkkQ`HVAYOGq$ zN@naE^$s3a^&5&Bt5&cYjxF3eqDwhd1@pQ`gBq(=vXXmc?Nr4ss~QGHja92yg<`B- zGiP|t`R!2DShbo}Bd7xl_j!ILD^fmp3#qYc4XY5S$YW!AX3e{8xTe zps2BGqZzB-h-`J$_;R&6#aUgEj`sES;`-7jja+QMoy zwkhAPRG#PgGEmf5wUw330FOWax}sxEg`&o)ZLEr8tVA)cOjUIpiW;l7v#JF(>|4#R zs@_9UW7Q5;atv!^DBwAUnG3o{gBq)Lvhu@N!JP+Y(6IucsIh7nD>-{t*806o)g< ztlDkVpi^hVR9%Lm#;QF=Jvo#jNLBJb-Tk7*s=cfNuwQS7-}8J28vsR(Rr^@UeApt( z@X0#XJSb|c+RsX^l#JzfdAIv30C8h1~t3#;Sv?gE!MkrS-D^}Zs;YBP)L3KvDN-P-E2@R`Px=S&}KPs#Z|cSap_FFpft5wc9*T zunVE6vFcw|ZJ;)_TkUzOybncLxsC^ zgrdf(^Q`0Q!R8;TmMZm^Q~tA65j zcT|0ZqQ)v8mk_%YJ#y^MpzeLRYNFhta`+%Hq@{7 zi({&q21Sikk6DF5y&U||^W<l5=Bjk&~WzK0`%!zo@b5w;Aik(F&fY zl;%*>SmkqmjW-%Rz+nc*YcaZcOL0jOQ5K+DjF+! z2FPAK$aCbMK~ZB>bXKLYUqM5@d+z3cR&lqG8mssWZo$C z=)UJu+d3#}tcuA>j>d{i8A5feH&E1A6^oU8t}GL|RSZ=HtGfF|ja9K($=MqrXkj{4 zZJ?;JDh?}|ZB{q^^Q@``P}EozmzDfV*1+SLAE|l*MU7SQSUIN=FRNe9OrR=THFv+L zu_`{RT2Om?-*g@#%dhV4Os=NC|ja7+R$t+srORiTsRs$$%tV+VFKgQ~oF6lN^Q=q7^Dk-Y~s9n*j z4pDUniW;kuv63yEwd9fWhRcypQN!IYYOG4mDhy+#eVFZ`s`^mWSe1g+BB&A>%jZ(H z6p9+FQnHfyu-=nz#Z^VD>24u4R;6M!4`Us9o+Fd0I#ASDm70~DhtI2Y^r#I`)L4~< zm7GzBM&{U{V?BbR#;UZeCy zJL6R(&wee2qQ3-@2ILQ!K?Mpnb2YUauJTDLISU+#WUV^t~hKv82=4puU6EZUdC^F(wPiW;kO zvXXas#pdrzbgUe8-2I})s$8t(Q^3mm{iCP~fuhE$+(rdop659?HbGHiRUTGhIEMSO zMDdLE8HyUK^0Ja=n_k=gaNc5hm&^OR`$dga`B(*Ftl;MhJx?j)ps2Bmt_=OZP<4sf zF1n6&8p^$Ta&--A(Y=NH@&#DQxv}f_N9RqDEsR~)-9l>YSOrnivi>hHz)L2!4mCU`d zN{2t7>I@V$R#jvr*Yfxk)!M5{(#YLHYOJcnN{)PtOxXshstHAnRh3zd#(5a?@Y1rX zCPGnTRTWlpG~%7xzDv~uC~B;#%1Y*q<$hg0s>Uh|Te$jQZ07~!{R)Ai z#;WS9>pG8bax^wVQDaqYR%5Y+g;qU^tm+*UHCEMOCCBh) z_#~e5uzXW@zo@awpH(A_73+?_=l8($hoZ)+x~ycs3WmEMs9U%liW;lxv8sfzVpK|- zS=ARPYOJcyN@mf~4F`B;n=H-T{i4RI2CQmftQ1$q-qW!{ps2B`AuG9mEiZU$sH(+K z)L7MsmF!o#dRzCZx&cLvRgGEsV+-G{DZffpjOOlsQDapTR?f#KUJ7-b;(4|y2Strl zP0d)ZTBUGKLOBmZps2B`87t?l<)v}MzPnW|g`&o)=B(ssWUhX=n5qX*)L0e3O7?5# zoH)*bku6LR;2sTXtZKokEVi)xz8sfTm4c$isz6pU&+kdI=A^2QP}Eq}l9kM&lOFe; zsA?w^HC6?&lKWS->LU}Y3fIEjFKVo6#cCGzYs~b+o^L9uKv82=Fe{k>>VGQOMaNnS zMU7RhS;@8hzwimFs=5h9ja6+}$=Q3c^kmQ7JVl_pU({IDmX*xCO|qQ#eDd{&qQ<0RPmhl2SaDjq`$dga9a+iU zAy>7hEmSp!qQ)iju)AN>Sk=dj)x7G?0;)PdQDaqKGuFBd z3I0~K1Bx1}`myrEG4xB(H;1a9P}Eq}pOu{R?=zP_s48b`cfY8yYJgE~9-R29swEUP zRt;n&bJWJnxja|OOekus8pKNG4PWdHp6`~=K~ZB>D648X8b5BIa!!A_z7n@__lp{< z2D6eYXLJMzE4kQuj}n@O;+0 z1x1ZjBU#D2ym#$K=W$!!uT<^a{i4RIQLIK|zqbGG)LT^$6g5_jW+mrFn#38Mfn==h zP}Ep8hL!Us@zUf*+zqN;Kv84WSXOd0riR<=`K(u_y}Mu3ST&B7yk7wgj(X0GFeqxQ z8qZ4Z<~d#__Iz)%7m6CICa{vLa>$D%|D(cPzClrA)kIeE43H%Ap=_%1ba3~J8mlI; zk~6CJKi)sJqYV@_R!wFlTNpLIOxPRe!URJ5h;Q8=t6J z0Y!~fGguYJSSzn3OQY%)6g5`OWK|OC?trJ)RV4{=j|MeX&0;0Aiz@sPc7k_lp{<=CP7O{ z#;QfEf}kGHY~z{d({y%^1~pbKX4MXA{@XLogeq5M02DP=Eny||#*yq9R6e&x%)+pRU26K#aJ1R-t;`P)rF$Qs*S8hLfx7;&GR{B0TeY>ZDJ++ zRcLrG&%68{iW;jnvyyW@XinBMRJco)?(Tk3W7QT`z0pnjCn%Y!KqzXg+R93v9J=gS zu}{?+C~BvNV^G!v<9`1foW7Q5;GDrEHnfgt~ zY79kTT@k<5b;(qQ;>N-7jjaI>1WaubtKRJ1-z-Z+|FitUAa_&ffn{M)qvsZYXN3I>bueuXItCd5&Sk z-tHDsW7T0+GDoF-8q2d^RiLP`>Ikc;IEHz$-|j<&yUc>3#;T*NW}qAR;7wdr@1dx% z>KH5MA%mCit(v7#RjrS^U({H2oK>ice7*Nh8K!Ci6g5_zU?uNzf!9}^lS}sNCKNSR z{ljWH#@bONLN8U>`np?4ja4UE$$mXs{L(Y`hCxwd)hSjzG1kbR?@H-d$DpXO>NG2P zO37VxjOT71tDn1t)L3=KsFjB|pVqNzK~ZDXSysW=!tFstofBD(;bbUktoqle6TVBH zZ$-{SQDfDAtmOW6z0jUXI#&Gt?tW2Y)j3u&A13)TQXy4Mp{TLyyiw=-YZsBGqYOK1#O3wKf?bmyr0m2P*w~!jEuCf{`S4xv{H+8IrP}Ep;jg`!z@w4nX zplT%)HCA0`C3gqE`jtGNIG#dLW7Q2-az<54p7gekm2r@}U({H2lht_aSLD^bcBtwE zMU7RrSjoHGFn#jwst!X@W7Ta|GS5#QRLXfQmFp{ZsJn&KSapY$oE!a0S95NFqUu6X zW7S<&a^zpNnsZszJSb|cy2mO2M`NFFibvgoqQu^@x?s*x4%n6I0bwC~B;F%u2qgIClMN zHdWcf-2I})swb@Estow~^1P}}P}ErUl$GpPyzR&xK^^wax$_1i;HW7Qj0&aIA@j2S(1QHBi)8^_G>K z8y_wVRQ-UW#;Q-Omq#MU7SeV*Fwrz6_wR6^lQzApH{1?3`H5MqOp=W zA8~0x-%f896lJW6&PqnUQ0n~2wbm6V%2*YHm8>?!HicwUm3Fl27iFx9$!a3{_4xD^ z@3NNB=nO>}t75UL1y!=`p^d5zLs7=6*sLZ)?XPtGk*Y6Hl(8xfD_H@O-pX=MRoyYJ zUzD*bE-TqBKkN3xOjXmNC}UMTRzYZCm+r6PsJaV98LQ&6@)mbK;t%}VO;wt)u7#Ab z>N{3)Eq|#My|$`qP?WJM0V|pF$wF68S2Z7sGFByI)dVdpRcCf?RS%#jV^tznvXAO_ zwv_MsN;A&&i!xRvW+g4$TtB>T3>!jG#;PQ&yn*8*Pv4|xw1xAaC}UMpQ)^GB_sLY< zhoX#C$yf!UR>Ru6POHi`-t~(zRwZX8V;J+^gVw6rLQ%%56s%-tp6aK&pH(e_qKs83 zS;@5=H1YXjRS%&kV^u0vvS&;Gd#vuN@=tL6qKsAFvyvyN5m6exP}K*DGFGK#)f!`% z{l&_=stV3 z$3(4_ce3jjWvt4^DhU0GpK49Y3%*iq?7y zMH#DdvXaqgF)wp-Re@7nzbIo>E>`kP^sa0N-_Bte6lJW+%}QEW^y%1QT5B&9Wvt4> zY8d*pJj>f%s$x%dEu@T9d07pB+I2gZ?`JnZK~cu4e5`_?@}Dd0YvC#=%2<`3RVdV? zucy~(3m-#K#;O9WhC$WO+_0gl!qZ&8C}UMYR&sq^&y>a2uMtp`v8oU&Sr4ZaZ{z!0 zAof8~#;U@sWZg*Kaf9!k5^lO{A!V#8!m2#_m9crl^OSH$PAJM)Rg{(N4dVq^cEAl(DKfE1A8!_PzI(5NY8vD9Tv%1FNy<$=Kx0daKGf!;J=I ztSZ6ETX6Xp@cWWks`^7w#;TI6ye zV~w>|{#mYtl(DKDD_H?v<&5b2P2HhTl(DM3QFnehlvQh;g`$jA6P?WK%1}nK&rb^b!_pEmtiZWK!WF=3C zx4s3g&|2x|xfW8!s#>PjxFMgt%UW7E0E#kJ)n+Ageq-jDF;wk=qKs8_SOuZ~E&iC1 zS5@@+u7#AbsxB*;hrcGvu|riwD9Tt>&(x~9dB|W@W1%QxRee^S(8A=8`p;E$5{fcb zHDDzztb8`xbX9Q|xPDQ_s)nrOEHAncyP2x`P?WK%5i7Zt$ClaS`^o-HD9TvXn3eRa zTKFd3DVDSR0*W$LHDM+10seXYT~$?i7rK5?#;T^QN?;5Z)@kK?HXi^*8LOJH3W54k z|N9PFYXuZ#ton(S*DOB9{JEu+s`pTou_}m_tTt~37E7Wk>mt`L%2?H$mF#Wq@ALo7 z|6QOcV^uJ#AlJZvMQwZeX4HBp%2?HcmE0>wj5-lPTlfNsGFG)@)mmyD&+c8Ia+dQf zcKxD^RjpW+g<3W9wy#z>6brOm)R&`)C4C-C` z^1ibieW`09WvuGRN>grba9Jz2Fy zt(v_Tq*pZ`iZWL9VpR_+^01zxRo#K2j8(l^ZGzgFrE6VP$yd03QO2r1tYo!`Ir`;E zRfC}@V^v>PwNNYTzy5!5_%IY@tm?-~X4H|Di}Gl#FHn@Rsy{1PZTcLWv0hc-m9Afu zv1$M-Z`;a8jb|@>&&va#C}Y(xrdE~8(T;1atx%M)YM@cmdTe~F>N6B&tooIe+?Tgj zO7C5uGUrRJa{Z!=RUxeEpkD(fy=$XtC=_L^8pKLw@2caie9sQMpeSQiD61gU%26SL zcLS6bCS2`WNExdJvyzqVUCx_@Rn>-~j8#KeZAY!hoevIIH4ln1Rt;q(vv<_dO2Mk4 zuW>D;j8(%}$?UBhfAdaN)u1S2)o@la@*&%*`tDytpeSQi7^`OJSJ=uCzN>O46lJU$ z!AfTD`{*+tX$wC=QO2r~tooqV>%+~wfsyl7V67Vs%2+jumE4y<)+k&~)vr*Lv1&A{ zsi+nBKJR%|SD`3l)fiT?`|7ecdMZ_U*SQu_#;UQbWIepLXsvGr=mSL=tH!Y!A|u~B ztbx}04T>^WjW_B^!ZzMCkueOn-nEc2R!v}41GTD6k2gwHO(@D(HIbF9hdGCi^1gx8 z8V*Gnt0u9MJ;2$`+k8(q`=Kaf)nr!QMCYSNzdft8)>|mbST%)}tQ*DWXYt*Mf_`(O zK^d#2vXU#MaidtiUCLG{%2+jxm3NZ(7}X@V?-}+b6lJWM&PuN3?45#BQo~j8*ek^?=$O z+M}zg@S9uY7hEo3Fu#){@{W5nOUdNoQ>NON)tXjrO=HdB+6W6HvVY3?z%2>7B)M|e)tFK=JpeSS23Rd0F!q!vz zzR+4npeSS2N><~cYL;8;U7&KM#NOgsNExeEv65?fX0hLWyULbOl(A|xt02^Rb+PSQ zt+g16GFGi&RR?NY^rXjB-GQQvRcl#wfyzF$T_IJ;wz_^%#;SFuRwR)x@wa&sf1jE7KJT84&Z^a`;rmd= zR{xz~3nX{-`4n-NOHnWnMIq}m|-W~$`J1> zrOa2Rdta&Xzpwavx`nHUdjE}%h!sZqo@KUpiVn)S>XCPZ3kdSQqGOoK`$`w{l|tTE zLd;iw^u9vo3D)bzOwg!U-7qjE4NwhUyZYj@EYgZ7Z9+*Q*=bq)&6}tUsctet`=pi+QCZJ`L6Mw_;z}upeSS2 zPF6)x>*V?j-t3ir?SZ0e&2 z)xF0E8N*_`UB4(})d5y=PwALoqHjGM0!10C4ziMdtqX12RBN4pqKs9CSd~W$>+Xx1 zK~?lUu7#Ab>M$$1hUsWB?$Ucz#h@r-)e%ZC9J4w z6BK2vI>xFK)c6yfd_RYcwAb~EGFBaDB`wVKxQ*{`kEskr8LLjPlG)pJT*E`!!ZA>k zvFfBz-@ffBq3RqIWvn{IO0LS?b+-7f%7pt|zbIqXX;wop8hJ8bc&N2XK~cu4Gpt5J zrTaZ|3svKxC}Y)GR?DHH9NO=@!`_9Wj8*4YHG+CJD@$svRc^oQ7iFwE&r0Uu=nZ4O zstSRkj8zv{wMMOmBNJ^_wHb;sR$XM(1*&WRz&WZuKvBl3KUg(`I#z9;?=1gt!1aqV zR$XFM3hL)`>2GSSeo&OL>N2Z{Q0-1V@$K}MLs7=6E39M{E#LB{@7ZBD6lJWs$|@3S zWk?&&w_<;VqKs94vXWIa%Cru?7A8OFMuRd|U1JpiwT3j<>sxJ_LQ%%5>#X8KWxrR> zH#hn~QO2qpth^MMJFI4+|6PJQY}Hy;d)YKP`OBO7;McPdpo8S-t(39qB`etjG>;wC zw==H^MH#DJu^Nqj1+@tA{oO~Cp(tb3YgR!}`+n-}yHXxOQO2q_tU{oo-fr((H!>b~ z{i2LjZ&|g4`Z?Ezjg)Xl4=Bo5^^R2_a)G6XdpBEAo1rLU)q7UnV+J4bPA|Ey>OK@@ ztop!eBGmqWANXc(iW9D1l(Fg~t6@+zqyA7-YjuaBj8&gljfF})zvnnr2calq)jzDH zg>Cjk&#WrxN!LQkSoJR}8N;PXm-uE>7bwbD^_i8dQC+g+@m4k&`FT*3vFZyexl-c1 zx)`SF928}&`pT*vMx$l)McGxQKjr#G8LPgrlC%8s*Mz>ELsKZqSQQY3{#={f^~!CE zzgKHbhN6sB;aDw43$xvSno!kED9TtBo>e!f6R&>rhEv9{)M?i*%2*YFl{avFjQ-Hp zw?7;PMH#CivT6&pcScwut#t*8GFC-mC96%ucAE~UN_xh%kTO<9W)+HBwZ`W-uBr(X zWvrrqAtXY$UQk~y>^!4tC6xPDMEvhJqOuwWb?8&#)~en>QO4Ga#!A-SfmxfSQB~%w z>lbCLiq1;zM9Y`$&Z24{6lJW6!Akm-`t9S@st!O=#;TaC>Y!gyKQAk%D#kh2LdsYb zifx(1eL4siOgDSClqC@`i_;X8-4eWJgw>z z6lJVRz{;C^e8l_KXS1qY7hJz6V^u;{a=sR<4xXf{GZba4O2n!vYR&)S)MHf#peSQi zVpg&?;QO2sQth~v`$L!I4QmBe_ z#f=7Ktjfm9{Z~*g;f|J2l(8y1D{ni_N4;mCJtC?%6lJW+!AeHsO#3{cs@6bJ#;TmG zhM-paSaXV~x(`Jet8%fDm2L66?SHE(aMksfGFIhg6^vSEvhDC*{QR$9P?WJM539vc z+alJFuWB_mUM7E;Ele5|IU)|j+E)YDq^p(tZjepcRc#>ej! z^Q~6(8x&=%DqvKj6uo>;ZTFxkV^u*`!%!>htE1jW8Nt0A>{zypX8baMH$<|BCNcD<0DR%n!cyD3s97?s;H^; z@0>})wO=u>yS7rss$#4HQ7cWelSx&Tg`$jA#aYRWy4UMycU9e?C}Y(RtYr7qwP}xD zsxClL##8!F-UXCk^~h_X_e(wh=SX?O^@}t7-|~51N$q{ouaxz^lG%KviT9O?|NDx6 zKVOn-$@R6l_;%k@KxfpVjO|w`R&tg{$2sPEqF)O|8LLXOYT~tnj%<$)&(P6$07V&3 z`Q~9DtHR!OU&d1l>e1hTBl9rrP4_AAKl88*E9x^H4N}a_ptbTrQO35gEUS(V1yn7$ zGL@=UP?WK%94qhC@=<5$Qr}a+3Mk50Ri2fM#=d3e^J=ZvP?WK%0xOw^116^Sy;;in zmm3YrSXGggyx%xFxN9Y?H5Q68R#jp(8vXh^sD1@iccCa_Rb^ITP@Uq`_5Ea|&@I8&@~%w`#52_go7pV^u>|3!%Q1Ub{xs7%0kE)rghMjpEm%R8#d7iZWI;W+m5G zf$vxOejgymeb++DSk;8p|ITv%JtMVNYbeTC)s&Sy>$R#kd625LP?WK%8LOojjp?ga z98vWYiZWLH#7b7|?y0|dHzk?#RUf#1QO2quR<%&8e(PVqS2Z4rGFCNb6$&*p|Exb% z9f6{ZRl%&}8Mb5Y@A|4r^w71CGFG)L!@-SriZWKU zWhEn@AagU{7=}Vo#;SI#WDk`l%bfgL>l_qitZL6HF%b_S^RZmtj zH*&@8>|3$VK~cu4UaVx~&yO8CTw56Vnd=v2tm@55*7wosI@st+p}jfST` z_t07kpeSQiUsm3u8XsX1HhW9H%&03+l(DKGE3W__AHQ^utg7g9*DuOg)t{BOiRa^K zhjx2Zg+furssXHI?XA?i@itXEpeSS2FRWzbTR(bUURAgku7#AbY9OltXyJr%=Srz+ z0Yw?Beq|+30Uzcj@jWlEgQAR8A*@1B>-L^-z7^mp6lJU$#3~Ea=m8&mYj2UiUB4(} zRVb_MP#uSldrJv-bb+FbRfAc17Zo3MrU&d(wF-(dRt;g56KYVthX+(Wg`$jALs2VNw3?`;FnO#-rA9S2{rydEu6qg z*4}`%Rp)B0sZf-$Eu6@z4*K;eUVY#7bq0zuR!w3h^Duec2(`6VlsB$ll(A|uE7|wX z$q{aE{Xrv<_ z_|A>Sod1mcTvqwf!W(xVKF}5hLs7=Ia2_k!+XN0N?c4W`grba9^I26ytysU*UZb^k zLs7=61*~L^3P{z?dpwdm(ce&%v1%bJFUrT5g7dGaO7q^024$>TWNLlBl;7J9NUeHM zl(A|tEALT_kMbXfo>vtHMHx@|&esxF;k<88Z`z-i&%aR5*FLBv|2bbvS@l4z@X6wP z6Ioh#9*Q!yh09pAhFXy2Wk*#>Ke*ALj8)57wTCL%YwrbB4WTGw)e2LqNIJk)XtXjuvEY$wO0p6u1XF2O9*DuOgwVqWk zs6!owc$b=}fl!pO>Ni$HpkBTk7O3hl6lJX1z{=bD^ATfg+eE4o{^MFm8LKw3lJnK{ z{=)% zE-iekD&`m0LdsaR+tg}&CPM;M^`IzY)gD%TFdC)Sobsl>Tq$#)C}Y)LRv}O;tDpL+ z>LCK^d!#v68iSV9B%I1A&~cmiR;&tB$j( zhg$u2KYOQYD->m{I>E}@sPWMung6PM1w|RFPO_5Krsm3&g|t?7+E920Wvn{IO77+{ zK27ja(yz`?l(FhGtMU9j0|L$l#+k3`Hz>+jb%s?aRL4i*^Qwvx-c_ZHRcBery3s00 z_rFxtg`$jA=UB=4s*<>IS5>p2C}Y)mR^`#c+%cApQS}mvGFDw+6$rKducY3VO2#lv z1ow$Dp7QPVF0%3p1Vr-w-*2(Xc^8elJ^})2KwXUTf8RO$!AjV{eoVzvs>T6rS6(V&b~S6Rv0 zo1o~?)2jMFQO2r2S;_wJpX434sM-%j8LO_blDW~ZMELBg-a}EwQ@-F&+MH#E^vKoyRPCq_!hpNv|l(Fg_E4fmx7P-?zRgEaFt(5VU?=0VE4!r z2|dfRpzioiLnlQKX#K^ z51}aIDc{IHV-?*~vtX3=&OdV_?^DnJe^ec)=l?lhFIdTp8dc(w@11!E zD9YG={mn|Quewz$eA0gHfuf96FIjmP6(7SURsLDkM<~iz^@^2TDQ8=qe5DmSM4ZmXQ|o@MH#CCqSBvT@|I~nLZ3vauIg_n%2*YSmDDORDYI|Cks`M1 z7iFvp&q`M8k+X_5*IIR;T7RViat3|3W9E62_stEuV_ zMH#DNvXT{h+AHtpoL<5m>!2v(Dc>p@i`60TMi;}2?%LYrf!_7LLB)#tf1d(kvkJp^ zU$E|mH=I%{emwVyGPZ?rSjp_oojCeHRV|??V^v&M-u8}HRbGFByI)eN=5=8ig}weCVu#;QcDWVgKR$8Fv+ETfV7JNJn)p7PC&#H_-+THf>s zC~=^}V4WLnp%VXRZX{tPE8CNjdm?MCeo&OLElkQv&eydcuX@8NE!+r28LN`9T8z=C z({)jZs(+v;WBZkyRVJ@fi99*)a+1c{uSN-6)#U%_R|;0Lw@LLdth?6g07V(w!j!DM zC5Dg75%T-?085}KV^u0vG8%bb4EarK{R2fAtG;I?ck{7z@1#{#I-%EdHQIo&O%Yfsw|GFGKyB_ls5({10C zQUi)IR;6cE3bn>1`g&PwjfA3%r+jms{vQ1Z;UYkd`JVn{5Y2u%wnAn2&)mq!%Dbre zXc$s6m)5!jMH$<|Osr&`Z<+1cMpda3yV0PGRhe1IlhoPos^n2s8;UYkWnm?2RJ}G8 zyiU0a0RdB?C}UMtR`LuxG0_ljnut0KMH#EIu^NWa$kJ>2T2*nAI8Pa?va^!)uu;@r zURkNt9EvhlZ4W+g4`d9%jvs_H>e#;QE5yc;AR8EdS$uWBL`Wvt4}DhO)Q(rq(T-GriyRry%S zYSTSYBHvrb6vI_90tBSCygIW`U-X&DE z4T>^W6*Ve$>73rHJ(=?_p(tZjF;@FgYstt`zI7vW3g;b%UaeRaIHZ+^8Bay|=lPFzB7y@R5RRn=L^{cBu<2)k9KPvfdm#;PA#bwR(L7ntU|e>H`oj8!#Q6^E)G z<54B8wFrtbR@G!Bv-i}KWJ^??hN6sBwOExxt#}IyUsn|;t?L(Mtg6jQ#_;c-#?Myu z0~BSfs>A9aYJFT#a)_#*p(tZjT~r78GTyYQRcnZ`^$e3#u9nMH#CavTBQ3KPBtz+re&zqKs9ISjh^| zAnm=CTI(YeWvpt$s#59QXi&zgCah$SJ?g=;p{k}rQO2sKMm3%{F{7$m zP?WK%8LLJZjgddLSgI;Z2G>H$SoIUDP^hHiqhC_h5{fcb1+kKQWuw*ieD9VwKvBl3 z=B#9wvUOwCLt5(_6lJUmHfmDiM!u(j${Ah1C}UL%R!z{av|Atg_8U{6C}UMiR@I@- zk7?z*md`;^#;R7Vyy52KbhET+DdCRDncOGJSk;=9>_x{#T6I%Z8z{4|3kS3@m0NnqKsATSjn9KG3~w1s)}WH{i2Lj?MdGn* zEv&LKRjAf#1w|RFy0MbcNILEFHC2ZLz;&syYEh8LN7*@@`su{8=Kk z_X1bOFjY49i85C8WF=Q+&JsE9tLg+r8LN7+T8>)9CWm=%0;Sd>D9TvXn^hQ8w3-n& ztBRD}dCFMThn1{011IG3jYfSa%2?HxRS;^8oLhUU)|v!G8LRrSl650(x61ETor9u` zRsC7jK&{t_H+E7LJBRBRWvm*&Y9UnYry<_-moY30MH#DpVHFBh=|q~=sun>}#;Sp= zWDFZMedl`*@EVFTR{hFKW^clI$-Ix!!kjtXC(2kA!m2%5*!XyfimF;cQO2r4tOB8O zo?2K`)p97xSQW}@7}TZrW233M3`H5M2D2&;RVCB)3#u~ba{Z!=RYO<>LsjlvrK75b zP?WK1D60Wb`O>|bscJeDWvm*;O3qjL3uAn>?mfEkhl(8y| zRZFNBw}#Ev7B+yQj8!986^F_@e&`5Q)1fG1)ks!y*E>39l| zCZdITw!ZD6Y8Mn`teV71?kQWZ?|GmqK|a?n%2+j-RUm3jd)ITBs!C9lv1$q{xl-=7 zN*hsCA1KOLHI!{CMIRUL++j8*ekNed6h zO6U8@$QLNeST&!OjK9leFejX^*__JZycWvp7jsv`O|HBWut`@?2Xl(A|dD>+}a z7VZqwTH~N7W7Q&7ZBZ-zfOsEO9fG2aRf|~#Lp`Vw-uLVfxsdA@Wvp6a)Y5jb-)gOL zP?WK1DJ!|Bd}`-@pUjmW0!10Cma%G!7FL`7!FQz`fTE05%USh;+E6H43vFS*PoZVYOTs9z}Dimd`TFEL9wf=mSJejI6D9Tv1ij|z@6jR3f-fwJ%qKs9m zS&c`nm+gB`&{|KSC}Y(cR+FKYJ6NmAA3x zBjV~kKdQ?6gKH~gtlGuOyQuiM{JiKMRXw37W7Td}vL1e17rlt89Z;09Y7Z;96P=2> z=C!JSpeSS2URJWJ{H5%l-Zzku&tAfPqKsAhSjn7kw>N>~+I@KSR6gQ5sETa z9cCrxD`A0ghgFS-qKs8XScRch!6XxJt2zrs8LN)63V}M^dhRc((w1`lqKs9?SV;>r z9q%(yRTn7ASaqD0tN;-%)QPKVJrrfEI>D+fTA1s2`M*`&hoX#CCt1m!?ftX;GgW0O z?fOL-t4^_!yZOm#t9{Q7KS5E(s?)5zA>d=_(NA}^)^aGySapV#tTxM+4E4P+`vyfB ztIo2L>nmdMUA~=p*+ADX%2;)dmFzcunZD5XzIPxLWvn{SO2#nXhbF#}-vLD#t1hsT zF^nUikESpC}Y(htjZ&|?EO;TYSR~rGFDw;)d#9v z(I?)wms%^KC}Y)SR;{5fUu&>I)mtdaSapS!tn-hzoc2CStpa7;C(2lLl~o{WEowi{ z_kN=<6lJXXlT|mUG3ncF(^|`+C}Y(%R^ICgKJNX!GKZ?ap(tb3byhMr=BAD8`}tS8 za;{&LvFZk^*{C(I@T4%U)fkF0R^4PJqtQ6Y(NI-epeSS2U#uph*7*U48mf8#MH#DZ zvGNM=QRG~$QL0Lmcm1M_Rkv9ML8bjVageGpP?WLi4l8eK!pHDvIet}j0*W$L-DTx% zCHd(8%aHF>g{$CNNExf{vGTTDPVMYIS5+e@%2;)umE4yP=9yef)fyHXvXq6lJV>%u4QGdp_ow zr)n1zWvqI_O4g_wXVR=t^#zJDRy}1EhJO88>9;7VidJ%MrHob2SjiZE8F<#aZA!mJ zLs7=6=d5InTDWq_TU7_4C}Y(NR<+Q=6S?|(i?`H@RM~x^j8%UdmFrV+-&rmWMH#DJ zvYL-t^A=`!sI|I7QO2rQtYqXrR6meT)j252SoNBfj7FrBiJzK^P%%naK;9vFa-;S?3$B8gWZic__+Q^^MgA)Y=zwdO=kKpeSP%{Y6O;!UaLi zX;#U1E#HNrj8)-S$v&#t-7dbTn>0VVeo@A%@T`JSt3r&WC$)vOpeSQi1XdwXX}i5T zqG|#ZWvq(GDnC@8zQp5F&GFC-q7&D9TtBkCp7cYUZC9QPn3X%2*YjmHc$+^^t#lZz`(RcB4TVtG;6uiWautkz=ve z3WK7IRS8%PfeN|UZHcPOP?WJMAuGA3#A)*Sl&Va1Tni~HFv@>}IRYmK%eo@A%WUORY znIUW3@v8bjQO2s|tYqD2{I#+7c;qU0f5r!jGFGKvC2LgWBOQWOJ%yr-RVi7?7zQ3p zT0vF%daf#EtV+d7uH`vPM~A4Y2SpjHzGvk%i;p9xQ^i*`7m6}grDi3g5x!xvAXPV@ zC}UL`R)MHByuu>iPA_hK*DuOgm6nxPfRCT9PMoi`NP?WKX z{zO`YaI((dtoleb;^Wlnqdnu_`+&ne!PE7e21F-a}EwsvN9>P%Bg8nEO?g zXyp1u8LM)#3WmCT!v8mt4S=GIRk>Kn$lu?1I;Gay0Yw?Ba@XRMGFIhdC9`){;Rq$Q)?p~hSe2hu z2wM2`Zjn$`-=HXCRRLBq@(WiiT&b#B6E_-^v8o^|c^W;nr>eJccG-Y{(NL7Jst~In zv@l}S9lpE6F(}GdRhX4L6WzJC$oEzxN>f*rGFBB~C8H6c+EL%Ww-^*&6Hu%2-v5mFz0JO<0qd67IMRMH#D#vyw5~K6#_>C*awdIZqj@elY6Ku(^4)R$C~_ zSXF{mDB6^}{K4N9+SNxDm)n_QmSXIW<%6qqkH@W0|)d+H*C}UMwR)J{Ys*BUw zt6By{8LP^%+6$GX-Ev>QEX=%CK2`DUqcXR0{i2Lj zby;~+mXGWQ^Cr?-zd%vOs(P%7Lrt1;FQTeFP?WK%J}Yk#|GV*EWrQ54242m*VHDc8XwSt~!jic%Y6lJVx%u24xPV29K zQkAxiYawN(9`$EtUeTFtZK?i_M%abgm%zcQ=uqhRWnvKP^{t?L(MtO{Z!`@^>xj`;dj35qgSHD@I&z|WOloY7j{p(tZj zFe_O_J2ve0kE%^jl(DJ>t3Zs#oz&lduPRwP*DuOg)sj^Z)QYbIeD{<}P?WK%6)Raq zpB?EGS!)f4qKs9oO|5-x2Q*f76^b%ewP7W5qs!a)4^$;?@A^dc>=*7v5|QgsK4GFEk9B`d(c@vbaXm7;^|7iFyK z$SMf6-esns%LW8Afuf96KeOruH7(`kJE~?vQO2rHtmMh}@%^WNs=5nB8LK+88irb* zde`>-Y_w=c*H+3{)rFO;Hs4AuTcNc^K~cu4uB>F8FWPJPQdN7QC}UMOR?rni(QK1bzJ1g`|aC}Y(xtm;4w>+#t49w0&&*DuOgHIS9ejbfpzysd|vA!|YBZ~0wD8}a zdAy58)KVzQST%-~++iaO_W#?a_n|0b)mT=eQEP7RL|$X1*7rT!C(2kgj@3-4YrDQ} zQq>)bGFFXeC9CM$v2~uSIt@h`t0u4tM6J>n&U=fuv@l6e_lYuAO=L9y>bLJ#A5v8T ziZWJBV$}rd-|X>&RZW7Tj8&6a)q={LGD8VfXP_u!)f85;-^kKC$n(;#NWI)A%2+j( zm8=`TXASiIM725;WvrUU%Igdt{gO;drM3D(QO2t2tfXJJnnXOPY6}!)teU|}TG(kq zM&Imx4n-NOX0j@Z7WQvdz;|~@(%X#&WvrTIYIPg7ErPZ%5Q;KZ&1MydT1oS6Nuug! zD9Tthhn3eEKK?2dXN{^^P?WK1E-Tps+?f5`cdxtvMH#E+u_}mK2Mergp|ukAaic*Q ztLC$k^A%(BwM?o?KvBl31*{sOR-S7geY=z%P?WK1AuG8P9pCw3k=9xVMH#CWv6_rp zx4PB#ZnmyB0ReZRC}Y)PR>4pU>reHT5K+bYx=)m`Y6&Y@4_gk6cS2QPD9Tv1l$EUW zn`<@pJ!NlzqKs9`Sam`R+a~{fM{7NSqKs9`S;>rw_WrH!=P9}RxqeZ`suipXqt=0L zKd#kUt)VDm)k;>f)61Xr`gB#}peSS2DpsMWRq^@sW~%l>QO2s(tmJMUr^z92F>t*J z2#DL?eWHw2YgoyfiWD6t2C6CvMH#Esvho&OKDOoib&{$cP?WK19V2B1yt9$!nRsumPwtlG+|EmY)x)(uuQ2Z}OQZDS=PU+>ez zFRE@rQO2t6tb$PM_`~~YRK*?W`b8P5cChLO)%WzyxT>l_QO2sBtfYmXo2~H8`AJZe zv1%798IAPEJNTYB4na}Is@<$)ZsaU=eT%j*@~^I6l(A|LE7{u=n^4iaQOH>?2SpjH z_OkL8cRq$k%rjKgSSZR^wU3pwu;%8m2UJ~#qKsAhS@l4zaQixLR+T8kwUshf9bhH1 z_imxe4OKOTqKs7sS@lD$l`V5tQ#B5XGFBa8lbCLI>JisL=9f8j;ghqLQ%%5qpak7g=QP@P1O`A%2;)b)&E+U;lXiLH=!tF z)p4WpUmxq6QK>^+zbIqX3087_Rjbv@_ck>ciZWK6WEF~$Z~9_*D{bL&D9TuMid7iY zqK1M0s(KGa8LLjSDi3ucXr=Ebj}->Heo@A%GpxMZ4<94jyv?e$dP7mhsC|Oeo4&^#`j4sMYGnLB98F51=Sx)g@MPr3C$2)O!e) z7Jfg}eWHw2ms!cv&G5{15~`{PMH#EEu#%PS=G91JRE0oM#;U8VWDJkR8BUhsSaqG1?7lL6x$Rp4T0&9AsvE4@ z<9ucR+|Bp1o7qs5vFau(ZwUBEc_okUJ-|&U%2@Rmt3ar;{mc5E9byc3{i2Ljw^+&U zYw({%Q&YknMW85S)ooTIk=t_PvG2LEH56s6y2DDY%JN|oe0TG0P?WLiu2F-x--@p- zd<;bytM0Lqo%xL}>wWjHq+zayl(FhQD_MJwHLvR3C}cE#grba94_KAOXuMj#-M8PE z0!10C9W4;-`j(OP?WLi5i6PV^E1To-M_+(aBZcGRgYQ8>}?gPSyoE8BR>>n zta`#qR-4c5l6_S5GZba4ddf=n0EM?7-KJ_O6lJV>#wr+X8g{+^1yzrsC}Y)gR>Po9 zE?k*NRpybdhm^7E1uHqrgPvwMs;UnZWvu#}m3JfIV`l$*g;ni=qKs89S;@}feD`wY zRK0_uj8(5#$;fZt@zu8i6dL9FMH#DJv+^Fg_}Gwqx9{1ZD->m{dc#U~di}4A^X&m< zLs7=6x2)uRElZo%H+vsKQO2rwtYi#p6+N_{67I+_+I^yoRqt8NMebsm)7~dhjiD%G z)dyCx_9ogKd{5O@D9Tv%kyS<1TC$@4D^>qOQO2rItSUpTz5Ld<0^}Iu+DaL#{$Vv6 zDtG-7zI$a56lJXXm(>uc^U-@8)E4f9qKs9aS;;)Cxg+m;RWZl97E;ElFRc2YR*5Q+ z&Z?>oMH#EUvXVX9>$Bs$Z!hO-IuvEB`o?NBYBi4;^-oo&peSQiKy>;&^OjIMc5n0T z57SU#I=qZk;aHV*|25$J#+j?NR&yxISQVa?Tq#3dr5mbh0u*Jeioi;q+8%da<9kNuWb(Z~oCrl3 ztD>;#g)yA8<>ypd>j)HOtcuFYTRQpJacS9NRdFY{eo@A%Xsl#q%l^Z%O{$7OQO2t1 ztV*HQm(vBus%i;E8LMKj3WRF9;hneeU>*fbfTE05Fi#;7cUgSjkhsx#L%Sv$rD@Wvq(JN=81*lQ`b? zP5QM6iZWKkV#JO<4Odjfn&#R{8LQH=lDpoPiy0HBss}|GtJ1ORhB5pz=*ARP!=NZ*ReDx( zeXVRZVW+B7P?WJM11oO`_(&Q)#h!t5aMGGj(Se1!YFjSu- zeSLrWeiamDtjf$v)~Mhbp}yJs1d1|NWnm@r@N~_1-f+r{Dlx--qKs8pS;-S(=tYwNR9?DmyE=zNQW>6RPSN6lJW+!KxF+@cW0;+NsJl)Afro zR^?<>59;RnIKFkhI}~NC%EhVy)Z7M%Vrs2bP?WJMH>)71;V(b=-Z|WZqKs8}Sjotz zz5MZ`)=D$W^@}oA@nL zu4*3?WvnW|O3v4^r#E~%hX}J>zbIo>K~}QP=PHr(rq-$mMH#CKv63t0K!Sl6RSk!t zj8%nM$(2$n`K9=(u0c`8sv@k~V>Gt6Ig&$FoH?#vl(DKPtA0>zsyyATswNa=tSZJz zR_wG(KPFN&3yLyU6=x-9xlN17g;d>wqKs8P81;RL%8OJbo9p^T8LLXLlJiwJ$va=a z>OfJ(s*U#8r zNmZp;;5=ols>EslRKsy!ed|V7D9Tt>nU$sAj)LJ{CC}UL>R?@FhO~&~48(*L( zV^vjFG7rbDPUriXRON-PUzD+`8Y?+p?|x2xOaq%g`tW_98mg8+ zQO2rztYn>^7kQ6&i+1e_2)F}98LR5El2tTvhO}N)QQ4QcPn5B$0V{bUJ!I{zL8>}J zQO2rz~f6lJVx$|?l40tXe$sJ}7btm?`t6tyBJNs(VwzSXXUl(DKCtLad0wp8$~Y@tw; zv8p?(5U8RR`uncRYfzN2ss}51PFYoO&2epE<~6Q`l(DKOEAJN0$JKVNyj!%(dVk6f ziZWL9VpSRHV&f?9RgHzBj8(l^$@P_N*xj_M_CZm`sy?jbT0S^6`)yUR*1EP*#;U%i z*2%2B�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πQa^6^t3{1vA!LE#68JsYP(c0W~{nqtcg>b{TZrc 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

      KqwffsRe;|nvxa)Ahu2XKgBhaAFMm3v% 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

    4. 1|r(Upl33Tk>&ItVVur+eGtcA@1 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 z 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�qk1tY^r}xValwcwWpHWadduLpNCv(v^%p$HN-ZRn*lFqW z9g+IRr)u1>BJ|~c1Rym%abqM0UkgMr;6S*<=pd!UTj**E^Mr|9YV-!@9wiBd6XdUZ zKWg$|JD?u4Jy;A;V@oIogqri8tGqd|$U?No30YuGL=8?WT1+EP4bnVQ)hR|+C#nXj z@QSJwNo9oJodA4&fw0HA@S?_+TzG|O`r=y6L!N;?ArE$>u8JY{G}_VkEM+Vhm5;t- zzN-4imPG0eAQ1Ok;yWUVRlFN{3PKG!(9l#;8QvL5ql7++(o??AkE9HacpoP%s$T9d zh~$CWu49-I<0Baa%JtRN%l(Csl)>C}7x{R21O7#kJbbbi)dU&ac#Dw?f`y1;s9Pd! zS#`cHYPJuu%HvusY!E~-Li~|or)}UJWqNc~Bqw(s#HIw+YUl=>pNc`HNe~| z%F_zL!V^Ng0dAN){HCRJJJ#_Tv00`65&GA& z7rpZ6_+A0Cvt?8-w_QAIq;f^nEZUNZ%)y?h?2n`tYedNl0?}i!rbnd^d*z>uB#xl- zDSly+x9vF<$t2jXE$d^uIcGUmBRRI@;L~?bmwN`M4xkq3rxS!tb9>5@oIU>%H3ot; zwOcH{a!I3kdT?(ft7uZEN?zC96v?1vS+pH3rSN9Wnd$2(sR zwWkYqek-aaZN_GrSC*vP8JHruZI^hv19 zk&@3^{!Ap1Yj`-)3Q7j0SCaDCNJ>*kXG`H~OY+1CNf5YLjp3vvIP`+3ZVO7|_Q-uF zPnW&<6HDQupX+l*#co@Uo_m(UL5m}vJRQj-P?gfa7SF8lnB}{oq$yY_%}fGUB5EYK zZTFaYR`$z3y_Av#UjB0G=nc8=ULVED2pd8nIs=vl5Y2V9hvi5}%&X@2BKZZY>F@_n zJpMqg*bTw{YEgEdm9YK$|2H$Iu4A@8zaPoYDGTdrZB!>+BEXmZ)7H3U`-9((Z9p4( z7TcaLMs-cNDf5V$&9|HqnJl*T)$>M9{XMDK8_Cd&T~l9K!r-B^5L2g@)0e*~Vy`n; zG#*0YJO)A}%ye zwCp@H>#0a~E|E9KAtZO?F6B3$0gtlkN-m7?s-E8e(EzhfzFj01XZ zew1~4;B0v`iN~Kq^62rscVQ{xPHSq69<>=vQwypLk93GHhi!L{@1fh5Qr=>UHVyWL z;SJ)9L8T>}1+&+mwMf2B>v`se8BU5@%$ss=JsA&II|R6R3g+b>TS^Vnd`3kDuxI#9 z8rNF$@3K1e-XAZe56p{rn4}Q%9igC|1E{R!_4@x`UXBv=mUs6>a`OrxN67A=@eY{Y z5J?(Q2?&)vVez&_?~f$+a+Y_TWR!U}Z|76@4kO2{isKjKF!b` z3SMV=O?KhkQS740r6it2{d;6dG-K>Kcxm(tsn;y8 z8jTugvenh%^hei^6|txLN^D*o$!h`+kWibc<%_l`Tktl{2Z~?*f1=8!G>5q7xR2(j zWM|;fcur+;z1B!|Pox+I=j3RyG%8A3&l@Pe?Y5^h;F%~P1E;}tS;zfX4^z^~kLhh* zI^*^cNxZTMTjs%FxC+RSwR<4yB%YJSdNj)p50)9BJ4B|0H!~RUm3so$^6YF;@8qk= zTN|lrPNJigyf{F0zEM!Lq;8_$n^Xe zK^D%8tA9nMXG9;BDWp?wlih$NJglbDNWyT2UNPUcOQhXThbNr5HWGtCXH~{i45VUE z%ntJ!#!?=@Ku{P%rT1=KDrbNO-n($<^jjA$-3dlA-(PQYOQ}zxhPMxHAKqTrUf$B* zkLQA5o#A4)LDf6=8dV_OEr zUKV;E-X-v5Vao4iq4(Kc3O5Tw;AL?@ZOpp_ZWdd%gqrA}kD}1myJtY*U^^_ayKewj z*G+{Fg;9qc{C-WqsYJCm?Bb97~O8!!%v>jd!lOOhx2Pjpc z!{l7FsobZ1^SQcI(>aAD= z3K8Vs6=JRxhd?2WWZ6P^gYY&Vi$Y)j9xa7o32TH=haLQ|gw3}g7$jBPAq|U2(?=@V z2$lS$N*NXrPe2!Z3K0uO;qi#UW6Lkc3@j$J(6%76XHQ1H*j-1#EiSJ`itbH8h{^L$|n~aL~Ca zuFzlLLnjtUP`H6mCyCpMB6?vI5ovuPx9Fr>WQ{T<-0VQyIN+mKYo4HuuP|9C(~h z3_6#a-7&Ka6rbjiOrZdSANMIn@EmWhoJ!(>I-V8IxW#iUj}w)Vg<^Z`aA~avhOAhW zTZ!xEPNIuJbg@e$Th7Xl7k3tv(=|(VnjpnuJ**I03VUfS8cYm1<1xjfKtsFpNrrT?k)oP4J7XXxe_M5+aNc?q}l0*KpbZzX`CWDhc^wl|BT~vQCECq z91G5W}QlpM)YleS<@ z>?XE4Z(*xlVvv^wk$wHj%UbV|O$=Nh|SRn=FzgMJ# zYyBdKI~H{_>3uD)X;XOSPF>+Jb2hvCN=+wH?xS%V%Crz&E%-cJ2V($M7{^)tX(WJ>p{?QYz3BR}cl%fM3**}XnQ zb2-RhvS9?1!{3LAJ2ZIKwj@`H3^qrNV0Q+wM>4P~3>sTN(AEdhxOs_t5`M>awt%2h zgZayVO=6>vrD7Dj=b;5;h&UFO?3?Ni()&EP_X}ANjf8TE)US=8bQ}R%(hGMo;nlsZ zU?LN;cdywzIf?ql$q0z8+9t62&Q@ zEh6sydT{mUP#pI`lhSm2?gW*{jSOc8v4x$$(W3HH9?d~+<&9DJsh6;A%ejG%HMY5L z>V=+bgcBIwWaZfuk(Zqindj_-$YUatETv`8lcwW@G)Y{TE<-;fYOl&-$meoOg!dRIa-^+LwKiyJ0AtY4f zGNW=8ovFA&FRAHF63=KO2-wPQzU_vg2g{`2e#fZ6_boD26AtALD;I&vSK0K^bb06rqm zC8&iUjDSbNF)jD+NrNx~3W7u8VPwKV%ydK%(CN@GurGv&%hq$Dy<*fyfx8cbsWe_o z$0`{bTy8|L(?+2@XepCOR9-70JgCm~btbQ=bs&13t3GODq0Tbj|yw+?iENA$3J6_$CnvqcQItiiTXGwYRK~kA6 zmPER(cZVF8kV?%5+7YNlNmcRyUSXwjAeGEvOUkRix4&1y3ZzWq`^m6MhQ*mFjg^OR zgICO0Vn(!shdB!4KQ|#R z)Gmnw$J{0}%FQN+dV+c$RoZ+rErPl?w2mR&@KVIA|Hs>adEQN1@?3&M9W0JWP|0MVkR=dncW@K3B zZOuo|)3QgV9TtXQ$G|$GvG=qY6-yw)@(i)vNJ#^plv3U$Q|=y7+cs2Dq?Wcn5p{BN zvahd<6)8PDC1W-eNyYYGI;qK-%Nvr*itc3O{bgAkvcBACBAu+nPEJR6$}!$GCoS`= z7{LkB8qxPIwC6@~>yLD_l1L{q)QV2sGcYE+rHSkplNXNe;XiL_s2i^el~3JVXe~R` z;-vDIt|gTxI$WNT&|k!p5SspDn~>NqIbq`B-cf|PQBqDP^m2>(nI;J|qalf^oFNIc z;Rl zqe$%Up(PNTUgBsW1Ai|?GvE;KhxeD--BP24wEh7eP3!hDRp3g{$@CS`R;JqmJ#ENZ zHIyL>^fs4Q-$wMg9V&Qd0-JO2!ljvAWMm961PQ;!4a(C!5Y#WBn#gd- z56UCzQwhFcDVQo;UlV26j{;~e%P1SW#jGYq+K-Ws!|;`8VgzRVKy0$&g1E#;BXpM^ znnoBQOS#(*%fnzFQwuCoj`*Q)@0H~^L8E>U36osTa2Y^&&JQnShSOe&@_wM$-{)w; z8~re0x~`wXoj{!3Hd>9D;4Luvag4WFvKCiuCb*&8h|3WnH7m+epq~%n?B7;ic#-Ftx`8zQ+$lccB-!56`~( zs|cXlk|Ff3{m@c6hvTr(Bw}~Sog37f);}@d>&HYyPn|f|kA`~DFhIdzDA9$5to|m1BbJ3iGK?M!A(7D_B0r`qqYs8~ zgpoorjrmXr35!i@b9^WS<&jDeUX`9s`)~*+Zsq51L$E;$`$!0uu&|GYV4k9QI0W;` z@<<3aWX0yu5Nr>G!6=BwLQpk(8Wr<+7@oqW0k*u)*Zuaf5C+ex>~Q&b2s{j5A6iDH zPd^dDz%C~CRw2Ds&ORB!Ne3A`1+xD{|u#zC7C!Pqw<0Y%UJ{JPwYztMkcG2fU2-r(wtiqIS z*}soM!9fGI1TC8{MB(_Y>n}#3U}weqbg<8%~zx0kZc6SHS3D6g^+NRj9n7j#a|C0Wd$w}pKx02?05*ew6m z4=ebx{B{87&+^{_P&do(1Ype46t%65FMU`$mnSW@E0+0T@v$UU0N6vZ2<;IFh=Dh5 z5jr9eFkbQ&VR-}solY#miU%9nO};vS0lz5NlHNLKjUOJzF$0#+iL}*bYeNXKpJ4R-DIu`985l`l z7XssucmnsfEdTW(3~7DCpgRP{-Ck@`r>#0WHH0yk%k3VC7j`Rm1nTzF{5XR$_2bB~ zC}y!yAg8y&f^lsW#2J1Z9tlGhiW3=x{jG_9RV<}_N0>AMJW-!JQ5BUMNVQw zSP_W;e?^)(L|7R>5SPrc?Na{b=({$7<6r<6(eXY3&P2Ct?pM_#SXIvj_w{eyBID>4 z;+jDBD>#~z#&E?Sf5P+IoIObqh_o!`AmMC%l-^;Z!%_#r+g&)KR3HkxLZEi~CF-Ec zsM@BoXr<*~x$fn8a{#>Yc9L=-E1*yVw2j|NlS;r z3#|6YnLK%Qy1c~2Hw&-w;Rr@riX2997K(m-WVFg<xi!!x))ld>pf`IDpZ6k63G6EaOGv zp-}<1*+C*h$4ZVIq>%?6hW5sQREB;!^q=tY1jaj+WajiqV^)4PN z=*Kc`+3jKpH-v~cVsFZ>WYQ@+JB~ID^EuV!pooo38x*Wc!mZa|ZRX}&> z%ix=}dL-CY3L3lxA6x1TZbmTNRjH|5N$u(kP2IP3>sFaSSqZ z8>d}jT;yUTV5nwNu(+{tLMI&}TWou47!&*Z61`DTQ87?N{ z%Ube7Q;+0Jc4S=M5)pgESQgMrfi-zfOFT}Vm=v&zbjw%>ml66-%4quT3YVqs61>4P zWM%A1AHwE5y>MU{x%sR+Eu0V9LI%GPfva3LaI_bHLMmWhn22uIo|ohoIY4hIr*Gi#V6AbzyYPb{BhK z3#@3yZKHu)6o&?K^x=R}$%^3)ml`xITe9q_!fPVoeU|>(NO->^#vL2ZJTq!Yi<0LY z#{xb#lFepe6TgtgIede4G)hGHjgP1(zlBVyWH!^t=DJ8WTPz##fAO<{Sw!z~`mxzc zT_4G2t0-ocMm%LbHn_|X$4#l^xUbgZ;aX$hNUbSm*Q=hn>A&mBE44V4CkQSD_0S1K~M zgiQI&4ObJ~+=g>GY(15+Pc>9h*Qji{hax#C8-tuy2RIGG^WNzZ&bLIv#RoUT!2*m{ zG`SDg6n;1|OK+^EBjH2Vh{{C5VeFZidRH_;pGDXmjiAnnIaadK2%E*9Hi7!e%?5oV zEf97V!_K^GiLlY)cC2nG&(53H^tly6EEa^k?s`JI?ja37{_0>PqDLo89` zJ}gw;hapPFkHL#yI0&a>@@i8i=Pm(_8m#2ZOG1Hrh}UZ>HKTdq;{sG;IM713O{Dqw zA+HaTBXgyAF;_JOh3RoW2jWrU|dOvhzDr0aWS zxL1Q!zDO8hxQhtbXo?qg%w{q|EEln%#T6n^a3K*Wxh#iV0LA2h+lb_X?H3r&qeED6 zsY^m6$7MvoP*B`@Rhta@`8>N(1=|m{95yCs#ghd06F~x>C#>(XLs+{F(=u1vHDwAn zT}$YAKxDjE3gofTVtfei?d8hxLB@%v8ziB4x0EGIq1Ov3oNg#ji+1cU;kp)_chIL2 zFHt;UaNh{`!R3CSOoxZjKccL7N{x6GbXUM#5?oKh@X@g#c=wy0-u=t4@+-3iJp?a5(W z2;<^lkJ!6h6_l}d=7!YE(G2SSU|h?iz^kQ|@+ctC>=g@8Emp-GS9_YoFuTQqfh-E~ z@|Zp^CD?2R3m6yDhR3KB*+GPwU0i|k4w_tZGf=ZXD^LcnpTKUPC@#{PomWK*V~|Gz zMa$Z3rW&xcyPPhN*zAxBG^dO?rkm|hMa4^TC@%I9sN@JYTb%;e?O`_0)OG~1%x0%x zVb{p48>L@}VD>pZ1nxOY%gQxF;+TC*RTMNS?;jFiHZ28^!JR>__6ab%lmcLIb!ZAG zBnZ9=v}bE!HY!#2C4FgI%ZSJy*_q8q!P=87=$D9MRON)5ok)S3y>rBeNQ*r{46_j_ z7ct5A9HG6E@O z5^hcD2D>KN86bNVDg*a&UP3Txi>ip+WFlGi6kyYePMtB@mxbp6BZ*h3WOIk!mb1&BE;koNqDizm05oqgi`uyt2(j3n zku2Lu3^LPTbVwky%?Fj{p|T@rnGeKHU}3p!PH4LiYRk;2jNlGGxTG#C6SCX~fxuGj z{{aAa@?9R##1?UGlwMnzo7Cgx1mewi0S;k>IGTjxzM;ZhaRH$J#t@Ge0}+bJ0P)zn z0QE?h&;%kYWQk|q1!&7oDJ1|;ybA!Xs))QT1B%Ib+Fg=GyF!SIn8#sA#c`{e>k*=K z8kRf<5EPBTHYLI;jX;(ke0G2C$JDWh#B3`gZWLHM$mj`4;{^YLu;~zeOj{|-Zlz&|7Y?vtm>Fh)DRLz1 z)IiJ!MVN9WSP1H}6@jZX5VE5VHD&4|q|1ZobJi3um1FJ1`Ggp&Jq$&Q*$>(r7u}QM z)J&W;Zsvj|wk1JpJ#rZ;UIU!sKwy@Nypv*`%Pb9}77xY`iDfOu`h!4$tzT^%sW#$s zbJMlSO0!m<6|wrfz%ozrn?b} z{de#o{@#kGBw?yqijGAc6S*ZDXW<&WB+u#$+w$nBi!B+^{ET=79`m+T?1ETl_fJM~ ztF5pwJ6oGQnA?AAb+TEi?4PcVH}_9N^K^Efb2i|q*@YRpj1)`50$2~g{|2ELj|diB zghK1=ULHV&RCacMC7M4*duR6-2ov7T2C}z#e$=Fo)Msmls|^7#2j+s@SYIDhE{qko}a(lhqfm zk5iELDj@3ifc*iSv#@c6{aRX5rPMG^p4K6C9I3Qax#pCFJDpNte06r;Zc3p}=TfDF z6!r|w63R8mlcljmVK*=nv4>n~Sj0-xKj*UoZS2@{=cwEJS zQ93qPP1I-RgdZ~|r4-oEvh$XcHa>NvHeW5)W)BN83$#*IxRlKd(w3H{I!~pEqX;_| zwsmLskHFPoAo+g^O_R;TSi(^c@KSrE>wW-Cx24NvEDu$&y!x=>-yut*0%Q!Zizz(; z(P8sG>b0D(WAl1#%PM|@?2?scMX4L9B8LmBXzRzS{6_UCjRUD3k?uq9@o56-J|=tw z3B-_uHApC8cSc3yVQt#nrkCC!SId$W`7f1?+dQnu&yk!-V&6(P?CTU7?R80G=Mx8A zXwcZJKP4IaI$PT>RU=*rRW2PU9;zK^CTk5$g`M4h#a1XC$T#Y9)kgCewT{v`tQ6`L z!}S3K2E)RW)%Y~H+5$@FGX+_DiKP1@B(iQIB20J}IB`1UR3szt50QYaMQJTE9)nKI z=CKlmCssiO=rt_s5JGijOQ1?h+N=CsCY<)O;?eKMjb zl@1gtvj?m5w)fe*wr$z_uTbRn9SXMN0p>9}p4+Xun-w_3;vN`oRF2e|$E0O$XC9ir zuxBTqCus4>X6;C|Se;JIPKhuu6Pp8TaT_#L7A^+T989YGaiR&> zAgHft6ONphvb+?A%t!kGl%k1Q#dP6ARj4>noy`$8`(&0}aNusC8D=ri)rhvVd zxE6^N6mAhhOqkzQESuZB(jXWRhCMc*;T%B9PbhY9kP?l5pZdyeP|+u{Q7t9elSKm; z<#B1;=ita7sksrs0sRTqvQV9@H>PYo*<1G$4}}vMp zb#d~54d2-vXB%?G!0vvM9JKIA_1}w3Y!_lx(AnJtKBjre@Sik#wKA2Poj&F(BAb9c zt7IY*2MHTqvdh6;g7?KbyFV5xvMMf1M%l|IblZ2fBs!hlXq!a! zA?4y;Rw7xOpQ|({4@vu-ht$9JvepH!=>f^EdO%ezHC1aCtMl_%NeCfT>>gE=#9k2x z76H;L1B5mD!{{~{Bl(W&gYdzbEZ1ml*W;9 z3Qn1^*~7C~WJw|$^QghMLMb3hv5YUsqD?ezI!BYwOA8M< z?I2q2S46aV2qVtb@aR{{>lcO*Q>1w~r2kb>4K2(eS%}j|Jx`W(QA2^w- zO0v+C(QqmB6M_6vM`fBTs{-0$NQbb$e|D~}P3>rPdZ^x*sWh?i)7gEEmq)O1=CKc= z470MdGW%^Hz(1wdX#4^?CdzS-RH5YD>dGPgV*Y1mFOe!H|(1^2aJ zmM-PSxEF$ANW*tvgFiijtx#;dz*uHc4=R?}Ax*-atdtUZ&Le}@d$>|M6kSTQ9fe_Y zJ*n$50^N$`=3xEk;6k%mpQT|eUH(p%V0TtZdD;00c;Z!hq&`)ZDh^yCHIk5xQtYQy z)9ETsNV`*BM48HvB7g*W+cn)$-9sKv?pBYIckb?m$H*BfazYsi}EhMl5 z4h8!xl|3i9>B_NOgQG+3e{m*#o8~2y3&m9iq;#`+4j*dNXY2E2$PS!H znz0_Fe<8Yh#mPg}nX1fLYxF2r)n=v(;3e6RG2fXRKa4Gkg~{eZqe`Pty0!)}MS69n zG6!=|rBl{<$Xt#(W0nEGN~qN68>&{wacCMFBekX)3pb)t6Ii9=*h2(`XZ}3r-CwUy zONV|L4T57oE8n!Z->pY>aiMXbGO3EkjYCL?*)^16Zv^hoRCOvdbJNwv-pT!w4GQHn zW&rFy(pV7P@@nM5Y?bVaXmix?q|A&XoRF#W6V9EyGD!U5WMy`eLe64w4MQO{%NV9{ z)rU0N9I}+5yvUReuMqBLv&$GV&1u=p%v`rYt2%1zFDZwFHAS#cGf9zk$2?=&4y?wgt9!MEgCE?86_K7 z1T`>qP|g^+ef;p?!hr*f?~4-H7UIa|IYAi>jgtc09cPdq$}+tb#t)027v~@;JO`xG zlOBM@R_2}z7rEyPVo^y+d}^uzWhcsuym^=k*4#}}t_6P6PndAN<9;&m^e(iFSqPsr z&30+NpKx${vJ7=W_H=Ggt_^dI`hnVXRn#uMI?6ajhmd6wkg&|`e6un=jldoV!%B59 z#~u{Bk4)&1X3NMcb0U%4spdHmcg?X;Ep0+~3s2P9i1VTsuYl_I(q+z)7NCHjbz-+q z9;!4T2N&VHPe7WrnQD2q0!4(C)$G(faA>cb0y7tL63j&&ezK8&jT}b_BUP>c zWSmlIQl9|`F%l7+kq${#=O-JrIczxy9%YE0ZWt_wDzL4Frt1~hjI+%~eR@7KJ5`;l z;y(-y5g0}+96v0BB`~Bo09YmQ!Jxp;;~VQf4vVd>OD3ZIIjxS-Rh)(j&`$ZG(ejbQ zvK|?i0?hE&&d3M_zlH+@ z9Xl|@scq>o07oYr-1FFycR6ry#ZxV8drC1zsx$S*vH0|KeX`Q@1_}#uD#b=tE6>Ka zil7_CqR4{k;yJ)uD|lXa6st|801`0%oE*45{_nJEO!TI1P+AJ?V;Od`$d*>14PXrb z_6b@gHnWS@^uIfEX}z&Y|jr?4`Gu9Q#wWW zH*9#$zUV>@QqJ8dndxNe-=Bbm>ebY-zsu+V@sf&ez!6i#G z_z8E)!vf=ny%x%20t++_v*%Qc><0m@R%T@&e}E;V`5;4fojYt$W=bV!%?3~8G1 z@XhS(<{j-q6_(6obv{vVq^BCASl%>hlga9V+H6%B)HLjpGT2xQ)0o3qy$qA?zFyB7 zx?^PEaLC=G=X%dvli8W&;!+qzRr*BD+)`Jz#V>m}!t%Ab>NJW`gleqX`GQi^&0(On zBiNd6;Kzglgi^AfY@VMc{UEvtxjFC#uUbVz8D@z_v~-QSS* zV#ICCzA#c}Dp_hGT3ejTFBO2aSA2dBd~7ADjDM`f6oXXef9Y?MO$ym?wLVjAHjWt@ zN-4YWG8oqA1WuEj0Vq3L(6THUQ0EWjuzjtHKqbYwC_E9dy*L0wSO>O9ecL2gy?&%( zTBhr(CX4Ek8gk==$Dz&KN)ln81wKPa)m-HlL1u))$pR-89~Jr!pkpAXDptO%u%9DU z(nFl}WH#S5qme34+L=8X8U$<-?xBMtdS7f$it1J=Qqs(nwiQJaab&7x&6PmCLQu`z zV6Dj(qRIKY+GxzyG5vF%xeebZ#601*9d&UT^mv`l~X=_6H+bkmojv9*eT&qC1wU(*6~pyW1R-ZI6F$DV!p``>J$Nrt&53!`$ z?!$D%qhVEBW%=1@6xJ&Ql=}2ds+SXZPb^d7%Rn;5Zjb`W7z>n#Gc6T~Xc1QWE}(h? zSVW3fW|@@7)^~ME+xpvpJ0WbT1F@Wv;bd2eN(B|Fw=L8fSZmHU=S>e#A&&{6m7Xi*ds!VtiLo15WY$YgFpKw~cHNJgctM-lV}#KvuD{aV|_YS z%Ag;nq&{3o#`^lVhZg`inS^POorHX$ zSPDQZN1Sp-s?Dr3TgZr83Ze{DOB`CymGQKgc!hVlXoNb@`k{@`2{4FtbH?Q$EC4la zB`M}WjO9VggN&g#vZxgjHL#U|3Ws_D<}C#d?`_ddL_6J?4Jl5d3}U3fc2a8pl}pia zG8Xx=^RW~{`DlQu+YR<|%=XjFHuZIs3>z8GJCO!K9Y~6w8pwx17gJjG$%HnG<6@UO zY*nBi@8onf5Vm7cQl;_p%n-MEsVXMd@IVN{qXPpp4YB6gKwas*EAX-z^aa9Ux2>PJk8X$cGa_K1Di*0zKPk-RmJ<{W|7G{#YIaqv6?o^StzW%x?XMrt9JY1uy?g4>@{U6U(<6tK|Mqjw9C1|s?AiMsk8R29hFBB$ z4cn&eUa+jO{Ei3bB=E)wHpR+eekK7@4iz|aNe`0Ek!;@1m1b+r-#pY=c?$}=H_f$ zc>l~&$9Y!ZNB`GvZu`(hcfI(W^VTH~%(#3T)MGbR-^IBWlKvJ zmd!71AB62B-PJyr8R+Qg-q<^T(|e*e)H#r8$1HXlZVJ;HoBk8@w!pg7*QqG65e~N3 zr+fN(+cBiwoayUthg@24+5+ThL1}xp&Ld^jU0RE z?BAXme2+ABov-g0OlJnW-XpQ0E$v&odwc&QCDxgN#8T<`S1KB|weF7pDC=(Z*4@F9 zGC0uL&KcD{76fM12FZ~r{SK9`cO%;5{Lc5(uymDyD26h911KZM`6GT1lUUVVSM<|U zAa6(7OY+;|JKreYdFL6B3wiO;zsE;E_5x7iqdzXZ;@fz66+b7wdjg&EXX7I~w?Wv& zM<3H50EP)r2>80n_jRrBYme{iX5ZH>zOOrcUwiQ->DaY5Gqrqge6+o!G`{ox;?%zQ z=#Q8d3!tP&>OOXhI0j9in4NJ>#V=3(qoc;#+4z5gykWTuhDd~+hyTRQbGq^WBzfD4 z|L>ExUHCs&-ad~1C(GLx@E@g#5Z}aqMfo|rDJqQobn(r@e^$XFWakX0ma2n&euuXL z{Cu6B|RH2~YdBFKRs`$S_ zZyMk$0awp4(4)>OS_&&v#8J#92&*i@EFn~nZN@LP`eqnsJji;1S6eDmTsD~dp=s0clu!`w7R zRBmPhRsk4O+8EI(&2bu8V1L4I7(er{+=`Kssc<=N=YyVoxBzYpF6*=!E^Dd=F5_x~ zdmG$y;C=`0xp41;+XDAt{r#-|{t?_YfU{nR_p1ITCzazj1y@+Aw*qIqg>A5~i!JPf z7WP>SqryTe1@}02MX>ju} z6gKQ{*zgTNf^5hNg@OeI*>Rph1**qo!zzrGGZ=o#k{VRIpAE@wWW&i4Y-)i0CPS$` zO9lWDr_)kUjHKe3h7ji#<=|t*Tx1i!f1P<|Y3AWTqcLLQA@`7VR;Y;NKl4h~nE-d8 zhQA+G%+#mgPJ_D+F3X|=?qT|yRlgWNRrP#RRj**IdIcM>co$jNCoF7_g*ixr3Y(|j z3dWGk5XlUts#!~12*Cf}WO7jM?!5C37Ut0G>hedb%lD$Y2nuFMWXNw3-Nyh^$z#gN zd7i`eMc&QBeF26t z+tNIN8TQXdVJ{0v;g^9y$?-${o(f_Ay1tGstT7(w7}%c0{6+?|p*ha|&L=?WHvIfD zc(#brb<-(>u`+Ozc#kcCpLDJVe|{Ig8E6@~AZ*0z;(x1k6zSH%1T;n@0j6nelXR

    5. %&|w4hH}&>a@E#e%5HujFmBprG5L?iA5~t_-e%3h_rFpWj^_l z;)v0K(+d$C()Gh~PrK2DyJezc!v}A_Fe;P@qigs#vK0E~`#yA4NyeoYuh`YNW}G&5 zgJanZiGz*FqP*(Z^*q*Rg?TR5&JRg(4s!aBRpTd)HLarjn<$l5YI@&{#!_j6j$0L~*1 zLVqb1=06i?3*UY5K)~$@2%elZ+6*XHdbuhqz7nX?|P9YyPNU&e|bFPCUmwa$++3U|yq+T%2>0o?7yQZQVo#zYjhibI7ZbNz@caHMf_O$5g4$z~wj`Il#+Gh?kIjtf{i(zv-;4)*bb?3^EA z&@{PnQ6F@qadWX}c`e2L+HXI<%jPQ4T%>Vx@pZuF+A|yq+FWg#i!^Soql7C5KHdA{ zrp0Won>80{+*~XNJFZ~v3FsDPzP_WmNaN;WEH>AN(@y@3&GoA0B8{8tXyN)8e7gTV z{}*4kxx6}3(zv;f0mkcLDbXF}`6-4CGljf3hmJIEF2-W38b7sQ&)qgxz2+i~n=4ni z%oNVt*Vkrq-JrQhGd?jr(oZ)&#tyh>}Jh%DoRXA{+1=jjQx8lm>;_^&bUsKxGvXmo&WUb zKW)eLN6mGb71vRm0JU?cc^a@@4+c}I<*U87J8F5R=9*^7DYE34xwtR|)0u*~G6i#c z3g#gTW0uAX7KU*-d&=pOW{%q){OG2owB9p-^?JA(<4FC*2ky$ZssE}apJC-|61%QA zGhcI3F!d>zNDAf#3&UJE(|jhRyLg|Ri)(t^);$!4n9Y@Nalru zHMJ#`HDv+wBb6(-q%yF$DqLMv0^QzGK3=)#s{_bEUDe`nRX}~yN{ulb2$hxwt13!M zwF0jBt;;2-q&yI;E`g$MiK%@IGUqoi7j<2ruC}VYtgNCuV15kCPmQ@QP+pDlEvc=v zsAi{9A;R*C^5W|9P?;u^Z)vH7b%DjjAsB0_sI|luq@${?4OK5@jhRWClS)-m7C<$X z7S|vLsUPKBd96WS>w>7&x`6&xmqr|jO3TC5WwoV&Lwv+@$wd-^wUwo{;p!S^+tMHR zT%@HXfr^T%%JQm;#ZW2lDwv(D#LLE8RH#1pN$M^tXmfE(OAo%ZQaM=`AEM6eHmOw{2$n(LyR2*!LqsZ}*c|HYOfALv zr6m=MLyOBx0?7nA9o1GJ-B28uW2~eWx7}woQOH7WAdT9VS{&K1jGum?*r^Z|vQ34; za68~>awcJs>Nv5X)8lTP*kXP!ioyl zQKMDVvP(sGTSZE1UvuW^fhHd+{Ux>4r6qNxV%w~o#V^LpLWCOW70}D0$Ddij`50@U z-MzRD?PgTgqC&E?(G$~8G9-0dk3EDG%{qeZ^t$NDF@Y!{2_Rr)2IE7rp6be#|B#Bj zL!X^y<(9^JUZ8fn|U*1S=NTu)lwbBafYR_Xiw8+5obEgm@R#7og(Y` z(CijjlD@ObxfN>Xba_{g?oFd*3FmTf8~6ql%$_P$W~LLZs{#2$-&4)Pnvro3p{}^3 zs%CL%0HZ(V6CA{mjN(suby1<-ZBkA3+}Q;Meuq1(-t^pg`T0Umz3By_H+?=4qJq9|y8r?AlI=-YmJO;WgpnDQ@&3dPT+XRwd$Lk?b zqK7yGyEhBCg9FFvO{d@bb*wdmpm|I0RF#8Hk)JR7-{Jm;!-@W5QoVf&;Xei4 zg?e{`SxQ$QX9E8;X#S+>xa3Vo$3?XVnLLXbg&U2IFI0;_vr5x>@tjT`={AC9%VFqP z4o`r_#~l^8(d5lX*fh|rI1C--T?v{e4?{U*@9$ba!jo(c*0d-FHEAihi>hjqWti6@g~;80a>E zW@rp_J3;gMVdz-S<$q~~zy>Vy3#4!Q?4?P&d@7IaU6<{0iB!Ht#=_P0FHT&U?rlgD^FK=YZy&=r90 zKG3{82D&#ua|-vZ;6{s=@(MxIHU_$@Ky&{X=yrkT-7(Nj#9+RN13KKH(zgUO*B^$C z(cKA}M>L&PA8E$%pM&OgO*h&&&iZ%*G?V=R;H>tXM&2SnRDkiL8%^FP5!UE8jA!tp zj8jNqJ87p$^G7Cvb5rO70q0f-C6I1vI=ZBJhWVWay2YCIQ2FfzO~0n| zfG^!VNd1>V(7eL|36AxXF2CF^_Hzfz;h0}6ss2-z!|-7VR&dmPOJ(O@vh1A3XwT)B zl()w!`c_}UweuytJx>cp!=W7^}c=WM^w++xToMRMowPHJOQPshfw7-7w6NQ;)3FFJY3h#1IZH7*Aa5KTJ5)t-wFg z;?1;q=NyKYdYj<&Nt_vqFPNFwOl7X&fPC{C_(9Akg=hw6Ayx6>IV*PcFG4<`Re{pN z7dwyA|3zu;YP%h1AQ>tpD9Q|vvUee8!{Zs?!6Y!$0bqE1H+;IGYIW;|$p6o3?*~gs*NZs$L>f{VO z^OtMPhp%uY7F1zDODw3tf-bh8RTdPnpvx_Y1DTS%&VsJCpneM)v>?8sD2_WV2mo{} z+>RrKQo_=;aCA~FKp7{PxyX|<&d9#yGa$~s{yO-Bn@2`I#C_NkvTyta+VhCI54&K; z{2=b_-61uwVpqWr=GX8V-}off1D>CsznmBS#wW8%@NAN^a-8I=G&$^Hkh;Z9&6-83 za7U-q=Zam6JZRh5x4Z~^_VwR~Ke+j$KQnblW#4$7ojNq^_+$>T%u?16>tBmuBLK*7 zwgeT1^u@LeZzvbS{jmZ%em z>hqNXEd<16J8S_0surjW&|-lq096T84X9k8Frbh?%K!xhx)4yAK$iewZR4a7pb~*v z02K?=1}Gp<2cRN>x&d7vPz(@9IiIl}&;o(30(8DWn*ebH_Zim%S}4$FK<5c`6QH>Q z-3mzM_jW*qg1ZwCJFw5V3lNw0KI0xh`2yVwC{LiRfMyF+*|oL_SLkR3On)0L8StOp zE~Y|89f)D+E_2}B*y=S42XB}PNv6d%Oon?Q)L8Il-^4ZM^qDbV)+l`whsQs_KscpO zhnudqeH~Bp3+cyv31fa<-`^5PHN-QOJ}U^Y{7Bc$m>qknYs3>S`-RU5EmxX@YC6mD zte};E_@wUZR=7?pbQ7Ru_`xJ0K8ovne=KPND%gQh2aAb7Zu&$ySkuj2YMJrR@UGa0 zq{&`G@^Eu9@J;y1;>%2TYUGC&5HST{Cgb907<~{+&R`A~Qp1FCSGoM@OBEePi7YYg zMqyZHic~6R0a9I*jlLbf!=w_D`q$4f`i@T2$vkLXf^ZzdGT=X0+ z?aO(?HgZtEBpk1p8V~!WBgndUw6yn)L98kgie8?BUYCnC|CD&e!gx3k?=Fk4uju<& zKQ7~sO=@gF#5&5{m80|;4tg8L9_ezl*qnH{I$ja(J4>QDZQuuexowaD1!8+L#`65I zb;b6x2|u5Vt*TkD!(ELZx^AQ^+S%UKgwGKE=BBQ$Xw1Jl;=dx&6J>w=zigJ*OZ=si}yTvg{BL&J|`bE7qX@(arpg6j#uE7~el>rx= zoAEnL^Ez|~zUf~TaO=M+;P%4{;GEIF5#2jmjsE5wz*pIHJ>)Ei{G5p8jDP3hBQS@L zBg}q)_q%k0r$f};hZlF~B2P(A`pF_|5#I=|>5a8I-cx>w$gS0LrX#g@4>j#^BJHq_ zTCaOFpMpu0iDE?q19N&>%E4d0U%!I!8)l}grTQ8(GFYj-ZjS^)T4K}d3M9*31(M(c zo8W*=z$1y0q{MXxZ2|-RLr40KVAHJBIcp-r|FTP0l^j(b$ImD0wC@7Sm1+D@fmXx+ zjzHb;zb(*L;XjC<&){kF`vl^_Hq{%a1A0twGXZTEC=bxX0&&I6^|(*2p?yf8g}~h_ zPyo=k1S$jch(Hy9xaRT6<+k?=6b9~_0xbi?l|F1J1L7J8Hk1KbWE6~F%VKNiTrzUD}(L|pg^9|-X42?@L zJY%}!W)G&m?mXROX(l3F3}wj3Q}`Wbz{6{$?8;0@FU670QM33@vZ6a+;*(9R_-$O= z{&OkNV$l1I_-*w6B{9=P4E=ve%ybb$|6dZrSFZSN^#3I>d|!*-M*m+D!QN zG1smsyL$W33^{`7N%?3%Y8W^H(C_fe#ZT>B3!uH<;xDcD$YbhWVgDlbWFz+OsN(sN zO1*%b28d)TqB8+G9edJYcEnx{X71jxd*{phXsWC1inDjW@zQRw+7&xlnbcB`hNV#ZLl$P@(TSIK)G_j?=8VmiYhsCSfXN>|MXVb zwHz7w^EDt4_irn;4ZiVPFl4ko2kS& zz;lHIzskP(&lq?Ip3lDd5BS^AC-0)&{K9WuB;j4c}sJ^--~Yq7A3 z`?(oUJ_jqm+Y-SCeihs%Pp>wt0%8dsUu|f6^^$39-DWa!S081&33_zBL1?nN0|2I6^E-e*h(=5+jg#yRj+Z{XHV7DClA zMb+hdfK$-*7Q_XK;^0b2al8PCTY0(09{}-^2A|wau6W-EPC+LiL_yrLQ#&EufHLvR zHEw{f_C!7nh!;@g8efFJ6#Tiym#xqTEQl}vpOjFZllS45YaD^rrc!l0AhjsxB%&6< zw4AF#gMh}9%cujSa#<-7@KWDd?Jd!@U&V;QujzqSn5~_a z$F-NnI5nw=^?G{YyPZ}sXXa#F_j)$F3Gn1RHsHmx*Yj!k8Tfs;E3;mG!Nr4M_}6Rr zMV8VnAjYsT`RY+)ls=k;0+%x`#^Ck%b#Qf45!w**K^G98aWXC^7sq0o>yIVz=WVX# znrnOtmruB+>hNRV4c=vQU9Pdd6s`%v<=5exhhBfm=DJ>EC!}y?3fB}J{>pl;R6Y9X zi~4V73fB?B#l0fBmv6s#rOm}9JKYf}TpVZZLoeHZ*N#qS#`O!~;YZ2jGGy=YdbYsl zgpsxRz1wZBcQn_L!o>%+WaZ3y=j(y#(%MLI=mcbe(0!2LNZGe@*6Adn`8xVVIiQor zt-H!j&$&9TNs=DgxM0kaK}#;TZKb1tu@8u@A6kdu2880crB6p1v3^j%r-_yvNS;Fs z8I)vT3W<0VoEC=r%*Gxk<~(Aab7JNZ^RyE)pBR3Dw&djJ0rQ{}GlvPzE(`^QT^Pm{bYYnJ^IaHbp2LlmX0Z-&x(mb1bG)@_nE4zR zhH2&)Xweif?|;M3#xTuqx-d-h@12-A#8f-W2RDkVS4~S!KJ#^llS^zO4Y)AO*IE~b zmD=jUFkhS{Y{|?QTc?GY!!&cnPmI?!Mr9L2V?Z(wef^2c5giIZ96uS+WgBL1y3q^* z7UJMOV_{61`%^H_x-ib(lmiLM4iBZBy6DPZ*s;H#b=Y{?+E1 zppu18?8#im2-j)!@oV^>HWZwhFn*AtJ4Uz&6>5x;BIjcWRaSsf<=Dqu&C-aBDkoRu zu%0OA@n7enYR&XqtGRNm^w4&aa>@Cc47At7mPWg zRnmJs=}Ywwn(O0M?7Rm@x#U{rdcf;p&nL;^Pc3@H&V`@L6S%3CoOv3PTB;|4ZnV~W zk>)zllG8D&oRbbAXS3$wky=$kUl>&mR}rJ7=R2C~WJ}JEMwR0iIqU@_`Rt|}9OWZ6 z&Vlt?at^xWAjmj|jYC{=$)5r&4l2{f@AC1t)Y~OLLvx*CNnS9joKr>4XJt#Sl%<0ScJAM|1)0fPH7Dm=2zjxAb`Z8X2Vlc+x4rC{W)0gZiT5^~P z-1X;(i`6RIt`?2V@7$mzMp+?a4aM=ZXk^a4)`elBH&_?|#=|=As;96FnGLS9l^oJM zpF+coaYV6c-bkTgR_k0eSzOwSV;f^!%zQC^R+?v1@^mX-&X#aGLhQNn$t&mn$!-bL zwdB){FqR!o@#o<<{H#o(^I(45-!#iTj;Md61Uh~_i3)PQn=1`aow~n$5B2zHP_iGTr*r; zzu$RdpB>jLnrlW1*Gw1J$<=ieY_5ZvYi0`9IWDfXg)iY1%L5$Uv5-J_P72p7V7(r* zH1;>X_FJ24w&t3Z!ga2T>$+K$SJ+%(&2?@HSDtXm*beCJga31^&DE{B@`MY)#wLwX zeaCr3Tt-U|S9cx~!sVsBNpVO~ZG(gH=dWJ#XPf$STJmfwuCI(57fZ(d);2pOF7|1! z=acYRIT_RA*V=JCsU^>mxSTrJ?2Ae=0OQ@3)1FW*l25xe7irWu>f_6_IO&6ql>zJU3q`63=VsEfw7dZ|MaSo@WmGdgiHP0&N zm?g*0^f=y*IS9MUd0t96pD#4jA7>k?z4fsh>~g+MOFloPoEHe!3GnG2xaE`Yo4JA# zt>z+)%IRya6q4ip6wG99QHWzM=<+O#Ddz$UW71q?VN9A13qzV4@njzUgtZ`bmN67< z?lTR@$Pww9D2`s2cCcqLwR9U4oR#hK?QKnw|n5&hc8bkzD4t1~{mers%UlwU?!pU2ez6$7=xst8U zgqsC}o428nc15H`vD!S=na+wpbxCPu1#d;ryNWn9EeiNJMGfIRn_L=_W63yvtm1bZ z9z}lSkgPr>%y9D({y=+Cfp+HW2JpPxJBH|x=Fwr5LAFBb7o*^TePpE zMG8)#aX*Bvu2DmlwZ}Tl(l;Zq*mNLMZ{b+SNvTc>BRSHkVzyh4Dcv39lATIyiIyOj zWJhyK5v{^pveS@T!bc&mZtrZjT9Fxti^-&L#Z=te9chNKH=NQRt)QGF=Di-(fp91c zBX*^@{=rsODk@akN=1dMVI`0HO8UgRE{pX2%SdB1s9cB%ybkRt1xiz_vL` zkPLLAgw;nd^7gik5-MddN|y`zR&>7$+q_ii{{y7aNhuO94VR05=pgCKjPw zaDMOS@Yf!<=vF7E}s|U6(S{=~w}b40Ky{`GshL@?^-tzg}}uEW9XpcI2sR z&WiaLO*k_0RP2~Vx+Yw+37d~&{GzCe${XD3(o3iAaT zhR+3;&-f{PrrT%y0zMasJ_Fy4WIFVTYWInP`y+ggI!d*YgMrUD2%qf_Z3?p>`@GM{ z0L1NRpQu%yDi9UL&JZXE(Afgz0-7bz6hN~DnhI#HKz=~y3p5ST1p@IyU4uX~0o4nX z2dGw{Ie@AJng=K(&_X~QE`3I@zP_&heE;&=#kF;fwf=_X)r*U3{em@${k`j&x|`dY z+PnN+QGZ9Y>oOQw>1>KMw?%sWv9^f6x38zQsX5~B?t%6Co)|8%^+(n>HOD$O%=F_V z3D4pAdt>b#9XyJM{pc2BSu_d>T^sz-)oZYa*6WY9ilo?v?ufswX>G*c)WItSH-ID3 zsD}G8FmSdy&Ez($n1??TLY8^#&2!($fxNKaK=~B8nvU ztZVO$_}javEsFg+?ywX)BvWOyuLlH4@?1pNyNz`5mcT=kbu?{2)LK$EHY>2%%ak;8 z4_A_lLgC${D3+S0?rz*e$s9HLJ0qRZ9bYVr|TZ&WS0)?kqUrA8S)(XATVzD~JD8S*u3h8tv<9@uTxc zdU~QglI@oE-fjfSD8Sy?&=?|=aC}n2pdwv{Nk^;1CnP`kxld*u07*VE z3*$svp24UlSKM^T@Wxk+PW*DAm1Iu+0Avv7U(8svk8qe2_b=j7aMZ%LkKF!aNe)1!D)S0J*W%|hIF+gl zLA6{=A>|roJ*Yi=tIPd=#eE5Ul-0TSJDD&93?yLCxU>!mil!ovM8U|-WVTF}NhSmW zY9VaFAedm7VW}96A=WU)t+nc{ORa5PT9AxXVH{QnHDiklw^h3|S7DFb)eI;>LdtE|KTQ8uZm4+|8PR*k##phezhG1U{L2 zwnAB*oGQprPA+8VBKTz4FkLcqGklz-irbhCBE9lb(S2-3JzMiOe82RMy1k~{jUj4k=+k4v1m zc~^Y=mYD1O23KNi_tvcLZCRUlCEh9Cx_`t;Tf27;B0tb#vKKVqAOy@v{7v}(8TxlV zBmKV5NPpln(jWYc^oJCE*AC9B>+^cneKI)MyvVGp?C#lnfdXx4&ne9K_*M?f%s3a2 z_p$eg3LOE@#uf{!T!KlEh955DUqKNHpi zpG?6GCXCieCB?T)-*@5b1#N*rJEbzTsiqmToaW0`b~LMLjG;i7maJaVwmcQQVcF6& z(CU?GFif(FXQU#UF^JW}`QEUYUvqjTCw?p2*2b4`Drk-7=X)owH3$Er<8zAL79WBL z^IjPIz*=YBs!&_vGR{+5s#KIAy|{q!1GT0yhKZ&>O=^l@&Z=5Aa8ZQFa89eE(WVu^ zJ0nyS%-PcPypQw0&+Td*yVFSgF8KbR&auR}vH_v9uGXC>0pgj-QWXQhz;sy-u`=>= zij}$3#L75OxLrPU1`Ys6R^9fIl^zO)(Ty-DqGdmd@&IayJl|RP{MWQtm)zGN6>*$Y z%(2@wmw|8(ox=eIeMLBSMLOa*sd4~uySTGL_vgdi-?6Bkmq3F!LhN@I0q^0*d^yFm zM*-q?eHl->-~IIdFIjvz-qI0AiVshN?`{0j`LJudU6b*oJN3b{v0t^ zz`TK9Iv)-yQg{#^eKn;0_t|n#FK94!k!9?53iQd5l8aj zeD+2B()o-5)Uv?Ud`qj(;=^H+jyRG}34A;7OXo8dP`B%BJn2q*@V%c~d`?#dMI6be z6h6p)X5f&)B#V)1!Z@ga`n!}@p#zjQw10d>33_=MX%?aRkme8#vXlsJ+P z8}xnnrSmx!Q0toGhriiaXYq+BKEx4x#09}SGx8}Ae8e0UzS4>3UTX3AisC~Y$%pNk zpV##Ckb}IO1ds7!@AhjfJ`X8A#F2d1o^QY}oezowe9pj=?q`3z>WdbicN8DuNIq=O zU&Sw-&+&j-LcT9v-L%T$WJeU$4(Gb3l&v%An+%P3aZM4BaV}bUjVmjq6{{s7VrACMfJF%B94>l zBtbP_QH{vG(l$mNP*lWmQk^WQPE}N69=Zqvh0fO$76Tk{oK&1lx?S}QgnQ__|Gn9w zTB@js11j4gA}UqoOH^r1*k^rr?ow3NB`3=Yo>!$vXyX76I&ij$dz=D@^Q-qoQHS=} zy#l8RPkwKH@cRkqC~Al^ey3vh8jQ43Uj zJU%`Hz8kLI@~*|FSW#J*W`a&WwmwK|w~ON&-S3}x!Z!Np>lDOs*5DLCtTA)z{qx?k z^8QT~7jc|aX9_AESJU6eqKWBx|COR5j+5#vLB)}iZtaOLJZVw=O;HiYNmT@h+r@E` z?yQZk-DFWsWCMaDj+2UC6Uz#4S^g(Ku&C-36>*$Y{6@Q7oaxXFbPS^Qb-wgv1>#89 z!-@}aoqVPO;&$m4_2BE5g*6SXyDKWKryrIN~^|_|>vf`0rnM_;HJBxuPPDlZsye%S!SEU-<-$SI2daq9Trjy{I4n zr10UF!tENv0Jw>7mu%29nD;3v;$#`4M(b-3rX?u30D>H!kjzi9$(AOrk9ChEm?O>@ zQcOOe^sUAn1d6GxGqg zytJ*oyi^{cm6xhBG>CP!YMW})f)QV+CKQQ=V3H80WJGG)SYE2m$>3Q*bcjsys0>#W zmaH>LAt>ti*VjQJxz2|(qViJnsI0tHos~&?ncwnKlQIzY)rTvBf$G|7Cf7!%PQuDd zSFUB+aUDXOYFLyJUtOp&^3@uyIVvjZEIIsh;!AvYh0 zRMy8T{Xw5PFq7F@g2EDKX1cgoJV^EmixdK=k?P8*KT;)2NFAerprgE0AEcF+%5xf! zo0Q>*FB%Be)S)FnhSh$grs8h1BIU`RNhneqs*l!GilWt=bwaH(vGl}-e36EIHSJGnyN@mb+A^JEzj4=OT_^jZnv;ZaKwhHU^-nS1OL%WMxY-!flRrtd-OdJpC zP;~l~PL+aaY3iWPOj{u0tMo?#^;MMtQi@YLS#x5$#!iZ(I$Wq|zs#gPFXpepnRd9= zr_Sx1X$t!4>uZ9wfsp8~_VzDM^lYtB9_pEV!*xE`uMAX!ds?5S)j2=ls4< zb=V(6cV%wWUX+f>8YIkvJ1fqJFI*Li*3?$X!9^Yps_d)tJn%tX@I()B+hYy*BEdQs z%7g_;#A+ScAwnKhvo+w*4n(X<9NU?(hGM?@>Z(vMTwgD9s*du6?N1Oa#VCcCY(t&8 zFC|BtMtvr)MX%d%$LmusYhhrXgR}mX9WBfCc9pp+W?9Lt_Qfh=(Q0-tHLMkvm&&a# zHDJjMN%N5uQO~f^#dBQsxj?Ai6jSy_6-`VXvj@c~drX~5(n6=on#!0KJ}0B2lBhlu z48u@vRU{OS1Z}yHXG^xGp--1spF%#~F5uoMn?Xt{hQ{D1CQB@ZWO(Hsgn?aHrVWHD zed&9)j?RT4B^<1%i9{o{8Z~7v*NG1E#IPwG^+!$4wmn`aYRDIY)!+z>GHT8nY z+^{cDABeL3YFx*jumd^fs|wWx>M`PLT-`nGANgQ~uePcx2(!SpN|SrS9AL{!)v%5v&Ub!d1iNqbNfGe3U9`YbxrrS8Rl$A_ciV_s~#tJnh~c->aX-gaLqCpLWySFYL>;X z%7-kaZCzn&SLGJp?yA~YxEAB(IvM*cyW!_^X3U%g8A{U~?HGGVftb6!$P5 z!HQ*_m~v*mhjD>gvMLlDTIB16bfbn{2hXD^cs?WFZ(mFkH;UhRSU%WYCVAyWK-dht zw-s(S-ZSBi1$?wxBx#0V4F;5ERxMd5MNCR6%ifImi@WAK9;sy?uiG75lm{!#F_0IUO!wt;Hq z!?vZsc$mKL0`Gw0H&pt#NFAMP80GlU4TZ;cx)3-&QFuee8wB1Tfpdmh-3^6z3GnKH z^OV9Hs=ZtTysg0Tvje~lg-7!;wZM5jPvY^Ps1Mr~2}6#@Zw)Ki<}%5Jvx$B+4bPW$ z|A=@u4ioRTVdC90OuYMtfyeTHGz~BPo&z-p{s-`$8!ron<;3#C82Wk1tzUs8%>L)? z>s=;w3Ve3KbsCg_o_l}3+n?L$_6rfJWL>_yE;qR-+g+EF_vjbrC%=-N_vra$+u|de z7Zq*0c;WW4kK?0~JMpp|FG+tvQ5Z%x;03dW?#_Iul6{&@m@+2wDVZV_%O(dPtI{)= z7||?*PohU!SqqmIHq4h|DaodMCDW1&9f6IA-p>5qaDm_?D7fLx4pJbtde|mCLV%c^ z%OmXFu-giuEUhnHn%Qe=U4Z163W5*Pcz}vhSQ6>=z%U7P|5EYq4oHcSAR8 za)N1Nk{j9vh0Nw(n$up%pJ*r;*W|xO3r&n!EymBex~Rd_ds&qUIojy zU=7(t^WIFlibA{d9^IAq=vFs494!8z=!5Q$1?Sg#22YD!}C`isbRQ6Fve&R%k zGL?PMF)}f(EHtndi9FDo5ShF3Q1`aN!RW!fo~4lfYQ8ubIv{e#(*ut5LOknVYqdom zv)!h(S}51=KI~15_%RP~o^F~qZ{FYEOFpx0-zn~AlJg3Bv!uD1+}^BSPhYmL=(+C0 zu1#5kS>1=T5?O;D)E2u@C}$_AEqS<1@|MXlPXhx2l~3TG6sRnM&ttG@orPb4c%CU> z+?$lXPmvSto=uKM{E%Rolp>>&=QzM6PjZ)>xT7z9@CbWZ{IA_qc%<;?|0UZ;G9hFu z6Y_8HaaJa)Fq8{%H;*he7}v4P%IN&28(2cM^SVq^vLm~9+9FVlfW?nqm$bB$8XIaw zbIMp5F#DmjOce3%9ec>%N`62!Ld`pm$_4oKHW$`!YIq30bn7GaZAU!;-`hxo+xPQ)t@akz*cb z`>8o#nmN@uDog5xPhthxx7L?=fK#Je6Na}&3~wT17~zGU@yw-nHsY1TUktuTYAVtj z1`Dja^8zC=rY}5AeQ_uo8O=5Iv1{8psrh7FGKTZvtJQIlBWxgDm<&&|=c+^u+cPn2 zBUj;RR30Cm3Dxk)uulx@K@lEN;g-61)E&deBDje|{v_I^Viz?>`NrZm^c}K=xt+_J zFrp+&ZbuRtl6BJr*Aj3|hG&9LO5Alm5grub5fyHWyDp#M$01n89VlCvyXl@q;!B9M zWH)0-9A!^S*8v*)xECOYxd0m3O?)w>!8St|eDRB-Quz_u6Uv1ZhONp9L*AAN`1oo| z46eM*9=yIOj=F?thP=&xLmYedHNExM;tzYD9DvYp|6K?0+&`-CJChiHa`25Fg5Tsc z-staPpomP`ba?amJ7OT5o5gZfQ{k!*P_3zp9vyXro&ihdh|Bqog_x2ouchAFo zzHt|yE0O}VqIYwGSbHAkQzoP96Hdf8UDJKl1x8=r5x|qLB)9eUy+e#!_wgyxva{zP z{KQ>^##cYBLF@0&>ARJSZSXA+cpKo8v0ZD1 zYW?+>EV=BmCA>G05GF2w54X2mJO}^c<9}msyZmn)Bz!MSU{n&!LH0lard9lcK>~R; zKZ>n<>0NlF_sRiT0uu-*{*Z#M4DU@G;uPm4c;$V|{W+?g+*JI=tc6GNZlJ)+em8`e zlc9lR?(NA5Bui#LZd!z+)rB1NfFqmw_je@6h~SbRihkBKP4u7=(UWJQ&!qITCZ7lo zitvaExAiklVP8wapt9;`$>>0`;ErVIkc_6cpeuPWDRLA>M#?_OyS@@roaDkI$twqF zS>v0`;le{wh`M-d&#q2yGH<^}z9&nW)Uw=b<0E}#&ululKO4{aNnzvysV_-3m6RQy zIHNCg5cVPtXnPTu--QlbYRrLrxG-uhO11mhDamttK1}>te8%ua9h1y!&BBI(uoRuc z1c_93@5~;I9?I*voT0Gn)`TJ?pK+h?VCQ_f6UJ8uOf*CUcR6? z7pM|0_+hIH5zG-5xx;0ptkz9WG+LblHYzZBa1`Q)M;djOK2D;gZz6mN{0f91frMGp zBtJsrXxeI0bifxE6ik_npBK4EC(HRvg<}XDhS2VScFvYC z24E>N$+-NFy!W;hSFNIwmLcqdU}FUpH-j|eF=>KeoIekxLwuPcvvl;Y(~OMNw#r!C zE>2LHyP46En2u{?-m0O?Poo+Ks1!{l)l}D?7Ftw~D5`O3RO1B|XZb9Rr;4Am^}%Np z)%Y~3V+9qzw%qgl^;H`&^eJTHb>%rWjjBLUak@pSA8n6g>qS%jS$PTs6@raH9V8(3 zzB7Rw%yHxWf84R#;&Y;G5U>=)Ql+Ck1?f`D8J!1w*jAbMJAS-0Wbvs~RF)?F3y0*x zvC8eb1WzXU-Pg~6RG&^fjZo7`P5Sm+6awmYU4tia%eNeN$fCMdQ5A|@*r_Nm=yq|( zmaXmBHLt#CQE35WsU_boY{)$>OH}Qrci(@PY+C>u_p7*w;}lssNl_iZ}XqT2zM=)lh<;nrgv+Up(8Q%4Ktb<935HE_4j!OH*C_>({?+ zQB6`*#Boxc;-GrpR@J)ku43Qe~1P+#k_ z6{q+W)JSLQSd`H;L&xm$#F~^7WBFYW_?28bRPf5Y)_O-lw{&QrwH^9(%_OO_{s8qJ zICCtL(zs^z%D6ukGZi|jWa&6WPL3wE5$nJ`?T(FRj+6j}dbd>g*(4?GVJYZJhQd5^qocdYoBSw|jHL8>%t2{ExvWKpDZmR!cVAiWLQ7Q_%} zxwJtX$QgoIT`J9rvkjuss>w`EiV>e5cl<-)iio92@e;NKA?r5?F z(`TG}Ua7#QY{4ucTks)12fyGT1!uQF$9Jxij_3iN0J*gF~HlUU-Z^F(2Zr)3&By0LSGuDR_ckhO_aTfp@RM<=CC+Y}^a@_lL>v1>n7L z6n>nQyqk$%NWfwyfKcCA{WIYGM&YvFGVz-Mc&bjzOn8fdHyVqHOSzzc<0m&$emOV2 zMd1*SE>rt^4Dbhlw}8_@IIeRu#XA}BEx>tH;ql|22@i_~<3-?{#YG6*Q0XI^ISNN0 z;*lwR7X!Woct1S~KhB2V83wD{!6uby{Yyr+Lg=eR82nDa()CO(U*U%0cN@Zrf%7YcXO>G!duajQR4i)0 z#)U21Nc=LD^83{j*C3 ziSwCc-J0$LxwC2gIzD-J7XN*5wwwQsSNdt(sL6dSEC{i1|Gw^G7y?B7ixx{doNFBF zU(~9PHbO^~DeM89u)Gl(xB~~i(l+)0*#lxXgPm+zGe?`a&S6r$h>2evkJz&2H@raT z666fRV>1D|4DS+lx#?SH`ZmGG`BQ;$jS0KK^xX*`XLSX}b9k~b7YHqkY=#BUY$t9n zc$W#y@ZQU?aEB3SV^+u9_(?dODd_WW`td^al&fdD6Yd>okX4C8y&ZG6gIG*x`CmJZ znlnf;ruy} zote`R8~i=b`=z7|MIgEdy&eD7J=nP}r)%(Apz4^;@|UnLtc^@no1Hm(sZ zxg2NQ@9){#|EE9f?calVKYTX$m1FfgUvdE6y>L686^q|`X3z8e4U79LTBWabzZ)dU zt_x(k$LmB}Dem7*Vib&UI-fp?KRP)tcaA)%v&vwu3>(YxHp8U=+`UJ@1x4pxIJkG= zc76$Eb0%9VgFR!@$l2cpwDW}7K2$s2>hQ1gnAtJ>i)T|4+|%$u(1k~~v*E)jTt?Xv z$kS~*+cgd2!`YGesgd~cQj1oreUuQ2<*RCgRP)|vgrmb!ES5$X_=X={pah{QvY_;DE$hZc%WWqe;a-dCOD=uAxuQgP?Ti-3DvUs!h9fcPimoa*59g@jU4c76_>GDg>t(GMy^*Wit7}`|J4+Qk(#+8MKL^` zDY}f-#;Ec&4i$JZX(*CC@1y%<_2)||we0>AAYigv_k;{>ZC*~-SL8TR0KyUd{>A-; z7+1#k`&;`@Sh&3*rnT6igMI;Nkk$1iGc^~&CqF8-qR9|XC}-9Peq zU$7X%OaFpa3_mF&qErlru{d*GoeExZY-oT_ey%<>1sql>6x3v%O}#hs`I*@88`FC;pPz{h zza70d^ZA+B@RQPeGoPP{4Zpy>H}mtd6 zcMRu1nH$w<2$6#xn}9hr(iuu0c8C7V@-&jmouiI$L$jC&@~@jL4&>`(Ot4E`?s=cG ztysf|hF&ycD+o@S@GPFV9guvc>utzuUDZ49$R92nm<-_6xHhmeGytCg$ez7#ZR=ln zP>>E2{mm;6GPWErkgb!uAhP|D{~h=h2>D@IdeiYPeT(7aicS{DfgGKi)K)_7{h=I8 zs<$b@(XXu0LZcP&7Afkvdk+OXM_kd=)W2JPZ-$%vsGM^_`0gWFVmnTHt@*yKNLa5Z zHF3WnqdX?&|3l@x9OU1|&m%PW%UoWK_xtcG5NaW1xqJ=pvNZTEeVo#9nJmRIWl8Eu zEme4XC$B*0qyleY=Kr=92s(RsiR&wKUx{Mzl=o)gm@8NZ%IcWX! zoMmpwGnMoA1!r5gOz%IOF!T(@+nY?;#Tm0YXC}^28NJj<`7b_33k@5yW+pyL=FRWT(MoT#v0xkl9NB=a^~DsxWTl*E zhH{1|i?I$qIcHf8-{bfd7_0G=6l+aiAACQ=@2E%n4d zPOPc7l&|~nLuLyht2$QiT3{u{H3aV{Wy;9up!gAf9)km=OrYQNRl@faeg$Ic%Sq!= z2PxK5*Pv@LmUF(Y!7Tot*){0q|7l%=+5A7HYj6brd%Ffb{9ib~6`YNf4=zgHo^6@o z`Mn-zUh|RHJTtG0#61XPc8F@5hiJHo>M@$}l$F&1pDclm@W~SBHhtH@_Y?dIgf2T- z0=mypOX~6^9n1Ar3}*hHuZ-qimF&0PJso4M3vYB>yVFS-P5O@ILpaKU&~fKmIt{7T z07FAKxJXAxW?8*1jUuS*Qc6sPC8ad#nsIv!6}Qy5OG4tv^gyi0bWT|rHeyT7U8p-0 zvvT^1qM@uOq)~0V(;h*UkEhGTAt$>O4tImyE-#*RH`L9VYGLmcFb;pIoO2N3R3bMr zO?GgUz_~>6sNY?Dk;VD%3VJjd&EpqL!17b4o);qMhLX{oB7=?IDPKW0HPvy-Gn9-b zJ3ie%rgrvPR8tg{l+m=87(0vG#cfTxEm<#|XHjVdr%Kw=cJjb(XUTO5QnMvAskn&a ztaqMCT8d<+KK#{2D=ywTpp){K_7t+ltvao||NWCKDoSP33kZ- zVnsz9XHHKLR2SpPxN;x93!h;fS5i?8C0j{ubpLhzec!g?x<^rQE8H0u&xNESN0v|P z?7RD|xPGUoPBOeHRA`!@!q6a6xZ#mkp0lX_M^T-eM#Uwc+jTCV__aO$%p8mAu%h~c zphB>bLnPr+W9QV*l7^3-^WGU2AFra4YBudH;S>keq^8baSX3p7>XfuJdmU6iF4^#m zMOCG!ylGSu9aJ0c>%!3M0*r2{qMDdSbt*!we2shkI9spmR8*&?QJvV|w+5*UxybI)#NlPPTbtC2%hY@ z-~PwJORc!}Dyq{Zm96ifQbEO$f$rQ_pT(?CH4@`*ii$WAMk!J0Qd+u)`J5&AWG;=z6xCTKpI;8ir%3SOY=|g- zsBS)Fs+Ds6d&Sb8K)o%kg<(RBk2@jSIZJD1PdA2qlaab%pOv9 z7IL+zHrZ{`;Yw$hAG+T{q55!jZNL&(mIwCGWr=hu)9+gSmuY++nQ7!s@y41K3b>oE zQJygQ#Q~E;CLL&Yd0_|&ci7(>mvywSUTud6MuF9c!VcAiM74f^3pr^m$E^RSVf zEsp4dFxp{9t5*Bo4*BJ(wGfntfj!z}(~{{**ctVw3lPdqp?PfRyL(te-Utb#uLFcd(i77AD z2QAJ5byRgKJKZoeykZ0I!8l0J8l0i3t~JovFLgE8s7!h zT(h(tyHHAlvoqIg|8-B8L6v)nnSZX!!SO)GFQB_&%acqEmIMNLYAbS6`R1k+`>meamWrcZ`9s!hXBVUdEOOQ_aY z9jL6Yj8yoo64G0c(E2OH!5j^L^f|>P@;U|t66ub1f1`BPc_k8)_cu-u_cy2~kFy23 zjQ2Mj~W zgvXtRbBBS)a+xy>Jn~yN3_S9?B@>=)-VGF?Yw{`J?NGQbz%t#ZSqC`vZ-!OFA$lfx z-b(?$9ylK=JeHHd%MkB1n7rP?2`t=D@%|QJcLHY(C+Bd-<2Mw)CiI^b_|Xl;kL$;b z_l#_-7}B%3-w9s!dqzXW%X>yYIZC|8g5NKJvs>YD?LdAQ13oYLt9ZXW@B<@NpR7kmC_bGq@!u1p&E)@(AflEa#F3^~_}1XbLBJ!_rZC+eV*{QA!k1!Yy|Oku zU)flPxdxjVYAB{&-o9ShorVcPEH5_14dR%Z>1i2TnVL?tnJVIq3h$cLOX3W(Om++7 z%ii{7_%K41dJ3Cmt5?#VHZGN#=G294ZHuKdS{r@}UVQ?_wpS=y--bRKl)8auk%!~gJ|}G5M>8l-yOJUtnF>D)OHz=OS(b$kwyyqtIdLW@0H<7f3jjyl$N>ybYU4z?N~F|Eep zuytehj?l+OUk?NKk4)~^M^3ROeO?aTX;AC6NI)q9!GY9|Ux7Gm^}#05)J`#3 z;1Ddp_icqw3UY{dA*d>BXEV)GlMp}69-)r27QO<}4Qqst9j{vW*e$DsPj((sup>tV zjOmwLD&doyWAO0}N9krL&m|<@V)(-NvFk9eP8Y(fDT0x=c?VvLx865^fA<~1O^UcsDrY{cPT!GhV!g}Cq6tJWTyUFz32HzYJiUT?o z+x@2RG5BPA_^Aoo2A^yw5YjA^ z@;hwF&G^ZNA{sYCm0N`W>V8Jfy@d6$dx3T&o}=;ei2f#h|L>$0HZxL(({cms$#mF5 zw5YjXdg|!!X79ey|`;>jhnT6{PYK`3@Jr{z7Hb*(YJ20v zS1dj!v-QCdNAO`66#X!r58IgAHH8Rp&5^qj7N2>F4{-#abBV(-HJuM9sg{#clkQgK;YwUUn5L15gS2GQrxGCjn3DGlds2gIJ{3BY%zxgagg9C0nP zwO_sPxr0`k^%=924zbrD^XGQ4Rk77P^4(`ATT~<1B;lki2z@6hNP4LjBGj3}wLvo%7Vo3Ccjvw^)ntXi0xsa56HG3+am2crC8Fd@x`Liib!=u zCQEvp&S$ct7YM=VRJb}?8&U?_)~;z;wsOVF78sn8t0dFv7wvtu#Z8Mdpo|4-L($q= zWvX1KFSu3n->Gf3kEEV-KX%`EYvgDG=B!oGjx@cux zb)+IB4P@D3l*^{_QmnI}si&o5EzXxr!T?O+1*__-YW)6BC!`@UuJ%mIdS6{dZDnP! z8ut4VG@}ONfXcF*-B6Jqh5=#SuP#<^+fx=RGf@_>e5coD4l76~!kVDJCR}SjS{3cE| z?JmQP{B;QbOA1~ljY@9;Z#_Qf^EhFIB$iI3EUz#Gd1z;SMrsaz%j{)oaM9$ltaz_qSo-Q7Ui(E6e6G#aoH+8EJUFG;2Nq;B6cR9@kDkO~Zp#os{;%Il}KV;iZ)G zFHz11Qt(7Mr{JvszaOHKkLLszj^Fi6cvXNG0Vl5T__5D~=LP&u;QUnKaY7{UZ1XpO zM7`6p(w`I_=PsE}DnfuC0?sTp6u6<{y#Qg|M4VAt_sDSa9V0l>4a1-&%l)iHTk8$c} zbD7e|A>-O%;IZA`Fbq5<|NFzl``Iw?I4^!_71?MTXTRTFmN5Mxp=G4T>oQ+G$pt7t#NJ1 z_if&lI9#+Nd9X>Fw}K`U?E4*)ti9_{py&C-Yx|FZf(7>{JF~J7TN2tp#AUEp!yFNV zvWbO@`irpR`zf(Di_LD40FE!=Mz7^PJ5cL*i+ZU^g31G2 zO(^TrXR{*XXU%2_#|ty6tiV+|ftA@YLW58>|{eW)b(sS z0oJ{Gwr&_t)jhBran-2qkFpZpo~@lHBOs>InZ_eoadM9+%6#PJl-XJQH)K&JtGv*1 zF{SHpRt#v~uEQ?=FU+84MWjzOU6ch!dTy$D#386`RA0k8zbGDqd-M{<9#$-1+fCRT z@J$o2cTL#e;X7NvT==$1+A{dg60nd7!zEJ@qsQnlVYk7@nV!eE*M#ZQJ~a-ZeXed< zLMkS=*U6s%g7;@Qs4@wz5woxb& z>E1D=cisWmak=nIoug(g%Ff$-IfEN!mNn()^|Zj>yD)#&g}I%1vlhLR7%kdQZzzBN z2;rM`VSZ=MtVR10ZdV9c1$;RmUXl${%3kd}Ci!n=A6+@3=rz|o1W#jdjtm~x{nB9B zYw?_-rrpWc^B#SD*2Zj%)G%z<^d@ZDx$&OEcZBa1@6ZplF&8!v8*+=9-T`FR#{Br$ z&V6~04!U0hyIC6x2r4M*JYaze2`Vh=JZOPVCg|j%&O;W+OOUsybHD;kB4|=k z=Mf7u4Jq0VqfR(vVlY{2w-vtwr5}vuzQDZFnS=bXYD62zbDPIU|gk@FHuX4))8^f z*7*6-*3Juk8(mw*Rfx~tOYY~&cEmkbZy59@MsIOl;EkWWd276|u_5_a^KcnowHKOk z#}|gDnit7$*uw4n?)XIKt2TZ7X3xeOl-#7>B&Q~?t??7PpMDc3!G`_zp5%bA!C_A(h*K@O}kwwdtF z(Xln?ygBq#h+?DgfV{1r9Dx1L3C>t?&6@~pU00VGda7gl4&_{|P`ZDy7q#qe+O#%# zV-DtJG%ectg=;uB!;yF5NN0^{De1Osgg3RiIdR*C7BVOK!j}B=$0bhOyemF_OU!kC zgDWw%duvwrwk)*RcZ#>}A92#w?%jhxjfKk+M>hSeQ8%1L7fXAkUlmh9!SQ93-AS#; zxpN}8NGCL=iP<=xT6D2!-hvCaX=Kr|Fl90FYa@%c)PzOh`!aqWW4;Od9efw!S77`N z&jt8-j6pmlm+>f?auFKZ5N~PY?yQ<|Wt>h~NNo^l;XJG5vNiais7acw)1_+apqek; zfX1g*<-+YlHz6-lC-ZrZnQAuJ#rSFUAdOm&l#;46`a)9Pj6CE(BiEO}mIS z*=5`EuKyE|641?eBsspUF(>bO8ehTeZ_|vF1hd^{Ze3!qWKZcT=d?Dj=MN~i?w^Y; z0V`lP$R05eYyILi>=9c+0}r_3qjz3=05RducpxhwXPLTm&^GhCuYk2)ARSalABF~U z_?F1b!J2`b z8apzMw0t=!YO8PFz?{}5X5r=ir>5e}OnyUTGdj>9adzQTH+v4S6NvT*Ib(jhf86XP z1R*klTmYpqDz#>YKFN6n zd|V=Wj8*W>6L_z|mk==a1qu5Az77HVy9qlE<=8G@C&4H2n&De5V9QO|ci~$pU=P73 z)50@l`DuF{KJF2EjCbIZshY#P3Txw-0cTivirMv-yqC1c&2_4ra9^@IfQfvEQCZtu z6PW|64MIw>dBy6)+E($_(Y~62p#^iBJIwh!Ar*7{86b|ixkeMajLq$dIL>zr+@FE4 z-khzV-*_VEaU; zFdN-~jyTTP*#RwKn76L@uca2%6h%cGCl$-VqIz%KY0E6Cn4%&MsB9a*9CF+)9(i!c z`S8mB`X8$XHz+Elh{RTd%#kG?Gj-#{x2?Forl^SHOd;EdCA{?bEq&jxs9sQ1#BoxM z5ma70>56`}4h_OAL**fklWHs=ZWlKa=mt;E+ip>56Jf-0QlWZ4g=Qq&%MI^hnycf| zroD*cq+-drT>(jCy!4H$AGD}`p~#8jq~btj38ZZrc?~2%bX)_TLGQ%!Rt5RN#YveojjfVf>eaG@JHVc9;bmX|3irHI5v#SLw@i$g18SnzU7(4yL) zs4M}MZzu>*Q(~V0h}%_#Cwuj~W3T_7#pgSUYJ%Za`S_{HM??BeNGfNRgWKih6TirR zobR_d|3y(LaTMF(&hf-|h&&yaCPu<>2-^mDGR;rj{nSeqXAePeg=U(MR}e!$>?MB! z@Z2tbusIT)cwoe>7N6;gN{XW(*a!^Chlg)&7mtS6W19~Ac8SGjk)k?L#%}AU-1C)6 z2jDRp7rlphfNm}86cuqK>``azHa;f{KBtfg+^O!HF48o(q@$>a<7{>8eQuWzPv*Vp z2NW7c2826?AUI2X$tenwUWVv|;KO65iKLkRjcpd63lx=7Ut&u$Q!ACHz+R(>oh2qgAcB`Tyj+2V%vPPT3ci&|j0scc#5ywe&s-R+TrCZW6 zA0H$g*FHr>94FOjfVf?n>hAkK`MpIojvpmB;y9@$0Rl6041`wlV7Kii$W+sxts_yEu~5-F^EEeByLm z`XU{1oK#Z)al81{p!?yaFRZet4ym|^U2wsidjOp-qs3)Fy@JW|n7%M6s4 z$~Ap?sXSI;f+)|T<#RCM49MFlYHwI45qDH;!;$(xWra^}DMPxgk(W{{Doin{dS577 z6OPr@SK4uA1!~jr>MA4EkvhKF5V`^$Mc-Nu!Qozp7+e|FW}HwVAt9s`pu40c}~za7CA_YSHaPHs6$X zJtTrd`jb5&y$6UCHm+Z?#-D(B!H!gkIY)?)4Ff6{XB{}ROi2cDtso*>nMxg8{V`uOT3H#csI0Sd=H8!VCU*bK zsO0#g$|ly)zN}*T@(vtjrQ{6-mmWArnjKYjQxV5e?$Wh7hrvo;q$U!s4@N>hbIqPQ zWa@ECwwV&Mah_M@uZYFi9o53!F%53qUam2ub5y=cgiu z>isp=NYf0>rD+n9n+_;Q zO)KPG>pVUcdCF59@uxm4eJGuv%$ACb4v2_gQ4y8-ng4gKz0Y{h32EvB{r`SDpL4SA z-ru$My!LqZo_S$QUu)+@6VDCW&767l4f7k$YdCL#-M&`-oO9mX`R6gcYNDd}ZdH^I zD*u|#&+k%{|MwVa;M?(-Quge5LGkI&eJ3csF+SsbTaV`F4 zk-qkpVtb^gyV$<5*jN(^sfr2AB|^zmHk%`0w7sj{0~k@`@uo~uERi8#qP>{!>uC+O zwe_|4_uEBA)nqc8%ZH;;LN4CW(wl_Ged}AgVk?%|p)oa_$)&VxG^s96q?<#F!p-Xj zx{8JVmUX>d?RIQj&E}&``D9a!v5?i=582JFh*n=umlK>zB%(Pjo;3vb7B;qbHFxy% zt!r_lfu?37sc0shNf_W(PBE5UmSib4lFX!XT2tD9cl5QaYhOLk(b3-5+`lLhwg)Dq z=A!Ae7L95~$VX;qQnf@hoJ`1+j%_TqclQ^1y89Ow`wHD_%9623P36MrR3aPl;6TFK zgOpbD2u>!Sh!cmce1wYdWOaWTOIA%po3y56C@Ve5Q-a1hJq1r;eHl|ujfcXBdsCB< zR+L{z)8>w@f&NbS+{>$}P%a!rgiJ15hBWu~^>h>*B_tA7TVq{geY^#r zw#NEmPh)*oPYbA?-uCV_U3GIC=e2cp8Py;XQN!_smdj+#Jhc~r=DwcQ1O3JB_I{Ho zs>XAfcqW__OjIHrOzr)1MNmzqm>Q2I@{y)I$IThYbuDY#8|!5fff(rPGg;$m49OqO z$HQ*%Ywc=p=@TsN-9;8+Wlh90(Nr?z%E@WlSf4}MAl=A&lQW?vGWl3OD@waFynXE` zEbZ$N=4hm`9+j)HeuK%IQngSbm(-wKTr#A;9ii-p#%V259#Q=?Su<)hk!nih5>YqS zjzTv$TEIR~D7LIdL8$LFc%uFwo2 zv+^b*S|}AyxTcgDUDhTPW0N(ZBAN23RNC;?TKr7bd^{?X%H++c@kl6_Z*onj_HGfy z{>~Pv{z&42!5Pb=P-uyKB4M!V*%({gSl`!vSp%u*O4bPJ^FXoGT|~ ztqe!Q|o=p*k8dy+9`k(VfYJDM!{&~<7y-q$;6`ZoVu*3 zxk+2pyrIxtH@CTeps%B))zQo*)nqmkPGyoQb^ThAQp*XwSb)K8%d2o!)lynC($th! z8RygxLL)ZT7ob(_oXEkr2Bn)s$t54WI1$*ko()c36rrYEJP!3R5-${JKa`TS%M%Hy z@oXd>j-h>Z<)wm&Lflp8UEM?F*~T10*#v8v)Zs`TqZ5ECvAR$+ihd-f=AqD%2@U#T zB-V8;{c9bpnwkhfw?t5FTv_|t*Pw!sa@)X(WqO)a)6tlQ&e&Uc+FxwxZbNKMPIM}g z)G>@@-2Fs;LYj%*(u*ELQcg{Vv*}1U z7x5HSM+~(lXLB=E6jjZ(uZi{yps`Vv=4SL{y3~2K_3gD5W7;q1m}j#movG_=*($KY zuq$5SvRKv-C~c?|Hw5w$iptwXs!%&XZ+2XyN+&n5@t)R!em4h{-iWTb#Aw0p9l5ht z`5s5}0++Zsj9FZ`s=bV}seMxx1D!H^dwtQXN)aO#**=zWEJDAe(AVCUlx5avP|E`) zV#z^s4U}+qi;i$9XVRbm+|n)yl~(B3;U|;Z&ALa1k*I_4lG1z6iax9(zCy1SO7# zQwGU~*m$^lds?0|hHvDQMv6Pr)Br3g6uX?!?Cja#mOsl|3Prd4G3}QW*0uKx6zvfZ zqPU_tyLZA#6qka#qh4Sf9Yevntk6%rW8vQ-*>(%3NLNcgRqVRC!gXo4-nN&y>m5D< z3rD@jhpt8@mW(x}k`c3+untDd24+bbql5y+d)zao&hC;dwnrx(3>f z)Idv}#UxWAkC`L4=C+>(qU)g)FiWrwwa3~r)uO?SC1SCB+}ig_w5(f)(I?bpFM1Lv zt6;?J0D5hp=IX6lEn4YVJQ>gCQXcu>*@v1F4ypNMBoRxb!rUT8DNx*uE+#5ZFK(K- z9leBp(j)WHl3X0rMF?nFO37+lRzH!5(#fIF;INERsa(TYT^vlw{>5lAyi|lEbW$xE zzF0~Cij>3JTK+?AExqXf8iOFpX5CLY)mf*7;^AC2*`y{D+$k}#32B{slvT3um*5w3au}@vg#}P6WjjjgEO3GlXGv#p<4ojrDc&Ya8pSDq<$I3*!J= zND?%cl8$FFR$JP=w!3Eoy4*(Sxr=MZXVh#c5l!TfF43gdsI1L}F{@&-rzw=B&S@Ve zb}%zsKZ@{Sx)1Xgn6Jj9kEeeHnnNxduA+8^bSbtw#%v;H)zzY$9>B zDXVFbGzOsM{@QrkT8gOdmdT!orsiU~WF)S+`P<$-03F30c-?o4w@EdeO6GIfIP#?| zx|pu%+k`nPk-GJ*Exj$Pje-h&qD50tEsY5^t2(#%7e&Ii7P$~FF!-`+Dwd7s67i%_ zxR!Uex7+8;(FKo36WN$%me&N$uF1lbSelGBhX;y9bOV^q=ava#(Z&#xR??d+^i?Lk zxC@G-PheJ<)|Z&%dzehZlcY5c%k|ECU5Dtoo4*&Zh5mb9?dtZH2D5i>+PBtrED%_7 zHSFhhutekc{0>atTioe45JGK6u`JSBO!aK)r>cvJ){UR&-&z!u9TF|{L%ElusBzQ9 zSlfAv#@3xf8`~Ya6lzv?6glDTUfxgFIc4`;#LH-rbypcCsl*oKW0`C?nTe{=4eR1G zVQX&^)KP)&+=GHk*uO^XZHV zO;2k}&>qozGK48bdxIRt`cf(q31u|YA4_Q$qcpqsn37G0QSuQEq41D`5vo#!u0pYZ zX<(b4)SxHh=}06Kw}zp&z+u45zXOh%p9^88tSO?_HO|9|0#vZ*U(hsbV?BC#11()V z>NRR&IH@+J^669FJK~G_Ru-$*8$VBA+SNSCx4&BUX~*M!>N*@}@-c@asYJ&oj2P5G4CwqadMZ@~?M zwF+b)8UsuCY>9&=CYHx6M_w(WABo~X-AM-`m(9fxmYmwgMRq~CN0^~bha#~sA}WgY zoMy42WRsLrn?iB){V+?eqfk(=?&LtFv+;Bjl{y_Y&kdE!rV?1QOBkp*Sahs_ zm`(&F1`EWZNSC$u(Ws z#7yt)X=*wgNou4j4KQjLOA8vv&NJKI@6p%6|F{&V+3aH+A+x^1= zZak0vCGs-b-rd8?0JQqn+S1J{TQm^4s=bdh!t@X^iAS&!7{V;S9wj}LExhhKK(me( z|Kya~c^&Q492!QX9d|QaCym$zxq|pdx_bKCX}$+j9u_v?7;RYxHCATLqwX?WIX_co zFFX1|KbE-~;~Ptuc;GN1qxZPU{Su9Emtn z!W^JLx>zE&3{YTaPHNep`oP6zNzt%b7;%6S6Tw{yot*FCjxs|n^IXJfpWY%HeUd`3 zGmm95ixBYDI)_D8_NgnfL4)mxdIS>;t6N&vvPd`!53G|+l215r5pn0?WOjGr87Z3_ z8AErtHC2ru>8Wb9aA#lC-hm~6PIt$}ojn6xZ5$1Il#NU>JRlnnA?BQyEmmTx%Vy=w zY51>CeG$%_+2YWcKdG^!i7p0l?W7`Z`Du-aRBh+wvB3ciSz28@&`P~ByCOo@5KS`1 zZV7#1VPorR_oc-sT1_;pk(dEpSHON5w^hg(CQfo;4gD)aYFEKSEH(yFFEt$tt7wAi zu^WNZEe-bi3u~|fjLiky2#yxODBLF*fu>}XAmM?+0oMoa4<+0e47 z3yWp$0oT+FbaFTz%Q^!yfGs?3!AW6BC!fJyhmdh{bW=uPwGj}iPg<} zWYEKew=L_jafUV>7)=Ly6k0TkekHm*;N<3zW{Z*FT`il4M})GT*7Mr?`Yhw!n5s2p z!--g)IXj_IFbr>B*F)o6IT6WnI$Mxs9WCbG1`N=1@lZ69N~g$A%U*^K>}MN5Cs76* z0{dwp-V7~P*tA#a;8Eg;XWwf3S-fW_?_pH7Gqd&Ck9AJ|b zUHYtscxGZKSTTJLKrdd#5(mnexmg7h35l>4!Lo3K;@Hv73wYF$%b5W7gp0u@nx@3w z3af`%%uR-)oSBy7!S*V#Va%RDCSyiTG-0MDg&h{0ut-c~TT5SG3-V+GMXT6@;?Tbi z`9nEt*@T3yik3=b!kGBrT{T@jYiOwyJF5`pUb%2;PGEEzo?^i?jp04bg_`BuI*TDA ztS@7lj8Qe0Yl@~Lv8b~ch|PSCQeXx)8b^OPsm0!>2CVJ}Zi%fv8RUP9@=uB99K zA&MLFgos46h%sO=gEJPvihC&Clt58%kEprliR**OnOAeEByC8^i9*y? z=M3FC8AjsN{Aw&HAb~ z*+Z1%Mfks;5CmB=~_8` z$F_R+RP0de?7^VPSnm+bG*yJjFvC`IV=1h?Oe9&_Bw8#a9}kBlrfldW?Pd3zD~AZg z;$F<0VfsYRQ*!}F=AGo^`A55zp8ZCj7)3&&^=`OnV-}je!n&5eO%kYkYa~LMgk99Fi%CYQd~3%v>HX}NcKY*q_}oAT+n$+xy0YQ_T9x7*B}GiPo)rr#IL<=r)U z(VtgmRtKs_roEiXmz7HtEG~{HhjKDV{N&)pXywNWV%tm)wNDo7D7saapZbJ$S<%KO z77HvxDTp027^}(^a7*1EWx3sg z=o72#WTOX8Ut1tMR5Hp=qlQ`Ruz=iOX7AXwq{GdGCV~8m3q%>eEd>oMlGKT$g5tEZ zCpWnD7&(DRJg1c<0i8~wAUSP0dG%`Dq~>~9iOFqnVoa3HB(OOp z6dRdS_7x4r9G2+Q_`)fLAu?@OpiZb9p7MB~b(yZwWPerPsKjMGh9SDKT|!Qj>s8)9 zZ%!4Fr^{uHWKLU=HhPHq)cJWybj0!~)GEF$;?Gj7lMoBACenm8CR%)m#M>I@+5TCP zVJv!~WyLOk%p5h-_cg{>IF4DUh#JdH|Z!g{pOPy6{?%+eJ{;Y(~J&(Jw&qyG?ZE0 z*RvK|@14ByWHdo#sVu7Wfy-M*7s?A?I5yF@Yo-WY%hg+oiR^kAbqxAI(-N2{MCCO6 zHW{(MrG-0R?HGs`tWzY|SCYx#qo+*Lnp84n$|G%hhM_qcFB*0>}Y+UDvOliFD7K-u~0ad zL(WEIyHVdOKFy<{DK#)X-CfA=wsw57WzHtXG&O>G(sVM0k1=}s__Lt~d)?v^p)(sk zqC1<8YgiJ;w@dPCH7W(RGK0C%d@dZ1VzQGzR273;8w6u(%pzdBdDIHAR}*B0h7VgJ z=mE2sB-%wxj;^-}%BitTQ#_x|VM)~tPeTOD|4v*sfe&S}VLL9P<1E9zco=EfQCOq* zKhe!9w8`YPy67tsBH`s{n}SJ1IoWO0RAHfz3ODVHZY(E~?)tf+JhsE9ys*cooN%8{+2R|gEa@7j z^nP=k^5zMC<)T)<@{O8N8p*jf0g*{<7W!&d~lh7$A>r3 z8V)O35(}zbAo@I0@&2%Vf5p|Kt;KO=f96$RnS};h_+X zQ!3y(j@_*OSFohX;36!Ae6r%lGnqNbm+`QpKML~^uqB$pO$g#1kN@P0a1${h8D1L%-BEmQxX%oPIAF#wpf0Xj{pLpnhrR|UMmQq9i zqf{OTDfF&j*_3`290PI-;BSKbt@F@tk(auS;1}`M?Zkgdaf+|`C-S}mp`*O?bLc76 zM7g4{SHgwD48Tz{OQv4|CDM%D%psX zbEcinYyPKFFc~4xZDg;;d!Oyd-NKRA8Asn~eEasS9nuDoL)l|I>a!b0y%`zJ&S;N$ z_=oqn59Q>DLs&~bg#Ch}UUoi&qbm+!7viCua&agN-~T*2%ny0i^nYy>c1YhkAL`D5 z|Ggtf#xQss%f$1cehF}B`)3bzW5pq?*61VVL)@Z!$eTCDFfTu*oqvbEP2>;{sTt$u zS#)^h0{aHraFNhx;7Hw$ic9MvrxoDLjT_h{n3{b&T`n zhq_-@S5#yEhH4BO{;?V`rrluR8`E+?_??)49MkbrV?Uf^jGwZN^}MUYISFMfXJv&C zw@fFdS&SD$;_SD1qg7k2{ z4Ik6#absS~ct=)n$9&S=VV$xxwndwz;GH|DQk#=2GPojMNp|C+CM zXd-@Wr#T+ZiNS}nZwCjF|0{iHgzwwNcslaf&&xcFkDK21O;Lw&1~gd5{3X`dkB|Pp z=o_vvo|BDx3&!~M*V}fI%ILP@{Uc6W8P$fqQJgFO79YmRvGu49%lhZrKqx~$s^cqwaCC+5_S>hxrw-ujy<;q4(Gv^>_+AfO3M_KT`V; zPuHt;{~UIn*SCVs)A&aH?Vt>w=jnaI-TVw!|Lu03k=Q&v+K+U-ZkOP1ckP?FBZu%k zul&GJ?CLgdo)ET&dpMTgMDo*5y+T8>{sUGMfW^%;ET+w#?oBv4@K@K5(WFlASKDrB+V}cx;{s z;N;Xx^*{JvQ~0TW((Lrna=d_tQ+fRKV+x{t1n+1rGq8Rk;;1v@ce0HJB zmx3eTK7rGL=$aBkgCKkKiz$#JuGaebFq}SK-yyQ2k(PSRwRZ0e#}WH@2FmroBBN*b z7MEz)`ULdtqOfpu1xyD~Ncm$*ft00IoG8WiBOfDbIX%RF#}E18(&&@5wXLV$(9zB& zUbnWl?53@3(4~d59hcUoLXZ~rqcPy^2q!%0Ir+bEND23JttXo3ZM!^j?$AyZvYgq$ z`Gsh`b-OPU1n0rHoJeHt1W4crZNEhDNgx*bEe~2jIAvq62ixBEOIb$EG*EgUz&KY4 zl|z10tYf%xk93iS6wWwH9YC1GuYblPZfQ`*5!8#O-aVkmxbzBywXHKiR%1LC_h07# zobppWpx_-U!glBfoJT%k%dR&7*K@!r#`Q=YF|ft)lh$K|Ew$DuWQ3D;DF5KSETfi- zu51qf?+ju(1KZNQvZc3>ZhfggA*S) zV0Hj?k?4X|q~=J7Vpso&&gd_WvAEpMt* zl-W2Ng3LL%zrMA&zFquMlztF3N9w=i|B2PW(IG)Ki*=U|f%uFArz+LqbLi|W9fbcR z_|z&zxgHN0Kb~N9e$_d>bfpkm@oO^PUj^oS7MxmLtDdvbj;jQ2zr^U=jO(-G=ECu@ zGMuV9!}q;_q9A(8?Z*mfv+&O=eCgv9Wd$BG6c4xXL6ou{m=8K}F7dqynD07qj`*Gk zc@F~fdne9CUghzMax5M)Ug0BobAic992Env^jje@B#(?*jr4P*^I5R}H#eN49GnB( zt-w8F@z*Pz{|L);PRDaupgfNX;zO8}tx}c&wjEBqwJYN2ufWmq@6d~9a6bmPOC^@#;pOipV76LtUjBYXVsx+F{CzW^DBlF` zYZP&qRyk z6u47?n|Ur?7UR|~kZO*O0!Q7Y)=}W7>vGj7ai16kj`YU2MuDSdcjqW@#{l<>QQ)W_ z@!}|O)HRq?i{XtpVh}Qu1|l$C<(c>!C5C}` zxs~S}>~m$fd|7`y58Mr-z+DF1A6;-5DxMp~4FXHkOVY{k`KPSwU*Fo>S3JdTJ1|ga zI|qjtkIp)?cv)o85(hSiD;-0b*y2-y&=AU>@w^{TNbyk*R*9a!a>?1td-~R{OcaXR z!0MGW53#bpuayb=e1l^`;(X=8qmtx-d_A=4ENPP6EDK32DregyZy4Gzli z)Zh`&m^%k%L`!hiwvkd%ZmU#$%5y{kKDc+m9=NGYoCmw3@dT6v-W1<}axvaVGKCk9 zn(03o>haJye>z1Pkb2vG#dieGDnv{%lYM?r+^-TW_5}4yM}obDjqP1QadLCexZN&z zT0v2lE({lX9WJ(}eVvmMO5ABORsst5fU+h;bh|7j4cT#NtOwiSVB=}%QB(+|an%!escOOIAgKB-oej3Ctu^=&+U^HkdQ>Yt$R%>&Y2>u!2zHuka|&%gUjIE5d6Uth z?b8h_zqEOmVG{{Rt5Zy?N@;bfX*F3|on%^7ORJMjt7D~A(6pK+t!A25CrYat(<&&f zjyA1o*lO#};)H#XSyVPc+mF&+El%^uX>ehbN_+8`(DtwmGZZ;%aG^$S15*YUrirN9 zau?pA?O(S6x9+Uk@*UXki`0_9=f8|sdRyj|(DqrNL;)tur|_$kdE@0>fvPP-pkLk< ztlDxdh^igGp4?aQ@-B5?;M%K)m4TkBTVpC{^3cl5 zFWW=&Hg$Lc3UxY3dsZl2k_ssA1ts+8R!~BZ{s*YJcmm4z@SeleOLz<3IS39>;5DdS z2DKlQkoN>AA@5C4q>BT}@u)U}I@6#oG^m_Gtv09ugSy_JK5tOpF{oVz^{_$x&Y;FY z=?Q<20VU#bx?y*&VYk4ba)xU^sJR^a6q=G+rj~)CE>uA20d*ErSA&|()ODal%s*8DOmruvRnj(BmxQx!Y? ztH$LCuP7VwkmOl-{G$EEy$8Xzz5-4j57O;uLEIP?#PxaYEq&A`^X+_nMRYpayAx?= zi;bhf+k!0s;kJ3)IcRIR74$}Cp=sWU6s3w*fiA?XJ=(T(P3`dh65e$OpjKk{mUgiN zl@C#_K`7_YOB(8Rh#V3W<Cf`NPVRZRXioVou*e@d#{EM&q0ER(~I6tuX;P-#9dwBP(>wvuxc@4Pd(cJ_mF6AA;9@0QY47q zm#`fTMn&0P0BRZAh47~3jew%zEjXyxy@>4yBkWd!61Y~w?g~(Z4JcO{b{jwm+%<+B zX{R)vfbt>3?&F{Y?sJCSji8cv0?OA6yKjRMxE~mHAe7zolIC*!7kMlwB%%^$J3WuF ze76{v(qIc&KW_HLFWv$mHq6jZ+6RKW=R<8+7sAD5u!&;fuh_0{m4JoZEhHADoJE-~ zM-TR(l&|Tkn|ltf`c`Z|L}3;sWa~Y}@v>l0kv2;%rE@19p$0_F#!r|69uYr5QT*1h zogP1JXk|@s>9XbM-Y(TUw`gimJ}ZEeo!fWE>i&={y{MI*h?Rb;m0pVub=3r;4X0FX zxe>}%D}`sFrWGfoOE)gy-$Og`PX=}9Ivy9GCc0IL=i7ixV~`NkN{?uzpFBsNLe_6f zMY8$`@upFCXO$kYcMRO69mn2FE(||PkBCrs`Ti_o8f`dx2`WX^mXG1b<_mmCuu$n| zvC;#v(w(DIQlUuTDs@p_|R>X`VEV# zi-FMK-M)s!$1+h_ikyh()HO_91wV?j7y7Efa>Tw^spSJ`-j7^3j(%6;_agkJ5y5rK zKtM#G6bXV;L-5*&wQ=FNJfO#Gt-FVJ?~87|?lVCoed})I#n$T%p1jaUt|vHM3HVt6 zhj*8n0)wyl5cGz%mBn)n+{c8J;oU>&t=Ad0ABSxzQmM7xI~3h^-SF-hLSp*-Nu4J; z1o1JHOVjQ2k8!Am5iSxaau9OU+hW&oP?M#H>3?Z>>HsT`BW!qpyU%nMP%N z^Ij_Iq02%mo6%*Wic^OtppeQMWU2>m=VbyrqjK2uPG(58y z=@>@0cXM0Z4{b?v1RDy)&Y*FXl5EI>a%tYF1zYJt)%Ldl^|u#;{ZOv0#r8IPlkW(L zF`&=Kqcog9M6PIrnZ%9^MO_RX3{~_vhV`PT-cvkkcq%o;+P*=uA%oU5clo%KA;uNiPAA9vY36`b( z;MBSUb@%9)fuqVR!96C=N#GMfq@L^zcmm3NyuZj)7;oX40rl@}w;XR#?5O<~93Z$I zq5ovQghxbAP!zq-u$>+~M;5ixB~L-R`U{uVc$JEEEo<9#Hyx{}%SC>O4qoXsYI!b@ z-8-m&+J+o`6Difl@*@w}KFH7Zk<)X11FtA*58uPzzyV1Vuf0>Yw;o z^~idL-#XIH^BqRctiat7^Qiq73XA@euckynRl`omCWIaeqJ_I%wm{1K>ZLTR=Ak>^JOOSW%xZQY+okXpcAcPv9SG%WdP#FX{)AN}E}y5pF!JpTbkYDJ9ekO*se(1P?0c zKbc?S5#bUPh3i*rr*~szis*weP8IP3V=~HqnNo%w<*w6?IwVdzD!kHes3M3T93v#Q zC{vGV(AG1DAEKghf*cE?gfIwJ6T~ded`oe{*tA5w+F>qE-aO;#b`Dk0B-`8Sq4sur zNHc_QYYeHc|F(L#;_dcu<=gGys<+!iYFysdJfx)^7Z2x&ihp)_#Xn(R1&!KB7w)U5 zmK68GtWC>on=Y8)5MzpfexE3QL0*|aNLP-BPXVP0l+gCafjXA$%trQ9!aNTRTK5DrB9Mn!c0p&M_-D{v|92HP}cnf*QfD-b~1|?kU4ObfW3D*oLA#aIc zcLk_%co1g1g}g0>>kWqMR}EKM#S-#<3`)qm)3AFI)G)$`FoP2E{${vVQ7gc%G(j$0 zX@XqHI~SCYH{Y;JgL;!WmVgo*9fs?*hAT~)3s;&n7xHcdCFFh0u=^1xO2dG1Cn&-3 zsNwo&!}T@8b+TWVcN8cgZ<=9u4ycz|-h5C(o@ThNHe9bTT(34k<}$a~$e!##h>i!5&%C?W4mP$Gq*hHKhzZ8lunKnZzk z4ZF>tXlx%)hCm5-(B z4K@d&y?<_Vuej9HOUTI1hTsmmlzR0*M@M^KbN`}5*bwLGux_BMSmv%-3$4mr{nC;AsAh&@@^=4#~)nG%heUgJy4e({~Ew+o4*AylO{RFvbW zx+i%G_4S4s)E-oAeG-|*Z3@3OH`2soX$o~u1{Q6L_!^og7mwe1k2##DX|d<`f~oY_ z;QOa3#S;e?QrALpAigXSL8W;5;6iGIl;Vto)6q?Rf5Qx7C~jz&L0yDm4|h&US^)Ec zgYU0YiWOV$sfxj(+90o~MWCqpyXHuJ%~yi1nWq$w)7N^BkZZlg0D^qh)+YyM=>sE7 zIX0n9O}aS~w5X4QqWTzQJ73j! zrK)X$QZ*0%=T7S7DG;%s6^t#$wi9`IZgBNLF{oEd@2V6m^au5u#Ifi_RpESn#!ObH z(aF@oZt_Aj^+mVqV%|kuT#e;58D=?mH!4q@fmKP|Ifb^K_1{p2(dhYYAJR~A`hER+ zk{bW5AJI@*@%uhxxaoxT0~IKGVA|=8=M$%#{w2``BW!?PFn%RSzFW5Gl8fI*6EVc~ ztM5$ute>~H;)g<|kql!L>&G>;JmU9JZj(9duKJryE-IyD7{k;ee$y+cj8m*1g^Y)t z-#1sfZ$7RP#hKzthDtUW!i*CK1@Le2f*i|cJDLvi`)G-I7O0AN>K-%hUzA)E%HmGp zH{*WMxv$5w@mZyYKzaRVLSO znFpU15ys}%B<4Di?Xe7f{q|=~E@(tHjIsH}xoPC-;$(cT$@MPDC34)Fr!+O?_mN)& z`C;<)pO{>{{R6g)!GC-bB;}OnDQOBbPgl*W{FIre&60~SBA-8R$RQhR*`WTs-**wWWuYNL#;lw6FlSvCO4wfRsA8;20x>UzS{qv4wCdbLkp@LTGZ`D!CYA z%TpSe`F)i8Wc;DC(|X>ZKPb5fV=oCbd*}C2UX!`z+=d2|i&lBa5XR0$Y2e3p3}Jrx zN$mlX>o}^qFodylkrO)gb(5k`1hkT$Sz$Tb+DfMK-LoImdGH~UlTeeY%g4A0G2ZvqYUB8=mwmXqwj4c+Yz}D{z;_aiS~ir&gro6 z`{t7a%=ae^Zq<44L965_jPp1$Gn@60lCd8XuIj4hYXWG=m| ze&y!J|7vnIN-oCO>KBF39_HCBXAR!egSm6%>YN$o%cY#zWnrc^(G2sKzkbdWvyCuc zBe@u33p0`fT-Gp~T>mM#7-K7$)ZUq8?A|-R^D#Yd6y*WQMHqW7pUYfS_Q*WC=JZ`A zS0zOihA<+RBhrR)mFx1HT1JS?h4vI97rze`n0sFz9sX(1OtIBcPHkC=QK>OgY{~ze zyt>v%vG+CY$dAB=GWZgKQ`awxT8?vx?xEeU$5v@#xJv)F*d)b&YC5m?)i!jm|UkyF2(?d zEkb&c0WESzZ!jn??72hpsD2+UT$0i%EO_+`X6`JLa?UHuodwLLw--nL>Dj&K8L{Y< zT#T{B0-XREcM!_8Csq8>a9 zG`YSgxfo;9hZI74m{pde(HqZ$2fy)YGt9fB9JMUWA?DJoOnR>7$*9(%1F~A|56Zs#%xE4^gVx!`1k3|GFejl~Kq^Ev->8HPF#^QJ>CxTem zN8(ZD(qnPlX{D7BBNnGiF2>km5o0br7L@WP*M*XcF*dCpXD;f4k$GzUQ@7~47^~xw zi!gSro`8+tN4s3B8;6Y$6VB=kV#G7^Mc7Wl?oaRVeDLa*!X=j$Pwn@k5B%L$rX}Zgt2p73>&|X zMi6AavhR#hB$Aa{Y(oB8;7DF>}%AiOh^gD<3qu9+q5$ zv2!hfjo+tpHTAY55_%erpF)xpg)rc<%q%U14SKmg@tMG@Cv1m&{9rR*axFz&2A8E* zxs16eD5S@-7ys|{PGdqrb zw;8X0lU#(cr^Y3)@%tzr$wbsTXj(lr?vz}Fv2(o#Hh$k_!~*luv>)AXat%u^!mx&% zt2eQfhU1lnBe87`8^)b05=spxT#dWiKsRkgba&))G5O#$aaOpzq#_zolMyYH!ewqM z=7}5Y8tcXPj*a!jp2m88gJfepuL3pJcl4-AD<3&;37a0Ox*8X!*3Onfca5u)h|64W zE>|bP<>Hf!ez{9?b7Ha9(%ps+Q6ru0t!ouC@>*OArL|;Ok32p$X{;Ato8Uh_H)*WL z_a=??;)9dMdR1v|F0AWq#;K?6x|qmVuHfVRh&T@PXVI-Vny#l+`h!C}Tl)&D+pVeH z+}z)e4UvW7CM>n}tS#U)WQz?&P`5Ai(+9Xc{WyKTr#r^mZrk+Ca(9zy=;|nokT};~ z7DT(9w&%F?lr{4#%_6L_)<9o8<$F#+pz_)zdp1QRDHZOj9h8A(;Kc3Oh2a z<`SV~Dx1v_()PiH0E*nSi!l5Ns|hU=&gPPN;Ed9`4jYT`oUT-mo{J>|TMV6|%N?!a%Uty;Hs%Y~B5^el z&qPy6SH;xI`@kFP#fnp7J(iq|@(~%s-Jc>waF(OBqUmusjLY(^+6lxtsO{RUmdpio95B4hM3{>{rZtkuuO)tWWs&RkUVbEjQSDzyq931;t)qoY0sQ!JQ6zt+4#g)5o zB&>JG&^LfaWR0Tgw3YH4*0L6cb80*kPN%h|CQ?Y=`+saLTo|{HClb+|hT8*mF76S^ zeL+reHXm)uC!1mncJ3Flfg=$$98YMuOqLa-2oEdw@_j_6hQ~#ixlBA0P6{USL9_@4 zld-kPU<&8eR45mYrV?fx987YRl!0kb*Zk*_onhGMUZg z!_g=)IW|App=mXbm}c^ccv%<8+!SSJ!8O^ra2mM~l0h;{w6R&r$)P2p;UsqoQK_7G zJ;1h`R6TYU`;7(X>g(4aco1NfL&p8$J%)4H8Sy^*W91c85H-)7VbIe867dp2dU$nWOP|onH0t zv#==x4;e3igK*mm%rg>4(7na)t!Re{ML+vNK1C%evtl z`8EJ~eZc)rVky2}=~8hfHk;!i#o=!Z4jEuRKAXj{JTHI03(V~n zoLf1V1~FJUR9=!eFMqp$dlQ(>vxL92>gVO}O~8Ct;=JNZ6I>4h^Gk{I@^=+*&jF*I z4FaYT5Buv#m#bj^SzwMnhfreC#w&bLVDb{@6~4)k(Je775HGj-LH=F^++QWO0>8cd zJ^fsqsDg*gNdD#}Mj+k&-3iB)z@1ntP$bXG-}8ZqTX1gWfbydan4%NsreA=$!HIL6 zGD+q6c3}29aW3-y2+ZqFoQu3^Se-o!4;dr9c%PoIzhW-11 ztD!YsmUyAQ^ zT5+}*xA-oEM>B!Dyj}n)yk7pEJ|E>74;e3iN$=)?DN39XU&ra26M?%%Vn`ktH$6`6 z!u6xT9SPjmMuDSZ_g`)}hkj9k`z>&%od*Jj;_H`XmuWj_`Kr#GBD$4Js!r(-)gu8 zfvI)kT=Z2InD;nw4!uG0HUe|K6XzoDtH6BEiF3$15%Tr}^MVuSB5&eCY?{ME#w)(0 zC*}d8IdLxXI)LeO;vC_l^#7>DkiTTy>PHIpUjXh|i6#Bwm2WQs^QOdk#e@7kf%Z07 zjGMpTh5PBiJtDCI{Pyzq@4!rK6au~crTm=*%mRrs^rS-%H3Jt0=07Bk7ko}`GLfZW31A{=q}W zOCIIhnZR7+#JR{@2~4LG=csQ~{yqrIrzOrSU7CTr5tw0%Jg@RMBZhK-hs;RvNC0!G z#CiGqKakN5%xc<^0#kv<%im7|bECw0`Ahom$G|)xabEr&1Kcyfykfzzzm9rII3M=C z9E*nx$@9XU1k9XK;4T0r`xZFLw-vy2z6FlDIDNp}EOC@BUg>uiFb6C+H@!ja`HK<* zl8syaeRUjeFaYjFQq(X<6ADW3)lM51N-*@bI^%%$&X=RCS}0@ z9)_oNJxm-EM zwX@(fsSKy8*6n4)O?smaxF(4;>ZMEhTMA5z#Elfb_e%`PC*xM`{{;K%fLp(WA<88D z^GcUzfO%2ky!@qda3uD6orH&sfpdw+g}`V|oI{_Ie(nI~DksiG-e-Zi$%%83w;Py8 zB+jdxo(PAhfO&HnM}yCV^-7n$%Q2S1L&k`&!(YnZKLRs;1;b37OFU|TsdeI9c7k% z1rAf=N|zhX(OA`m&$1aFc~M#CH>X{v%!gTq#w!q z6fj?R;#}nI1LmhroI@Vv$DbtzBpbKy;W(!ZS00Zl;NosLM?9!GSPIaxcD#MlM2g#eX3NMRsD_3X1{nS;MXT?Kir2bm#D%|RV zhm2P|C>^$~B7|u;9**?ehz9agtFY$SC2*95Ug>vBkD~lH9x`732I2NNFt0grF7^EQ zUc?y>883O%{)T|L*okwI*8|LZoj8Zy2twZHfVs_ybCLHbFu!r)9P%iCeOF>F0uLFZ z{dLseYPg*$F$}~@tuDX4i1Mwj42N>%$hW@&cL8wc_6cc|@y{#Yz6Q+qCC)3I$=`=0 zMo4ro_wR<|<7K$=a!>l6uhP|p;lEqC_aVWK?Z@%UMFE_Ge_rwU3@~4jIInn+zq=$x zNR;t#q~DY9_h-O;cfCLzHG;qI*?@it9x`73QvPlM=95mGOS$?UFh6$U9Oa7S{T!GV zoH!SG6E~vIfrpG&_$XcG0i!u_F7i5n>2u;7;Ujq;1?DCv&PCpCU>^!TzYEOm797iS z#FzYiLSo2IGH&e*;hrwTsVcSty;HZ8U5g-v$8bxT^H%i3xu#4T+@vZ4(*`$9R*FXt zZo)xV!>HpePrqboji9p>w zuRMk;2i^y(=(Y~uzSt*xN)Q)teTFK)zSu2vK;cmABl}|Cr;`fz#eRr4{{1)J!{V4> zx}2d_+qU#Nx)Q8(H+;YWw~vueL3s{w>8Eu_r02x1%+^1+-`qeW&eHNgsVY{wKUTtx zYKDMx=_w5dV9qQ%);w8yKnShd`TQ>sqSAz_TM~h-JFmG!qkCSG+m`#PPTm3soVIpr z*hjZE?G9Y;tGYGyriQ!aYOmLbenZmZK>uCReik6)X@k20+7RSj@Z$TnBaVo#N>`Kd zOCu^zuN9EEAc|0{_(9j&U6>wftI6Ysmd0%vD?~^UWTcKx@gD1fErPML?X}oKh`XSz=lW@=@ z-ZaVyC=cOH(3CNFGOwmE1!u14Dr?K5$P&G`^%}>JaafA9j zs8iXM4j>9L^#&**Wg?XDT(-kYp&fR*ISz!V2ZEw{K=JY`)89Q&nU2p>r@T1nsU!AJ z*jdpVSmm!3w+lT5#56oJ7`dGEhV^zov8k7ikMHm4Q@orD_|nAFaa~LQ+TiL!aa~KV zCkBTThIEX&m<}Mv)fE*8lDI+z#f@$RyOw^-8^UlwM$K8#(!HgJ>UL6<#Z^M-nxMQ{ zPgb5NRK~36Y+TWT5_Q(>XiZIY=v_k-xOf_+VQ{b3eCeKv5G@J-t<@~V6HuK z{L;;Q5F)7sMM-@j+fB#8KodUT?;S@a2ZsJpcTprS>q3fMzUmB=bw?CCs=BXSg;%Ie zD}~f#>DAH`q1z}RRhPb8b?MH(R9*feRpp9?(6L3_m_q86ejnEmnp`|;2kGL5P-Ss4 zsGp2KSb=}a2StrDl7*_8aor)(rnCfUNa-_sNlne*8@}S2!8axpR}a21u6Wtt8!nJ@Kwa>bWn@&1e67MFJdZXP?%Qa z)=wPVXvSF%Dd8$UP#19~K0lAs^Gr>jit94^MB${ONvR>?x_Q^|m);y6e63=``BHak zt-DGe`Tzim=D&CN*W2lamOa~j{Py#Eh~HcIy_Mc|JGpfx9;Z1H7Bs~WU~O|5C_f)k zzmlmm-ZXLK=ldaOTFuX&QeVQ<3cTs@^VKrTnKG(Uux@x;u3DsP)g5>9shqFu0_NIn zT6I}Ak;7`WgMy1DQ6}XLpAgpeqFjUWP_CkvG%ffq@<&jV3v1ZUdQHJQ8^b*qj;h-FS-5FcJD#4_KXLmdsJ*D^o!oO=B{GI@%D|Pa z(C>8zN{`_x+#on)uHmMDG%D1B&9Bi&rZ{c$Yq()fDOPWOjRw5M%FVA;;QzoZZSZ|H z>d^y1?GaU(1@KRt|h)g6I6 z1F5Ed6i+~j;QbM%zK!>XnffZ;JMrj-8W52tf}%8eFWb$Okdx(qnjbVVf}%!b8y-L3 z3`4SY<0f}A9O*7ZXenqnGP-Q?)s!eG(s)8Pp+190H*T^?>q0j7tq(;u$<#wZw3}=Z z3ci+NH}XKgMWxr?Qm#VxT-$ary2?rQITEFnaw=(K^bU>RbS+wxECmDwBpt;oO1(=J z1*oELdvV;Jw43gSf1O^tdc^BvoEIN?ph_%7=bmD0(B;lgER5d&QkBbMQ;t z7J36y^>}}gDGl#0Fh#ljd8Q~0|DCB%<2{!ty!hrD`cLK)ctm*-R3(0Yj_syTr&jAI zW#R$RYOR7T<%FfxLQF7XN~&7JCDjAfbq8d!G|BWDr2CernW=;DtMv`%LHEk zfky;FP!x!-v7LTiwz`<^zgy;VtMitcYk{P^qJWfM!et-mtmM#H`ETy5B9J+*g=%$+eaHqSLA0vS{jQI@8-8RbIRWfFx0Ce)NXsNBH zGg|7Z={mR=IlT%@*W!O0{f{>E%_;_}b{w2m8b?|MxChWH>ct=w%BA$vGzKA^uqcW$ zK%#m{R53c6gwBRgt&|lv4r{p74;?VqoB93<&-hv?{3n_E{cJqsK@n^tOAKz%t-*zE zH27(&sip22+*UM))#Ji=_X&wrF2Q;npXNy&9(S# z)Es%!?&Y{M?$SL+!9~=Z&7edrAw4Q;&J&;(;t43P;7whNfHEHbK{bG)`gf1Us183OjVDVfPVGg7@D+-O6@f0rh>Rz5z<;@ShvhUkwU3j`1D8 zXdOYBb(eO(>*kvvM70qVRh$3AcGIt%q+I#%yOhG-6L3w$(aMCUcr=#R2MpH&bs`>7 zmlGI|#ue)Ecn!ViaFd=5xY}I+>$nSB4({p3Rk1}}D@W*Hu~5Xp)VL^i>5}-_bLQJ_ zY2$t@s@Q3=1nI?xJGk=4zCl8ffdYgknFdNE;z^($#3Q;64={z7qS8y6yYOEmj-V)U z?q@q)r_en~dgU>%^?+Zq0U=0-=18Uef#)|3#_@ic;liwllJUj^LNKfkBDi z`y6r7{1lYlyJYbYGcV{niL1Y!7Z9PGO8fP~bD!CNmN`f@U)1OzsNHx1eA%L?l~Mfu z6Wgu8Thv|<-2bQlWM0H0!Y?Qa{~y`T+Q(Ee^@rjV)SzTBrhW{~QR(+v4^(aOBO_^& zNxO}jPMT%Pvz`_~zHJgLqot?BFI?dIW16>&mL7|h{uV7gvh@$wTokLi<>zVY7u<&? zq(h%83zbxw%~UY>mD8EKuO6Q+{W*#o(|9^_XLS z>j>%`Bne$XfZn-5(edF&v)u-R8UiKi%I6L0W>EB1hi;~V7G+IPRMuX@W8ODTHe^Wq zm>5A(0i$_9KVNM?vUTGocNmUBF3BXVM#f7nT_)sbRPZh2(jW+Oj~%ZZixc0f9-gRF z>^;Jm0U$qU93VnOD^7wU)h_(7h6a|>-5xH1 zmo1RK%79WiH_+=}HLlheAE39(rC2MyPBUIhFnvw4=;-9jlDKuaI369VT1@_JeUiy} zLzt$f3oNOm?Kus8F2X}Tiun^J@S?tj$az6gC~1E`Ru?SyCh|P6Naz&ohd!!%~u^^wcq z-c{Dwrfx8ZKGx?zeI8Fhq0yz;ulX*1>4vTh5vd_4N{v};$1_Xc6TO%`Y{^CRVJMe^ zq=S(d6(mTj!vY1uYGxW`SrA!f&#hTzZkP+1D73>*i29z~+h(kDztSrpDf zxM`>vP#W+S=~n_JiU&2;qIm2#TtO&L&`X+yM(PTRQuo5QC>~sOP*;t)Rs#dpF+nAm+6>ApRFp8fNy1&!3PDk{<7~&Z;^U%LsIVm$ zQ7aI=sx8z!(FMu9_UI!u9;cXBZFvfKOKeqIHdv+C>WC~!m}Kv#b%RKobD<#OSSW}X z3k4C^g@RhB7g04)WEKd2kd`VXsz$3RwN%~~P(nv#`bK9zp(k$4|2UGmBUIJBM=V!} zIe%n|9}9XR|4s-^hi211nFlnhzsgxvdN2KpWn4&wPvpdZf)YiMru9UgPy&iPnFxyX zvTmrQ7kMHmO8G@>H&a69%m1YFO^l$Z;$O~aLXm9UxXE21;M-uHOTOg<7o{=LDOspl;Ke2W#a6(Xm3W}oN$#!DO%3HhA9MY1|Qq+acvbu14 z%}&VS2`#So>C)3Yua_+SIjOIV(-aNQ?`fncsT|iGpm`Oevg?&aw7R3O7`ix788Ta+ zDNaP`uYKjQ&`_X8+xmy%5u|lqd2A?#G2P4TxL`IE^U!z=oepxmFf{v4vFK=R5IRG= z_KZ0YDi2}~x32E2 z6A*ILjlSEZlK*J%f0P4!GANqg32DFN)*liUS7jfoHKfoZ_&6Hl=U}Bge?6#D zEDzxQ(V?Yxhqg@~SBk9|%IpW_6McfA%)=S<3dctq%mPXl(_k^Vc=R3AEdUAK4U*n~ExjLEfV^Pu zkpWT|O$clh3CdBTgbw|v8UjSniw#vfUOZXEt^%PxcqGLww4EXst1`kAowU=EIH4ca zQV1f)Qli$qymhC@cD3qLchO940O@Zm?B6qRbVJkR;uKDVGdCKVfY~FhOEt0^ zZrcCI!+w{vpK>>t#i&Fw8~UGGkPqWQDZ=|s!9eqmw3n?~PD1{fT4Rl8@m?2kMU7dY zl|D>USkx!bge^6_N1{iJcK9z<&+dGw>L?!f3#+uW;_*L*3C0bZC&T0Y>@h9g{e&qH zN)NrHc?hp`}2-dBmP%&eEH&Uy&X?xBx8g#Zq1eujc6QVk3VR&iGbZzv@>8COk*n2P@5qcFZprsoF~2a`{ucfQ!>WZu78@I2)n9G@8Mlij}=e8C)72 zP+4oQg{N&DR^JZ6piOaeq0FZIgb1)P`_hpBdBMY+HBZ; z(x5;nU!j*Y&jTqENl=tXzhyi7WO4amY*pzAIn_<0&`H=8Q+3A|!Z)H*qqXj-y5mD( z(g2*4XsD-R{DgE{W$0F{4_~@x*Ke?a0K=%zcB-?b`;0`!-ZgF8j8zao>zOJIy%zBJ zD>Qh|aNU91p8p^07sb$31shMJ7@VKsO^szfnY)Ni0E?(k=Y#qiya*_y(S^n=fch)j ztv7I#Tz_FZ>cR*d2xS+&q@f*&A{hlm$@mi6@ksZ880oHpExA~=Q>e5HeWo-Lv-CJL z0Cx9=O6X(U$0=8L54z>rP^7ZzQ@cvLgvO%UcpM&4;LihP7}O#W2vW6Td($unLf2SA zA#UDHTbkhC;Oi9|RDB((b$98Ln@N=Be`xq=E~^Jm+djzVue?5+%(?iov?ZMaqnt$KT))IZ8EN zHzyl@3yS&HFEYAn>o-AfzU^APNmEsArLF=s8gd-Cb!XL< z>&Xh0G)OJWDy{T=YCNQly5O#XHB?m*{s(on#eGY*EVI#7H8gjSe3@m`&zaN&jmN%} zN|YlHeJJNX78uF`Dzt1;^F)MJ)Z+*!p$=Dr66$aOlo&D6juO#Q&^)f7z7DD$krVrt zMS*${c0z$Z1xnQNM?w7wk8b93(o;4Gin3!C+fflEvqb#ktTZu#qW;r7MiYu;>&8v) zIYKV=pW2Ailuf>x5(P#2Q^>X=iFT7Mkj|-x1wfNeR_)|i+&s=&p}G1#Pkv~mm7%AK zXz4K6K*!^aj+buHUU^8{Ht&dS+BmKBh+afqCB1M41|HHvUfx})_)zwUzeN1hH4~Ec zRubDjw9-%UDZq2=Vd*Ejz$qFuoL;;J=4z(PD80}HJ$l;|h!($eJ1o!I!X(Gk)YaRA zNA$^7Bc}qqt6eA`YNVUlZZ)VKjH7nta<=;bD1oDy(o5NnN@golUk3Farl^dH@_h@a zOW5vqP%D_a6O@pAKd9ww_ghdxGL1%-u-$8*7Be*rY7tY@kYIwBlK4dY(oGxOMFS!z zDrt>uHt&ex3m=7gKN5aR=0Eo zJNf1rx-NYrE__zN+gAFEeTD8dmJKVSiLuuSw{2LcVYBvdfwy#@RPs2Vc^z+5>@F+P@?Ex1xi%D5Bz`Jy$gI))ww>r zCo@2}=tKksMHw&(ieeyuAR;ql5+;y9gmAH<5Rw3qK+O3D0mVjXy6X_Gnv$Z}l$HrkJ$$Oh zdb4sdRN>g56vYO$N+gJ)e$#pBu2;G_T#Wj6bW^8k1!*tc$_n$5pw!up^$b--CFVTN z8aXz#!kbmsY7?xzO3Db!a<*N1q^1ek{Ex>{8ZxEQaRJ4AVuj6Voub#d=IqtFN7~9d z1CU=;x_0iG;3p=ed?dwMR~-v3>qHlMf$0{20)XRx*AeT$I>`u8*v6$18X`sV#o8*#SDHHARWGeKbu~ zKg_GEF`31*0{1qr#)cza-HFWG5(3~6s0>JTRK>)*9;%pPpj0uf1holQKpr;!FOhf< zzaJ9nj}{Ju@diEZ9!0pSqKaa1{-^MKC-pE+iU*C8DvmWyDm}(H3D3o!bn^*qsm)w1 zYIIra8hd`|^m>$Io`i|WOjWa`z_8wFnjjW%;~bk~dL*$1kw#{t^!c1tY{HK&2FuZ| zlV^*#@(5OmP!tpKv`U0t4e_BiREfra-iILPjfrUXN^85KF!5C}UjD>m?J;v;I>bU; zzy`Ls@koEDY?xfw^i8*hWA-uT)&k%DL0wR}8ox2tAgnjnFlRJf8|cyy62O7}2nsML zi$OglsEY(~K@}@X>?%%dO}wO{+rJkbbPNw|-({c<;XlWiqLxRpH^~2|ve)5%(~)5C zhD=xzY~~(CVoTFLf3W!>kWKqCg3X5rA;Fby$By9IY0%mD^cwt0vT21?Sz-EBS<`CVuISgaIt%YQ>y5=HS!gOv*sj#KBk{{|9+0z3}|=W93z ziNeE0za^8)Z9KO6L+A7U)520Z63u}j$eCfhgV`0b84aP_gDnq=;JD>sKGCYJu#y-{ zvclm&HJ(vuLK`|HJaEW`tU#TiY3st|IduRGqb5`6D6oB8r-D13MBZ)l+?Y+ z{vYB;;}HXX@P_|JP6V6Z6HW$lDR=`vp&4xc8T{6~LlZth76otMtX+4B!N;2M1664K zb^IsqtT{~N`ZdPF4X))Yv`wq=o;qJJPO?^apN?2CtTej<4{yZ#Hmxr0hzI4Z$bN}}Qru%|nLZ#CXR?8jtj5*jlb-3KLsT zKZM0p>>LAG9c(_x#@w_o9PbfpI-C<+%SoWh&t}dvVfl9cJE(Nxj@CA%wc!}_868j* zY+i;U)z#bZnm8Q!a&P1N+~tcj zz3+ezKdU&zxH5oEejphI;-Jo*35GQveMeMY211r!sPbZ7RDA$Y>PN|!t}O*DlGrxvdbSDN+t^L|Ek*A*(4CLn z>;?OI+}+rNYp0pMrl(&8$Y^-Tn+OMZxWTYxnRDf-Gjjpw+6Xq1CEeb-0&~W~nkrmL^5zhfy7HAI{vJ;>`^}itH!CUqE6@ zv!n1a7MfL3S$`1qsib&q$LfXA)@2!qe+38XTY`zbRy2i)y{&V7=I$9@hf3_l{1U;j z#9?I!7676S{|j3JUub5>_Kt0ZP+9QR9j<<$u(ZM7K=>U%_>HqceG4jJtOLbmRKR!#l+rv1(+-u6KY}Wg z(C0vXEfRkR)gU|{)-5VD2h?E+jak$spj6(k1I2xyfbp;u`VlA<+fdB(zZBV3puQ05 zCQ$zp>OoK{9gl(f96Z1ACs3aWm4|x&iQr~|IwaH&Kq;%1g8Eo^cY;#-o&ohw;kAR> zFVsPc_b*T%3h!$x^t4RF2#fXeL8-@JR)FHr9xxK1)DF*`pxzW7=D0dVf3t80EL?}h z>(<@e9qa>&GdeuP1B#Eo1dIZUH^-tDfcl$+R)hKul;5ZY^{!BHP)CGX3F;f6t_Jm$ zP-{SO<>5D0_P`Bf6$74G^xc87X+!%l zuXuLpcofFeiz=(N(H14g-B6{MDC#zym)^ZfZz$6U!Tx@*KMVF}{#*7_ziAO^uXvP2 z{Reb4j`8(1y0)p8Zirrqi+!QGg+>nC8u6|FmxZxEu?{>;jxg2C!7F1W`v}2V3jCKV zlaLZnn2d}%jRBZc=!eerEmLyz=7rkA!duiLEb~+~U}KJ==a_sq8EZ+X8ya3CYD3Vf zSMHQ3;m*hD(bljJLOKc)jo^@;5(ttetKW+tc1^&3n=!V0b>`a6NP#W z)LFP#r%;*2SKcWISM^>|nPB%3o)1&%ZocDEcdY9w7gyECE9=acgv+bT>g%l+i{~4K zMxHUZP-==c9HZ3{L}!fHzu ztn8&@GZS}v<8lNMHs}XIHSdn79rQD$EI6VM6>1@OH~L!QU>_HSm?}O`w!4 z7Zz%Ke*)A7RH%TU)nm*rfu|m0ejU^;xKw%bH3-w4C1p##qFCN%2+!9i)96!ytF)WZ z2Yd8=MrPHr0Q=4Hc(9qPKh}IT@z33Z))8VXD(jHR^MeDUC{WzI?u||Q#3?%v$XDvH zicpysOPtIT*$y4RX0+9WlF4-H8-5#0OxP_d_1iJrKiohD_6@ldmzwd!U7*Y-|DX63 zeqe8E^MRnUGWhtR%^w9}Lukz=PI-I{C#v}LmcTBoKh&1M+Am^Q=~FGS@42vZ@e6AU z3){G94RG9a;cfs;YFMFPisiE*3sl^A+)!Ng|ajJtuO zS$qPXaZ;x$MA6qQxFgykuwl=LrWd)ms%R0Y)`}e^Xw`9W&01^iKHwmdyI>6ZpEdY5 z-|;p9yCGJwfK1KQ1c%*@nryMNDV9ol1*jsSZU&_!egR5JaIc*=fdU4Ln$gmPpphgOBvgYB3xM@}uRurpnuJ8tFggIcbn%fvf zaR{9%XucCf-KO)>JI>NeoeyhhI=%UVCW^XE=cRX|(u>`S%!=b>fHie9HMXUS$^uX6 zc3MIGUb+=>5OtUKCdeAV)9F_E;Y5=5(yfsF2Ly~`M)fg{`Bc3ESqn7tRSomJ=dS7_ z?_}(!DolQjxkxgOr~`G5P~;y^PrHjHOPIBaqOo&?XWnUr;<29wFP4E_UfhwXL1+_X zJ}nBKy~B!htVBu$izKSSpvr|B2Fi~9T>LWKVk>$@QF@^rJ^O09@J-=xdCjug;Z+qi zD}IOLIXQefzw^w3_xtJv?DU-9ct+a>X1z05XyyB+Nqf`&jO@ zb?#^DG0&BL4JI>j~8U<3!UAkj3zWuu`m8Y288AwVO@qXW6WE^YskGmgt z#I}%q6&OEKVrN=3@c0H8*a*^h;9k5060-mUfYO|hAeZ`(G1{%G`u zzLw40o}d$q%VwyC6!V`pKUzQaLR*R(Cv<`lsuwd+I~B+UkLeU=q>JM$3+9a9w*WqS zqK#KRhDi@&r7O@<{Ulx4Mbk!*I}sP9x*Fh&BxjtHlS>Xg3p0wGbDW&f2WI4<~oSHfq1)?>-*<#sAK>e2O=R5*K4E>P{#ncKQyLVv4t>a>(# zT%~ieB}J{LKY#J*wp6p05)6Y4ISE^+gp{3Mp z#W^;eDsiy~rlZZa)NU;$7zy8}IsD;n1?=9n?uA~Ht(9f z?BGDl=3W5=!i8|5k8+HsgUFFqK*dXUJ~zOY8my%R;~E(UikL<1H=OqKdu*u6&J7OiWb@r^&@}_M)79`+c;N`WG}C z*z}=gbU)Kl!&1_IHbU+CbIq!89}Kh7e!rFyj4SQzN$oQI&3&(ZZcA;_Qi5UR#$VFf zJY4ilfWgeihwr)z6GqeKPqftV6q~uSux(yDXHLs-%jWO2lwe#obJncpQH){f!&g3I zOZDb}3MUw$hG-6dsPdZN;yCAi93}id&RXe?>w8nHDT6h=mLdjq)$xrS4qNsNcJn!F znrx}7v=lKa_QzeZgKa$H;y5*P!&C#C4((9Ek%stRakmL;5ch0hg!ccOdr=dr@RK0W+~sGrADWeGKXWkln*}h zi!(=CrTh~uB^XyJpC?kBN6@im+ETyMQi752Hp^x+6)(Fu&Qy$rgx@!aKCa>MWA3z5 z@qv~ai&P-(j#U!pC3Y%yEPP}1SSuA>wV8r(rQ&>%GE?#5xNSjO>Kx4$3~>0WnF$1) z!5NXve;7iWySmC^JUD*et?((-zy7!>b}Fj1p7ANExIm=L9^Q7aV!g4>VC}@3~)Gn(gcE5HR|schq=nRpP4YG!kw-Q!SVa%!Dk21)a{hV?R5Q1 z>$xx`U7SbSrPK03OU8v(x{gC%L?;+my29WpDTZ?j~EGnnPMr!6qY) zHoH?10mtuq+NXAW#(voNUv?^%X+4pYR7?^nvvj)cx%RISD;4Xslwe$`$P=k7`nWFs zEm*OvNRO9{pmSAi?8Lu(&< z-j?d8yIaAy;+iZ{1L)&=;QFn5ZK(^ilwe$O#awX(W<311Eww;P3C0yyp-A=7aXs|% zHb>6$wke%pTyaeS*RFMsp8Wnxc3k&qDZ#knnrcZ=>%C)su+NryR!a$n!Nx(&A+1`I zY=`hCoZ_6w4HE67W{#9a5jd=e?wVNyj^9VCP&tjSb~N8-*UaHsPf<$EEEXxVW}g1{ zOE(r-H8ZBA1mjBSG)oGEvF6k+AK6k>T1qhN6HJrkn=x*ir;DD4;ByjpW?}hY+vbGU zGd;!T5|J`(zV|O*{AIdj^F3NhFfN-f5-GMO=Fj%~w%%<^ZP!wQk$%kV0%)Pz<{6@A zK7Cvr?~FTW+q_TfnUP}iOp!8ezWnX3>t|Rt`^knAjLYUyaP7U6dw%%f&uppFwUl67 z`AiGlHqR10e-%FV58HYnD&_)ROzWAIV)JZ-+O6Q_%l~%UEX(F{EhQM2&2vP`na{S= zS}i3Q$!CuAbhOZI^IUNJz65;MjS+*|pR{ehPwSbRV)Ml!#bB1s`a3QFu)ncNyo@P@l-n<=Hj5vbJ`=0sc@(35^(&!Q<41~2UpMA z`fgSH%Vx_B0O9{r6u1iIV>0)l2@X)`$wx!l4 z-QN70=WMCRwUl67aY>7ieLu!EWyjP^Tk0JxrCN=1_O-wj*VjMzb)GGCjGiD1#uZnY zNSWnTzje}ZTWXA!5)A9uNY38qnDg$kSO|{a=iQbUXgv#4%A#DP%sR%lywEC(HCjqA zE}JVviX)K^7u&Keb+48Z3~e@>g+UA5Hdl(CZ{f546#U5lh+ThnX+4!GHZKw>)8?Q1 zmRD3-Hh-+81mm)Ku}E>Grp=lE_|?s})Cobb-~=Pog_^@3YP8A~zG2X2cPf^E)e{~OJJ98Q zTk1_MwMPN%j1S8Zq&EXH#`^8c? z3tb%4XR{(0OqaVR)Pm#p@$PtUP~Wt+J#VLUmDW?6lF}cFl$p}^BZp?!S}DCvO9{r6 z(mIi1F#D)&M|KRirJmMOf^qeS^{%+KKUeXFE%m;Z5{xUZxJa?RGp;$!|9aGx>UA7g zaDs8g)c~&D&!2hRFK@G@a!7IS=`%Z(;*r)#Fj?e58+^+Rpky3&yManF}M=QU&;tHz--_}xs zaiw&XNIC1OE#+qgf)k8TXJ`(8NRMPD!l2FWR9p#;+LK`__Wz^yOFI=8Xgya-DiCbo z29f35dns3epH9ybEp?Tprzx$Tt2@zihnBk9((_naJ=chyQ{c0#=iGVoY&%`swA3}0 zp10HLSuJ|l4^YpW=N7zR>-k(utrk7b@%>tnGE4cyhyUDtwN=W;9*;mc!MI9!4Y+Do zpW*j5PCsZ%ovWn;!(ihg%^|Jo^CB0=IUi#x+~wW~4(>B**>ftIQGI;)MYl@pX-rAi zbqKZFY0Gohlr>uEx*st|8r=()7NSUQm^VT!j%~mP`?7H9t<4VQ#;HtDUoVzQw)EQbzFbp;d zHHWk+ol8Z2-?te)Q@Y_NpOo1tZPa>hNJ;5Bkup_Q&Ab&oKP4 z@9Y0<=lm$0iXW%s{LLa|=KO!0b=e<&Y~}oPEhQLN&fg+ZX3n!8v!#Bhr3B-uEws>G zTbMS#?_>BqaqS!Z)im4YTeY5BQ*8c;NSQW2c;Mx_TP>S^ucZXzviYYX#kR~kw)@2K zOKhn>Ybn9F=3}?H;#zU)J-N2j0WBpMS6pbQNLL>n*JlGJA7e}PJP~X-!MNhO16;f1 zUhr-8i?-A-EhQLNTt5>j#^u8`<>Hg(+fs#EN-zk;!7-XcTI#da)3PkwrSo%e{63xt zMeX-o%NIZy2i+A~&(96^W6lx(PK4U2xc`LtbAN7?&TU#sFs@YmLZtf9$MyP;AHLg` zYSU7JamDo?uDGUrUU|GNwO>mK#ue8uJBh0|O@I@OE3Ui1wbQjdyI`3e*LW=@7*|}s z5-BrX7hL^fg)LQ~r3B-O>({QhjM9DWwp6Q@5{xS@j{fd@zP8jOT1qg$;YA?LA+7ql zPf|FU{TZqpO4)I5^lmWyzK{wsUVeJ_A5AT|ldh$RQJR0?(nF!8DV%FlI5)dE&e+jq zBla;=1UK`B#s4&8!q}yyh*7csEv=s40^|3w&!vm?=-*_@;59TYMT|UOS6;hHVDLiV zILB_b6nERX7aYHD8+=ZU$G-dtd><~lvoI#o-79*WZRb94?K*bP%zgvzwc5@UEhQLN zx!*5RW^c22;O=*9sd_CX7*`$pohz=N96#WQEp?}s5{xUZ-@D@a^K}1jZK-WqN-(at z9&p9Q`fN*mq@@Joit9f`$~nr|QhiTGAe>-aHSqA!EIFVa)aDs8=;ltpn8pZH_Kj)yqgEac;1U^5Fs?j&99%mO zx!$p*W@#zGxbkqLNTKqHdwkXFXrN}=Z_-l4xO40YaQwb=m5_1%^%JAE)J`o$j6D}6 zl)2%~pC`fb``&=h_S5zL;EQ(te5dt1nUX($6e%-*W|lvE(UVsG3_KNqaDs8=&r{&4 znJ2@`Zfsj%OHI~Nf^p@~pG0aHMc}SK_190^DXrB~#Hc*`z2>C0Q;0cYpM8G^QflV& zb}dDWwm>-4{ow@touL& z!nNUYKef1-9P2Fr&Yx|m)3lUefWx!TnnT)M?zGvRif6#_`}k__rJ$ZU=}PokW-6v@ zJ8v8UNm%e9nXTyb$sw8yw7 zN3PDdrLNObf^o&QU8J&fT=yOK*XwMlpK2+=xZ-Me#r4jimPc)=-)SkqxZ>I&QXw7J zk{36gZA(3^r3B-OYo{x&=#kd(w$vUiB^Xy+&x#Z$UM!^xmtX71!}qk5U}Q`g2~1HJ z^&QZzpz+eW#*kLEJ~Kp`E~GgphUBMs3UjuLgP!(01};HY!TKYs+Ogz}aB@bC0%wSm zGcp&PE*8f*dj1(9_6}Z6)4_ykAD&$ZArOujsn5Bb$?fT8#?G+P5PdqP!m0T=@a(oT zWyE_J1XQYUpD9EM^_g6ynF+hs(u|bmGGRAb9HOrY(WhfvbT^0OpLmM%8y5$9#^fM$ zI||_${FfXXF$%p4U(_c@t=5@kw_6;rjg2AtbY@&Hgyg4qDz5h|j)^(q;xKmR*ed}u zb_#bNM4ygQz{u{wn`oMrg(GS6c@~G*e#uf}#(~QhbS?6CoCPVIh7`_CDV%##IDfJ@hAyu?7RSu7!zrAT2h%D#6O(IksK>dN@;p#}-{v2lI%bWh%rW;!vaI&W6*frth6wUz`hpkDvNJukX?v(BY$M1U`DLoF< z?g@TMaAsS}EYx?5+O}5n4T1qgkxc=&jtJ~Kw-d$~}H?@>tTyg!)71wT~aHB0{oQ^;^!MNi3JGgdS z9N%rJL0U>MuDIS5DW(h6!&sVE+TE54Ybn7X)G!uk4r$d+uW)ft53MHvS?k>O@GWrE zQw@~u`TBF~?0R^k*7H_MJ$zfF%oev}%&1S_vg+Y)wUl67>3T<`%wCH#SX*kFmJ$qb z_=HSyDmZZv_ZED2D&7T0t$mwVroVQt_ThnW^}?c6R7pD-|c4fj~IH zxKi;xxb|FP#I@_rv!yQ3Qi2ira?Rln_nhPdm!6knmtuLL$`4OEYbj#XoP_dpOleo+ z=Llb18OLe46*X7PjIXM$w14KWRE+W^H8u5>h0DqoR~p$eZ_jqI8kS!HaTl*#&fqP? z`P!C*gJTNVtoidN&y2}w^L2SkD$AD|6DQ8k3(wD)R1%&ZE0{XHpdcES6MZM!RfX5wfS5&p|pO(teXB4JB*S~xZ(7R{SFwWM>|DwwGx=g+TNRy$uEAWY*6 zmseEPRhGvM6%ehgu8dbsUwAoL+QPj2aLLrk(+elZCUqXmvae_WtEH3Jy7VEN zr@oP6F>nBQY0XU3wMs|6ArkNjVtz1=HQ&Df4 z$X6r$;DI&DyghoT3lIQkFIHsU86Opv}#$UQC9xL2DIVg zn&nk-v@4x$$y^;n5?fw4lt!t=RkhEAm?|M=Zn$|`rHiT3 z8m%i^94Rlatc@3-2S#$GyM*Z_bv3nfbe}b1+>}WrQw#H^6o%QUPNr8xuYlehdc5pz zx+FZQAT~KRy>NQxUECEiMk!ep^CC1zZA6}V=sSk7{FRn1)5C?6rWNH)nx2=|m|SYi zvCUGdrSK{msw>r~WGc*wM#6c~!h*s=Bu~mIWk6CNpqMyXn>!laJqy@0u%dFNe3hc0 zu4dV+(t@#~#Hc`7)zz%R57=)OOA=F;i<_$p#wD(JGb)$Wtf*8aBNohBZXO<{qRHdY zVJdpvD!vz{P53^XGQf^c#pG@sQJ2Y11I+f5gmA{~4RPg#%ss?VttYQ$InQdDGr7oZ zh}D2gtKyjbcv+GR@iHX|qinI6j5$rb&RNpvY%$qPpCzv_sweIoqx#QLN1>;4jM9^P z6nZ+xn0^2Erz@w^xRjpGv~*f3sygWYYI#NKm?3qvsAl=%l6akCD4Dqmr|m5(u0)$H zPwn4TLt^*tRc+9RH~?Pexe(rIOQ+nb8UpZA?n1bfThY#ROyD|0c&T?QaYvf>ChmLV(m>UMi_wRwLbRtB>bFe%yv_2M!H!5%xm{4zzK;sp zd9(7+nyz)Zpq(``7qHVzbRu0Dgep@|SGKHjVZ)+Dm33(=hZoE%LJwSWbgHN%($1nw zfu)Hq8E5tKsg;2pPSqlFMAyJ2HCHGV?x8@>)VzX<%T}U(Uuo4rP9?0-A&t5irj}m1 z3Tnz5IN&>`7_R(sg?r_I6JRA>nD$h#08`Gzbu|skD@+rl)1AaGaVbt|O=*o@@LDM` zd&;EQZn~ym!8&g-7OeBuV!@QQbS=e#b=FEOkXQa${gH{XGEwCWhabn-<6^SlWhtV# zT0@>*ia4u<0!Xpoq$sa}DGA|asvDy0M0<;1@4)U5Q)5-Nz6$Xwk-~c6l)LM@Qa-z? zzG@+6TqZJ!o2uMw3%2qf)YL3vTuv;;!+8F(+W4yc63LkPuKmM;okke8S0fT+jv#$O5%mfQ>O|dKoMo`Nl`Y18tHy;FqA zE5GSGakTmv>O^xF%bc*G`?M0_uCgQD3mq?@st!j1RMjDAK9*kNQ2;$En3q1U3g&?` z>&NtPao(hoNs;2I-;b;u&9*H!0)=4Bf`z95H^QPw&=SK^s zhrK@1>TFK)Q6DQBYR$YU2^Z#1%bQ-D7d0jIr$C)D<;*KNOi{RK%C!9asrl))(Pcj$DU+}HqRnVy zk^hQ?H8ZAky6-V-Qen7oTJfYQ#f4Llcq{tck@k0BRmEUKfF@~YD#2z-y+U-_Jc6WZ z6ynZORarF_=@rHmvbx5md%3A_bheXcj@C||>XSx!;M_cg%k{vyc?#!@K_|e$QiBZd z=M+>euc}|7T8FGJqqvu&2O)-E)KFQsN>9~gif=J_4~VmT-q;R@r&TVF)-+(|tP4tX z;g)Glbu}<3&Fb)|oY9pz4(EupxCX}>V??pWKMv4kwef~JbHc9gXIo5`hQy)fU-{VF zuhV9i)|Hhn6^(icn1n5^Q8&OXHgA6FqQnjOJS-R-Kj%o1$}EC?8E#vo1V+o`*$7*O zlHrOnnJ2qYHZyrU%nng1^e$408t0}xhLXM@puZ z*Vp2X=N(lWpaP<>e^0M!vC&GS+A*aJ5?&HRcJ8#^1ZgyxyPR^JyV?v>kBgc$V_ys*GuJ37#8|RxdIe_QM<#{)p z$y!l|E^tMq{%O>Mc+O}3(*Jv80f##ji?e5%A?ra*G#{wb%&?I)$@$DS*%4g)$hLXf zeHZ)=WtA*&KBY|@pA)>$kGG|9(eYn6D<|wcS)6=6-?&6$_?u2}jyGY+%f?lkf(wU} z?c-}iw*vRD#`0e}`*`B|8xCAL`@Yr~s1heQ$2U>P`Gc3$uPCpriw|~l8yc!AhF4cDJUVvq%-MM}N|UhDi=xva z#rZP_hiJhkxURu9(ZGk;;G*ZxD?MjUP2JLYldIyfhK2Lk&CaW@D;Huoo)ny?Cn@u; z;21kUUR^)DX5r<=`Njpu@hG+3k`py6eAfTsDol{-YZk>rLuZ^BnqC{{y&l{s3FYA{ zH<(`Gp>@0%Y<<$FrOVYpJkoi%qoJSvn%)zchEIKN3!l2f2Yd9zkilT^MY55KF^FT7II6tJu;ZVFL zWbQ_UN{eQOFomjIDG6zsAm^gRdnJxxTCA@I4c$U38G9G`Op&s(FMhMustQ5MbbRs1 zFMLJOqEm!tS`gT|K{h0nBg=s z^Y*(3*$*A-wt&Qj&~Thx2}A5h!t0+o?|r}Z(6OW#;ev5Jbj%p+hmQH^v@KPPFgn2q zwL*M)61$`0VR5PB(iwW+d(U5_8a97jPY;fm3^l09Z{;zc4P&$VA-+7AJj!ISM{z%t zjrXMx7mJ@^BVH(b+Rh)oWZxbvJZz_8zSh%2Qh{J&wM(0;%Iat-1so3@}<@FYClsnmsZv-t6GkSWRE66-w$@C>U+^@ zaszwR7B7bcbN;3_|2ZSq(`|EkT3wHz*=5xYSlc=Uu%yyc_!I$ddx*ffW1z_%Gd@gP)~#I7&35QZ7jGPxH4a?5c>hCV%(%VcWvBC7;2zXiW)b84 zU!23Nh6&;S<2ejg1pfn*7|vlF-xtL7gAGn_f?U6!CTWhTX1y70r)dJ;n}U94TW z{MwI%u2D?0k}W#vShHM?T;U1V-VvjQ?BS0>@7!MbR=lR>EH6~*ZL3(uanNRqd(0x2E; zHzy%6#LD6S)v`Ww?P29;Cn0lRTZsh$<>@%br2F?KA?C|jY7!zHq*5ck>PDu!ICw8@ zw8>zuxrbdfQDGS{Y*_t_1$Me>z@h7EgfN&oCs%69!I>hZ_(oS(D_uXL2%KPClPi{{ zd-7mQJs>jXl!HHZX%7F%ZFZ+ZrW|r+0~^Z&&mR9<#gbKMxO>$%b#z_$jg5#+^GNH^(_#TBD_V5Vdv?M&yniGfo6JT8=T!#}2}a7%I1` z4E7u?n_1{i=P_DtK=_wQIIq$2Hk92BDC$$$&%v?&r5m+=3e2xHj&;;))M6Lc2F&hc zoNQ_#P&>x+5inmT;~d{QBb2MZegL0M0XQpO4}DXBnVpRD&==PjrBSEDvCtr&=~$P7 z!wyFh?o8lr_rfLZG=zcM44llOL9Ea!Vu!X?EdO2 zBN`(>cwX_|27V!MZ)q$?f^_j_qH^_N1%pc$?*N321ZJAXrAzN4z|94w7dH^#IF_V~ z7ay)Prf6Je@h$w{hyAAQ&2+YhA7_0hHZMt|L2WE@LrHhv%=-a@2rE%%vm3Qt> z#J9X~(Xkn)i#GzMdFXo`m=BY2N%~l< zUC=mBVFQIrS6@O18=^79(RtOEt|+Liaz~?HXt1-~ZyOu@NTa{hzKHm#MdH{|6S1 zMtIij$Sf?$!m-4sMTz~fwR_@SW35x72LiFC&Cz|Z(ugJY#n!ep4Dj9)4@WM&?9wf< zmU-C=Vl7u^FDYuN$gVAJtqjCkWyH?U-C3A;8K1OQd(lsF?j1|)h$Rkd1_!NJVprl- z^*fr_lGq(fJg=kP6*B|CQ;5iyYojbd%=P0v+MCvZ=FeE`Eo<n&{vFHGz%9=1F9ct))0nT$n|mS}H@;3K88wJD4^L^UHy zuRE4Nro|FlVhQG8(^i$Atf)h91&rbF&k$-X{L_TG6#ihLs^JqGkXtEiegQeVT2Vj4 zZ|>R$3@m31wt|512l(u60>&U1sMgchSk$?oI7>F2T7$8O6vdH&#p*W(X$bbE#knyG z&3=X5x!)j)x=rV$my;Oi?UG@1*~*nU`egCdn$Fg!DE8S(w-ZU)OSeM$F3L16iXUSX zjp}7|uj{hgzaXO|iZ8^?G)nOOvWRgpq*Ly+l&k0eLU=Tew~lb{1y2;7Gu8;tM6=0h zdZL-hiX~o)4~;eLUlWn<<)XUh?unr$g%GCi!n8LDlHjJTIhSnV;5h;pGY;Lf_{tlJ ze`*s$QOxul;rY;Wcb$=u!{(M1Yl&y~V+{+=+ z-IKc$NmxLLY6olEg3VV$;f62P-i?30__$bW>q8h!a`z}rT7E5gjG#i)w5#6^H4URA zdQ+@pi!0*9OQ{hztUu6YljJn*&Sx4_lu_hD*cOkKznNrue(rnBu9%&K2&~g72sVES zrRql@8qEJLw)XX4^V7^Ucgk`*jy7$<=DVSCO6!344|jBQpd*SR`?eP*o-gd!8Y}-x ztZ7STZ1X#QWlpU1CuUwPC`#;;IFe%SXrIy&80Hmw;uVjay>)*G(K{n_L{@ya8A(y% z5Ic2`8=bH3-z&*4&91P!@PD)aE=;_jl9I6dZ}3!_zm&>@IFh>WC?ZU}B-JK1Z1*BM zk6wJW>cw~JUYwP+g4G(`cu{r^`&#M6bN6`kxs1Fw=u8I{V-i^$UTo$=BGVjtYXCX5t;tEI)6cMT({)Ix_0blW+w0L_g-ajqg zaVU3%8v{zoHdwr$TD)zbCO|4+yatNBWx)8%!u3JpP_iRIDcpsih6t`0lp2lZfKsE; z<)8*j=n7D3G`a!QslvO>qV5KzMk7{vH5xquN{vRj=pNK)G!IlnWUm0FZ229iu<+m+ zT<4o^5(w2Ad#|y9j*kg<#@dL(?ihmeGM(sC-_}(%49XjEyKD&FjWtC`oBtHc5 z0+C>6npxD^*oI$4iJdVH+--%4!;3!sL+r~JV;wu==f)bJVQ3*n{((j$_;@C+K-RDw z4Vi^aZ5e1$2Xfoi?hM}A#&JD!ORV+DHH5b|@?UJ&;o#$0!N+@z9rj{FW{d(m8x9H* zQhOk^1t_D5o_0m}uac)ICU2_nd>km_KJ@AHFape;!#*FS=GMHFa0QGXz@IJD8u($M;2F2k({2v_s{|{G37#dq z{)4(1!BJ-#LEm5_v$orUu4Wk`My|NbGMvXzF`gajG)H2Iub*~h$M%%$kc^0%8Ifqt z-i=72Na=Ie=U;(2zV7#QS0=qqSnd1Vy$yBTPF93whUAXlX9x46@38=Mqdy@ zUoaH?!2B)P(n!gxQt%ey!c!FR%Y^zl{IF2)j7R8cSC0QG*A&HETOhpt+1-rZ6+?{P zqs}mTBj#f-#Fx>1cVPk6KVy{=mI4WHUjceRWtLJaYf=X58 z&IUCYS3o|?qPnC){9Z1+8Sn=PH6Q*mq3YoCc16Hwv8cN&>LE~JTrdcZ+fb%sZmNt| z6f?eBc>M=B>$Wmlfa+c0SmV%v>rLDKEfjR$Hp|b5uo%sG@;PmzyTmk8kPZO#HzRKvu7PZ=< z)`L<7cRMImaQB0{5?8=@7``gFXF!F82hVtgo_5rw3Pe#XkX6F_{sPf+|H);`mX(EY zl0t2$9u_~3 z*uYitDaqPtI@UI2uA*q}4Z^c-Sbl$uVYFrIX6g6Ec#9RIq8Q`N?ie|uuwIH@S7(sJ zm=dq;10J=eG&=`v9ZPxr8xyct;uZP9r9vA)Esta`fRNSMmP8Yna0zA+!fqudp)l>u z*(`O#m}exqwKQjc12Qo=0E$_fn4aaI-pfBdvt@nuVF~GjkW7R$eHE zkamt=`8mZc<^76VmhLWYxoSsI;u8$~xnH!5jBI)Xma+FN$=#EmXvgvw3&njjmvf<# z!qywtfX>~sDB5z(t!g-9ogM-Gk;I$U$|O;IIMT5VH86PH2f!!tzbS&wFm+sj4Wyg| z76+(;V?mEf{&Rn!1R*pF$+fi$;FfO%hLcQ$Tv1R`4JSvM{<$WWc%iU-Ypk_T*s<(P9O~#6 zEAPfw`J6~g^o4!+KMMcjfoh$K%Ea%- zg*Qk;2J8Q9oi;{My};Xo%P&J9b(_vh@1F!Ys8?5`*XKix%$LtJ0$WFlfEfo{k&^6V zQOs-=2cagCv{xJo*?(|1qYpl$)cvh)wOto<$qAGYk3A_^NX-}E^8b%L%e#T9UC#M* zrXL}GAGau(TVGz+AGVko#XP0sv%Kz4U@*jfR<-Xr{fF9*(exG>))-1UUlQmdQp`oh z`bhuRL$=hJ;Lr)i^=J!6eLJpmmURrWrNR_}6O1b^tV1Ei++`z03IQd|hp3C0x{ z>z5tZ+|SnEVM{F+8S{Y{XS%wJ6yu_s+V|`~*iuc3DYw*UiD7X2!E~ys|F`)Q{}t!y z6wdP&hmZcyy=iewsn1*-=feg)5MqB|V*IBI512CKD=}h}<~*|kpxp78k>e(6PtjwR zRr{~LeA$%2O=K-ajM8(XTaV+R2G%vdFASfM_(%Eo*|qM!v{WxcVt3r4l8tho$U^Gi zGru^qm-Ud7`C^P_$0Zox@RETtU1;|c(u~*rkW&yGzmJ1_>3X1`%^1ysVXfc z7=+?RxRna#A>Gd{j#)bQr*O8UaQ0dp>RDE~46_AM2ag;)$|fH=A&U8A}w7WID@$H{7s7=w586{ zQi73>edG`XM+@CHbMlJ*5I*~_bAJBV&9=?OT2J2;oB6zh-EZvsQ~v3FEt{8UDZ#jE zCP!I(G7>&>Wl+}>?y{wRq@@IdP|SighqU|gJKF3{1xF>n?-BUyPtP57F1jc)=bzPj z`lY0zzet%mf9b1F&FE*P;yo=T7*{Gz5-BqkXP3OxXiIg`Lx^C2!?vg9sQN?BXp5uM z#fiQ+rox>rZf&X$1+urgr~ai{J6$DO&&et2qHT8R%q%Pzd9szR%e9nXTX{SRAGcZ721Uh*nCOE_X`VqxgNVz-NE@^?A`eJEd=E z&8McMlnZ=2rCqLlwb!XuO25!jf^nrZBvQ_l+EOR70>OoFsVXo|bI5g%4ugpCoyGvT zKV6#l5E07F&{D*>`&FjYo%X@t*dG`B#a}<0W~co|t!Hpb+8M8%c79xJu$A^-Ybn9F z(w;3+9QWz?evvKpCoLry34cv<_`{tF+U!on>EPI@_}Ob^8|+m4L+d#`B^76gl-UNE ziqoxBe5a)Z<4VO4k#eTOmg>*R5u9M8$5y}bF>(-Yn>oJteVoB_PBZ$ckrlShqqUx) zDK>LHVCQ`JhkIIwS~eGHDZ#jGK1-ys=;N9;p|ahUs@771am~<%x#D_w@U_3UrPgaH z!MNf&TclL~Zx}D#Ip88&>H#e!7*|~9xZ?WtDdP|Iy7YWmA2GB zw3J|6Gpln&Dg>YIw^uLxv)y*ObD|1IjA~DlHOKBnFLQA)E{_!vcq~(QDd&LW=dEv< z^WXf<%%|*9uGe~UQc9VtJG+$MZhZUf9IKT1i7-0BxN>78xN7FfQf|K~kYP(btfd6w z%6WE-c3gKH``zWX)L*oeU|eyH5-HV_<6(xA2luw6zSdHLam6*-71yxJnSZpUPSs6H zFs``9SaG4T7_are@;+NCtfd5lP&|00Ii#iEz>yZpu`Ie8wFoblBV^2@Hub~kx!Fl< z^Av+5w#<^VM|z`E*b1GbLO2MKKTK&yz$)^X$VcBH@z4yvg~Kr%aN=ETTN1LJqE&NvedN9M3N&S6s}Wyu#)? z1Sv1=O$p~06c$XIJ|)ddd-`#dl%vCxW$6yPk~DgMvB3EnK^lbfH3Dyl$}t@6f-g7V zIF#DzvQ>BqFOCOh>g6bqr1uDPMq9^VhOWK+NLmp3fa zR;d!L=jkN&7g##~CX36s!upvwKGUoy&b%|NOG0=hzzuQfN2SxsJ2^1biSW|zR+5qj zot2FBISbE|RG`=aNE5Yat zESNZ&H>A+)aYqVAli`*WzDERVWY}QiLPBJ#JW_#Uop7*$w$(F8Tj>=hdBs)_(^7rN46??mKRR3uA?d@_=%A07Nh_Z|T*;@i&RL|X%FSZK zXG^9{iA|ealJEVhb$um@YXxsxpzLtp!Z8N$EQ&J6cVzUTR(bMOFe@)oUS+mItWGrP zs32!s1;!kRC7ovVPQsX@a%UK&C+ScjPd%M!aptPGF{-7Mt8TokijGrE@hMsTbyVI%d8n+@Q%0Mnm4MR2SV@&-jx`EnEO6^$W|&Z{0U z2?vh?#|<1GcV8UNOCRgssYii37P#R@f#X)~1xJBnI*N}HXTEI%5piDW;P!Zfmp;el zJcYTXcwG`s$|DK)M-=F7z|CMr!m%C*PP#r}iAVmk!2CtyxEPc-ppxD!VLpEjOn|#W za2C!(-(X;dC*wTy6#+9Z8RwzzN?@)}#(C(w8<E3?aaRtm zv-A!J=KN%whrYSMR43y+?E4Wg=GWk@cs=wz0^E+H(Dwl_pC;py^s&3h3SmuK!4a_IWI1hb6>=vHP z9YeTu>1F*J2h2suI1ha_z+9D#OR|sUb_XzzYMfPWN%eUMaGNv+q&Tns`80%la1=Ne ze|PS4I-Hk2Zt;#d3LMih+Y6V}-|s*I>wr6-`<`%Y?&<1ZEp|Dt=1wPEy7FMWKLh5m zWSmENybR1+$+)EQVEKLr%n95pg|p)I&^HR0a564QAN%LafT>HydFa~!%$>=&Bz>&U zPXhC7GR{NaK43mi#wF=vda=uCoP~?7v-HM*DNV*D>C1wSI$*BTIIBJ<)q`6CxZw@V zK<dlBz#z*Ub0 z0oNT@y865wm^~VouKuy#IHWPuN9Q%3Uk-j?93G^{MaTO?>EitzFpp_mx_H@sUk2vA zWSmF6$~YhG78hMQeN4yMz=V@=9{Mf==JI4*QaxooSf??Jm(HvHak$@*f=gXD9s=$O z;O-w!O`Yf8`@npnap}^_@hEr!&RxPqXSJiG`oeKnz^eHAZRluFn@D@NVGV z(b&%7{Q{T_3c#g{m-Qv2F#?3=mEMcN9|~Nf#)@2;vy5K^=5HF;S-eLy#uaZ;zs7pt zpJ*b~f6l|ORrbGi2Jm&TB5L@!!|?B)0erbWg8zTuD1;GfR&6>z_Uq!`-EnEf!7;ZP zZ)Gg|&1XAz9k;1Hnm-fu^X;VH?HJn8qpl77FN^!vS}--nWZf131L6_)b-9UW_= ztvi?;ioE!&T3&oMO)oyXWG_CuRxf_PH2eW+_#yDKXn&I96vK-@G!6gkG((t2c`1xu01!?$`)9_h3$+10+pACB;89c?eh(Jjs}^<0 zqB1elP@y64*au|bD#68e>2wU^vfgI|AB*@pb~GLCcE!A+)-J@vZjU5xT|=tSzq{j| znBwA%7zzE}|6fEhGU9mM(HqS~b?UeXq{RWTpZV#RqeWQ~0Z9kTJYcZJ=L^NQ!+IRR zh-JPt!t!L>RIfL)7YN9^BkWfK1}Ds169FM`{i+d z9SHY==Ty~IR#(>7hr9w!@w$d(p{Z4IL;s%KP!-2_ddyHBN*O9Ct1uY_)m4j^#6vUr z`5TiLsVgt5sC4t@EUB!lHWHCQG%+a<8Q&HUM259(N%)3k;K-nAymDTOceWOwE;--X zYR=}XJw=JPa}V-ur%<#tKPz{q`3_dRTW;I_xd0@JvO`a1Ausrj;Yu(RLPR1PC4lD) z9a3x_>z{>pq0}#^IEE_l)_bhwsq8hRzvcT~?}@%UvunYLCH~%YRc1zT?ZadydgiwA z-L7mN3^bJQJPm!ar(r-IFHq6L2^4r$ipNfbfXDxA{q)KZJL3e*k4+YkSGq547vD{;UW4NCDMpwHGxvH z_kcNcGUcgrjhB=u6~&otDHvGua+@C(X$fW4RA<${!#H%AS3 z>1Hn38WqLXqI5g00Mj!s6jF4@b6ok6PPfVrXU?V5t&r-aQ?;3BmSH;GYoLnjB2_X% z!1KzJHQ@V={-G|$v85x7V|`~E-P*u{V|`~HG~)6bg_Gy2UNqb@U+`0IWCV6z{Sfmq@qoB>ybL9$8V$$A60ri)?^;h%(t zI`XnMQeO-M{8)PsnujC!64lu&)fsv7FOySKegs?q2Pv8pIrbHtzWR+h7S#l*hwwI7 z6i0MUk^ROdi+UdvGskayYEk`Q2&c_{<8+IPfjU8Wvn-0!4^E~1##)Q=Ahe`4&pu z9caj!k|^qdVlT?>)eyj2*k)S|Hvbx?M>^UfO^1W4ak|`7avDxi%L8&q4w^iBxWo}0 zEYdH?!)~^17}qb}6DJ-mz^r8a=GC7xbp%(l_170-O4Vl{Y&FmYEQlqJS%Z`pwdS`M zV(N#E(1&BVI!gMjZCmAW0!j|5XuCNTV!fRUTuI824uWE^S+TUanAq%=Tq>Su*Rwn2 zI3G-Q?m|#x9uK!fBzVWZb=H@$mV90~H!{B)t{|=xTk;3C=YM&&=s^^;6o&xy#cyN( zDonhTG*UDKXkO>y%5Bdd!m?}6A13Yb(({l~bpL2LYdQP|b6BN0 z`?2y_Z<2*-0}VKihxJm0#}fJNiCG`|XT4ig{^r!y0hh$epN(yPw@ab_Z?TrVa0GME zKnp&Ui~pG|c_sYct0k|L|Fc?VW=U_=k~dc=OB5e?5-kVSI4?7i|8Z-tM&Hy>tbA%n z1+$i*L(4;F##HAGP2|7Xl9wa(268wgX;-_v7>uy7!rgxyte1Xd{{T?z{ZwZ$43rub zIpQhmc8hu%6i3j2vD4yx0O}>-9fHpq6EMDoKUAn=VfHSe*jcDhzLBh&`36wWN$4I> z)EO|kp`6zV)f*I>dqCd5-7eJm;3+NBK&jDvA*h)Wx*XINq5cR;Y5A)~eF5qj3GIb$ zRgL(4K{-F^@*9M!jz&?L_AWP-t4&W^hOtYczBjw=y$+F-HfE4IgkQo68yJ zf|wdea$na2Ni4A~I52ELMh_-iC~&ChNbuU@WeSwLCxK3I1L`!+P#J(#{@2J$^xdwh zMAO#rd~83&aqe#U7By*V9Tje!k`dedL6?~SU+o21T_L7=9_f`@ryLV&DadRu2yxFy z1+;f%B?7x&@Udw2AhofDBQvGvkKLYFe;tC2nE%<1xApm22Z~K1Y7*m3Vx&o&X%e9? zqS=Ep^e?@~6$?gp9Kfk9(idCyq4)bU>=@g!I<`;Z#4(pkr0e4`mvcF5!ocdBOi2zb z+CXq;4uz#VO*CHJRSvSKB8!@3QEM!U-J0qGcYs=lD`32BQQv_o5gt!?;q=jO91p)( zcmqHc3dLDhzEHzKMT9yJ)C8fzpw!meG*F|3$2l2yC9nwx>Rh3gfci$Lt3au4@lH_6 zzWYG2JNFw8fZ{0PHy(nYA=D%AeL_i&3iTBH4v}aBbwsGGpqMJZL47-LneH#bWyh!} zR8Hd!;SJ*b^9mGZDZ0W@J;77Q*ziBQM1^NppePPvtk8a=1^O9}>Ad22N08F_dgy28 ztEAj9DgAdNlyR8OOF!$HKCc;Ra9YF^DhYQi%A%VPO8utu()|$v?T&q-hPw06jzQT> z6m^@H z&pvGPzJdPTE4xI-?_KT30adZ`XCgQyKJk}mqG;`hFri;`?ap}D{B_yJfk0&41x8^< z+l!lH9nUtrd*J*pqJ3{$LrlCo0SG#9hQ=H?Wl?ZBf)Sb-yrk{3;M~oh1uuK%v*2-o zu7&hcBW#C^i0^sc`W40q> z+L1AcA^*oA)-y#>`UFSBK30EXNGLw*7Sydoybie_YLG~rCd z^OH33^g7U^WhJtJ5%mf_mfxCOV}nC=nun@fxZuwiaREUitwnXQf}j(P~*JOz!7Pzkwb8-BLQmL2H@Yxb-ct z=Hu)%Zf~fS(TAYUhhV_?7!-%ufUy#FR;`f|pxC_zjAubzAfbCeDG9DYMhR~ps1ZWt zp*K*t>7Y1(2MiogWegMQSD=Op)r>l+hT^M1@lj3FadM#6DvCla##w>Rp<$GUQpmdhcYT-^-^NSzB>Pa>XDDNqqdz>4VZR zz@kE+R33q_kfgohQponJcfaA73nEI*U8eDxs%E*V0x)>CAK@U*!#js*bM3NdUYeTjXDo-uUPLD``U z^Ox-DVB|Wi=E9(MSk$W)wNFvlg>RkO=GcZGFc60d7N*;ImmUsx(6A=?+v;Y$F~#`1 zn$gbVai`VTqvWyj+^C-~2N9~~G8Ac4)O1j48Go@wm0Q#@i@F-rdRzhHSMYx-)PKQO zT0j_k>1kIW)r!?qQEVFd!t?dXH2PHFD#fvVqq-V>{vYbz1iq@`>>odun;snata?ubWn_Mn$ozE8RgP=`h_2 zDI5AOLU}dd)ALRIkchpQPv91PV@mGiPu5q_-Lj;M7Lv*z#?5#ygYw{Xac%x8a&(JX zS18xi-`t34;Q4}-wt|bl$aX!Y!(Cwq9YKcs{L3) z-D0TwK&g@FkD%1Z0mA!`CmmW%)ln1+ak22!hUmkwoW3_UMBmeFh`tI4_PnccU^%^U zlU(_$eOYtmhTW#uu{!YBJBXLfBD-_x0PaQVtDMRl^wPrWe0>enoqS9O>%D%a_mgQukZH)Tld&vciaw1LuQOCG z<%6=hbRvHF;bP;5qUZ;&S)-o0(W&}K?rr0xO8f^-u<)(!NaRw}eY}?AUiYRi9KHga ztlgnh7TYE62^HMCG)Hb0DVJm55s~9fVysXcIQhYj9N9CguZYPcnox&ftW$g zMpKNjQm?+Us=!L^OA!QOTqzcom8z@Wdaac@lp+YkxKix*t)Rx1AHt(boJ=~_$?1Y%q%j=EOrut#>9siZ3AR3;YG*UhCA zF^~$pqt6wCXe5S$WZZc(_B#&$bV%v{f^q5wM`%dlj4byW`%dDJq63Eo2Elm2Erc8ZvODuDYelrz zU`kz|nPOWyTb|=Gi?4^XM+Rc-W`ULXm8pjVWi;Z?km_c3{nYB|(0YgwJ%u1-?KV>n zd+w-u_8-)NlgIqn>iMqLLyYK=I>GhcOg$_Go2x_f{=M4j*{JmpBYN1+%GPh0df1~_ zJukj8&p|149FY1o(!>_GIC;Sf zR;o!$;c}8vfp>5?+p!zn4Y_5nk^4(O3bxm+r3B+_KF3*%s&!1u;}ds@SScd_W4OZ$VEhQMo)mEtW^2EjPC4hGlS`sal8l~(F`EhQMo zR!pRPTfaN`&ka`UJuM{|#}-T4+FJ5P*$=E#R28<=26w~YLq$s39jM2*%>2HUIzUSa z#<6vnW9x`J`(CnA{NfgaV4QU2gKIYsYAJGQ=k$DZ$5sc&j2!8o>#aBPiw_0$bk>Iy9-7{}IVkz%_;wfAbznthy=x=l+7 z2C<&EQFA=B0#%sL8jiHVz}$wtKs18kOG4{Y@BW+!6<*a+#3X-~pWd`SD!=cZa8(;@}fTN&38u<>+JK=a^w>nG(m@f?7TF+5PyW0aCjaXZIJMKQ} z&7({Yuv$wA#>x3HBE|U(!%gd7{=`asPfH0#;%|3SA^S)PU!C0EkMpu^Lz z<3x&&V6dlt{*iybXFc327c7Kv86J)Y*XHxTA3o{_cEip?wUl5S4=0F}-y;>YuP?Du zQ?-;}oYqv}*cz7eLa&wbH$oPSV~b-{G$JD%sFo#Xud`BTXj_7DY;iJR)Aje;cHhNH zov)Z$>60DEk%qgH4PlQC3gJyec!ZFE436cuG9%4#h#O4#IZlbM8>yu zkCr0FmEzTTG%|`J2*ZE+jb&EqLoG#&(lmyhl!REC9^R8xt&-7$-+uoWz6@?ZXenY~ zJuqvEgAeU}OM&b6(wM@z*sT4k|F`TfSQs`wpo({FrBO9{p)wosR_X>VB^akhl{&Vjom2FtmEvn541#fNCBU_hD@gFpjNqk@Dvx7o2mzjaF)i?(7BQ*s5@B{cXS5)2!5?T1qgEt)xi#J=+OC zz3(k6HBCzi#<9h#7uzbMC*JbDm71%i1moDM5-Gn2`0BI2jandd+dKIBI~6 zMtFN~cTlT`&5GF;_qa|)jTcLsZ`6vEUo-zT`sIgeOpE)ImJ*DUt92sf*On#sKC{6} z{Yy&;#wo#i$JT})4?oXJ?Xfc=5d`DdngOmIn~omQ@dGP0MoS6Cu{Beq{B%_m%(~r5 zRcI-}IJRbqlwUJzrgmIwr50%^!8o>NJGLJEXmZR-ouj1$kHBUb9l) z*HVIUY@r(sw73gTy)a^>eyODduk^eww5Bs9e2I~j-9Lj{*{02YNh_ArHFB*P7*1kq?EB_z@{IWxoW+u!s=O$SA=j;M!cR+Iz|NGfWB2)KY?RQrad`oY&F933IP{ zz)GE`r3AxTH<9BhgQ{J@mVzZB#waVb>rnF4dZnzHPgK9v z=a${lITKOQi0^ZG>8LjA^Ej>N%nYBqL@Ma>na1aOEhQMo=WZiKf9SK7TCSx8Bc($O z13h$oPJt7RoQN|^=an0;IL7*Xz1EY;@VQ5%e4p!zD=teJpMRsJ1mpO;Or-p_!*voX z^_rFvjN>ysbbVefdN_(vSJ_P)(bYvjG30Xkg|Ixs=M~`ER`9{r)~e;k=aE`UFpkeF zMauV??cGXE(^7(Q+WT1|#X8S0>)6XMNHBjHPSH}tDBkxqhq2NF6p~_KN(XztKzt=` zFjWR0q?qT)O{e+AcmqO_->~FKmYlgFK(7qYXIXky8#Zt6Qd&xSQmKx1wIh3-ynd0u zixK4=T}vDAB8DtiS%!DIzuAAHxx2BewKLTUS-o$3Nku$SQB_@DTT&a>`#BU9sy!Eq z3e}DdYNvP~Uly;btt~03tSE_dGl!x=Z1qr7X!m+>(Y5iq%H;Io+A3^HueN}I_8p5A z$E!Up*WJ_E+0m8iR(axox1caTov(Jt&*aM_ zCx2oVd?sJv3$oxd`3gTF3qF&t@Z+=KGx-WXE(<=Bukh))qj&yKV`uq{OLwXZe|~Ez zNEVlu)YVo_kK+Y>zt~!rb}qo@2WB=bm#3#xqp56f=_uA890`2#r!n|Zm<*xn*6!5T z_$*9gTSs@ZUq}4fkjB)Bb-B_(h_k+QseCubQ*U&s>Q)L@7d2pW75yQP@HnkMG*U6s z^-Ro9=d0?P$ydc!kOiN~SNI88@R@vtAD;!E$yfMv@0}bliIptg!55Jhu;!fEjTY_K zuhL|^uB@)Iv^-fEPgE8a6cwsR^@<8p_-u!HSg)v1IZ;&D5jUcVcu9FlaaE!+OjN%9 z;R`ijG~!1zbMop+0o70R3E3Pp8+3 zEt~vqVO9$7dHR_;IX@&yr8YE5xiKlbRA`ivIxf3ZXq1wgm|ZF~N=b#JO6OE&%z_2{ zu2;OEW%4)%bk_2F;)IqK=l8hAaV?V-#^o<+ZkR%j3P%1oyoJ#m(8u4<=*Jg`cK+rk zk7hS_Ep2T_$@s<8?R>|me~eCAzaWWBG^g-Dux|nrymtJ=%+ax>zlpR1tg0jf!>TgT z-%1*g-hpA2-hrenm_z+L;D39mDxOSKC6d*(b@43yb?~A<_kXTxd>pPZJc~nI4g+WR zIs`2`{jVPRMO@$2+}+%c2?*<$ABj1NA78uzZ)S&mfh+?P^d+03Y*y5z%?=G2*bZ#@ zxNPQX@h!a_B}!p-U`Rk>g&!~T^DLxghD8T;hs68WUiI;+dR!FMV4%z#rv35JJXD)D zKdtF#>S=3EHncajHP7>QId;Oh@v%VI(f6#zA2)7Fq2T#Fs}tpWR{zMyhdg-+j1cxc zD{k}Rgplu9T>`))y+Y|@<5|9EwK*M!eS?FmSd{0Q((`FJ*&jTxZbjTqxUByJaIbKI z1Yt6cZ2O20&BI+M91PSi`zfdG(>)CQNx)R3So0B|FKJ7@qn z+C6RnI3}TZ0JwdCs~-T4%Remx#H9v+Bjo%6;Ar>q0pe~L01ivE-p>bsV?Et8036qz zpBey;cHbEQ?hxR<7yyp-VB{V+1wvT;V>(6;02c#p;s9{$T4smg()t&!teytk^BPM( zvh^?1_w>AZI2f|^FKoX(8Y4iQ!uECFlIwZrP#+r<0@ppW+1+C#@(>3@HoNruc#RPt zPGNR;!{TlQaI+3lC@vLev-=`2uWMX3yX^nA1GAT2pyk@J*iGw)4hMgvzlaN(A*>#- z9hD9MM}0HGaB1cHW8jtpcVG+zLJp2>=}pAY$KYV-FTL$C^a(f^3@)Umk-9^4211mND+*#7cm??aJi zI2f|oWjapO7y;rGX7`ui&jc>_Fok0OpRGKu0p?bX%VwAD?O}~k8pG|*N90q$jlx`r zf&Ef8yH@~ny~g!t_kN8Lg*b(!SNsF+DUFTzcGKDiyMaGu=!?fOmHU77y@hj`r2p>s z7Fsd8{$Kdk!d-I?s_FRW(|cU>J8uv4(Bt|xZN?kQ^PP>2lD)YLk zo7y+Suijj~Cg^VFgk7zAxvQP83vXAGG0ref$xo7jy`I^f5a+MCO_xtTq9 zX*BWY(aG(b`Que=Aex>leM1Fm5^`D4X>JXoE%@n179a~ZDD|l@eG+H%Z4ByrEJI&! z?lW3dSjN1BxD9MSc$ag&ygt4NKXPPy&ILlT6FN<(7|y2(brjAg2{jq#ZwOV4^IV~l zIL{HP4re9H-%1}Jol(5Spl0I8@w#wU`c{FWRE~Ek&Pv~RK`DtJf~uC-n+)$ZPzrYk zs7i^w*TmirO4)tL@SXuxjw44d;FRoZCiZWjN+tI1ILC$h0_PKi8j8G{D%3%sCJ8kL zl(JC(N_kofYNEu>1Ep;6g?km-3~Ic@wi#ZR!L2mBRiMTS?pvUgjmu5!b)b%x*jqs< z8$UO(_kbELvD`3A*?rL99yh#aK#daIA3!M^ub9|(Kw)G-UVQ{g+1O@cuK~r2Nk6cq zs2xKTh03Kja6LprF4X^X@ZVw-#bNef98uY@fx7(=rguLTw49j03$<^A0oF|BJ()pvC?Vh{gBXKV3td@j5lwAa13v7@VbY*SmCmsq~Eysf8u zF^S4K8 zL3Nni?8EO9hpNs!$Wg;nkfR2gAV+ngL5}JREoaR`qovnV?St1CZ8+2$;)=)lgW|ER zDc*60$6i74l7?q{J@#ozw!z@|Tk$}6Jv`~qjQ^_jD2nxXiSVQ*mT(X@{< zK3ss7wB`xybF220O0GNMhFtQw|3R|vX+&+M`VH)E9?iWQGE?xrOG|I=%^){S02lNv zqze?y$A>qt>jM8Lqze_z?fEt^;o!5E*}%>Z^c|!*41ne?RvU^H{b$nfnS2kWNY7IAtE6WunlCVH;Lrxllcd=}g8qv1 zJVmq5-N2bL`2Qiz;S%%{q**~ge@6NUMSn<|gCzL>B0WaYgXuG?8~EHDW5Ys4vtQo8 zr&z&%f%Gwo=BU1bg9rFSD0`}+*~@P@UeSLieXOE)A?8L!SCi&mjF9E%u_0H{<)~~M zI0S-!BI$^tUn0g+^o^ucpMUE@YgsM z(?*(mc!AFihc`@6bSG)fFu?C3JyFpq(uIm%M*28KbMvqb+(!)fvq(=?^x34RDEbo8 za}_;|^c+QR!M_c&75xcm&SIcvE_3$)Mek1fBt>JdUQ}#FZ^7l=hWU!#jXFTZKU9aij+;dMfFi6+Mo0T+s>YDOU7}q)QYXCta%O64D7pA4i(6)I59RrEB{Rf;YrJzde*+65hmqF-Wqs};RFF*S;w2s-cHXv+l~ z&mEG?dthTr?`{>_H(_I*L94g1Lp=M9z-BI-g{X1lAW+M2Pkc1V5r*-wZTvi8H#geW#i9=;=rPKpBRdrfa0+WP!wCKqS)pX z#k#JjX@+81C?0E`q81ve%}^^0wboFV8S00IT5qVk4YkowPa5haL;clI?1hyFUl@wL zsN%81Q53rdMX|F{6f2yfSZx)>rmv_|48<-$@z{hFwaQRznu_;*L)~nsI}G(3Lp^4w z7Yy~9q24#t$A;Q&s9jNsm9>2hb(o=!HPrEjsxZ_nLoG1W5<@LF)EYy5+fdgS>Q+Pj z(ohc=>UV~E*-&p8>Ys-C(oj32iK-Ow^=?HSVko}Ot$0%mRc5FehC0&e&w+L%m_~gaHGW>_7g*;)`t^{@|$7zM$D7f!;_|evviz1=bg)#gGr?W4Y zsRXBq839hJFLyUZt?(~luw&LG`K!S6cVWXvE-u5*lQ$E&4o8k$phYL-w0%KP>J`q!Z z3lZEn(Z6EeVy_ujMx8i!c`-a%-s-jE6`T%v$Xsv4x90tED4@Q7R`+c}E{`r=^Z53H z=YI9hm%KE>3ZBmE#?Mg9vb|dh)n&~?gcF5{{0$f6tllY5IA*+}hJm^X2e!_`nfm<@ru$k%`nxTD9o^LFdqFx( zxAH=odehF{E;G6JU2vDtI6f;Vl-=`LoUE_G z1!G6w4hnXtDOj}qs4m6&bSu2VWwXlh8gW+T$%d+USA$aJ2?Bf5*>D#~Ri27s9^WCn zNW&1XVd5@cUej(~-t1kyyslljJLu@G6h?)^*5gRv=*`&ovmWWg4xp%>XbgHaz4%wG z!|0>HjTo*LPHh&Vx^E;Gb!#s8Q)(B17jJ+5z1^{QB^S`SK0avsGrq)kgurSur(TR( zB@7*%x3(R$;pFjFm>)KSP{p9AA^81k z;hFUmwcMmqZx)3l#fd&Cfr94}_%uZzv#~lgANinq1)DcQvFP5R^__4i-}eOdEDn`Z z&j@vpi9HsS$|)|aD2ZvHRJAGw^)!wgS*`xPP|U}tgyIrJvrssByaw>Yb0Ac@6~%Nv zDLj+zbu2+|a}=kSaO8LeV<(Iq7nA-wHm{;OHn+9Ar=hL%e{FNZOK8st!G~(-hk6;4 zkh1qXP=#328FJJ=q=>xWBTtNpM#yJqTK#@NYJbIqbSzDZDUU|DYCRd$*b7cT0Yo%9 zU;odAl)LfHV3A^nOM7p;{sT;{BoFax0uBbjI4@_h9@v*mk8Qc_H7mtsEC#_iFMhJT z?2BM$k9u&Um0Cy<1i?7Ab_UmO8+Flxmws%emWzyf71&J|SI(`i&6j+I>7k!4wmSyF zIJR~L*S=VN<~v8+Vx?{p8Fe!lwgR_gCHErx>iBcF<)AV8rTi<+B?hG&kYfK4jnE=P z;iE^dw^CabQ~DTJYInp$Bg_+q%RfH;11rUaCkA3%sXTDh_8p90fAhniS}CscFc9NP zaqzVszWc)5hpZIWM;M54rS`&~rhk3((cc7KJNlOvq zO6?_5OfN(2Jyq`bZ14S1WqqkOO%UTsjSwlOm*MTHFWzpYF4t1T zxKjIpqgo23c8~nN)k@v3rHFB**bmw5aUMGUwQH@^>spE!SLy(f@;w~$PS0X1<$v{y z7*`5a0k#gonPJH72Yh6u;<}q8#+4cgj;+1dw5|EfO8HyB5u=>FPU`_9O%F#kn?D`v zn=kZbFe+;)Vw9d2jh0ORaHu~K zHDmn#89#w6en{ZD2*VK>K92_1j$fZ2^wK|%Fg|~xr3B;ne56RR@1lh*JtJ3Jsojxl z41!UV=CF3CIyTjCBw#`jdU{udz~p(^AAJ>kBzy(Lr&RXK;EACq`R=c5w_Oqmduu%xr$- z`;Aq$yndvmj*%P-ZecoBr2IOzsZH!L{?K-_B~e(@G_^lwcfN6GX~S*Zh}P{KrbAw3J{R zTLnf6gm?O>Lm#kG*J&xiFxq=ub4aW5^0ySToYx%;HooA6g#?zDyG_AFaH5g>aApZ! z_`+)RhinfFpKCo6GfJ=!v9`r^JaJsbL{owX>8?vKPD<&9-P+ficH^~HDygLeL*rhz z=8%>R2TUsHvzv-Z;6x+8#F=xcwvYE)W>X;_Oa^ySMk+Y>x2Z@xyK?>{lZxxLb-_5P zK-Ui`-#PZrR*KIWFbGDd=X{`8C+pn|&Q}?nUHwU`kvc4cQ*1bXO*qwX*iQXTjA@hk z?m#^#C;LSH;z1R+$#-TF ztczFImRC<_S@=dLhM}exm)BL5CTk6&z5k7J<`aI!O-*_d%8}4dkG5qS|xrj(W>r(E+dVpo3+bT#>$QON>AOSnclo|HXl|r{Z9s4t4rsr-$}W}gOcGL9^He5#W+eF zp)9+Q%xpd#TZ1%rsa+0gJ5sGJt&I)xHnyKj=xeGIRh3oK(aJ*WhH|8+P~C?rDqJ4N z+vVJWq7<*Nr<#@5Wh>@sh2yccPDyQbX-QpaoaJ4?Q#DWJJk8^&fTwXh@$l=~c({UH zET-3?3TG89Dx}C_o|<`*-m%mC>>{Nw%SpEK)XtM^*V92tB1rfNK@E0aa$T^XyScHa zt2MQ9L1Rb9lGbLV*m4#(H!d-J)@45&x?0;$FYoGDI%jtIWXVpyJSXJKCHD@n zYM2@r)*rhDu2;YDz5^eW-hpV<^>F}DRb$wgbmeIbZfH}})0S#2S($2{-7ycFRiOv$ zQVSHyQ|2Y}lyNGDotzDr&x*|SG#gZT>bo(!!}#XD-_EzK{h}2I{P)#WM9`iSBiN8v zwGE#S{dTGJ86IvbxYp~j*GAbgymYTO?eg2XYK*0A4c+<$a+R7{E71uot#9bUOY7(j zy1B{FJf)GY%wCL^+*I9xGMSa?=)!}{0sFr9X7h;9R0m?il5V3VP3C96mJKTHrFd6` z$(uRtUAni+k_*_yEY;PqQpLLYi5_4s@&yl_tNP`4j+jm*>WWLMYNnUQF$=)#1ACT9 z=HOpNby197{9%@Rz!j&Grsj5}4T<$AtuWw=C^lKQ7dF0dsyj zPP!CYP=S~FHvn^cIxbBglkfyEucqTd^nC%$5Uy7vWb==g9ESsQVmdBF-zmT>PRE7# z_bp(qPRE7l+W^c%>9{m~yqF`oipTb@kRXoY+n4ubu+# zcHma>t`7ol@?`UG67KPo@;(njfBDj&F$x)8@A-&nD{!yyUJgPP4zU|p)F7Wta#IYa zK#+IJ)6#J*;$Mp4(Y`|zkV{F~((xuR|IoPp(lPWQq#t!oBrsWHZ^$uX3&^X!+s|Unw1!mA;AP}LF7)Ou=_0z2DayH_4!g@uGY9HaM|o`&=~4t5L{Y& zW7FN3fs1GC?ZbTj6L7hQQ&aZ(G8=J+0kb?E7m|P91?EQqT()#PpfO??C&7i(`$vI$ zJ)kdJz26SZen%*6%)e~7Nx;n50glVJ9l+eKaXG%eko3L)%xeLC+0y%!#wZWN)64cY z7@g5Xc1Q>&9U*pS0&`jbm(A|k8lyCZ+hxD87P#vI`oi+>>hoHSQONN6%m)lE$-rgS=Ockz58SgFYx>iW{Cf+Se`;KR{^jxBW*~&s z({CVtU*I}5w!d<_6qu_6xNPMnujuW-F3W8rbZyc4OnTGW5%cBm!0gNWbqEF*k}pRC zGfCt6%a=JCqcn!sE8b>26}ZbZwm-W!19OMQ^=J3@8nYw2e*kW0HYkMt?2ZKHNR8{y zZiU7ujoH&%2i*A@+n?R<0du3q^=EgZ#_Y)MW59i`vHjW2!#(W-cwZZ#Kf6;jMj^AO zw-~sT#`b6TB4Do6xc=@r{KfmxW23+bQF1?J*(T-rRF>qF~- z`As@5MBf%*-cHA*>7#!+lRa;591JEMA^Ii&b7DF!O&|R`1(?osT!_9)fw?*zm!@w7 z^l`g@XEYAel+bxG+tC({0V#p?3QLXuul8;_3rbr;8l@v$-Z|k zcrJBtvUlh+@F&@~ny-=K-Hp7pSMfLAb~-h={WZQA6XzaBd`YQyWDtrso$C3nM^3?W z+n?$CJh|?kOCXqcu(#^ONYCDQg{%CUhBdfQcg0ebyi+TlW z-TiA3v8pK2GfYc74+(|doZSBCn$LGS_w{5SP5JLfow}KIlkG3ZJKj(|pg7&mk@uH) z@sJ}gX>0=J2hNGq3k`}Ig5N`hcZi1QNfl)M2lt3k=-oi^0xK%-Mg1C-AHwuUyb;iyi}#~~`st_DswlQTr9X(I zg)sdJskX$Sx1Q+d|7^aid~@(fZw_P({4TQ;HNtMe4DkG)0{|P*h8dVfjpNLKJ%@rFA9*hBf;OA9?Nq#rJ;v&W2YZDdDjej>a*>tG7jl4f687eI@9; zwHM;NZuR!PlVxxDXg?3I$-Y}`gBG5W_EmACdLoY$@X>L2uP_q+?a=SR4I zz4CQ-C}B3>A1es{v3B4es|NnDp5Whs>R(L#%UAzcRMw+0&M(#{$c=ND6BTp4`nQ7r z;OSrJ>5%1(*}Obk!B?q&ECg$m^~Cip zN4K#(K&du11=Mvoa%9K6Ye7Z5IXE-R)l0LAV(nGbd4^hNsA~*$o1yM7)XSihjWrrnAs2>Qm8z|PksE1xezka?qDAwetHv-fZLLCU|a-q4~i8u>Wv2VZK1}1Vy_tW#(`pKN4<%lSl^@GWKexVO#^kYP;pQf3B`R=*nwfJ z0rf4RszLP%RS$|SD(cM!wMHlojw-#UfI44z3qh?GstMF8p%#NWSEx2n=LppaiuE$; zRkkl{z^CT)Mg_6O_?|#)RI7*0D%QLo)17Xz@8zC7?0^|NS(;}OyVZ3RJeOR(i5@4` zm8{qbjcVjf9{&z~9 zrMQ08y{~vg+8EB^LZyQ+df*3+p30h{Xzd>1^*b{5&KR*7rIOKog$|=qoMGsFpy7TT zIo{Wo+az*GF)rN(^$x1Rh{H@iXIaP!EfqV3uai-PWv( zdp)_5#c3J4pV2i6)YGC1C)r|@{~1^nRTe9XS^Rt9`C0rwPsIz+mn9c_XN*qt7LUnV z2qPi-l87S{Ci?{u$b`uvnq(&QVTYF98TGxzr$FWGL~rH%p1d_Hhj^)-xmSpvL6bKR zhCbDTYz7sB_lDTPNp6<&KLbZ0l|hPP2E8sk$)H7;VD&q-rf0n~7Q&^bo>Ah?!DYc+ zX>u^)n~AvZw5#j=wKFzho25?H%%U zrH-yxV?%p;M=G|cId)caR|gyG|FG(Eq|Ra9OfEw|31!hl@1D{S%6f;@p! z`kEBw=hv#tW|^&9z{PB~3Z1nkvpX5`-<0E9k~sq!mZUQns;ZH{MQGMxgSXiB71afx z_7Mt%Y<ckBkm32kY`XS1?UQqb@ zg{RUPY_ws+)aw86>gBxlRKvRS%~jRwFdu$BU|MiLL|^d`>7e_Hchmp(R{vLX_cr?t$XwjXB<_pvr`50aYqg2dHA9ZU&`fe-7#d@S)LV%2RH2%1=C+$rZ!yla9rbw0FiEIRoVjsl)Jx&a?L4F23Y;ejg=BbV zgYpBnq*U!dQEUg?OjLJbCCD*%D%+64WBrSIQq7#t?x?OO`-twHgubvA1m&y z8dKT#d}ZGg#l0odqyoadWME9RQ{Q^1;Kf-E{;RF&g}`Znaa2)s^i=EU`B^&tWbcev z=rK2Ft06PSpE&v@Ri1} zqGodUOZL^A zSJU@;-$y-ZlfifX4TTqM&%5+OR7!0qpjV0FJAudl7X5$dB^&D9eM? z1NfbksG0}3cO~x1<+4O%J4=qC_&uM$XXlS${AB!Ih~L!`hf^Gk#b6|R%Ps`jsmO10 zJ?p?Vzv4vHlPuT;HDoJ(;7ahFPY7C9bCvw&o#(f{+P?k1t;h)6Mxv@8=6{I){?3_0 zA0v}{YYxF$7k~7w7~R`BrmyDd-sHHxn&*3y6Z>lZ*qfZ(H*`H>t9uv5dy~^}DLA>e zbO`>%drNogE4#3_bXZ?m-=k|*0TYSyK2&MF+yZ*EbiV$-kpFv2_ZH8p*VQ~-y$*$d zja`v1zf1OgCVX689Fp23YFwDNE1&+CHpGpua#leByTUmXIPg!u< zsoY&upvg7gjC-l+)$0=Z`Lr7Ibs-U?e{l4J&wkdD*ZvrO=gW_e^WJ_OjAu}u(>w9w zIS{kd+97tOeD8uaXXj7zQv3LN)||7(OAYaV0r3t~oalQ(H{?X$qrYNX){ehZg;+M^ zK`5IX`H%}Qlyl|YscN(*;rD19IbMUI78{Ca70X3aMcIY>D-G{@Lve{w;qEik!-jg% zP;VLPQ$yvV_9)qX48^NE#VZ1(eCEdM5lK-8C|=a$c$~c`+!{mu$WZTqQp=!}+m2s3 z-d>>8f+&}?zY^YPP(Omo99gthvD|(viX+E68E3^yfqFr3>p^`fvcCbfuTW2bVhVD+ zKZE*0sCPgq@BaYm6C8fvm6+_{1{(3T zpRuh?9m{@#0gt5?eB%+q*j$9I$PHtgniut)oYTU^d~*{QPvq ziEpd>;P@dN{>L>gbOkqCBGzu%QhHw}_F}sVr05J&0v9%MpcC)2(Zarjzm0B(`JKi93#k@Utw^HBJQmoG? zi@?)oJBzIm!pHkL`(5z|D|L^S5{#3sT||nljAih*2UqT6rPu>72*$CsE4VgY+rNAi zJJL3{nVXZ8&0=A^OGSAG39gM z4Vgp0jYgirnQdm)ZYATb)OWSiAsHz>RHXdUd3)wfuiI@kZ`V?SaZ-AiNCjK2m3l%; z2?jWP-&=F&wJN%8hU0;=w0UWFb4s8%5fkjAm@YSe^1+ElIM1vib>+54ZA$s|A%=Wk z4|2it{t_Wa^aP&K9|exB&ns?Pj)isQAKt;!dWaE!3P5--89ly-+#*Q_-9tX9D%` z15U>J1nP-994eaNaG3a`9S(<(e22rtk90UpJm>n>789T6aG3ZZ4u?KRf*ii8;{6AQ z(NjR5KXy3u`TZbgA~|~p^JhFcHv}=`nXbzn4%4;P;V@mx91hd9*x@i;CpjFZt2)S; zNL!!ibgAlJn*){(n4JdN^5Nh{BiG{0+0wA-*Q~HLoF9l|INW1P3C?Mc0N3_fu^(M< z_u;13YSU7JaoX}|k@DN}P3vFbSDr36Ex-t~^p$d_NO~h8GN7TXgy<;&w)}tMx;1qu|9M@b_tNaRJ)c^ z+r%Q;Tdg@>h92Gpjz+@uT&tzViWK$yBC8%QW=10_m(WM`-n_y3^MsZ<*68_DRy}O5 z(TI2jYR@nKv(oDMR7;IhsR+#QStD!-Hg$gS{y0;DgL!#`AQ-0v*{0nw*Ge6vr354L zlQc)=q2FUOiaxt#%J!NqH)d!(1tvEd9nHbE%pN5gIfQ2%bq5{$H=7&hYN?4v&t+Nl zupf#>WW)n?-WNMPZ1wz9OBH71D*Gy%tD{~$72hoN3r_AuAzm;}uChO~xjO#5izZpA zH?%Fm0Earill;SpJpgi*3MJ5IH&@v&Mk8}@rWdD8{Nf)r6^Cg(lQUAmF~O$d#xEZk zIoYIQnwAoblZvS#6>QyB>J%*{7~t^0qmzo@yL`us9?nr2&iHN5FxAfa>v}CkjHI2} zB7rG&)6V<$*=p2_TF*376W(|I3G^E$h@ROzt9Q3~T-u*warL!{^Q4mT+PjKu` zfNN{`?d6XhRBB3Rgq9MFQ#xfL<-5YM+e(eqQi7pTuS|1PJ0<5dhZF1%nF_bO%E8Ij zt1r`f$}`ecAyR&=W3OIr(shBB5{#3sq)7Sc;<#+3uF+D00nYR8%9;xL?53g;oNTr3 z39YA6r6SPcq}Pq`DU*?qPyV60%a-XDEmf6~_UU5FPy3Q@Uvz4fN&DZmlwh2+SBq3I z?N(~%T@Z;N81}T|*}(RPU-S?u4P4#SfMY+eanK95{m1rNqqH7kq}P(^7-!~64>WVo z^m2k64v5}190tRoOv9Cqg3y+O_d8k?{E zk?S3qL#_#8WQPAuheM~k4F`m`U>BYlVmj^Adu)kiIng2cYblkbyliYO9_TXy(OAsYJ${f#?WUs6|=!n{RVUX zvDDB*Z7O=Tp4loDfqsMY99v%Be`c5GtkjKKYEDMl=ZciyZ?L@Pn6&>|O9{qF`#h2I z)6PEAO8rSo3C1Zedg!Kh!yJ1SNNv^}c2q=axw4V7HK1=zUmC5U7m+U&<_$=?G zL0Z*;;L7Al;M#d6eYR4C%m4(zI6l)u*XNVLu|6NR^N&_ppXX{lCujJ4ib(nSOrK9S zK6h#u(tMJnjCm71-k1mpNj4_%*|M33)t*`1|VS)W&GJxv)tH)r_VWPH9-O9{sDxh2DA zEA?MmN-&Pk^w9PBbjRl}KkOK8eSTT%IX%PY#Th=IZhZcimJ*EPb8CjrR%-v<5s4re z$7g!z`g{gBwhjK|sheN1J{M^{XJq)iM5I^+IXbXzoMC)EO-l*J@wrW;f_1}6t<_S3 zaeStSuFp$F&;C5)a93b{s`V@tpAqfdr#Wi82#(9`)DYn$DhJ28pS*#~!3ZdZ=d@IN zM%p_NYum+}vreyUH)(%eO9{qFd#6YR({82yt)&D*4ak$oVrb!K;s2iWq#{tfei5uNAP_NO0FqQ{ZJQiyO3_R7P3!h?HLsSr#c%7QfU| zf^o`XnMei8!b&}*r352>Zq=O3vY^jySu7XLd=_Rjs7Kb!JI!;GUOPQvK3rdcl3o;>R4?{FwSc8St8}z`mkwHg_Ww*Qi5@8 zadvL+{(nAX(=V)4qm~kkW9w|k)-m@ES!$)u(NcnOY@H)gjLuBgRa#0gj;(VYTfe>X z)@9b#omxsTj;-@VYHw|8{KefbTB+Y@DZx0lRynqo{P^q>t<+muN-&PC)gm&q{;QeSE*!5|iQVD^xIIK|L*f-UZR@YI}^h&#T0<~G~nj?hxXsFu6P(L;%|GdNde zaPBl5U(at1hyF0UWH>(NUBe-U*SS*!iM>1Vf3P=bPh7{D?~JG|-^)81d&~zqCaTXd z$Y)5L=*Gnjt?l_)qh&ohzo38VtkFtZf8HUR?X1yCT7SeLn{?J_C7mTxf}8edXtpvn z9q3j|+gcl!1acQ2KMDL&nOWaqa@tAezIS}wq#br?@k?Gnh8#~%t zTUKUMXri;|^y97Ca(+}{QBO-tb62>h8GsDc=?JS_JDtBRC6F0Locw=EDxjcy&o>Ws)D#($6R2%Qo_WBEED3xA+a2(sKEH zOdOvqsbmS1G<5rk2!2UIf3Qb6=tMZK2V;VtL!q4ik&S*nQBl*dq`9=CooffBJzZV+ z_J?XIz9>JprT7{ZNcpVA9X)MLQc`|d+iYcp3d9By84~Rz zF(jTg^;n_mr(4C{D1v9AAMWVVU(<5IZWO^a4J%Mb&I(1R#SxA+th+#`Yy;dtVgq0& zkurMKIe^X{)ZAkYiH%Bj@)`QGFfo{Ge0f?Dx;xUeWy6E*jEhEx#J0sSyHK)6|tG)xHYjc;3P9{mgh=3#E@d0N- z0gg%Z>ZSP9*rEnZSp%AlpH6&0b11;k%ub|V)h-}Rw}Wt$%UIp7_B2G8dKcp8pV^FW zv2`!**Fpv+%tkuMu_D#CUmIzNFbgik(XYGFel28R!fd32w3W1xB#WJ_DA!Up7;UA0 z&&}^z0(`>eHMFMmXWs&KImiu|46vOh8sNJ+`Q^Eeo|Ks)7ssd9R3vMQ%h5lo4H1e8 z`Fg7A30w3R6vh3vhEz*O*HWw6*R@~)J}uW4pVZRa5)9J%(ezSfOFL65B}u{7nI02J zRa%sjva~pQ=6~ui_+`z4{LC12)gKn)U$SSDnGm8)$&3$)QFg*&{EPc+cE*KhQ!<$n zf&6kZAmb~c{s=f7Uk$D(t*OIDZ%t7z*H=T`=;!p{w<35=M6-T9MQ@3VkM0ii?&gbx zs)JEiENYzAQNB=`Yy6~Wqy8!+bys%J<$iMhHBU!-OY7;*cR2h1GUu@qjvF5fgdKg0 zZ~Wwm1(O8NZ}H8MZ}FWo%JaCF4ny$GH2&sF^C|kC34cq-@-4on({OQbSV{2i0A+cn zVIJ1gAJQxITr`eMM0Nymlgs{-b>VF19wUoGaJVrGH~@7-wv1r z+)>QLKnT;v`_l~>xJ-Sh>fZesxOj%$BY=Bj0JzD(?TovU!4T%(;Q$m50Cx;!0rhW^(`+);}|!U)LCr62kfyJ{R&1aEbjCW+(j1X7^%XzNc}f zKMm>E?$#KkQI8*K{SYC)$-tp~q~#0m{J#j?iM&aU(BHUqDKJ-STz~#;&={pr`&Kiv4D`d>MnvKbZ{xA)8$efpdXrNymkZt80O|EFG6t z|ETZh!2C8H7ozXaz-&#&h3FfMPG%o=GzcagA^Ii)6Hmvb>5DKVdD(T9Y05~x)4FVY5_?U>`aV}%l_&d#df+DecFR-S zKW)dCMjjnf`;-kK70iYc}n&W?Np~h1ZET zc9veUaZ}$V=L;2mV*Bd@)%|}9cNsnVpM>Ke{4E?g@&TMRLY3pZN~l_#`K(xuHy7u# zgyQqj%Y|Btb4sX7aqh+um5)uFDLiH<+g6V3kku;GT{t%jbsx?RLOqBxuWNF=Cvg6T zP|x8!N2o10&k*VjoY|UlymxV~6zU_K%Y^z5&c#9vLT__|P`iL)pOAySoNyg06yF+} zAQacYjumP&DCR@d8v|;pP~$+IDAYtyB|`Ci73PiF9k@!UIC#t@wL9=kp_1S+zoK3> zsFQ@M2h}CiY*6h&@x7iiggOOOi%<(eEfT5;6!SXjmCc-4H*;!iPVMyCx_Py+xpS(g z7uUvw>lMekmp63E3T&*sBi7b|XHvRiOB+&+i<`S+sm0B)?w+oehQ{VtXIDpOb62Vr z?B*2>jj6VkV`A9fxK_rr5IPuI|>3cFN9`u_o5q4G&ZBr?a!8 z3j(o4D@AQnS1Z6VY%vc+2VCx2-rC(9Yi;L7TDW=7dyK^a%`Gt3(*;19J_m#+N}Ain zfqr3a4J%<nj2 zoCfjEt%k_>)MEIo@(d#K$rt68svj*KJ?%{~6istiS4Wpr^rqJCPDDzBVMT5Tw8N$j zv@zO1Yf@>z({yNmQo9;Zol$^z@+t;--kL%a)=iXYK~qK(ZbJ13yKylTFNc}bVtTHf z_glGbANW2^YOylq_XcUrQQi1p(fDl_k0`aHbu(i-U}f%-S;~v)$(duAz2J6tz;9`h zNKX4Px*ZqSR|b5Rw&Q!$undiWDcs@a)P1=hqHi;sQhx_Oay^c?9MROqlxlj1pR!EF z{|uMoP*XHTapLi9;rUYs&Pcfvt=+ymZO2xzy5E=V}qhVcqj9u!}a*DlBB31 z_1LA^JUc&*&*u`2U4~xUM8$O+IKjfhxZ!M?7iN0LUbQ66; zIrUBS4d+}q(Kj+5|B`^$_Z<@xGL=7{m-XYSdzr@tC^NIC5k^uLFg5 z41TNLaH5HggW6AG*?+1A!2VP19^3#*Y2lUCUV`Jbn8IBFiVZDCuEJPPa^%x%Dt04c zh6?X_P)f_Ipp?X0pmvkkk3cDj&q1k`mBSFDB#tuFcti2JNX3>K>SRML1GO`b9PdJ$ z2MhH*oR!2aprXRN%kUlq#hyCH`@P}43hGO+arI|-{{hA8z8nu9A=di1bF4wK|8t|Tj9}a;f)zK(w2qK=uVb_IzrJ?MkEJjhgf%h*# z^RpDx?T0YE&k6DnoSADZF@|h<-$h*1n+l!O?T0YEFA0)*sdL&6^!`=QL{YaN!t}BZ zAs_Z1;_d$srf{jj-ms=!z1-QmICfb7mGlThad=R6f*ygXk#3q5Qr4bc$Z_(9rJ-~) zrxi5}l**f6E`k}VTOs8e-xGHx$n(oHn{HK}L{YyV!t&=sMC$dpucezheJ@Cd=~iCI zV7CZs4$~K4^1fhcYu5sOMd7n>3DMTj-jvQ>(YPps)z+H9!?i=fgmj>>AQ$&jW94%B z%c}-;UDn#(ooe8fnw_6ajg9K|{Hg4Y@w@_VPh}CpWocI{E;nP#mXx*kEahcnbEP&} z=3o2Qnef~P~ z1S>U3O9{rYHCUwBOes})^iO|erRHcU!8oseazM4O>Yn_!=A@PC)>49TY%vdPx(@hw zMqqny&QBQxpd+c7{``aF`JJ3XZNbLR?6>;lqbPWM}~?mrk8=6j##Ntx(gGG#Fqp* zHP!!f+0qYq8J!O^`akhsURRysGg!9ni`~0}6OAl}4pd3+p}T5PaeRdfG_kuUH8XHa zl~YK&nbQwPJdPQTKN_8-rHDa&4oFFzlo$FD<^AN?^@1RcO|!HVF|O1e;6x*S&HZ58 znwzby_q7x;Hl^G+is?d11J?HxJ*VKz@ZxW79b@$zp`9m2z2G|z)J~y#_CicFG74vg zLvK6gM60Jk>mf$z84qeZj!b_z@J1t?2r;}_HNDH~@wdSyM(LRVij$#CJ)F5mBa?Av zc=Xf@ime`hLu+D`o&r$+z>%qEA8@0Q!*OO2oNe;p|IHChibO3!hi{)i(}4|__R zu2DZv#;rfU(RzqcdM1H-8b_ucF0Vu*`8YE?cjWhxjeec~m)1j!(!=t26i23>1Hg?& zQ28XhH0~5+s;_4pyL<##ujrd*7uVS0ew|bt^dWcbaSf6hV)pM}u@!Q4y zZ=MGsKYw=Oz=c4J(!=_EJ&sI&V&K{hJf2!LcZt;nGcUTy zQN`P!rNDqxux~kp7}=zXabri+A{%_4mue|uT&Y7vif4wQKRF2lk}q|umSU_cbr?9& zNF7BGe)8kD*IKF9wG=U~R6aPiHRbMh&WTp)Ko0B(#JEzUz==jqWh6pQY3aLGYQB~t z#+70pqPCc&)YyXOp0rYzYbjzN6?n{!B_53&%`=WuJ6n(y$bJb=YN;c<7^MQ^`)I`5 zxrBG_fj1w4r9Ks2(^7(Q#`hydDmdm^sn4~PU_{ZrJ86Yto%9ig!&IQQu=+?~D%=tF zC~%??uAfopdv}b1SwCHqwVtCg(k1y|<`S3vqk70uCS50KDV0~jxdeL^Tjx2Kuu^NZ zlwh3N%f31qVIRn_-;yU^v*qj zv!hL&|FU-b=XQJMW-Y}Gcdt`8(zELioJWf@B}kv$RB-H#Mz~DG zTDxt_tZgGfI#nmo34q|Fv_T-JbbHEhQMI1gDA=XRWNg3y=7Fr{x_I~t->_2trmBK*Y)x})y|l-mm#oyGyC4!lFpjMgz_sc6>bkM_TB+l;lwcfN z7#<+yrz^3t@p3DL6(k9QacmViwqE{E(JU*qR7(lQu@x7o7|%Es?tJskR_a??DlW0X zp1+tJ(?hPmV&c(O>Uu3D7{^wLNbN1!Faw#h({5I3gO(DElde+7*2K@}G+3!;wUl5S zTM5V39sl~~$yVxJEhQMoR+(e#-R|@1tyFYZL?Q^ru~iPPy<$D^mh}f)sROl?U>sW& zBIWnJmpt{W$E{SMmJ*C(D=AWbXT(jotyHy^5)5#jhc!nX(tE8+@S~BvbnGAQzPr}; zTHn@E#JGK3l}PQYr8eF==T$3ppOzxVm6|S6zOA|c-W^j&bPy8W(Ne^?Qq|z7TqUr3 z|KHtXrS@jFArRwA)qoR?3}+<5Q7iv=nU#ubDPmkHBpyiB2|Jj!=mdi zKEz7-8*mciO3ehvUilu7_$CziwrYk_lP5RjU8z~%S`V)t`LnyM)cIP97*}exNbQ3& z!?d%$I^0U#uce4l_TSSSVqHCRz==lu=tJI^xWbpg1J9aGjEu1I5gY2@NHo~X-(7DH zHoLiNX=^(cMAd4h{}Qs^z$+uxe@$4{bTVRP5}dEM@5+c(ve{yl?0B`WSQgoAu}W5N z{FOyETda}|Pmg|$I5bl2U{v1KjQwU7bv1Nh3$O)zgBNf8>TNEt(5o_arabdB3yaY0 zr<<3{YvOe^WffJ$mDA($bY4+GQK5cnuc%NxwpUcBV)BcNfG!ZW@ zDl`xD6&1F36cwsR`ictmGkthneX)^DB;#e%%aS!^<%u|++9RlaWl^DiZVyBY;ds-T zkM3a)sD@=m6feM+l+@K?hmhJhp4=-cG!IG@73ydAl)OrBQK6A6Esxig7bi-qs;lU3 zKu$lIS5(;AP2aKKlsxQbC6n>mvWl{jL`|BYxkuoN8o@+myrQ0huMw@cG%r?19@YRuu1zC#x!IN|Kc-hxB885a=o@ z^dIaiDpb#nLEK1|C*w7xiRrbd33&B9_=umj-ENKYNkbzj-j>zXOs|lv^)>sB+Gq4K zoh^$er`MKLl+{-F6?|B}gZ>IVveHtBn^!MjroDg<&56R9h*tTe`-+Yg48tq;GprXG#RfbNtV`CR+Lgwo*GmoC-)sF~`yS7W2J zG@eY^nFAR1VCGoPV@{)S=H7p8!=g`j@+rycs2jjAphU$1``Hu_x!x-;8WJCovhe(f; zo?f}NAQ^y@S6=yGdUbCZ92&)h|HHuKv7FyKf3NWVQ)#p^5TYpU4bbw^uJRH*Jg z>Mm4O0~s%vbg1<`^lw1&LD#_6DcKONZ(&N*Xb1VAW^J@yKggVr=a}pD!>oL4S(i|n z3j@Hr4((V#O48qGgI?~?CBK!H$IG!VVp(}I5y)lrKwY3d`j6DH>N3^;r?@wPud2G* z#?R#jhz#DKs92|q1O%hZ2#CtP$xU(t35g7X6=e(%8G;!=EFu`Fq*olP)wWt&?Q3hT zQ(IrhHh_v)2h`eX9ZI!Y6zkYmgVe9k^+ zujBXSpe?$TMqU4mcm25rMM5H!#JF4% zArVSqY%YnA2qodUkqufE5}_nK*Rer~kO(D_v#>%Ul!P86ObWUlgM6$0&;&aeG~6DZ zN|aZYrYcHG%M;lzXjqdSrqi-ia&o#VUFkvtFK*cIR3bIGW>Qsgm8aSFLWd14O_Y{Z z7pJR}#jfTHeJ^_0*s?@Pbx9TH7Z+>20Ahh_5*4LWN~&?S<6_;>-G70bN+v2RDpJ*x zN_^cjQ_4!pDmtr1OO}@4dMsHvxg1w=W|Z|C z;J!|RYhS)k;!S$EibzdKYeC8z1+D19}h|J7T;NFdl^Z<5>*f2xR#G+k+5q`sqQ)A7tmh?~xAUF2->qaEI%a zjXeC$cBON?*o(NK`5|;ocbOE?&VJC`wW;Y z4?+QbTo$7TA%6(-w84i|g9Es*@;e*2lY#rT#&V$|SNVM(7}twXN9FfeAl)$gnC{EK zjpzdcf%2guI6}TNfeYw(o8<>xMxUh6tAF)H2nh9a) z4nw~=0=P20M#yfIE8QAkW@}uoa%O%n0_HnGTu3|p88E*N;sWieAN0Kd%zHsxh`xL@ z>b`8)2)XQI^hk{nAWmWB!hT*Bz)86T`Z*swZ0-b(4?`XU?kkP$XgnB%HPn%M9W_@z zSidzI15!d*KDZP&3%IK^wxe_(0Om1`>nPnfHAW{JT7D-Y@;%`C>NQB}%T<0Ofmxw( zUOx|%^I*td3d|irTu3|kEig}MTu1rXqcI)jV-zAk0&aj_dGDzFCId55<2p*WSz|g% zcLpLa2JQu)zFhs19+E5X^ zZqi}tu14eozzsW6p|GBxa~xU<%xaCxRnE-sbsD2IhWGPni2N~d|J2xy>i1~8=QJ1x zLr3YBX^cXKr+YmjrvkS}WBJT9SN#^_y{IWT7;>e{@nD(82oR^Ra()T?Cg3WLR;V8M zmn+?00`s88<*#3I; zHyBd6aD6+8JGzs&!cO4WuTRRt4bSql1~(!^33{%rL)WHn$pelXLB8Fc4NZ=A%-rjYnVN?b{X6Z)XrY6K7;a~yAVock_DM$ zUMe%GAa-{o6;1X^MJM&D%sdY=KQk#0zw%>u_b8pPwW)h)(bi<9Z9B+l(bnzBOmW|$ z;=bDx)3DDoo^Dyw4;v6)Y3lhv1X;qiN9EoTupLH1jyYCnwi{BZ34vhNoe_2Kap!KiThH(lU{jIG*4ca;G1N5;_viWq0YmZ z!(pEIB)J%r8#oiFJ!Ohwk7n!To-%ZbCTc=okh6N#P2o7xDvD@M1KiS~e4gN+gfQK_ z_|p53zLst(jPs;Jm~Lf-w^O_I%!2LQz?#o3qy_2Lrow(RSwq+yntA1+&8VFRaX87$ z9(SAS?@=)>4ZlyVtMj=NGtpY#i<>dWrCYnFGdoycbGCD2J{d=zylQrmP&kR_82)D% zibIvHqFA;?!i)6Hcls{GF}=IfcXT(W@5q9c+SI1P0?*2Q5Anh{^Q^K-|9};N-{tw1 z(P$n`G`74znaYY+rt+*PUhpXjgk|(N{8mOQibjtWUL@Adi7o8z#9(l2WY3kly=PuY zXAW`=nCzJ{xj^wsN4;9vdQ@fWIr%sWaP(6R{$S`-O_GgWQOA1}2yuMF{|v=AlvRqN zRY~Ew)t#6&8SQSz+$^`b49OnT*a4D>K#oS}O}zW_og?^4wHrX)pBBm6d2d@l>XT7 z?81iXWXr$WoBAX($^2x|_8U`~w$!L?siJMkmVdW5#lY^BEPDLLQQL~PrJ}%orI-cD zq9;6NCX&ol8ScJ*zVNG9P0}S%hrAs?N7xvohw_4VKp}k&#jP#JJ`!O zFJ#z<@|@$)3Ai5MhFKs~Q7ei?&6kBZBB;PuS{U+h7>uGgF3iLcm6uwm+YMoQ&lF_; zL*N_fZ+TAFKTuk|4#WTarKC8Y@J+$c9PZg-H{+TWYr6QtQUP+v;Q;Zlbit^%QqQ5222Qh1&*oKIzb z+R=qly1}F~`!T0BAL)1Qfl?Rei85X8AsDszUZy0@S+oR`6g?|SBo{1IIh_DX)!uke zJ#cW0QC`@D!0G!ql#z;}kv9r2(j(95fyt@I$ZjhSSZc^fJiX=YLO72Q*ty=CUy%GNnNmf%>K&OC>I7wU|#V7HXdRfS7qRN->XK@~2C2{q$R@TgLc zS_tZH94e!$LAl``5GtdJqVBtd7a5l43`5a(8`(u&$k>^c*5SH-F*PrJw`I*Nr}?1t zmNOID{6E3zMF7K@KxKm0Pbw3qf>LHygL(*uGMH;SZg?1kGFVYG_(9=WZDrHW*v1Ul z>H?k@G!+TA)F-Dss>UmST*knU$vJ5pH8|j_WAa=N=2h5aQ(*w1vd%$eor6n>b1sB{ zzNSxSdb*OXyA<9se7gMz7^EtR^RA+pdqt%^inFoe&Gsmcdy03dM=^tn2g2b>lp7ug zp-M?nETzYU7dg0#bMVL>xapY9E9hl~{mw$iijR6Vo%uMu;Jr;R#ICprK=H|v&Ybo} zdQ*GTx^$-6E4^y3^s4=(HwUFR2c%F}vCEg!Bam{Y@+@1^I9|dh*eA|Qw-1ETGV-YcIUTpbda zkGkEXp7*FnK)r;+4X=VwMXe|n^|QirFRt_olQd?7Q53tup9M`6b-N)@MHPUjbQ9rPK{`ygLdqS%^nBbA;I3d~&$)@S(i`5t3KIjpl_8`@J(h0W zSeO9E8}~kL?&F^&-d&ElD>igz>^o@^o4DmWHnS}@Y-_CL6w(d#Xn=SB)6dSBe zj}2B?O1GvsKOtsEs&E|Dkuz90q=q;5N^dzUkWl9R}TMxIGJ$a*?x^2@38y5dX%J zC%&}y3-u7rp9}RS&fHa==g|3%8me1B5s~Ly3F@Ch{TP%=<6cn8HO~rAT%2`7K4{f% z6qS#Nzu_=9C37{DlYqe}iv8vz98qU3&eZLOFum^~5_)I!a%S8x&>69LkTdwg6P$ia z20H~!GoAd=ED1+6@&C~{l$N+h6@pUff$)%|!_rg8Bae#0iOW={%Ut4cxqv#M-5=wK z!bPXNni*d_Z~5|hbPd^D8y~ocIE393)xY|L{C7T*-@DsCOtiOOatX)oxZE1gNOJT} zR4zDqH-MFyfpQtYr8j@2TkkAfkN?snGKcL3Svu-7xE3QOnfYMT3+omqGhfAyb1E`# zly3URx@xzRz*8SF6`8)T(Y>}Pz@2uFbo=&-39ql+z4thc@M851L{;YK*D70&?ygd6 ze_R}Lzqj^B&>p*j&7~sqWku#6$;=Z-{J6>tE*mAK$_bICUhQq^maX{{wyphmZywI8 z(wSqPgh+bRt4&kVfQ~OoG>@%B|5?edff?iXDraD%a4SEYoe9fn7nY9NNylg}0Kgt6 zpmgRa=xKgH83t?R!Wvhv1?fx-t1x*^`z{>^AL8luXJVUX%50;G5XA(8SD>6?$E8q= znI|eT&$7ti+)IkHGSe$sHKEtjO}*3YTa)c=6%(FW`{CXmRjs3+)+ImT@wK=x_0sL9 zbN)~SX`>i>y6LxLHEMhQg#By3pUk{ek$IX!%4QZr%VUY;dC7CR${`n7ylq~BBTsG{ z6?MGFV=wQIUXds6iB&AykfIiN)Jjls!EN$*SAhC0jy#8>fs(k@qn`07nxSIp9fS)5 zdCpLrj}?k8o>Xj!N6qr6D?I9Mk9ydnc6ijw9u-0Fc@in+ITwP*<$X6CkKbw}QB*!6 z`UtPTh78jGIg%KRqSzzpN-Zj`+o{_PVS0~Hdh@$D`O^yo=;~&wMx&yLP`U|qk)*?P zD`cckzSC!PAE!@4@7+Cj9n{u+Ww*HrzJxxsZejhZJDm1*+UkEjiY7-RjZ|xep$qY; z^~Hs9^~~amMmAgV{Ndlh9u-Wn#x(xd_6cU+DNBxlOTtLq_fVfP(a6O(lbW=3;{`^F zOT!F#O3L?WgHyNJ{rHPtz4#~=iv(+KrUhf|-0LP%Z27eHd#nF&zL6@?(t@#e33eAL z)-$E1-?XorkvdOH3C2o`^=Wn_PB@|aP$R{QaR$LyX&nTv$=6x)SM4)W-xV3p%a88? zP7jfyHU{nnH&VY;OuaPEA3HRM|5P`4A&c{d$B6^uudkkniALPAetTH-byHvav{X;j zmn|iw7dad8O!23yFB@m1*e4izDJfqq_XgLL#y|GdP3q;48I`PrJoAF4FYw>b2LAwZm%3wy7144kOsi)~{`&6*#We67}cVvdxCFJJ7} zcD`a>zP4y7!C3j~BT{PAz~0>r)&DS3cW5cW&?AFqGcB}j=Hf~;at6;h?tCh8o3Z&x zt>=&|n-3K!w-;0=%da}bv-x!`B^b+Q>1z>x%QRB^w3O z-1lm6=WtbR@X{PCXO17HoTGmnF#a&l<{~X67|UkfW}Cg=Gmo8qmyxQ_Qi8F1Za*un zTi(C(MI%KAjtqja(mE2{XhiYhVE6f<|1wgWw3J}1w7wxyZe2Y5&*%|G>Q*f!7%Q!# zM2e-&&~(*AybI>`|7^`67``WGxUf)I|#X8;|=U>x$j#hQy8|RM^snfL7 z{M&wUnW@1~wbU_LQpbwasW@|XxbWYL?l4jjHeZBev+Dgga814crn-0EW4)aA(Nco3 z$|o*TZd;`{3L`aGO9>{#%NRtRgvQ{CNRK2n9*1KKN_8}G49u5Zs{O%Heyo_&wQG*w zU~)Q7>*=4B)8j?TZ3$1N2jlBuZk?{yQi8E^IzXiSIW)l!0?&8Gk?ffm{}7lIRw zoX9hd+gopYz}S4B)>9}pBieaPb5!~G=ahle5MkS3Ls(uDMG-_mG5keK4ODsewJ2T> zMI(c8rqs+qkKbdY_G_s@O3F9(o*+_giM_Sv+7kzPCDxlok02PU#F&cht;0y2prr(3 z)iN!#OKgbf;owZ6Ezke_7Gra<)-xo_W+`FM*Tc=zi+c|7Y(85{sao)R!{O4PZL^VD zt)&EG*-Q&9937jA6EO|xtBt6I;nESramlxs8RxM7~n?`tW+ zST>LFq(C^ezd5+Kk;>DZQ80{lj&ZxEr0yRRXtSM*k>ErltA&qOw8k8Z@x#r*BHjKlrJUx?4*L#>!Vxq?j*;&!;~ArjdG5O9_T`F~V&? zEP1;wiouCSxPr-hkG_vBMt8>#32$mW#SX6={9b-a5O3<@^Sj@vE%xf-LoFp3%jT3w zxpgsf(j#?7s%v+ZreLhJO0BfUyp)=3q>j>3g0a#n6Dc+K;cjBtqjwmo5n4(xR$Ap& zS`Xi{cbAbW*HVJ9(n^a|Uz}NTi)&we#z>u`r38amI5gKBN0qAYh1Lqh8sCwR+KcMl8?+QLwhxp^B9%`N!t-zR+he5e*HXmTQj@_keRybs*!oziTiBY^kZUG2q z&Z1>a@@+2sVo;cI9wrXX%6iUVZXky}#hoyU5n=a~YH+Z^09Cy6`Do&AdYhh7qcvA& z^^_Ws@_P5!|30nS>nTgLlwhnDb*4zUJ>~QbQ@(AaTD6p5tkyf#N~^W~*`Y@24lN}Z zD=p4|X4Kj<{a5E2so!fU!B}Zcx6*ok>5&tS)caaWFjiVKytF_#4SV*@G*Ue|fguP+ zs3Of#J%y}_EY89#&LtKHb$SY~au`^H-JBZ`FQ0;Hs6DH0VQqa?{leNtr=b>JYZ{mM zINC+P$ik2)*N;y~lw8vn4$mzW8l|K{)ai}Y*)e`sJF@%tf=0MpSNDLvP5-_O>CM?I zo13cCyU1!se~ElSO9>{IEvsLkW8J;k8cOm5 zX`Ua39FbY+_(esA&WHR=U1{NQesw`XktkVGU*Bk2gLatr>$I8*Hm0nBfc827hhMiR|nd0g<`Nje3IB6^xv zfF;Ttpc21Hexy^FLq%4>ddl6xlg>7E z-tv_J-9Emp+eApi@eNHTMi;1I`0|dj^6`DTtq4nZb_{!apdpHc#n-yCB7zLB$LQYc zQ-Ub%W<)vqu%q0mAw;2)(*8EWq(WqJ*sHpLTLx}5ol@v8WY^3fS6MhF6dU9!tgSVq zdN2!=PfO!#D$8mcN|w~3pSYer(urbx8?m%3nTFRdd23+en8lnM;NgMq4NM#}v9P3U zk?X<%U+Y|!7`3Q&xIaL<@JA0n#fowHqZTdl!-u>4(Zg%;`i#-#^2aV3D_`is@5b5% z%?));YvwGduU}dRhju;=^WpJX1Tr4#7N#du-G+4|2?JP7B@AFSm@t6VY{CFagEXG7 zXnzw5i5EGy$D&243kJ6%S+N*iRIH4&R#ZjfGz_)5q%^vmg-c}Z z738wUtpS|u74$7uGY#T)cLH}2aK~Vg)gN;0J^UVUw`y!h`P~}OC;1K7HwOvs4B&F5 zI~Y%jM)PSALauaqTQyZ<1c*~ux~N)begKy%-8H~%IzYOt-&+Iv!qVju(JunHTI-4%@^=5|04`U$i-Bv@*j(kz{9YZ<7nUx|`NjY)SGxBA_edww{c}KH zu5{lF;BuwA4>;}*XXq%u12jekGkSu=%_y4i(@>%!O&5Dv-h}TuX&(8V$gAPe^KR~WY2t{y_}EOBH*sm*pBRb z6qubF*O7gH*BCe9u=c`f_rok)c6*rzT=(Pg8VnAGj_U2(z+B_Q<*K)PG)8F*Z!a8A z9{?^oK%qJ+mm*-sY8>s$mF^6U=_uV2M4k)WEgBoe?_BNlx4=B*!-b{G#mhY!(^0yk z5cyBwPAF8UF8G%#UHT;`*SIKfVd--IsMQ#yF}$3a?sDL6(b$gC{WUOc8rM;}Z)nVc z(tQWGBL^x}N9mpn%y^CKDBYPFbD(tR0C$bXc9iaa0dt?mb(HQdjX6-dF9X+e(1G)N z956*1*HO9^8grm@&jfCx#&(q78-Te@<2p)ro5ma{-KT*2x5jpqZl4oyZH$AVqjV=| zj6&va&n3XE(%6pD{SGkKYg|X^{#s)?O1A=$j{w(outIgkzg+!yEHEV+*HOCjG{#Cd zFwgM8SzQ(`dmQKT{l&mNt+5^1_Z2WbIAJ4nWZz(oQONN6V7kMByF_CE1+I75&#wUHCqZ0@zBXW<4&nm(Sbpzm z3`hx5Z-Me-K0eFBq5J|kmUFjZN{@TakM~ORR6>J$FC5T58T5V+fn;F4$owZ^mEyc z+Fu1QX9sa1<+mD`mLM+BUf2$P49vYjT!_BsfO$2D3+Q8e-Um!?zFUUiYt) z5PkOpvn_}V=wp5C))gx3xVbQX&bttCCTxps{008E zUcDaY^!VPp@GrLM2Aof)X!9Z1nSIy;_=*3$@4^4Q%aqdQy2>qG83D!Q@4?}4yXH7? zl?M39WPcLtvvehXC}`&Q_+6sBTww3!xErx)vuNA%UtpW|F1kj$kw36k`vowb#Q&Y5 zHFNEHXmU4zit*bym2+JzPd*`ds8DC(e27qsJZgnUUE)#S_NWY~J~;B6n>^kf9`)a# z3MBTgILCzg5a)x1!bzTV@IM1b2emCxQEb(G@__>H*2RHajp6PVU_3sKTc+Jt$%=7qNy6J_~X2s&Re(aeqeX=rh^(~;Q z;FhN+Dt9h-=O)`dx|4v2FRPdc1{|Elm5#lqv=B?=E4+VkdP65Ahdm=*A_mdt!C zKEhh|uUnPBVgD@DhADgyc;;hDT5S6gN6$)(ih&|;6%;y`UX!>Nb?4r0@6ed2a7^3;JaZ02&GU_ zRCucJJkLCId$zy(>Jg>be0^wYd~zAK7cba`(r3j+_x5DDZ&tsM;QEjRCj#h(QV=RZ zMKQsY@capGcyK*=33T5@i#)is zOe~YO2x5sQ)~`pr(A_{>jH9b;b5kQIo90>^$_J(5;itn<)D7!Es9YP%+BTl?M8&=$ZX{1F1GQPP>9?u!O<^}Ll4aX>jgw6W7oBn zqPN60UJ5C8p1~DcTGe1U6%F|~l8&=}d^C1{1Y;<+?8Cj@=45;G`=zZ(RYCz>OPWrl zp8n7yBl1HWk#i_;OLkX9Mom|N(mf7otCD2zRHa+x@!kf-7M6#@aXyf3RnCfH zIbS9`w{`hSG_4+`j4|T0~+tdk>||8*<|T_{Bi?(h02nmn5CZ! zFPNp}^?1uWKEJuCseXl4BZ^{1?iZe$5r1W5*{82lo8vx1W4`%` z^RF?@G@v7qgfcA-N)755uk@uI2yv6i{|sAkC?gd`Bin@M8R_}b^PD5mWodH`KWWM& zxXm)Y(Zpqs8ilcdrj6ru#_w^cu2}-g4NrqmCMk+0JtaKL8yYVpP8XT*aUrvT7iQ^J zxjvKXGi78(2r3vQTGZ)}_@@$A6cc|*cwTuNIAOUEYrR_jv6?!Q@NO?*MKR&O2=8ko zEZ2msSIfW7Cj6e4u%ehSCn_`5`I~8&%T4z>4fj_p@y;gvPcLCbG2u_YZo+bn)_S%4 z>ukbbc?m0u3IF@+CM?%qC3RcV5kv=VObaqWP@aZh=tYa&rkGEFYSrL40ADQyIRlg`(xsqO zkv4+5LSkXs!$9NjQyfF^GB*%X%-F*D07sg9JYVL)PZ$#8!vKOD% zQ0^Jit&O<75$}swWaU>ZGSBUyx#{tzxA7mHhF5MmhICVYRpzLQ@e`WApufk=a}}*o z?E#oJZD%Ib7Jk5jM<3-$a6M=QW95r)XzaZDY4gs z`V|g0JSBz38dMZ*xLbJrHRL4y-^M63y99k1MrA>ay4?___cxwi>O5UTbLrhGXrj2- z=7uo6^sA`724k7puba6smMV%}P3iU{sXt7&LiYD{V@fgP(yhva2p35@Ot(Vnhb35U zus->sXT4_?(#pwAEoBl0u;qEeNlLkbiR|uz!}3QXJYu|jQM(tE*SXk z?;9u*bfR;%Z`c=^i{;|fhJ9W5|FjMJqWnL4!#;dR!)ZEc!@jQkU$|jkH~v35=UoJJ z=|WvwI6PRWc&gHxFQxfKpfnHj`aeB+%aR_yri5>qh-YuHk=ay*X%=YC0q;X8q*_p_ zfY*ak1k@5)2*xsK3i;T!j8gu4GZJ?AtTl`|6h6&-3McP z<7l6H*I?rXf-RasdlU7&CcqfuFJ)e=aCa1aN(ELhgJ3Lg2}Brg8}y%Pq}JQ;}T z;$(Z|@NcK<4oo!S=HRBA)?m90+LVO%_5bd$(Du>FhHIoo-|)?GMryy7%FmKINTe>( z@$*LCJK0DT=tK{K6msgT!5$*T4id#NYs*!qALP{_Jp(fc#;U=d;F=m7amnVfMv6D& z41y8gBO??;JUQ9EM7HB!7RV-Sqx<%t&BHpjp*ZR46}UcbfIyh-bcIl*#fx~8X$9Jg*&%q!>X zwUl72a^^f`%9%bAjnrLQN-(sU7grK!p=~q!Vl*;QMLWkX-u5SBGv{rFL$YkJ8>ug}lwfExTDA(b(6;$7aH0`3VhL9kY`WIie3%*t z4(NmQ;Ws{SGF~@N(o%<0vt{!Uf89s2RLKQcCd zru7`iPbtgUcpQy!_(R~mirqHi$$YQ zDresdx5on;jjX_#^XN&_+W&2&=IPXr&#IjPBISa@)xi0+ zzkAl?eUH{NC@b&0f-t>l+SqSiZ+wUD(^7)5@;+Fk{CPK0eOUAef?+L>a&4xCw#`Gp ziALlM>d*1JD~-)3YCS`;Z00JcvH9XPq*?1Fe)lw%zgWbQ_BkcZV zq<)~K1Y@lvO^U%a9*_0{-DQF6G~zg*9yg0bprq)7Se%Sd%&6Gsq?mD5q+DxcMi|Lf(q{>0?8 zzm_7#&MEU{=aiQR(a1cWar~@xI`p_XovHPV&dMp*icC%i-jY0ew3pK*T1qfhPEQdj ze@>0mdMzaw_NEbTZ=!{^&0|FmuK`#UKYIO^8OG)twVttAHnX~o&AbK}>)CvVmJ*C* z^LUZ++iaw^X(_?bW*R1egl+Sw;6x)OJmYxoi<|y#Y<^YiIW^1X2_of=*ats;$nB?k zHovQ-1Y_BJnkNN9{I43Rue6k4813NAM;+p-wXnb?&}KUqyl065g|^KJ(c{`2{dxCujm?c( zPa@0aq)7Q~PIxw7rlka9*<37A{?=loexjuWW7$j#ZJVW?c;)=?o}#}Pn}4hIlw{eQ z%Cfn{v-yu&N-&nqrCBx`ssGVZg0XC-g|^LQqQ@=g?=0_v-w_-Phw+vdp)AYha&S$r zWZNk7Y#y$q1Y_Bp7Ab!@8>y*UN-&nqw9vM>LiD&czh1NRNn>-f)>DyX^Q0`BD?FR8 z&{Bf2Z02}nw`U`DmzENYWiu_bZLYLzuI=+Sl5)%WIjyHM%jT*qn=3t=-_ufpv231_ zWwVj$rHfxMmd&)#wz=A}dE`k$FEus~(|Qi%O_XiJ_|GiWQZ>|U*?eY}%|>dzmJ*C* zGcB}jo@&|r{!6=YW8s!Fy|Xe*%_`?<;M(nZs#nh6)l!17Y@RMsI$G|Ijnv(mEf~vY zT4>vhi4du?&2X6i>b?y>GB&&3O=o1;e3nSLW8D+4yl~14&*s1A)CFVNJX56nHXEt^ znk^XXx@DF~^~IUtlouaE=i^AhaQH#$KQW3|t~rj_?4MzoQ#wrxlwg3vv!++kqCkjDy})%bwQi$T+9I{S368- zJ#(^hF;}GAT(BL^@p3U;O9{rx#XOPn=fX(UYbn71hsWnRb3vQ!T+9bYUG4BX^Y9R`h&>XB;b^ zyd0e&0*aws>!}r+$vM0y&kVfw^RH1a0x#Dc>nU1lQC8j;iaucizDT*bXuSR} z$JcqexL->N#>&M~PYQ(d_mc-5W2AO!DZwz>d0lgK$@?~EFGH-kPWax(b^mflL&y12 zOA(_+$i6gF0&5VZ!5b(E%)4D0ymOC6-olv;A+~aBF28+)C`Vk2~WKBi+hdKTUv@3TWXahwWcs}hmrc1mLkSp8DQJ6Tgz(E zGlXXx_L|k9y}?3Qoz+?{1lP<&9068)t!1E=5{y-k3N0lVD_>hg%58_YEW2i*k-ADt3C3z0S6FGi{lVUZk-ASy3C2q6N-M2irzPV? z>JM5@ZlWXzW2=7-FHvksP{y+Uy07(cSw=5(xhMDE@noxs*@9u_dNyW_)6}FL`wxFSY z*|KbDm!BoCBa8;gP02E3Gh2&4E=!Xy(r9yQw5hIsMYcXWHcO)w9n@L6qNz5ln4}@< z$Q&9~tWlV1sP{f45aed55U@c_(tB`F4=WaXjX!sMmcD=jCE19tPpoK~H-DM;!3b$R z{{BUe?`YyazE+(T;rhBSPn48TN>--IlBTWK(K|{=Q`Z@&YpR>K44Y%#}m0`KD+oo?gubFy@~-M%JKGdWp2xu&wr zl*H27HCAWWihP|rkc1UuC*_ZFOTQvfQ$1-)<)l=#Npm?zj)`N`-r=y+RS)0*=KC6j zHLwM~qG1GRKg!=Qd>U-N&vq-q(%?71Ls{SOFkGv)3|s3%o#yyli4|j8<&Sdh!Z4Xb z5eG#RWoxqHe5%m58jXzAxG7>sXREa0wOU^@$e}qDVJi=VxMs^(ht`opyI1!n-qxKB zur$j!X=Lp(G2^U3glV^xX#Hx|F@l!rV5F@z5UUk(RL-H!j zf2+@m@~H~Oxt+c=QI)E$u1uGfnofVdo-wTcZgrWUHX4Rb@3NB@;#*<9-kcTXGb|Wq zr4x({q~l)FgeT?2hNtF6=St9x52P6~HMrRh`y!GRmn$j%_mW(J9Bm~#+Lt?wWLfbv zpCjC|x|Q?m@hyJtw8HhEL*$q zf-1>uz?Xq8Xs%tc0GF)#yEmhP-?w2>zS&yD&f@2E+{*}+qU!Y{+-nHMT(D$b-HO5h zQz3_kAp=ZnBvBfD8ADYF&+VVd#N?{-^ps>-mFb^N$fW9<_Gf=ak20U?;rD#J?2jBV zVr1>``L*LljuyVJpc_=K?RupJZiLS^RH-kUjf-M{tp@Y8?TLG zObI^q)KqJiU^d^EkR@PsC_6^JpSS?uajRb-y+p-M(|b(p1XT%#BUHI`gzy(?M>VWsieHRJe@2yUDVxqGjYrUxeT$UQhdW{^q9CW9OxTP zW5Fd;N%-l^Begr!VBKIjK^`D^-iMA z|KN{Nx8Z2%hDRw}2}C#ohxjV>J*Fa`j~RQrt3qTTBnlD<|E3x83UQp!N!;X4;08cn zeJ60kfxD&?xWT|}>jaMLneTN1cQkNcbOOh6>C06~UkEEd>KoSy9Q92P!}(qvXHvK0 z;L8oi@reTht2vi1+FD>P&^RvfhWSk9g6EaM+^TV0HV*TF%f|RiVB-2QCZ8STO7|zg z+@*23(q$1ptuY`agr%DggZ=>AYh2Go@Y=HsE{ex9qqo7RXK5Hhu5{Ut-UsH(ATC7T zH_&JXvEd+eq%Q@`^dK%oUjs1fg1CV1UDn4Bfw?D$3(@y1FnLiBwBOfS7a?Bydw z--*DS62t}cvEHU@49kTftlrq3X9sZ7UIOizL*IJfHfb!|Ul@+jSK@TD#&PMHI1J(c zTfT<*EcDd>6JNu1|GBH-4O`pWziMyUchKrZ+L1+i!Pd;>e7xqQqffQ}HN8b9mF@qx z|HqDF5}gWcnd5Qfi9<_1y^6|o!UsNivip3bP@{1kD%5E>pD0uc=RrbM;(WYN({Vml zsM$Dk0?Tt2;(WMJ%WytKs3x4*O7g_HBOgUXo%J}65^5vP!-U$5bCFP&<9vcpSK&NB zsPE#;yhfcHaOQK5sJJWS02Fm@!TC_3N~cb(o_cD0#+1oZs%K7#msgg}j0?}1zN9wZ zxUzOZ-J-hMh4IyOD;CzTjxU+l7++BzUr>*g=?j|#BezP8O~5RwZ&*IBDPGqYZ(cEP z)x5f8vbdX!uUs~-iE$@ubqnIPd_WPeUw})S1}wZXDWhh=vN|kF#PQA2_^R55My#p_ zRp!J8lCExUiq|iSFRxu*->}AUy?Dq+Pibr%pKrz&Gr7j@#?5P3+`OErGrD#~^Ku^s zsW#No6czvt2h3j(Qg+Mg<~QJL%nF9GSYeiz)2-7B3o7BZxL;*!Wnp~U1HywD1JL0}@uORt0yyo{ow}r%OUi15z!*(Nj)T^6bSa*85b!}mMRJ(R64oQ}3 zI@7Cr%bHnEQ!KsZ%!KGyGVSn2yd!_YpV$78jvC^=m~^JMsgE6^1&W*zg0eEC z=Ee7ms#xOSsYCgH%*T(eGUTapWsNCnh(~b{=j$eU;wVMMR(P?j)pZifS65Z+5|3)} zsOv%Tb%s0{S{3dd{9Y@(`*BvhM?GpAD8A5>Cw?RtoA11+WAmNYKr!t+@vEd{Kf-U- z^8N*idCSL31vs-Y>#!dGRr^pBQS*h@A7=&*_6&JA*5inZCPlHc@#UbXb2rZi(93dw zI~bg)vjGP~F1?)0qJpAsH>?K{w0DK@#1%|ao~4_)Q4+LNQ3arsZod^^>Ui58h4j0b zamyo@ZdD%C=OT0IR!FZOZra(@ZAT;uG)L@iJGyiM$q~GJatBp7pKgDb|5(bG;ehuy zJ@U88*tVUbYN+KcjiUZ;cF)j)O;GI~)48$;xYWq3M zQ>3g{dWnrjZo`?EA3t`w|IEAyGZ-8OPB++2;k(ag`;SJxA+Z<`#=Ur_n-X61&|G5d zmk>F6M59|#-B4W@}kE`!s>9)LcF}=OT9ZdM$dP@{qMy_&+Uj~AV&0z z;;(r)vh_%bL6+W6c93hW$WS1Z#2S-WQJe9{mEBG&*fSV zF``GRD~Vs(df2C?95$FMp@4mX(0gX2AyA$PT7>%%1vPE7|cSB#(zkaNx3Y<8leD}?LL`upZ)O8z9NVYBY*UTUPC)KY?>8fUj>GgD{y*yAu43^G~@<#G;H z83vD1bLK2qvb3>jse+K>-;Tq)+ppbm#8$7~v%ZT~{J2`#$|dXyT#r-Fp;@KD9GTZY z`Re_lUTG9*djw;Z#$h7GKF&Z#9Y$(`mJ*D_S6cZZYe5!gT^8qiS)ALmIKQ<{&p6@x#~Z0$?8FFyvC`t)Vbbbda@$Ep zYJip!jFpz$EPGp;Cck&|!$#^R9 zE!;@`LQ4q-IJo}P9M$T`c`=K#CyUd?Z8p-zDAm{Ea6FWuA2DpJcI)jAju~msy*mF| z(|QMKJ^fYd^^KXwixi_HIPUuCV*`!U7%in7nIPJkq&X^I{;_ueVxti?lEdNuphLG9 zJ+4E70h0Q~&>`1b9E99=&V(WFYkH6C7uPlkLqBJC9}-PY)Kpa^)02{u6S6=van!^y zdf8^;7_L1`9HaP!$z;NP3#_CxQ9Y?_QdMPXMFQ&=6UTTfIupmJC7p?5u%Qx|O&o(op^0Pks*opGQjsW6Ra93@E-vm^ z(6!f-tWHcxR+g8iCY2?yRs@R{;XOfFEmCj8x@BLLC{CtIrqopXo}tS!l9UB9=`JK$ zVkrE{sp83HmHt;_+!ZD*$u%Zd-ZQJX3NP=aYsxB-o~$~lqLw;R3s0)Duml%Ou(-6e zGFeemt_ngm3%w@gDnUNoWvK)v*NWxy7S|TfYpit}C*GEn_UAr4*KO9Y^@GnKf6kop zX=%6%TvppqvZNO8)~YAYs~T6VGuJhp)x2!!ycPC)Ez@fo zme;Mo({P*Z*6NcG-D=umZ%}DCP5(FP}Gc-tv|5%s=~e1IXpZa+X^8 z4g3sy^~ivAEVF`S?Lie!%*T$1`@(^qn2$JR?8woA=M(cvd18KRA-2$QIzR|}V*XFw z@c2W>6Z6f8U(5>`Uyvu}zPX7}MVOX81ddPf7^phe6U)uOd{^Um2^IFFl-J4k0kbWL zlln)b4m52yFz&{iT>5yW(*x7qv7Gu4JY0yr(|~a|&UiTAwG-ue&9_MF;%^4Yhwq-8 zyrDSOW#JN8PyTr?d}k+c)c2cC;8^}|bpprY{h*V$FT-$wc0k95XhzOEycI)WJ?3f$ z-^PvCHN5#k$W_j~lDkJ^1c*~uIismN4`ku8%Xt8BuXO?!2d=#nI9}}@$6FL%2zxW3 z9Py`R;cBwlK?!gzoxt%v;E60;c7A#NxjPIOsJH#7x6cB&T=n)5ZV|uaZ6ZRhdSktR z1BstV0}wo1NPkNMGd+k4^tU*4;I_fJCWs5scMmX+1aSd<95?=~F(4&`Jz2jVG4BAk zmbZooTm#5eE>{8bLyhzD8%USs@{q<*A46EWqrra)xUV#pHzAU4px(HeGYErGH3uXF zrkl&Y<-n}*;UwLFee7@F(-`Vw2(xb(_&);fS&hwQUj=ZV0W*=ey9m57$z|UKz+9|x zxyq0B{Xk==k0H#yDzxWYf%`}=$a0M^SGv=2dpwu7$OyU8Wj5CVbA1pO(*Ax8Oj{5a zC}-+>1DMZ(xDb7PaU&k*%{W3w_MHLDSwUQgz9wMS2XO)WIA7ij%zZ&zh`wFGycWcT z=-Us>!5lCVynKY{I|-O^L0mu|+re2HBMNbnb`Y3<2ZDcI7A||7k%uz8i!Q2$QgsPB|c;MnfdoxsI` zo81W<*L2r*0>}BNwG%jAuU!{{!=?ZK)|*-1f=Q=;{Wr7pyD0zpci{QvKmk9P(eJF} z^yG}>S;?9B!cC2S7c0GG4D7>O0BO9+g0Hi)!#Y)&cdIfVRc7{AX8uZkg5P+-+Xu4? z(>o#&becUxJ=g`KLi<&NG3Tc$oHx?c#T#x^;;}UqX zzq6g+ zJMs#;T^J)9$^AL1M_x{q_jHHUuG zXLoE@@3x+Er__7zfi0?UUa=4_RmDTz5yQ3*Zc7@taH#w_*c%jljZ8uCsu`fQSij?2 zTJsy~m)5Rus#n&oD6fo{PKz7z+>1<$4N9nec%CtR* zZ;q+fuHQuxU~JRd$a^Z2%uBX>5s6*?Fn(o{`J38eo9_WhX7fQUUv!OK`D6973x7sp zS6-ujMw<^xPH2l=*+RK9`{C7s=^OS(;z)YHhW%amzr!zgw|voMT~8zuZ9WF%#a^%D z*TbY|YFk^@^m1YwnFzpLF1gt45mmcq6^wgB_`hiliGeISVH_zjJ2hw}(6x0Oa@pA}D7C#;LGY6!3<)nJQqSz0|3D12S#eJ($&kShz%WARE8=qghWZtSe zyy1w?xnyDL=QlStt*C8m^ggxjLQEfV-^(0WH`J#>$J>!*^$n}BY4GF)^~+bzYpR=H zw+!pQ?0EGnmaT~|tX)*MLcKZ~4~UN%Iy{cmM*36)vY|CuWnhL3e&}X~%ziVIEl;&hAx; z*EC;Um!BFx^>3+I>iJ}5O~I!2bqBRvw8v?VCfm0qGZ*yT^cflNyNu*ubeo=;9uuCt zxNFhYRCHG|Q!#wgPGa(1Or&(wt1Vx&H}y@e%0PyDWCSjn~3s}FMN)Rm6&-P^EzhrbGP$LQCz=q!(tGsrzwg(?VG~u zuOV^$pYyE2D2ns!A{iL5s|A$~L2;gR2unvHBl&qw{zu(*<+XLGVN=d$Q!e1;UOb(_$HzZTXP(Em z_|(NxB|dJpsjaEZedp76S@!w!>Gqu!(cf22colEDt^Zbgyt!xW{>W+ZrV}@|H4Wlr zTjmwNmgcRzqT?H?@>RbUexc9&b_ZoJc{Owajyz|9M=@JmM{+|02vt9dVp**eUL?kk zoS_`~v9pmqSGr$2wLZ~`FBLW&*7D#-teIxU^uV6Mu$DvR1;$8AJDaG!I3L2(QY8H=88?w)RM+qAR!AGpYy*S>uMl&syF z&OEDo2hwNBo+lNcbgCOF1*#)cL|20*Y&jZulJtRmF;872hbl z{%jCU_>DfyKr0wHt}1MSM{!*IZyZs1PRBId5T^e}g8V!waO zhor-FD=T!@om+ZgQ|$`b=F`FbnE|c9mK|O{)-GR(3rT&~XN^^uYQnnzIotQpAa;9x z+mhpzFjUXrS0qEnEYk%}fHbp~Czsi(LG$Kdr|@vH3YE7BszED?#rCA|+%Zc}xL9Z5 ztQ()n%T0`8m=Zr$hP97B9RgS@dAYd&7JJ{v&Ft8Ff*|~3uVNsom)<6$7_BWFjFci7 zr#&tBYG$X^RBp+9iOy8H1vjNIXv?)6`O;f5oHNs{EnLx&f^2dvO?D7;CE&HNt=l`dMA#pvTHXoif`n}7ZvEgAF$-DK~roW*yTOO8C zd+kyV*s~ry_EL<>*RqUKxEz_4{A_!qsmG2MNJmWY;23)5`*BJbjZc@sXf-N{1();LXGI+ zIByGeDyTPwng~k8PWNKZ1@#w+o$tlo0qQm3-RN8=kfZ3dPQUh zfl@Y)1I1FxbI>xJKdRI~9WNA4&IbH)!~cL#gQ=qO@%u&LMf&w{`Yr73^qbzx={Fkm z)V{k8X)9Pcl^%R#TWZK!p{!e+6klB5Fjn zU6@?F3@?CTU^_)>i_9idAS7L6NP`oF@ru*;~RdUB30mRE;jP` z9z!z5yyQHrVckgcecdCplwhovoV$t?FYVY4o}M>og^?Pir37Q8)lH;$(IZk7_17CI zc4G#?SZT2fnwPgP`_8ea8>yut<1SqL^TkGJ@)gfqfR72%B8JPjo`FjMB3yryh>_(Fko|XuNY+ z%$0$A7%fGNov(wzG24;e?K5D3k$O@~5o1e1wNL7eZ~b+?k&@*A#1jK4-(zcOlMyb( zl6q&y>Cc&7z>5)v0w+!>UoYqbu4yfQU-J0pX5-9AEhQMMWga3@Y-tSKU}B`EX(_>2 zwR|YB(Fi9shM{ZvziIN-tfh#tOM^F0(Z~RbAl!G&7R+55?EF#_#Mn|?!-z)WI5QMI zwQ8D?dPhqUV@n+lPBg;B9ftNnvF%1`NK|o&v86a#L?dXj5_X;WHWn0I3zujqVr(fc zk*P1>QS7K-j67%MHo zds|n|n!jqFk$Of;DV_eUEB%>@NP%#Uy!6D&jFh_xMKIh@Hfk(E2rPNKE{+E$8bN13 zt>KH9ZReGky2#T5zS=6{@9zUd%AJW;J^JCh=IgcYcQOTIl~18aaa>`zeM9v>j8v&k zOE40DzB}FEm)c0^wkX^l&pJ*w;Sl_;&g?4ES z5k13jW@$Wh)8t>7(kS2s0>TilG~$}$s9gBwf)jx=-<#Sq@1X5Q&v-3$VpiUZM9R%O zzc+QFm-k6pN-$R5PZB9N@AQRlq~>cW!2pM?#+J=!;bVl26K%Fj<79B65iZB^8lvjQ zm(4c0xK8UiIV%^O>&*zz|IK|hCwsZLQ%ecP$_2|@UH?Qu)qL>NLL>FGmJ*CL0t~m( zI(__CdyUllT1qfhS|d70t5VWUc`<^{=CT zVx%gylwhp1*dI+=2em$SrIA{ur37Q8#i}&dtM5EDY`>AZTuTYYO6wFWt;Ck~D~!~g zT1qfhS{xTmT9dy2W`lc)6IG1WE zV$|Htx@2JAv3t{L;6x*5;>-bQ=&gL02VG0Tqgu~tS-pu%eWoSM`t zT8bF^3atbjQ(_6LOA%vBm4jo_y7|_x{%E8YYbj!EskBJ- z#hKyZLw|aNk-Az-5o1eLfD?_xab|d<`F~~@sYkUGF}BnsaH0|3yD{8+!$`Dhx8(O} zDPnA?$>6AdL8*Js|NT-Ubxcq4uCCN#DB;%$2 z6AMeq7ET;({ga)>TCAyI#R6>c3vLSa*;AaVDVYpS>cu=aUA4~-8FZ@k z7LL5Yh0kf|H@Lhl!zHOid9q@1YI1tA@gZ#FyroL_J19mlnW!wQNR?w}xe@f2rPp*= z^>wNR=#K@t+oPu>Qt8R1#Z@Kc*(we!UYbsnRHaHPD@v0I{kGV|@zzqR+PTcPy(W%X zSnHWyno5+FCX1`9E2p zNrtBAZJv7~@x-OOZErp!dsG->P{_YjsuX4sQV8HNgDG!O%#)gZMJ8kv6mBr1A7Gb!uE%HaWK(5L+;QeBET*&78(xU=TK#J5I z^{g1`F!j*9a%Fu3d~Uiaj2Bn+VezU}<&Ia)W9$LsbH^+BF$a*(9k1loM)=(J=Z;tM zYFB%1`P}hJK3D1b>M2CIJ7$;R6AM-8Db-aK2@e&V(a;>!FgCv-Fu8dm)4W=B$D5i& zRaJR;S+abJUoqc+P`czD2rnfWcbF42@S2AD1<8dA@rjqN@9q;nv2njJuN_EY7F^yG9|bt+w&@E+#{uUp*f2R%D^WBk~P;$%$? zXEpsy&$=cko{}h=k}98ET9Qn3^sLVoDoK>!(_#>$jQt4E29_mCCRJ5bR27#Kne}MU z2A3pCtBWU3N|jW(VDre(M#7m(x}qkXuA1Z`{f`nYEb>*EN+ze&U~ZI0jF=hujM2To z@-;{9f3ReyBx))uCzTXer%-mNdNq36bADB#x~96gELBqM$5?7`37Sr)N=onrGEw6` It5l%>4{5MQ*Z=?k literal 0 HcmV?d00001 diff --git a/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/README.txt b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/README.txt new file mode 100644 index 000000000..c86b90965 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/README.txt @@ -0,0 +1,8 @@ + +uSynergy client -- Implementation for the embedded Synergy client library +version 1.0.0, July 7th, 2012 +Copyright (c) 2012 Alex Evans + +This is a copy of the files once found at: + https://github.com/symless/synergy-core/tree/790d108a56ada9caad8e56ff777d444485a69da9/src/micro + diff --git a/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.c b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.c new file mode 100644 index 000000000..8dce47b8a --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.c @@ -0,0 +1,636 @@ +/* +uSynergy client -- Implementation for the embedded Synergy client library + version 1.0.0, July 7th, 2012 + +Copyright (c) 2012 Alex Evans + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as 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 "uSynergy.h" +#include +#include + + + +//--------------------------------------------------------------------------------------------------------------------- +// Internal helpers +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Read 16 bit integer in network byte order and convert to native byte order +**/ +static int16_t sNetToNative16(const unsigned char *value) +{ +#ifdef USYNERGY_LITTLE_ENDIAN + return value[1] | (value[0] << 8); +#else + return value[0] | (value[1] << 8); +#endif +} + + + +/** +@brief Read 32 bit integer in network byte order and convert to native byte order +**/ +static int32_t sNetToNative32(const unsigned char *value) +{ +#ifdef USYNERGY_LITTLE_ENDIAN + return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24); +#else + return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24); +#endif +} + + + +/** +@brief Trace text to client +**/ +static void sTrace(uSynergyContext *context, const char* text) +{ + // Don't trace if we don't have a trace function + if (context->m_traceFunc != 0L) + context->m_traceFunc(context->m_cookie, text); +} + + + +/** +@brief Add string to reply packet +**/ +static void sAddString(uSynergyContext *context, const char *string) +{ + size_t len = strlen(string); + memcpy(context->m_replyCur, string, len); + context->m_replyCur += len; +} + + + +/** +@brief Add uint8 to reply packet +**/ +static void sAddUInt8(uSynergyContext *context, uint8_t value) +{ + *context->m_replyCur++ = value; +} + + + +/** +@brief Add uint16 to reply packet +**/ +static void sAddUInt16(uSynergyContext *context, uint16_t value) +{ + uint8_t *reply = context->m_replyCur; + *reply++ = (uint8_t)(value >> 8); + *reply++ = (uint8_t)value; + context->m_replyCur = reply; +} + + + +/** +@brief Add uint32 to reply packet +**/ +static void sAddUInt32(uSynergyContext *context, uint32_t value) +{ + uint8_t *reply = context->m_replyCur; + *reply++ = (uint8_t)(value >> 24); + *reply++ = (uint8_t)(value >> 16); + *reply++ = (uint8_t)(value >> 8); + *reply++ = (uint8_t)value; + context->m_replyCur = reply; +} + + + +/** +@brief Send reply packet +**/ +static uSynergyBool sSendReply(uSynergyContext *context) +{ + // Set header size + uint8_t *reply_buf = context->m_replyBuffer; + uint32_t reply_len = (uint32_t)(context->m_replyCur - reply_buf); /* Total size of reply */ + uint32_t body_len = reply_len - 4; /* Size of body */ + uSynergyBool ret; + reply_buf[0] = (uint8_t)(body_len >> 24); + reply_buf[1] = (uint8_t)(body_len >> 16); + reply_buf[2] = (uint8_t)(body_len >> 8); + reply_buf[3] = (uint8_t)body_len; + + // Send reply + ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, reply_len); + + // Reset reply buffer write pointer + context->m_replyCur = context->m_replyBuffer+4; + return ret; +} + + + +/** +@brief Call mouse callback after a mouse event +**/ +static void sSendMouseCallback(uSynergyContext *context) +{ + // Skip if no callback is installed + if (context->m_mouseCallback == 0L) + return; + + // Send callback + context->m_mouseCallback(context->m_cookie, context->m_mouseX, context->m_mouseY, context->m_mouseWheelX, + context->m_mouseWheelY, context->m_mouseButtonLeft, context->m_mouseButtonRight, context->m_mouseButtonMiddle); +} + + + +/** +@brief Send keyboard callback when a key has been pressed or released +**/ +static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + // Skip if no callback is installed + if (context->m_keyboardCallback == 0L) + return; + + // Send callback + context->m_keyboardCallback(context->m_cookie, key, modifiers, down, repeat); +} + + + +/** +@brief Send joystick callback +**/ +static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum) +{ + int8_t *sticks; + + // Skip if no callback is installed + if (context->m_joystickCallback == 0L) + return; + + // Send callback + sticks = context->m_joystickSticks[joyNum]; + context->m_joystickCallback(context->m_cookie, joyNum, context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]); +} + + + +/** +@brief Parse a single client message, update state, send callbacks and send replies +**/ +#define USYNERGY_IS_PACKET(pkt_id) memcmp(message+4, pkt_id, 4)==0 +static void sProcessMessage(uSynergyContext *context, const uint8_t *message) +{ + // We have a packet! + if (memcmp(message+4, "Synergy", 7)==0) + { + // Welcome message + // kMsgHello = "Synergy%2i%2i" + // kMsgHelloBack = "Synergy%2i%2i%s" + sAddString(context, "Synergy"); + sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR); + sAddUInt16(context, USYNERGY_PROTOCOL_MINOR); + sAddUInt32(context, (uint32_t)strlen(context->m_clientName)); + sAddString(context, context->m_clientName); + if (!sSendReply(context)) + { + // Send reply failed, let's try to reconnect + sTrace(context, "SendReply failed, trying to reconnect in a second"); + context->m_connected = USYNERGY_FALSE; + context->m_sleepFunc(context->m_cookie, 1000); + } + else + { + // Let's assume we're connected + char buffer[256+1]; + sprintf(buffer, "Connected as client \"%s\"", context->m_clientName); + sTrace(context, buffer); + context->m_hasReceivedHello = USYNERGY_TRUE; + } + return; + } + else if (USYNERGY_IS_PACKET("QINF")) + { + // Screen info. Reply with DINF + // kMsgQInfo = "QINF" + // kMsgDInfo = "DINF%2i%2i%2i%2i%2i%2i%2i" + uint16_t x = 0, y = 0, warp = 0; + sAddString(context, "DINF"); + sAddUInt16(context, x); + sAddUInt16(context, y); + sAddUInt16(context, context->m_clientWidth); + sAddUInt16(context, context->m_clientHeight); + sAddUInt16(context, warp); + sAddUInt16(context, 0); // mx? + sAddUInt16(context, 0); // my? + sSendReply(context); + return; + } + else if (USYNERGY_IS_PACKET("CIAK")) + { + // Do nothing? + // kMsgCInfoAck = "CIAK" + return; + } + else if (USYNERGY_IS_PACKET("CROP")) + { + // Do nothing? + // kMsgCResetOptions = "CROP" + return; + } + else if (USYNERGY_IS_PACKET("CINN")) + { + // Screen enter. Reply with CNOP + // kMsgCEnter = "CINN%2i%2i%4i%2i" + + // Obtain the Synergy sequence number + context->m_sequenceNumber = sNetToNative32(message + 12); + context->m_isCaptured = USYNERGY_TRUE; + + // Call callback + if (context->m_screenActiveCallback != 0L) + context->m_screenActiveCallback(context->m_cookie, USYNERGY_TRUE); + } + else if (USYNERGY_IS_PACKET("COUT")) + { + // Screen leave + // kMsgCLeave = "COUT" + context->m_isCaptured = USYNERGY_FALSE; + + // Call callback + if (context->m_screenActiveCallback != 0L) + context->m_screenActiveCallback(context->m_cookie, USYNERGY_FALSE); + } + else if (USYNERGY_IS_PACKET("DMDN")) + { + // Mouse down + // kMsgDMouseDown = "DMDN%1i" + char btn = message[8]-1; + if (btn==2) + context->m_mouseButtonRight = USYNERGY_TRUE; + else if (btn==1) + context->m_mouseButtonMiddle = USYNERGY_TRUE; + else + context->m_mouseButtonLeft = USYNERGY_TRUE; + sSendMouseCallback(context); + } + else if (USYNERGY_IS_PACKET("DMUP")) + { + // Mouse up + // kMsgDMouseUp = "DMUP%1i" + char btn = message[8]-1; + if (btn==2) + context->m_mouseButtonRight = USYNERGY_FALSE; + else if (btn==1) + context->m_mouseButtonMiddle = USYNERGY_FALSE; + else + context->m_mouseButtonLeft = USYNERGY_FALSE; + sSendMouseCallback(context); + } + else if (USYNERGY_IS_PACKET("DMMV")) + { + // Mouse move. Reply with CNOP + // kMsgDMouseMove = "DMMV%2i%2i" + context->m_mouseX = sNetToNative16(message+8); + context->m_mouseY = sNetToNative16(message+10); + sSendMouseCallback(context); + } + else if (USYNERGY_IS_PACKET("DMWM")) + { + // Mouse wheel + // kMsgDMouseWheel = "DMWM%2i%2i" + // kMsgDMouseWheel1_0 = "DMWM%2i" + context->m_mouseWheelX += sNetToNative16(message+8); + context->m_mouseWheelY += sNetToNative16(message+10); + sSendMouseCallback(context); + } + else if (USYNERGY_IS_PACKET("DKDN")) + { + // Key down + // kMsgDKeyDown = "DKDN%2i%2i%2i" + // kMsgDKeyDown1_0 = "DKDN%2i%2i" + //uint16_t id = sNetToNative16(message+8); + uint16_t mod = sNetToNative16(message+10); + uint16_t key = sNetToNative16(message+12); + sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_FALSE); + } + else if (USYNERGY_IS_PACKET("DKRP")) + { + // Key repeat + // kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i" + // kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i" + uint16_t mod = sNetToNative16(message+10); +// uint16_t count = sNetToNative16(message+12); + uint16_t key = sNetToNative16(message+14); + sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_TRUE); + } + else if (USYNERGY_IS_PACKET("DKUP")) + { + // Key up + // kMsgDKeyUp = "DKUP%2i%2i%2i" + // kMsgDKeyUp1_0 = "DKUP%2i%2i" + //uint16 id=Endian::sNetToNative(sbuf[4]); + uint16_t mod = sNetToNative16(message+10); + uint16_t key = sNetToNative16(message+12); + sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, USYNERGY_FALSE); + } + else if (USYNERGY_IS_PACKET("DGBT")) + { + // Joystick buttons + // kMsgDGameButtons = "DGBT%1i%2i"; + uint8_t joy_num = message[8]; + if (joy_numm_joystickButtons[joy_num] = (message[9] << 8) | message[10]; + sSendJoystickCallback(context, joy_num); + } + } + else if (USYNERGY_IS_PACKET("DGST")) + { + // Joystick sticks + // kMsgDGameSticks = "DGST%1i%1i%1i%1i%1i"; + uint8_t joy_num = message[8]; + if (joy_numm_joystickSticks[joy_num], message+9, 4); + sSendJoystickCallback(context, joy_num); + } + } + else if (USYNERGY_IS_PACKET("DSOP")) + { + // Set options + // kMsgDSetOptions = "DSOP%4I" + } + else if (USYNERGY_IS_PACKET("CALV")) + { + // Keepalive, reply with CALV and then CNOP + // kMsgCKeepAlive = "CALV" + sAddString(context, "CALV"); + sSendReply(context); + // now reply with CNOP + } + else if (USYNERGY_IS_PACKET("DCLP")) + { + // Clipboard message + // kMsgDClipboard = "DCLP%1i%4i%s" + // + // The clipboard message contains: + // 1 uint32: The size of the message + // 4 chars: The identifier ("DCLP") + // 1 uint8: The clipboard index + // 1 uint32: The sequence number. It's zero, because this message is always coming from the server? + // 1 uint32: The total size of the remaining 'string' (as per the Synergy %s string format (which is 1 uint32 for size followed by a char buffer (not necessarily null terminated)). + // 1 uint32: The number of formats present in the message + // And then 'number of formats' times the following: + // 1 uint32: The format of the clipboard data + // 1 uint32: The size n of the clipboard data + // n uint8: The clipboard data + const uint8_t * parse_msg = message+17; + uint32_t num_formats = sNetToNative32(parse_msg); + parse_msg += 4; + for (; num_formats; num_formats--) + { + // Parse clipboard format header + uint32_t format = sNetToNative32(parse_msg); + uint32_t size = sNetToNative32(parse_msg+4); + parse_msg += 8; + + // Call callback + if (context->m_clipboardCallback) + context->m_clipboardCallback(context->m_cookie, format, parse_msg, size); + + parse_msg += size; + } + } + else + { + // Unknown packet, could be any of these + // kMsgCNoop = "CNOP" + // kMsgCClose = "CBYE" + // kMsgCClipboard = "CCLP%1i%4i" + // kMsgCScreenSaver = "CSEC%1i" + // kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i" + // kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i" + // kMsgDMouseRelMove = "DMRM%2i%2i" + // kMsgEIncompatible = "EICV%2i%2i" + // kMsgEBusy = "EBSY" + // kMsgEUnknown = "EUNK" + // kMsgEBad = "EBAD" + char buffer[64]; + sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], message[5], message[6], message[7]); + sTrace(context, buffer); + return; + } + + // Reply with CNOP maybe? + sAddString(context, "CNOP"); + sSendReply(context); +} +#undef USYNERGY_IS_PACKET + + + +/** +@brief Mark context as being disconnected +**/ +static void sSetDisconnected(uSynergyContext *context) +{ + context->m_connected = USYNERGY_FALSE; + context->m_hasReceivedHello = USYNERGY_FALSE; + context->m_isCaptured = USYNERGY_FALSE; + context->m_replyCur = context->m_replyBuffer + 4; + context->m_sequenceNumber = 0; +} + + + +/** +@brief Update a connected context +**/ +static void sUpdateContext(uSynergyContext *context) +{ + /* Receive data (blocking) */ + int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs; + int num_received = 0; + int packlen = 0; + if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer + context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE) + { + /* Receive failed, let's try to reconnect */ + char buffer[128]; + sprintf(buffer, "Receive failed (%d bytes asked, %d bytes received), trying to reconnect in a second", receive_size, num_received); + sTrace(context, buffer); + sSetDisconnected(context); + context->m_sleepFunc(context->m_cookie, 1000); + return; + } + context->m_receiveOfs += num_received; + + /* If we didn't receive any data then we're probably still polling to get connected and + therefore not getting any data back. To avoid overloading the system with a Synergy + thread that would hammer on polling, we let it rest for a bit if there's no data. */ + if (num_received == 0) + context->m_sleepFunc(context->m_cookie, 500); + + /* Check for timeouts */ + if (context->m_hasReceivedHello) + { + uint32_t cur_time = context->m_getTimeFunc(); + if (num_received == 0) + { + /* Timeout after 2 secs of inactivity (we received no CALV) */ + if ((cur_time - context->m_lastMessageTime) > USYNERGY_IDLE_TIMEOUT) + sSetDisconnected(context); + } + else + context->m_lastMessageTime = cur_time; + } + + /* Eat packets */ + for (;;) + { + /* Grab packet length and bail out if the packet goes beyond the end of the buffer */ + packlen = sNetToNative32(context->m_receiveBuffer); + if (packlen+4 > context->m_receiveOfs) + break; + + /* Process message */ + sProcessMessage(context, context->m_receiveBuffer); + + /* Move packet to front of buffer */ + memmove(context->m_receiveBuffer, context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4); + context->m_receiveOfs -= packlen+4; + } + + /* Throw away over-sized packets */ + if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE) + { + /* Oversized packet, ditch tail end */ + char buffer[128]; + sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", context->m_receiveBuffer[4], context->m_receiveBuffer[5], context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen); + sTrace(context, buffer); + num_received = context->m_receiveOfs-4; // 4 bytes for the size field + while (num_received != packlen) + { + int buffer_left = packlen - num_received; + int to_receive = buffer_left < USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE; + int ditch_received = 0; + if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE) + { + /* Receive failed, let's try to reconnect */ + sTrace(context, "Receive failed, trying to reconnect in a second"); + sSetDisconnected(context); + context->m_sleepFunc(context->m_cookie, 1000); + break; + } + else + { + num_received += ditch_received; + } + } + context->m_receiveOfs = 0; + } +} + + +//--------------------------------------------------------------------------------------------------------------------- +// Public interface +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Initialize uSynergy context +**/ +void uSynergyInit(uSynergyContext *context) +{ + /* Zero memory */ + memset(context, 0, sizeof(uSynergyContext)); + + /* Initialize to default state */ + sSetDisconnected(context); +} + + +/** +@brief Update uSynergy +**/ +void uSynergyUpdate(uSynergyContext *context) +{ + if (context->m_connected) + { + /* Update context, receive data, call callbacks */ + sUpdateContext(context); + } + else + { + /* Try to connect */ + if (context->m_connectFunc(context->m_cookie)) + context->m_connected = USYNERGY_TRUE; + } +} + + + +/** +@brief Send clipboard data +**/ +void uSynergySendClipboard(uSynergyContext *context, const char *text) +{ + // Calculate maximum size that will fit in a reply packet + uint32_t overhead_size = 4 + /* Message size */ + 4 + /* Message ID */ + 1 + /* Clipboard index */ + 4 + /* Sequence number */ + 4 + /* Rest of message size (because it's a Synergy string from here on) */ + 4 + /* Number of clipboard formats */ + 4 + /* Clipboard format */ + 4; /* Clipboard data length */ + uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size; + + // Clip text to max length + uint32_t text_length = (uint32_t)strlen(text); + if (text_length > max_length) + { + char buffer[128]; + sprintf(buffer, "Clipboard buffer too small, clipboard truncated at %d characters", max_length); + sTrace(context, buffer); + text_length = max_length; + } + + // Assemble packet + sAddString(context, "DCLP"); + sAddUInt8(context, 0); /* Clipboard index */ + sAddUInt32(context, context->m_sequenceNumber); + sAddUInt32(context, 4+4+4+text_length); /* Rest of message size: numFormats, format, length, data */ + sAddUInt32(context, 1); /* Number of formats (only text for now) */ + sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT); + sAddUInt32(context, text_length); + sAddString(context, text); + sSendReply(context); +} diff --git a/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.h b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.h new file mode 100644 index 000000000..cedc38783 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/examples/libs/usynergy/uSynergy.h @@ -0,0 +1,420 @@ +/* +uSynergy client -- Interface for the embedded Synergy client library + version 1.0.0, July 7th, 2012 + +Copyright (C) 2012 Synergy Si Ltd. +Copyright (c) 2012 Alex Evans + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as 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 + +#ifdef __cplusplus +extern "C" { +#endif + + + +//--------------------------------------------------------------------------------------------------------------------- +// Configuration +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Determine endianness +**/ +#if defined(USYNERGY_LITTLE_ENDIAN) && defined(USYNERGY_BIG_ENDIAN) + /* Ambiguous: both endians specified */ + #error "Can't define both USYNERGY_LITTLE_ENDIAN and USYNERGY_BIG_ENDIAN" +#elif !defined(USYNERGY_LITTLE_ENDIAN) && !defined(USYNERGY_BIG_ENDIAN) + /* Attempt to auto detect */ + #if defined(__LITTLE_ENDIAN__) || defined(LITTLE_ENDIAN) || (_BYTE_ORDER == _LITTLE_ENDIAN) + #define USYNERGY_LITTLE_ENDIAN + #elif defined(__BIG_ENDIAN__) || defined(BIG_ENDIAN) || (_BYTE_ORDER == _BIG_ENDIAN) + #define USYNERGY_BIG_ENDIAN + #else + #error "Can't detect endian-nes, please defined either USYNERGY_LITTLE_ENDIAN or USYNERGY_BIG_ENDIAN"; + #endif +#else + /* User-specified endian-nes, nothing to do for us */ +#endif + + + +//--------------------------------------------------------------------------------------------------------------------- +// Types and Constants +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Boolean type +**/ +typedef int uSynergyBool; +#define USYNERGY_FALSE 0 /* False value */ +#define USYNERGY_TRUE 1 /* True value */ + + +/** +@brief User context type + +The uSynergyCookie type is an opaque type that is used by uSynergy to communicate to the client. It is passed along to +callback functions as context. +**/ +typedef struct { int ignored; } * uSynergyCookie; + + + +/** +@brief Clipboard types +**/ +enum uSynergyClipboardFormat +{ + USYNERGY_CLIPBOARD_FORMAT_TEXT = 0, /* Text format, UTF-8, newline is LF */ + USYNERGY_CLIPBOARD_FORMAT_BITMAP = 1, /* Bitmap format, BMP 24/32bpp, BI_RGB */ + USYNERGY_CLIPBOARD_FORMAT_HTML = 2, /* HTML format, HTML fragment, UTF-8, newline is LF */ +}; + + + +/** +@brief Constants and limits +**/ +#define USYNERGY_NUM_JOYSTICKS 4 /* Maximum number of supported joysticks */ + +#define USYNERGY_PROTOCOL_MAJOR 1 /* Major protocol version */ +#define USYNERGY_PROTOCOL_MINOR 4 /* Minor protocol version */ + +#define USYNERGY_IDLE_TIMEOUT 2000 /* Timeout in milliseconds before reconnecting */ + +#define USYNERGY_TRACE_BUFFER_SIZE 1024 /* Maximum length of traced message */ +#define USYNERGY_REPLY_BUFFER_SIZE 1024 /* Maximum size of a reply packet */ +#define USYNERGY_RECEIVE_BUFFER_SIZE 4096 /* Maximum size of an incoming packet */ + + + +/** +@brief Keyboard constants +**/ +#define USYNERGY_MODIFIER_SHIFT 0x0001 /* Shift key modifier */ +#define USYNERGY_MODIFIER_CTRL 0x0002 /* Ctrl key modifier */ +#define USYNERGY_MODIFIER_ALT 0x0004 /* Alt key modifier */ +#define USYNERGY_MODIFIER_META 0x0008 /* Meta key modifier */ +#define USYNERGY_MODIFIER_WIN 0x0010 /* Windows key modifier */ +#define USYNERGY_MODIFIER_ALT_GR 0x0020 /* AltGr key modifier */ +#define USYNERGY_MODIFIER_LEVEL5LOCK 0x0040 /* Level5Lock key modifier */ +#define USYNERGY_MODIFIER_CAPSLOCK 0x1000 /* CapsLock key modifier */ +#define USYNERGY_MODIFIER_NUMLOCK 0x2000 /* NumLock key modifier */ +#define USYNERGY_MODIFIER_SCROLLOCK 0x4000 /* ScrollLock key modifier */ + + + + +//--------------------------------------------------------------------------------------------------------------------- +// Functions and Callbacks +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Connect function + +This function is called when uSynergy needs to connect to the host. It doesn't imply a network implementation or +destination address, that must all be handled on the user side. The function should return USYNERGY_TRUE if a +connection was established or USYNERGY_FALSE if it could not connect. + +When network errors occur (e.g. uSynergySend or uSynergyReceive fail) then the connect call will be called again +so the implementation of the function must close any old connections and clean up resources before retrying. + +@param cookie Cookie supplied in the Synergy context +**/ +typedef uSynergyBool (*uSynergyConnectFunc)(uSynergyCookie cookie); + + + +/** +@brief Send function + +This function is called when uSynergy needs to send something over the default connection. It should return +USYNERGY_TRUE if sending succeeded and USYNERGY_FALSE otherwise. This function should block until the send +operation is completed. + +@param cookie Cookie supplied in the Synergy context +@param buffer Address of buffer to send +@param length Length of buffer to send +**/ +typedef uSynergyBool (*uSynergySendFunc)(uSynergyCookie cookie, const uint8_t *buffer, int length); + + + +/** +@brief Receive function + +This function is called when uSynergy needs to receive data from the default connection. It should return +USYNERGY_TRUE if receiving data succeeded and USYNERGY_FALSE otherwise. This function should block until data +has been received and wait for data to become available. If @a outLength is set to 0 upon completion it is +assumed that the connection is alive, but still in a connecting state and needs time to settle. + +@param cookie Cookie supplied in the Synergy context +@param buffer Address of buffer to receive data into +@param maxLength Maximum amount of bytes to write into the receive buffer +@param outLength Address of integer that receives the actual amount of bytes written into @a buffer +**/ +typedef uSynergyBool (*uSynergyReceiveFunc)(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength); + + + +/** +@brief Thread sleep function + +This function is called when uSynergy wants to suspend operation for a while before retrying an operation. It +is mostly used when a socket times out or disconnect occurs to prevent uSynergy from continuously hammering a +network connection in case the network is down. + +@param cookie Cookie supplied in the Synergy context +@param timeMs Time to sleep the current thread (in milliseconds) +**/ +typedef void (*uSynergySleepFunc)(uSynergyCookie cookie, int timeMs); + + + +/** +@brief Get time function + +This function is called when uSynergy needs to know the current time. This is used to determine when timeouts +have occured. The time base should be a cyclic millisecond time value. + +@returns Time value in milliseconds +**/ +typedef uint32_t (*uSynergyGetTimeFunc)(); + + + +/** +@brief Trace function + +This function is called when uSynergy wants to trace something. It is optional to show these messages, but they +are often useful when debugging. uSynergy only traces major events like connecting and disconnecting. Usually +only a single trace is shown when the connection is established and no more trace are called. + +@param cookie Cookie supplied in the Synergy context +@param text Text to be traced +**/ +typedef void (*uSynergyTraceFunc)(uSynergyCookie cookie, const char *text); + + + +/** +@brief Screen active callback + +This callback is called when Synergy makes the screen active or inactive. This +callback is usually sent when the mouse enters or leaves the screen. + +@param cookie Cookie supplied in the Synergy context +@param active Activation flag, 1 if the screen has become active, 0 if the screen has become inactive +**/ +typedef void (*uSynergyScreenActiveCallback)(uSynergyCookie cookie, uSynergyBool active); + + + +/** +@brief Mouse callback + +This callback is called when a mouse events happens. The mouse X and Y position, +wheel and button state is communicated in the message. It's up to the user to +interpret if this is a mouse up, down, double-click or other message. + +@param cookie Cookie supplied in the Synergy context +@param x Mouse X position +@param y Mouse Y position +@param wheelX Mouse wheel X position +@param wheelY Mouse wheel Y position +@param buttonLeft Left button pressed status, 0 for released, 1 for pressed +@param buttonMiddle Middle button pressed status, 0 for released, 1 for pressed +@param buttonRight Right button pressed status, 0 for released, 1 for pressed +**/ +typedef void (*uSynergyMouseCallback)(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle); + + + +/** +@brief Key event callback + +This callback is called when a key is pressed or released. + +@param cookie Cookie supplied in the Synergy context +@param key Key code of key that was pressed or released +@param modifiers Status of modifier keys (alt, shift, etc.) +@param down Down or up status, 1 is key is pressed down, 0 if key is released (up) +@param repeat Repeat flag, 1 if the key is down because the key is repeating, 0 if the key is initially pressed by the user +**/ +typedef void (*uSynergyKeyboardCallback)(uSynergyCookie cookie, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat); + + + +/** +@brief Joystick event callback + +This callback is called when a joystick stick or button changes. It is possible that multiple callbacks are +fired when different sticks or buttons change as these are individual messages in the packet stream. Each +callback will contain all the valid state for the different axes and buttons. The last callback received will +represent the most current joystick state. + +@param cookie Cookie supplied in the Synergy context +@param joyNum Joystick number, always in the range [0 ... USYNERGY_NUM_JOYSTICKS> +@param buttons Button pressed mask +@param leftStickX Left stick X position, in range [-127 ... 127] +@param leftStickY Left stick Y position, in range [-127 ... 127] +@param rightStickX Right stick X position, in range [-127 ... 127] +@param rightStickY Right stick Y position, in range [-127 ... 127] +**/ +typedef void (*uSynergyJoystickCallback)(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY); + + + +/** +@brief Clipboard event callback + +This callback is called when something is placed on the clipboard. Multiple callbacks may be fired for +multiple clipboard formats if they are supported. The data provided is read-only and may not be modified +by the application. + +@param cookie Cookie supplied in the Synergy context +@param format Clipboard format +@param data Memory area containing the clipboard raw data +@param size Size of clipboard data +**/ +typedef void (*uSynergyClipboardCallback)(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size); + + + +//--------------------------------------------------------------------------------------------------------------------- +// Context +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief uSynergy context +**/ +typedef struct +{ + /* Mandatory configuration data, filled in by client */ + uSynergyConnectFunc m_connectFunc; /* Connect function */ + uSynergySendFunc m_sendFunc; /* Send data function */ + uSynergyReceiveFunc m_receiveFunc; /* Receive data function */ + uSynergySleepFunc m_sleepFunc; /* Thread sleep function */ + uSynergyGetTimeFunc m_getTimeFunc; /* Get current time function */ + const char* m_clientName; /* Name of Synergy Screen / Client */ + uint16_t m_clientWidth; /* Width of screen */ + uint16_t m_clientHeight; /* Height of screen */ + + /* Optional configuration data, filled in by client */ + uSynergyCookie m_cookie; /* Cookie pointer passed to callback functions (can be NULL) */ + uSynergyTraceFunc m_traceFunc; /* Function for tracing status (can be NULL) */ + uSynergyScreenActiveCallback m_screenActiveCallback; /* Callback for entering and leaving screen */ + uSynergyMouseCallback m_mouseCallback; /* Callback for mouse events */ + uSynergyKeyboardCallback m_keyboardCallback; /* Callback for keyboard events */ + uSynergyJoystickCallback m_joystickCallback; /* Callback for joystick events */ + uSynergyClipboardCallback m_clipboardCallback; /* Callback for clipboard events */ + + /* State data, used internall by client, initialized by uSynergyInit() */ + uSynergyBool m_connected; /* Is our socket connected? */ + uSynergyBool m_hasReceivedHello; /* Have we received a 'Hello' from the server? */ + uSynergyBool m_isCaptured; /* Is Synergy active (i.e. this client is receiving input messages?) */ + uint32_t m_lastMessageTime; /* Time at which last message was received */ + uint32_t m_sequenceNumber; /* Packet sequence number */ + uint8_t m_receiveBuffer[USYNERGY_RECEIVE_BUFFER_SIZE]; /* Receive buffer */ + int m_receiveOfs; /* Receive buffer offset */ + uint8_t m_replyBuffer[USYNERGY_REPLY_BUFFER_SIZE]; /* Reply buffer */ + uint8_t* m_replyCur; /* Write offset into reply buffer */ + uint16_t m_mouseX; /* Mouse X position */ + uint16_t m_mouseY; /* Mouse Y position */ + int16_t m_mouseWheelX; /* Mouse wheel X position */ + int16_t m_mouseWheelY; /* Mouse wheel Y position */ + uSynergyBool m_mouseButtonLeft; /* Mouse left button */ + uSynergyBool m_mouseButtonRight; /* Mouse right button */ + uSynergyBool m_mouseButtonMiddle; /* Mouse middle button */ + int8_t m_joystickSticks[USYNERGY_NUM_JOYSTICKS][4]; /* Joystick stick position in 2 axes for 2 sticks */ + uint16_t m_joystickButtons[USYNERGY_NUM_JOYSTICKS]; /* Joystick button state */ +} uSynergyContext; + + + +//--------------------------------------------------------------------------------------------------------------------- +// Interface +//--------------------------------------------------------------------------------------------------------------------- + + + +/** +@brief Initialize uSynergy context + +This function initializes @a context for use. Call this function directly after +creating the context, before filling in any configuration data in it. Not calling +this function will cause undefined behavior. + +@param context Context to be initialized +**/ +extern void uSynergyInit(uSynergyContext *context); + + + +/** +@brief Update uSynergy + +This function updates uSynergy and does the bulk of the work. It does connection management, +receiving data, reconnecting after errors or timeouts and so on. It assumes that networking +operations are blocking and it can suspend the current thread if it needs to wait. It is +best practice to call uSynergyUpdate from a background thread so it is responsive. + +Because uSynergy relies mostly on blocking calls it will mostly stay in thread sleep state +waiting for system mutexes and won't eat much memory. + +uSynergyUpdate doesn't do any memory allocations or have any side effects beyond those of +the callbacks it calls. + +@param context Context to be updated +**/ +extern void uSynergyUpdate(uSynergyContext *context); + + + +/** +@brief Send clipboard data + +This function sets new clipboard data and sends it to the server. Use this function if +your client cuts or copies data onto the clipboard that it needs to share with the +server. + +Currently there is only support for plaintext, but HTML and image data could be +supported with some effort. + +@param context Context to send clipboard data to +@param text Text to set to the clipboard +**/ +extern void uSynergySendClipboard(uSynergyContext *context, const char *text); + + + +#ifdef __cplusplus +}; +#endif diff --git a/libultraship/libultraship/Lib/ImGui/imconfig.h b/libultraship/libultraship/Lib/ImGui/imconfig.h new file mode 100644 index 000000000..774b8f0e0 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imconfig.h @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------- +// COMPILE-TIME OPTIONS FOR DEAR IMGUI +// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. +// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. +//----------------------------------------------------------------------------- +// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) +// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. +//----------------------------------------------------------------------------- +// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp +// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. +// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. +// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. +//----------------------------------------------------------------------------- + +#pragma once + +//---- Define assertion handler. Defaults to calling assert(). +// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. +//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) +//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts + +//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows +// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. +// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() +// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. +//#define IMGUI_API __declspec( dllexport ) +//#define IMGUI_API __declspec( dllimport ) + +//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. +//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS +//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. + +//---- Disable all of Dear ImGui or don't implement standard windows. +// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. +//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. +//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. +//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty. + +//---- Don't implement some functions to reduce linkage requirements. +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) +//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) +//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). +//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). +//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) +//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. +//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) +//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. +//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). +//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available + +//---- Include imgui_user.h at the end of imgui.h as a convenience +//#define IMGUI_INCLUDE_IMGUI_USER_H + +//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) +//#define IMGUI_USE_BGRA_PACKED_COLOR + +//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) +//#define IMGUI_USE_WCHAR32 + +//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version +// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. +//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" +//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" +//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION + +//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) +// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. +// #define IMGUI_USE_STB_SPRINTF + +//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) +// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). +// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. +//#define IMGUI_ENABLE_FREETYPE + +//---- Use stb_truetype to build and rasterize the font atlas (default) +// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. +//#define IMGUI_ENABLE_STB_TRUETYPE + +//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. +// This will be inlined as part of ImVec2 and ImVec4 class declarations. +/* +#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); } +*/ + +//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. +// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). +// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. +// Read about ImGuiBackendFlags_RendererHasVtxOffset for details. +//#define ImDrawIdx unsigned int + +//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) +//struct ImDrawList; +//struct ImDrawCmd; +//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); +//#define ImDrawCallback MyImDrawCallback + +//---- Debug Tools: Macro to break in Debugger +// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) +//#define IM_DEBUG_BREAK IM_ASSERT(0) +//#define IM_DEBUG_BREAK __debugbreak() + +//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), +// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) +// This adds a small runtime cost which is why it is not enabled by default. +//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX + +//---- Debug Tools: Enable slower asserts +//#define IMGUI_DEBUG_PARANOID + +//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. +/* +namespace ImGui +{ + void MyFunction(const char* name, const MyMatrix44& v); +} +*/ diff --git a/libultraship/libultraship/Lib/ImGui/imgui.cpp b/libultraship/libultraship/Lib/ImGui/imgui.cpp new file mode 100644 index 000000000..5bc813356 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui.cpp @@ -0,0 +1,18796 @@ +// dear imgui, v1.87 +// (main code and documentation) + +// Help: +// - Read FAQ at http://dearimgui.org/faq +// - Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. +// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. +// Read imgui.cpp for details, links and comments. + +// Resources: +// - FAQ http://dearimgui.org/faq +// - Homepage & latest https://github.com/ocornut/imgui +// - Releases & changelog https://github.com/ocornut/imgui/releases +// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!) +// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Glossary https://github.com/ocornut/imgui/wiki/Glossary +// - Issues & support https://github.com/ocornut/imgui/issues + +// Getting Started? +// - For first-time users having issues compiling/linking/running or issues loading fonts: +// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. + +// Developed by Omar Cornut and every direct or indirect contributors to the GitHub. +// See LICENSE.txt for copyright and licensing details (standard MIT License). +// This library is free but needs your support to sustain development and maintenance. +// Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.com". +// Individuals: you can support continued development via donations. See docs/README or web page. + +// It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library. +// Note that 'ImGui::' being a namespace, you can add functions into the namespace from your own source files, without +// modifying imgui.h or imgui.cpp. You may include imgui_internal.h to access internal data structures, but it doesn't +// come with any guarantee of forward compatibility. Discussing your changes on the GitHub Issue Tracker may lead you +// to a better solution or official support for them. + +/* + +Index of this file: + +DOCUMENTATION + +- MISSION STATEMENT +- END-USER GUIDE +- PROGRAMMER GUIDE + - READ FIRST + - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI + - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE + - HOW A SIMPLE APPLICATION MAY LOOK LIKE + - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE + - USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS +- API BREAKING CHANGES (read me when you update!) +- FREQUENTLY ASKED QUESTIONS (FAQ) + - Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer) + +CODE +(search for "[SECTION]" in the code to find them) + +// [SECTION] INCLUDES +// [SECTION] FORWARD DECLARATIONS +// [SECTION] CONTEXT AND MEMORY ALLOCATORS +// [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO) +// [SECTION] MISC HELPERS/UTILITIES (Geometry functions) +// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions) +// [SECTION] MISC HELPERS/UTILITIES (File functions) +// [SECTION] MISC HELPERS/UTILITIES (ImText* functions) +// [SECTION] MISC HELPERS/UTILITIES (Color functions) +// [SECTION] ImGuiStorage +// [SECTION] ImGuiTextFilter +// [SECTION] ImGuiTextBuffer +// [SECTION] ImGuiListClipper +// [SECTION] STYLING +// [SECTION] RENDER HELPERS +// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) +// [SECTION] INPUTS +// [SECTION] ERROR CHECKING +// [SECTION] LAYOUT +// [SECTION] SCROLLING +// [SECTION] TOOLTIPS +// [SECTION] POPUPS +// [SECTION] KEYBOARD/GAMEPAD NAVIGATION +// [SECTION] DRAG AND DROP +// [SECTION] LOGGING/CAPTURING +// [SECTION] SETTINGS +// [SECTION] VIEWPORTS, PLATFORM WINDOWS +// [SECTION] DOCKING +// [SECTION] PLATFORM DEPENDENT HELPERS +// [SECTION] METRICS/DEBUGGER WINDOW +// [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, STACK TOOL) + +*/ + +//----------------------------------------------------------------------------- +// DOCUMENTATION +//----------------------------------------------------------------------------- + +/* + + 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 setup and maintenance. + - Minimize state storage on user side. + - Portable, minimize dependencies, run on target (consoles, phones, etc.). + - Efficient runtime and memory consumption. + + Designed for developers and content-creators, not the typical end-user! Some of the current weaknesses includes: + + - Doesn't look fancy, doesn't animate. + - Limited layout features, intricate layouts are typically crafted in code. + + + END-USER GUIDE + ============== + + - Double-click on title bar to collapse window. + - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin(). + - Click and drag on lower right corner to resize window (double-click to auto fit window to its contents). + - Click and drag on any empty space to move window. + - TAB/SHIFT+TAB to cycle through keyboard editable fields. + - CTRL+Click on a slider or drag box to input value as text. + - Use mouse wheel to scroll. + - 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. + - Controls are automatically adjusted for OSX to match standard OSX text editing operations. + - General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard. + - General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://dearimgui.org/controls_sheets + + + PROGRAMMER GUIDE + ================ + + READ FIRST + ---------- + - Remember to check the wonderful Wiki (https://github.com/ocornut/imgui/wiki) + - Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction or + destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, fewer bugs. + - Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features. + - The library is designed to be built from sources. Avoid pre-compiled binaries and packaged versions. See imconfig.h to configure your build. + - Dear ImGui is an implementation of the IMGUI paradigm (immediate-mode graphical user interface, a term coined by Casey Muratori). + You can learn about IMGUI principles at http://www.johno.se/book/imgui.html, http://mollyrocket.com/861 & more links in Wiki. + - Dear ImGui is a "single pass" rasterizing implementation of the IMGUI paradigm, aimed at ease of use and high-performances. + For every application frame, your UI code will be called only once. This is in contrast to e.g. Unity's implementation of an IMGUI, + where the UI code is called multiple times ("multiple passes") from a single entry point. There are pros and cons to both approaches. + - Our origin is on the top-left. In axis aligned bounding boxes, Min = top-left, Max = bottom-right. + - This codebase is also optimized to yield decent performances with typical "Debug" builds settings. + - Please make sure you have asserts enabled (IM_ASSERT redirects to assert() by default, but can be redirected). + If you get an assert, read the messages and comments around the assert. + - C++: this is a very C-ish codebase: we don't rely on C++11, we don't include any C++ headers, and ImGui:: is a namespace. + - C++: ImVec2/ImVec4 do not expose math operators by default, because it is expected that you use your own math types. + See FAQ "How can I use my own math types instead of ImVec2/ImVec4?" for details about setting up imconfig.h for that. + However, imgui_internal.h can optionally export math operators for ImVec2/ImVec4, which we use in this codebase. + - C++: pay attention that ImVector<> manipulates plain-old-data and does not honor construction/destruction (avoid using it in your code!). + + + HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI + ---------------------------------------------- + - Overwrite all the sources files except for imconfig.h (if you have modified your copy of imconfig.h) + - Or maintain your own branch where you have imconfig.h modified as a top-most commit which you can regularly rebase over "master". + - You can also use '#define IMGUI_USER_CONFIG "my_config_file.h" to redirect configuration to your own file. + - Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes. + If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed + from the public API. If you have a problem with a missing function/symbols, search for its name in the code, there will + likely be a comment about it. Please report any issue to the GitHub page! + - To find out usage of old API, you can add '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in your configuration file. + - Try to keep your copy of Dear ImGui reasonably up to date. + + + GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE + --------------------------------------------------------------- + - Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library. + - In the majority of cases you should be able to use unmodified backends files available in the backends/ folder. + - Add the Dear ImGui source files + selected backend source files to your projects or using your preferred build system. + It is recommended you build and statically link the .cpp files as part of your project and NOT as a shared library (DLL). + - You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types. + - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. + - Dear ImGui never touches or knows about your GPU state. The only function that knows about GPU is the draw function that you provide. + Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" + phases of your own application. All rendering information is stored into command-lists that you will retrieve after calling ImGui::Render(). + - Refer to the backends and demo applications in the examples/ folder for instruction on how to setup your code. + - If you are running over a standard OS with a common graphics API, you should be able to use unmodified imgui_impl_*** files from the examples/ folder. + + + HOW A SIMPLE APPLICATION MAY LOOK LIKE + -------------------------------------- + EXHIBIT 1: USING THE EXAMPLE BACKENDS (= imgui_impl_XXX.cpp files from the backends/ folder). + The sub-folders in examples/ contain examples applications following this structure. + + // Application init: create a dear imgui context, setup some options, load fonts + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + // TODO: Set optional io.ConfigFlags values, e.g. 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard' to enable keyboard controls. + // TODO: Fill optional fields of the io structure later. + // TODO: Load TTF/OTF fonts if you don't want to use the default font. + + // Initialize helper Platform and Renderer backends (here we are using imgui_impl_win32.cpp and imgui_impl_dx11.cpp) + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); + + // Application main loop + while (true) + { + // Feed inputs to dear imgui, start new frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // Any application code here + ImGui::Text("Hello, world!"); + + // Render dear imgui into screen + ImGui::Render(); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + g_pSwapChain->Present(1, 0); + } + + // Shutdown + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + EXHIBIT 2: IMPLEMENTING CUSTOM BACKEND / CUSTOM ENGINE + + // Application init: create a dear imgui context, setup some options, load fonts + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + // TODO: Set optional io.ConfigFlags values, e.g. 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard' to enable keyboard controls. + // TODO: Fill optional fields of the io structure later. + // TODO: Load TTF/OTF fonts if you don't want to use the default font. + + // Build and load the texture atlas into a texture + // (In the examples/ app this is usually done within the ImGui_ImplXXX_Init() function from one of the demo Renderer) + int width, height; + unsigned char* pixels = NULL; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // At this point you've got the texture data and you need to upload that to your graphic system: + // After we have created the texture, store its pointer/identifier (_in whichever format your engine uses_) in 'io.Fonts->TexID'. + // This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ for details about ImTextureID. + MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA32) + io.Fonts->SetTexID((void*)texture); + + // Application main loop + while (true) + { + // Setup low-level inputs, e.g. on Win32: calling GetKeyboardState(), or write to those fields from your Windows message handlers, etc. + // (In the examples/ app this is usually done within the ImGui_ImplXXX_NewFrame() function from one of the demo Platform Backends) + io.DeltaTime = 1.0f/60.0f; // set the time elapsed since the previous frame (in seconds) + io.DisplaySize.x = 1920.0f; // set the current display width + io.DisplaySize.y = 1280.0f; // set the current display height here + io.AddMousePosEvent(mouse_x, mouse_y); // update mouse position + io.AddMouseButtonEvent(0, mouse_b[0]); // update mouse button states + io.AddMouseButtonEvent(1, mouse_b[1]); // update mouse button states + + // Call NewFrame(), after this point you can use ImGui::* functions anytime + // (So you want to try calling NewFrame() as early as you can in your main loop to be able to use Dear ImGui everywhere) + ImGui::NewFrame(); + + // Most of your application code here + ImGui::Text("Hello, world!"); + MyGameUpdate(); // may use any Dear ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any Dear ImGui functions as well! + + // Render dear imgui, swap buffers + // (You want to try calling EndFrame/Render as late as you can, to be able to use Dear ImGui in your own game rendering code) + ImGui::EndFrame(); + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + MyImGuiRenderFunction(draw_data); + SwapBuffers(); + } + + // Shutdown + ImGui::DestroyContext(); + + To decide whether to dispatch mouse/keyboard inputs to Dear ImGui to the rest of your application, + you should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags! + Please read the FAQ and example applications for details about this! + + + HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE + --------------------------------------------- + The backends in impl_impl_XXX.cpp files contain many working implementations of a rendering function. + + void void MyImGuiRenderFunction(ImDrawData* draw_data) + { + // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize + // TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize + // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color. + ImVec2 clip_off = draw_data->DisplayPos; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // We are using scissoring to clip some objects. All low-level graphics API should support it. + // - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches + // (some elements visible outside their bounds) but you can fix that once everything else works! + // - Clipping coordinates are provided in imgui coordinates space: + // - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size + // - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values. + // - In the interest of supporting multi-viewport applications (see 'docking' branch on github), + // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space. + // - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min) + MyEngineSetScissor(clip_min.x, clip_min.y, clip_max.x, clip_max.y); + + // The texture for the draw call is specified by pcmd->GetTexID(). + // The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization. + MyEngineBindTexture((MyTexture*)pcmd->GetTexID()); + + // Render 'pcmd->ElemCount/3' indexed triangles. + // By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices. + MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset, vtx_buffer, pcmd->VtxOffset); + } + } + } + } + + + USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS + ------------------------------------------ + - The gamepad/keyboard navigation is fairly functional and keeps being improved. + - Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PS4, Switch, XB1) without a mouse! + - You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787 + - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. + - Keyboard: + - Application: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. + - Internally: NewFrame() will automatically fill io.NavInputs[] based on backend's io.AddKeyEvent() calls. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), + the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from: + - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. + - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). + - or query focus information with e.g. IsWindowFocused(ImGuiFocusedFlags_AnyWindow), IsItemFocused() etc. functions. + Please reach out if you think the game vs navigation input sharing could be improved. + - Gamepad: + - Application: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. + - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys. + For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly. + Backend code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). + - Internally: NewFrame() will automatically fill io.NavInputs[] based on backend's io.AddKeyEvent() + io.AddKeyAnalogEvent() calls. + - BEFORE 1.87, BACKENDS USED TO WRITE DIRECTLY TO io.NavInputs[]. This is going to be obsoleted in the future. Please call io functions instead! + - You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://dearimgui.org/controls_sheets + - If you need to share inputs between your game and the Dear ImGui interface, the easiest approach is to go all-or-nothing, + with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. + - Mouse: + - PS4/PS5 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. + - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (on your console/tablet/phone app) to share your PC mouse/keyboard. + - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. + Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs dear imgui to move your mouse cursor along with navigation movements. + When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. + When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. + (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, imgui will misbehave as it will see your mouse moving back and forth!) + (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want + to set a boolean to ignore your other external mouse positions until the external source is moved again.) + + + API BREAKING CHANGES + ==================== + + Occasionally introducing changes that are breaking the API. We try to make the breakage minor and easy to fix. + Below is a change-log of API breaking changes only. If you are using one of the functions listed, expect to have to fix some code. + When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. + You can read releases logs https://github.com/ocornut/imgui/releases for more details. + +(Docking/Viewport Branch) + - 2021/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that: + - reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore. + you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos) + - likewise io.MousePos and GetMousePos() will use OS coordinates. + If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. + + - 2022/01/20 (1.87) - inputs: reworded gamepad IO. + - Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values. + - 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputing text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used). + - 2022/01/17 (1.87) - inputs: reworked mouse IO. + - Backend writing to io.MousePos -> backend should call io.AddMousePosEvent() + - Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent() + - Backend writing to io.MouseWheel -> backend should call io.AddMouseWheelEvent() + - Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only] + - 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details. + - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) + - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) + - Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() + - Backend writing to io.KeyCtrl, io.KeyShift.. -> backend should call io.AddKeyEvent() with ImGuiKey_ModXXX values. *IF YOU PULLED CODE BETWEEN 2021/01/10 and 2021/01/27: We used to have a io.AddKeyModsEvent() function which was now replaced by io.AddKeyEvent() with ImGuiKey_ModXXX values.* + - one case won't work with backward compatibility: if your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A") because those values are now larger than the legacy KeyDown[] array. Will assert. + - inputs: added ImGuiKey_ModCtrl/ImGuiKey_ModShift/ImGuiKey_ModAlt/ImGuiKey_ModSuper values to submit keyboard modifiers using io.AddKeyEvent(), instead of writing directly to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper. + - 2022/01/05 (1.87) - inputs: renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. + - 2022/01/05 (1.87) - removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn(). Removed 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'. + - 2022/01/01 (1.87) - commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019) + - ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen() + - ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x + - ImGui::TreeAdvanceToLabelPos() -> use ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetTreeNodeToLabelSpacing()); + - ImFontAtlas::CustomRect -> use ImFontAtlasCustomRect + - ImGuiColorEditFlags_RGB/HSV/HEX -> use ImGuiColorEditFlags_DisplayRGB/HSV/Hex + - 2021/12/20 (1.86) - backends: removed obsolete Marmalade backend (imgui_impl_marmalade.cpp) + example. Find last supported version at https://github.com/ocornut/imgui/wiki/Bindings + - 2021/11/04 (1.86) - removed CalcListClipping() function. Prefer using ImGuiListClipper which can return non-contiguous ranges. Please open an issue if you think you really need this function. + - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead for generally 'GetContentRegionAvail().x' is more useful. + - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): + - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() + - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder + - 2021/05/19 (1.83) - backends: obsoleted direct access to ImDrawCmd::TextureId in favor of calling ImDrawCmd::GetTexID(). + - if you are using official backends from the source tree: you have nothing to do. + - if you have copied old backend code or using your own: change access to draw_cmd->TextureId to draw_cmd->GetTexID(). + - 2021/03/12 (1.82) - upgraded ImDrawList::AddRect(), AddRectFilled(), PathRect() to use ImDrawFlags instead of ImDrawCornersFlags. + - ImDrawCornerFlags_TopLeft -> use ImDrawFlags_RoundCornersTopLeft + - ImDrawCornerFlags_BotRight -> use ImDrawFlags_RoundCornersBottomRight + - ImDrawCornerFlags_None -> use ImDrawFlags_RoundCornersNone etc. + flags now sanely defaults to 0 instead of 0x0F, consistent with all other flags in the API. + breaking: the default with rounding > 0.0f is now "round all corners" vs old implicit "round no corners": + - rounding == 0.0f + flags == 0 --> meant no rounding --> unchanged (common use) + - rounding > 0.0f + flags != 0 --> meant rounding --> unchanged (common use) + - rounding == 0.0f + flags != 0 --> meant no rounding --> unchanged (unlikely use) + - rounding > 0.0f + flags == 0 --> meant no rounding --> BREAKING (unlikely use): will now round all corners --> use ImDrawFlags_RoundCornersNone or rounding == 0.0f. + this ONLY matters for hard coded use of 0 + rounding > 0.0f. Use of named ImDrawFlags_RoundCornersNone (new) or ImDrawCornerFlags_None (old) are ok. + the old ImDrawCornersFlags used awkward default values of ~0 or 0xF (4 lower bits set) to signify "round all corners" and we sometimes encouraged using them as shortcuts. + legacy path still support use of hard coded ~0 or any value from 0x1 or 0xF. They will behave the same with legacy paths enabled (will assert otherwise). + - 2021/03/11 (1.82) - removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018): + - ImGui::SetScrollHere() -> use ImGui::SetScrollHereY() + - 2021/03/11 (1.82) - clarified that ImDrawList::PathArcTo(), ImDrawList::PathArcToFast() won't render with radius < 0.0f. Previously it sorts of accidentally worked but would generally lead to counter-clockwise paths and have an effect on anti-aliasing. + - 2021/03/10 (1.82) - upgraded ImDrawList::AddPolyline() and PathStroke() "bool closed" parameter to "ImDrawFlags flags". The matching ImDrawFlags_Closed value is guaranteed to always stay == 1 in the future. + - 2021/02/22 (1.82) - (*undone in 1.84*) win32+mingw: Re-enabled IME functions by default even under MinGW. In July 2016, issue #738 had me incorrectly disable those default functions for MinGW. MinGW users should: either link with -limm32, either set their imconfig file with '#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS'. + - 2021/02/17 (1.82) - renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) to style.CircleTessellationMaxError (new default = 0.30f) as the meaning of the value changed. + - 2021/02/03 (1.81) - renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox(). Kept inline redirection function (will obsolete). + - removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size. Kept inline redirection function (will obsolete). + - renamed ListBoxFooter() to EndListBox(). Kept inline redirection function (will obsolete). + - 2021/01/26 (1.81) - removed ImGuiFreeType::BuildFontAtlas(). Kept inline redirection function. Prefer using '#define IMGUI_ENABLE_FREETYPE', but there's a runtime selection path available too. The shared extra flags parameters (very rarely used) are now stored in ImFontAtlas::FontBuilderFlags. + - renamed ImFontConfig::RasterizerFlags (used by FreeType) to ImFontConfig::FontBuilderFlags. + - renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. + - 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.63 (August 2018): + - ImGui::IsItemDeactivatedAfterChange() -> use ImGui::IsItemDeactivatedAfterEdit(). + - ImGuiCol_ModalWindowDarkening -> use ImGuiCol_ModalWindowDimBg + - ImGuiInputTextCallback -> use ImGuiTextEditCallback + - ImGuiInputTextCallbackData -> use ImGuiTextEditCallbackData + - 2020/12/21 (1.80) - renamed ImDrawList::AddBezierCurve() to AddBezierCubic(), and PathBezierCurveTo() to PathBezierCubicCurveTo(). Kept inline redirection function (will obsolete). + - 2020/12/04 (1.80) - added imgui_tables.cpp file! Manually constructed project files will need the new file added! + - 2020/11/18 (1.80) - renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* in prevision of incoming Tables API. + - 2020/11/03 (1.80) - renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply to other data structures + - 2020/10/14 (1.80) - backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/. + - 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.60 (April 2018): + - io.RenderDrawListsFn pointer -> use ImGui::GetDrawData() value and call the render function of your backend + - ImGui::IsAnyWindowFocused() -> use ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow) + - ImGui::IsAnyWindowHovered() -> use ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) + - ImGuiStyleVar_Count_ -> use ImGuiStyleVar_COUNT + - ImGuiMouseCursor_Count_ -> use ImGuiMouseCursor_COUNT + - removed redirecting functions names that were marked obsolete in 1.61 (May 2018): + - InputFloat (... int decimal_precision ...) -> use InputFloat (... const char* format ...) with format = "%.Xf" where X is your value for decimal_precision. + - same for InputFloat2()/InputFloat3()/InputFloat4() variants taking a `int decimal_precision` parameter. + - 2020/10/05 (1.79) - removed ImGuiListClipper: Renamed constructor parameters which created an ambiguous alternative to using the ImGuiListClipper::Begin() function, with misleading edge cases (note: imgui_memory_editor <0.40 from imgui_club/ used this old clipper API. Update your copy if needed). + - 2020/09/25 (1.79) - renamed ImGuiSliderFlags_ClampOnInput to ImGuiSliderFlags_AlwaysClamp. Kept redirection enum (will obsolete sooner because previous name was added recently). + - 2020/09/25 (1.79) - renamed style.TabMinWidthForUnselectedCloseButton to style.TabMinWidthForCloseButton. + - 2020/09/21 (1.79) - renamed OpenPopupContextItem() back to OpenPopupOnItemClick(), reverting the change from 1.77. For varieties of reason this is more self-explanatory. + - 2020/09/21 (1.79) - removed return value from OpenPopupOnItemClick() - returned true on mouse release on an item - because it is inconsistent with other popup APIs and makes others misleading. It's also and unnecessary: you can use IsWindowAppearing() after BeginPopup() for a similar result. + - 2020/09/17 (1.79) - removed ImFont::DisplayOffset in favor of ImFontConfig::GlyphOffset. DisplayOffset was applied after scaling and not very meaningful/useful outside of being needed by the default ProggyClean font. If you scaled this value after calling AddFontDefault(), this is now done automatically. It was also getting in the way of better font scaling, so let's get rid of it now! + - 2020/08/17 (1.78) - obsoleted use of the trailing 'float power=1.0f' parameter for DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(), DragFloatRange2(), DragScalar(), DragScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(), SliderScalar(), SliderScalarN(), VSliderFloat() and VSliderScalar(). + replaced the 'float power=1.0f' argument with integer-based flags defaulting to 0 (as with all our flags). + worked out a backward-compatibility scheme so hopefully most C++ codebase should not be affected. in short, when calling those functions: + - if you omitted the 'power' parameter (likely!), you are not affected. + - if you set the 'power' parameter to 1.0f (same as previous default value): 1/ your compiler may warn on float>int conversion, 2/ everything else will work. 3/ you can replace the 1.0f value with 0 to fix the warning, and be technically correct. + - if you set the 'power' parameter to >1.0f (to enable non-linear editing): 1/ your compiler may warn on float>int conversion, 2/ code will assert at runtime, 3/ in case asserts are disabled, the code will not crash and enable the _Logarithmic flag. 4/ you can replace the >1.0f value with ImGuiSliderFlags_Logarithmic to fix the warning/assert and get a _similar_ effect as previous uses of power >1.0f. + see https://github.com/ocornut/imgui/issues/3361 for all details. + kept inline redirection functions (will obsolete) apart for: DragFloatRange2(), VSliderFloat(), VSliderScalar(). For those three the 'float power=1.0f' version was removed directly as they were most unlikely ever used. + for shared code, you can version check at compile-time with `#if IMGUI_VERSION_NUM >= 17704`. + - obsoleted use of v_min > v_max in DragInt, DragFloat, DragScalar to lock edits (introduced in 1.73, was not demoed nor documented very), will be replaced by a more generic ReadOnly feature. You may use the ImGuiSliderFlags_ReadOnly internal flag in the meantime. + - 2020/06/23 (1.77) - removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems. + - 2020/06/15 (1.77) - renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete). [NOTE: THIS WAS REVERTED IN 1.79] + - 2020/06/15 (1.77) - removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017. + - 2020/04/23 (1.77) - removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular(). + - 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more. + - 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead. + - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. + - 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017): + - ShowTestWindow() -> use ShowDemoWindow() + - IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow) + - IsRootWindowOrAnyChildFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) + - SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f) + - GetItemsLineHeightWithSpacing() -> use GetFrameHeightWithSpacing() + - ImGuiCol_ChildWindowBg -> use ImGuiCol_ChildBg + - ImGuiStyleVar_ChildWindowRounding -> use ImGuiStyleVar_ChildRounding + - ImGuiTreeNodeFlags_AllowOverlapMode -> use ImGuiTreeNodeFlags_AllowItemOverlap + - IMGUI_DISABLE_TEST_WINDOWS -> use IMGUI_DISABLE_DEMO_WINDOWS + - 2019/12/08 (1.75) - obsoleted calling ImDrawList::PrimReserve() with a negative count (which was vaguely documented and rarely if ever used). Instead, we added an explicit PrimUnreserve() API. + - 2019/12/06 (1.75) - removed implicit default parameter to IsMouseDragging(int button = 0) to be consistent with other mouse functions (none of the other functions have it). + - 2019/11/21 (1.74) - ImFontAtlas::AddCustomRectRegular() now requires an ID larger than 0x110000 (instead of 0x10000) to conform with supporting Unicode planes 1-16 in a future update. ID below 0x110000 will now assert. + - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS to IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS for consistency. + - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_MATH_FUNCTIONS to IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS for consistency. + - 2019/10/22 (1.74) - removed redirecting functions/enums that were marked obsolete in 1.52 (October 2017): + - Begin() [old 5 args version] -> use Begin() [3 args], use SetNextWindowSize() SetNextWindowBgAlpha() if needed + - IsRootWindowOrAnyChildHovered() -> use IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows) + - AlignFirstTextHeightToWidgets() -> use AlignTextToFramePadding() + - SetNextWindowPosCenter() -> use SetNextWindowPos() with a pivot of (0.5f, 0.5f) + - ImFont::Glyph -> use ImFontGlyph + - 2019/10/14 (1.74) - inputs: Fixed a miscalculation in the keyboard/mouse "typematic" repeat delay/rate calculation, used by keys and e.g. repeating mouse buttons as well as the GetKeyPressedAmount() function. + if you were using a non-default value for io.KeyRepeatRate (previous default was 0.250), you can add +io.KeyRepeatDelay to it to compensate for the fix. + The function was triggering on: 0.0 and (delay+rate*N) where (N>=1). Fixed formula responds to (N>=0). Effectively it made io.KeyRepeatRate behave like it was set to (io.KeyRepeatRate + io.KeyRepeatDelay). + If you never altered io.KeyRepeatRate nor used GetKeyPressedAmount() this won't affect you. + - 2019/07/15 (1.72) - removed TreeAdvanceToLabelPos() which is rarely used and only does SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()). Kept redirection function (will obsolete). + - 2019/07/12 (1.72) - renamed ImFontAtlas::CustomRect to ImFontAtlasCustomRect. Kept redirection typedef (will obsolete). + - 2019/06/14 (1.72) - removed redirecting functions/enums names that were marked obsolete in 1.51 (June 2017): ImGuiCol_Column*, ImGuiSetCond_*, IsItemHoveredRect(), IsPosHoveringAnyWindow(), IsMouseHoveringAnyWindow(), IsMouseHoveringWindow(), IMGUI_ONCE_UPON_A_FRAME. Grep this log for details and new names, or see how they were implemented until 1.71. + - 2019/06/07 (1.71) - rendering of child window outer decorations (bg color, border, scrollbars) is now performed as part of the parent window. If you have + overlapping child windows in a same parent, and relied on their relative z-order to be mapped to their submission order, this will affect your rendering. + This optimization is disabled if the parent window has no visual output, because it appears to be the most common situation leading to the creation of overlapping child windows. + Please reach out if you are affected. + - 2019/05/13 (1.71) - renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). + - 2019/05/11 (1.71) - changed io.AddInputCharacter(unsigned short c) signature to io.AddInputCharacter(unsigned int c). + - 2019/04/29 (1.70) - improved ImDrawList thick strokes (>1.0f) preserving correct thickness up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines, they will appear thicker now. + - 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete). + - 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete). + - 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete). + - 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with an arbitrarily small value! + - 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). + - 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead! + - 2019/01/06 (1.67) - renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete). + - 2018/12/20 (1.67) - made it illegal to call Begin("") with an empty string. This somehow half-worked before but had various undesirable side-effects. + - 2018/12/10 (1.67) - renamed io.ConfigResizeWindowsFromEdges to io.ConfigWindowsResizeFromEdges as we are doing a large pass on configuration flags. + - 2018/10/12 (1.66) - renamed misc/stl/imgui_stl.* to misc/cpp/imgui_stdlib.* in prevision for other C++ helper files. + - 2018/09/28 (1.66) - renamed SetScrollHere() to SetScrollHereY(). Kept redirection function (will obsolete). + - 2018/09/06 (1.65) - renamed stb_truetype.h to imstb_truetype.h, stb_textedit.h to imstb_textedit.h, and stb_rect_pack.h to imstb_rectpack.h. + If you were conveniently using the imgui copy of those STB headers in your project you will have to update your include paths. + - 2018/09/05 (1.65) - renamed io.OptCursorBlink/io.ConfigCursorBlink to io.ConfigInputTextCursorBlink. (#1427) + - 2018/08/31 (1.64) - added imgui_widgets.cpp file, extracted and moved widgets code out of imgui.cpp into imgui_widgets.cpp. Re-ordered some of the code remaining in imgui.cpp. + NONE OF THE FUNCTIONS HAVE CHANGED. THE CODE IS SEMANTICALLY 100% IDENTICAL, BUT _EVERY_ FUNCTION HAS BEEN MOVED. + Because of this, any local modifications to imgui.cpp will likely conflict when you update. Read docs/CHANGELOG.txt for suggestions. + - 2018/08/22 (1.63) - renamed IsItemDeactivatedAfterChange() to IsItemDeactivatedAfterEdit() for consistency with new IsItemEdited() API. Kept redirection function (will obsolete soonish as IsItemDeactivatedAfterChange() is very recent). + - 2018/08/21 (1.63) - renamed ImGuiTextEditCallback to ImGuiInputTextCallback, ImGuiTextEditCallbackData to ImGuiInputTextCallbackData for consistency. Kept redirection types (will obsolete). + - 2018/08/21 (1.63) - removed ImGuiInputTextCallbackData::ReadOnly since it is a duplication of (ImGuiInputTextCallbackData::Flags & ImGuiInputTextFlags_ReadOnly). + - 2018/08/01 (1.63) - removed per-window ImGuiWindowFlags_ResizeFromAnySide beta flag in favor of a global io.ConfigResizeWindowsFromEdges [update 1.67 renamed to ConfigWindowsResizeFromEdges] to enable the feature. + - 2018/08/01 (1.63) - renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to ConfigMacOSXBehaviors for consistency. + - 2018/07/22 (1.63) - changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecisions over time. + - 2018/07/08 (1.63) - style: renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete). + - 2018/06/08 (1.62) - examples: the imgui_impl_XXX files have been split to separate platform (Win32, GLFW, SDL2, etc.) from renderer (DX11, OpenGL, Vulkan, etc.). + old backends will still work as is, however prefer using the separated backends as they will be updated to support multi-viewports. + when adopting new backends follow the main.cpp code of your preferred examples/ folder to know which functions to call. + in particular, note that old backends called ImGui::NewFrame() at the end of their ImGui_ImplXXXX_NewFrame() function. + - 2018/06/06 (1.62) - renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish other variants and discourage using the full set. + - 2018/06/06 (1.62) - TreeNodeEx()/TreeNodeBehavior(): the ImGuiTreeNodeFlags_CollapsingHeader helper now include the ImGuiTreeNodeFlags_NoTreePushOnOpen flag. See Changelog for details. + - 2018/05/03 (1.61) - DragInt(): the default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more. + If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format. + To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d, giving time to users to upgrade their code. + If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your codebase for e.g. "DragInt.*%f" to help you find them. + - 2018/04/28 (1.61) - obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more flexible "const char* format", + consistent with other functions. Kept redirection functions (will obsolete). + - 2018/04/09 (1.61) - IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value. + - 2018/03/20 (1.60) - renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some backend ahead of merging the Nav branch). + - 2018/03/12 (1.60) - removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now. + - 2018/03/08 (1.60) - changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. + - 2018/03/03 (1.60) - renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. + - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. + - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. + - 2018/02/07 (1.60) - reorganized context handling to be more explicit, + - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. + - removed Shutdown() function, as DestroyContext() serve this purpose. + - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance. + - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. + - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. + - 2018/01/31 (1.60) - moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. + - 2018/01/11 (1.60) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). + - 2018/01/11 (1.60) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). + - 2018/01/03 (1.60) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. + - 2017/12/29 (1.60) - removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. + - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). + - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags + - 2017/12/21 (1.53) - ImDrawList: removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. + - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. + - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). + - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). + - obsoleted IsRootWindowOrAnyChildFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete). + - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete). + - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). + - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. + - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. + - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. + - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. + - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. + - 2017/11/02 (1.53) - obsoleted IsRootWindowOrAnyChildHovered() in favor of using IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); + - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. + - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. + - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. + removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting. + IsItemHoveredRect() --> IsItemHovered(ImGuiHoveredFlags_RectOnly) + IsMouseHoveringAnyWindow() --> IsWindowHovered(ImGuiHoveredFlags_AnyWindow) + IsMouseHoveringWindow() --> IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) [weird, old behavior] + - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! + - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). + - 2017/09/26 (1.52) - renamed ImFont::Glyph to ImFontGlyph. Kept redirection typedef (will obsolete). + - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). + - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your backend if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". + - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). -> (1.52) use IsItemHovered(ImGuiHoveredFlags_RectOnly)! + - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). + - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete). + - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. + - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. + - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame type. + - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely. + - 2017/08/13 (1.51) - renamed ImGuiCol_Column to ImGuiCol_Separator, ImGuiCol_ColumnHovered to ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive to ImGuiCol_SeparatorActive. Kept redirection enums (will obsolete). + - 2017/08/11 (1.51) - renamed ImGuiSetCond_Always to ImGuiCond_Always, ImGuiSetCond_Once to ImGuiCond_Once, ImGuiSetCond_FirstUseEver to ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing to ImGuiCond_Appearing. Kept redirection enums (will obsolete). + - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). + - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. + - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. + - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0))' + - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse + - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. + - 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. + - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetID() and use it instead of passing string to BeginChild(). + - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it. + - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. + - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully, breakage should be minimal. + - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. + If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you, otherwise if <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. + This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color: + ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) { float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a; return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); } + If this is confusing, pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color. + - 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext(). + - 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection. + - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen). + - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDrawList::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer. + - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref GitHub issue #337). + - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337) + - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). + - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. + - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. + - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. + - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. + - 2015/08/29 (1.45) - with the addition of horizontal scrollbar we made various fixes to inconsistencies with dealing with cursor position. + GetCursorPos()/SetCursorPos() functions now include the scrolled amount. It shouldn't affect the majority of users, but take note that SetCursorPosX(100.0f) puts you at +100 from the starting x position which may include scrolling, not at +100 from the window left side. + GetContentRegionMax()/GetWindowContentRegionMin()/GetWindowContentRegionMax() functions allow include the scrolled amount. Typically those were used in cases where no scrolling would happen so it may not be a problem, but watch out! + - 2015/08/29 (1.45) - renamed style.ScrollbarWidth to style.ScrollbarSize + - 2015/08/05 (1.44) - split imgui.cpp into extra files: imgui_demo.cpp imgui_draw.cpp imgui_internal.h that you need to add to your project. + - 2015/07/18 (1.44) - fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (introduced in 1.43) being off by an extra PI for no justifiable reason + - 2015/07/14 (1.43) - add new ImFontAtlas::AddFont() API. For the old AddFont***, moved the 'font_no' parameter of ImFontAtlas::AddFont** functions to the ImFontConfig structure. + you need to render your textured triangles with bilinear filtering to benefit from sub-pixel positioning of text. + - 2015/07/08 (1.43) - switched rendering data to use indexed rendering. this is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost. + this necessary change will break your rendering function! the fix should be very easy. sorry for that :( + - if you are using a vanilla copy of one of the imgui_impl_XXX.cpp provided in the example, you just need to update your copy and you can ignore the rest. + - the signature of the io.RenderDrawListsFn handler has changed! + old: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) + new: ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data). + parameters: 'cmd_lists' becomes 'draw_data->CmdLists', 'cmd_lists_count' becomes 'draw_data->CmdListsCount' + ImDrawList: 'commands' becomes 'CmdBuffer', 'vtx_buffer' becomes 'VtxBuffer', 'IdxBuffer' is new. + ImDrawCmd: 'vtx_count' becomes 'ElemCount', 'clip_rect' becomes 'ClipRect', 'user_callback' becomes 'UserCallback', 'texture_id' becomes 'TextureId'. + - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer. + - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! + - refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. please upgrade! + - 2015/07/10 (1.43) - changed SameLine() parameters from int to float. + - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete). + - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount. + - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence + - 2015/06/14 (1.41) - changed Selectable() API from (label, selected, size) to (label, selected, flags, size). Size override should have been rarely used. Sorry! + - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). + - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). + - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. + - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened. + - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). + - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function until 1.50. + - 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 GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function until 1.50. + - 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 until 1.50. + - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth (casing) + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function until 1.50. + - 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. + - 2015/01/11 (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels. + - old: const void* png_data; unsigned int png_size; ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); [..Upload texture to GPU..]; + - new: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); [..Upload texture to GPU..]; io.Fonts->SetTexID(YourTexIdentifier); + you now have more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. It is now recommended that you sample the font texture with bilinear interpolation. + - 2015/01/11 (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to call io.Fonts->SetTexID() + - 2015/01/11 (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) + - 2015/01/11 (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) + ================================ + + Read all answers online: + https://www.dearimgui.org/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url) + Read all answers locally (with a text editor or ideally a Markdown viewer): + docs/FAQ.md + Some answers are copied down here to facilitate searching in code. + + Q&A: Basics + =========== + + Q: Where is the documentation? + A: This library is poorly documented at the moment and expects the user to be acquainted with C/C++. + - Run the examples/ and explore them. + - See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function. + - The demo covers most features of Dear ImGui, so you can read the code and see its output. + - See documentation and comments at the top of imgui.cpp + effectively imgui.h. + - Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the + examples/ folder to explain how to integrate Dear ImGui with your own engine/application. + - The Wiki (https://github.com/ocornut/imgui/wiki) has many resources and links. + - The Glossary (https://github.com/ocornut/imgui/wiki/Glossary) page also may be useful. + - Your programming IDE is your friend, find the type or function declaration to find comments + associated with it. + + Q: What is this library called? + Q: Which version should I get? + >> This library is called "Dear ImGui", please don't call it "ImGui" :) + >> See https://www.dearimgui.org/faq for details. + + Q&A: Integration + ================ + + Q: How to get started? + A: Read 'PROGRAMMER GUIDE' above. Read examples/README.txt. + + Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application? + A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags! + >> See https://www.dearimgui.org/faq for a fully detailed answer. You really want to read this. + + Q. How can I enable keyboard controls? + Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display) + Q: I integrated Dear ImGui in my engine and little squares are showing instead of text... + Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around... + Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries... + >> See https://www.dearimgui.org/faq + + Q&A: Usage + ---------- + + Q: About the ID Stack system.. + - Why is my widget not reacting when I click on it? + - How can I have widgets with an empty label? + - How can I have multiple widgets with the same label? + - How can I have multiple windows with the same label? + Q: How can I display an image? What is ImTextureID, how does it works? + Q: How can I use my own math types instead of ImVec2/ImVec4? + Q: How can I interact with standard C++ types (such as std::string and std::vector)? + Q: How can I display custom shapes? (using low-level ImDrawList API) + >> See https://www.dearimgui.org/faq + + Q&A: Fonts, Text + ================ + + Q: How should I handle DPI in my application? + Q: How can I load a different font than the default? + Q: How can I easily use icons in my application? + Q: How can I load multiple fonts? + Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? + >> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md + + Q&A: Concerns + ============= + + Q: Who uses Dear ImGui? + Q: Can you create elaborate/serious tools with Dear ImGui? + Q: Can you reskin the look of Dear ImGui? + Q: Why using C++ (as opposed to C)? + >> See https://www.dearimgui.org/faq + + Q&A: Community + ============== + + Q: How can I help? + A: - Businesses: please reach out to "contact AT dearimgui.com" if you work in a place using Dear ImGui! + We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. + This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people working on this project. + - Individuals: you can support continued development via PayPal donations. See README. + - If you are experienced with Dear ImGui and C++, look at the GitHub issues, look at the Wiki, read docs/TODO.txt + and see how you want to help and can help! + - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. + You may post screenshot or links in the gallery threads. Visuals are ideal as they inspire other programmers. + But even without visuals, disclosing your use of dear imgui helps the library grow credibility, and help other teams and programmers with taking decisions. + - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on GitHub or privately). + +*/ + +//------------------------------------------------------------------------- +// [SECTION] INCLUDES +//------------------------------------------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui_internal.h" + +// System includes +#include // toupper +#include // vsnprintf, sscanf, printf +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// [Windows] On non-Visual Studio compilers, we default to IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS unless explicitly enabled +#if defined(_WIN32) && !defined(_MSC_VER) && !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) +#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS +#endif + +// [Windows] OS specific includes (optional) +#if defined(_WIN32) && defined(IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#define IMGUI_DISABLE_WIN32_FUNCTIONS +#endif +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#ifndef __MINGW32__ +#include // _wfopen, OpenClipboard +#else +#include +#endif +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) // UWP doesn't have all Win32 functions +#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS +#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS +#endif +#endif + +// [Apple] OS specific includes +#if defined(__APPLE__) +#include +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later +#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types +#endif +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6). +#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#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 (typically 0.0f) is 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 is. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wformat-pedantic" // warning: format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int' +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +// We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association. +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +// Debug options +#define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Display last moving direction matches when holding CTRL +#define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window +#define IMGUI_DEBUG_INI_SETTINGS 0 // Save additional comments in .ini file (particularly helps for Docking, but makes saving slower) + +// When using CTRL+TAB (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch. +static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in +static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear + +// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend) +static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow(). +static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time. +static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved. + +// Docking +static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f; // For use with io.ConfigDockingTransparentPayload. Apply to Viewport _or_ WindowBg in host viewport. +static const float DOCKING_SPLITTER_SIZE = 2.0f; + +//------------------------------------------------------------------------- +// [SECTION] FORWARD DECLARATIONS +//------------------------------------------------------------------------- + +static void SetCurrentWindow(ImGuiWindow* window); +static void FindHoveredWindow(); +static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags); +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); + +static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list); +static void AddWindowToSortBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); + +// Settings +static void WindowSettingsHandler_ClearAll(ImGuiContext*, ImGuiSettingsHandler*); +static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name); +static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line); +static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*); +static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf); + +// Platform Dependents default implementation for IO functions +static const char* GetClipboardTextFn_DefaultImpl(void* user_data); +static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text); +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data); + +namespace ImGui +{ +// Navigation +static void NavUpdate(); +static void NavUpdateWindowing(); +static void NavUpdateWindowingOverlay(); +static void NavUpdateCancelRequest(); +static void NavUpdateCreateMoveRequest(); +static void NavUpdateCreateTabbingRequest(); +static float NavUpdatePageUpPageDown(); +static inline void NavUpdateAnyRequestFlag(); +static void NavUpdateCreateWrappingRequest(); +static void NavEndFrame(); +static bool NavScoreItem(ImGuiNavItemData* result); +static void NavApplyItemToResult(ImGuiNavItemData* result); +static void NavProcessItem(); +static void NavProcessItemForTabbingRequest(ImGuiID id); +static ImVec2 NavCalcPreferredRefPos(); +static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); +static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); +static void NavRestoreLayer(ImGuiNavLayer layer); +static void NavRestoreHighlightAfterMove(); +static int FindWindowFocusIndex(ImGuiWindow* window); + +// Error Checking and Debug Tools +static void ErrorCheckNewFrameSanityChecks(); +static void ErrorCheckEndFrameSanityChecks(); +static void UpdateDebugToolItemPicker(); +static void UpdateDebugToolStackQueries(); + +// Misc +static void UpdateSettings(); +static void UpdateKeyboardInputs(); +static void UpdateMouseInputs(); +static void UpdateMouseWheel(); +static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect); +static void RenderWindowOuterBorders(ImGuiWindow* window); +static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); +static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); +static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col); +static void RenderDimmedBackgrounds(); +static ImGuiWindow* FindBlockingModal(ImGuiWindow* window); + +// Viewports +const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter. +static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& platform_pos, const ImVec2& size, ImGuiViewportFlags flags); +static void DestroyViewport(ImGuiViewportP* viewport); +static void UpdateViewportsNewFrame(); +static void UpdateViewportsEndFrame(); +static void WindowSelectViewport(ImGuiWindow* window); +static void WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack); +static bool UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport); +static bool UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window); +static bool GetWindowAlwaysWantOwnViewport(ImGuiWindow* window); +static int FindPlatformMonitorForPos(const ImVec2& pos); +static int FindPlatformMonitorForRect(const ImRect& r); +static void UpdateViewportPlatformMonitor(ImGuiViewportP* viewport); + +} + +//----------------------------------------------------------------------------- +// [SECTION] CONTEXT AND MEMORY ALLOCATORS +//----------------------------------------------------------------------------- + +// DLL users: +// - Heaps and globals are not shared across DLL boundaries! +// - You will need to call SetCurrentContext() + SetAllocatorFunctions() for each static/DLL boundary you are calling from. +// - Same applies for hot-reloading mechanisms that are reliant on reloading DLL (note that many hot-reloading mechanisms work without DLL). +// - Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. +// - Confused? In a debugger: add GImGui to your watch window and notice how its value changes depending on your current location (which DLL boundary you are in). + +// Current context pointer. Implicitly used by all Dear ImGui functions. Always assumed to be != NULL. +// - ImGui::CreateContext() will automatically set this pointer if it is NULL. +// Change to a different context by calling ImGui::SetCurrentContext(). +// - Important: Dear ImGui functions are not thread-safe because of this pointer. +// If you want thread-safety to allow N threads to access N different contexts: +// - Change this variable to use thread local storage so each thread can refer to a different context, in your imconfig.h: +// struct ImGuiContext; +// extern thread_local ImGuiContext* MyImGuiTLS; +// #define GImGui MyImGuiTLS +// And then define MyImGuiTLS in one of your cpp files. Note that thread_local is a C++11 keyword, earlier C++ uses compiler-specific keyword. +// - Future development aims to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 +// - If you need a finite number of contexts, you may compile and use multiple instances of the ImGui code from a different namespace. +// - DLL users: read comments above. +#ifndef GImGui +ImGuiContext* GImGui = NULL; +#endif + +// Memory Allocator functions. Use SetAllocatorFunctions() to change them. +// - You probably don't want to modify that mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction. +// - DLL users: read comments above. +#ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS +static void* MallocWrapper(size_t size, void* user_data) { IM_UNUSED(user_data); return malloc(size); } +static void FreeWrapper(void* ptr, void* user_data) { IM_UNUSED(user_data); free(ptr); } +#else +static void* MallocWrapper(size_t size, void* user_data) { IM_UNUSED(user_data); IM_UNUSED(size); IM_ASSERT(0); return NULL; } +static void FreeWrapper(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_UNUSED(ptr); IM_ASSERT(0); } +#endif +static ImGuiMemAllocFunc GImAllocatorAllocFunc = MallocWrapper; +static ImGuiMemFreeFunc GImAllocatorFreeFunc = FreeWrapper; +static void* GImAllocatorUserData = NULL; + +//----------------------------------------------------------------------------- +// [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO) +//----------------------------------------------------------------------------- + +ImGuiStyle::ImGuiStyle() +{ + Alpha = 1.0f; // Global alpha applies to everything in Dear ImGui. + DisabledAlpha = 0.60f; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha. + WindowPadding = ImVec2(8,8); // Padding within a window + WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended. + WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. + WindowMinSize = ImVec2(32,32); // Minimum window size + WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text + WindowMenuButtonPosition= ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left. + ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. + PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. + 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). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. + 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) + CellPadding = ImVec2(4,2); // Padding within a table cell + 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! + IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). + ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar + ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar + GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar + GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. + TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. + TabBorderSize = 0.0f; // Thickness of border around tabs. + TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. + ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. + SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. + DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. + AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. + AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). + CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + + // Default theme + ImGui::StyleColorsDark(this); +} + +// To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you. +// Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times. +void ImGuiStyle::ScaleAllSizes(float scale_factor) +{ + WindowPadding = ImFloor(WindowPadding * scale_factor); + WindowRounding = ImFloor(WindowRounding * scale_factor); + WindowMinSize = ImFloor(WindowMinSize * scale_factor); + ChildRounding = ImFloor(ChildRounding * scale_factor); + PopupRounding = ImFloor(PopupRounding * scale_factor); + FramePadding = ImFloor(FramePadding * scale_factor); + FrameRounding = ImFloor(FrameRounding * scale_factor); + ItemSpacing = ImFloor(ItemSpacing * scale_factor); + ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); + CellPadding = ImFloor(CellPadding * scale_factor); + TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); + IndentSpacing = ImFloor(IndentSpacing * scale_factor); + ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor); + ScrollbarSize = ImFloor(ScrollbarSize * scale_factor); + ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor); + GrabMinSize = ImFloor(GrabMinSize * scale_factor); + GrabRounding = ImFloor(GrabRounding * scale_factor); + LogSliderDeadzone = ImFloor(LogSliderDeadzone * scale_factor); + TabRounding = ImFloor(TabRounding * scale_factor); + TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImFloor(TabMinWidthForCloseButton * scale_factor) : FLT_MAX; + DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); + DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); + MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); +} + +ImGuiIO::ImGuiIO() +{ + // Most fields are initialized with zero + memset(this, 0, sizeof(*this)); + IM_STATIC_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT); + + // Settings + ConfigFlags = ImGuiConfigFlags_None; + BackendFlags = ImGuiBackendFlags_None; + DisplaySize = ImVec2(-1.0f, -1.0f); + DeltaTime = 1.0f / 60.0f; + IniSavingRate = 5.0f; + IniFilename = "imgui.ini"; // Important: "imgui.ini" is relative to current working dir, most apps will want to lock this to an absolute path (e.g. same path as executables). + LogFilename = "imgui_log.txt"; + MouseDoubleClickTime = 0.30f; + MouseDoubleClickMaxDist = 6.0f; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + for (int i = 0; i < ImGuiKey_COUNT; i++) + KeyMap[i] = -1; +#endif + KeyRepeatDelay = 0.275f; + KeyRepeatRate = 0.050f; + UserData = NULL; + + Fonts = NULL; + FontGlobalScale = 1.0f; + FontDefault = NULL; + FontAllowUserScaling = false; + DisplayFramebufferScale = ImVec2(1.0f, 1.0f); + + // Docking options (when ImGuiConfigFlags_DockingEnable is set) + ConfigDockingNoSplit = false; + ConfigDockingWithShift = false; + ConfigDockingAlwaysTabBar = false; + ConfigDockingTransparentPayload = false; + + // Viewport options (when ImGuiConfigFlags_ViewportsEnable is set) + ConfigViewportsNoAutoMerge = false; + ConfigViewportsNoTaskBarIcon = false; + ConfigViewportsNoDecoration = true; + ConfigViewportsNoDefaultParent = false; + + // Miscellaneous options + MouseDrawCursor = false; +#ifdef __APPLE__ + ConfigMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag +#else + ConfigMacOSXBehaviors = false; +#endif + ConfigInputTrickleEventQueue = true; + ConfigInputTextCursorBlink = true; + ConfigWindowsResizeFromEdges = true; + ConfigWindowsMoveFromTitleBarOnly = false; + ConfigMemoryCompactTimer = 60.0f; + + // Platform Functions + BackendPlatformName = BackendRendererName = NULL; + BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL; + GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations + SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; + ClipboardUserData = NULL; + SetPlatformImeDataFn = SetPlatformImeDataFn_DefaultImpl; + + // Input (NB: we already have memset zero the entire structure!) + MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); + MouseDragThreshold = 6.0f; + for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; } + for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f; + BackendUsingLegacyKeyArrays = (ImS8)-1; + BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong +} + +// 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 +// FIXME: Should in theory be called "AddCharacterEvent()" to be consistent with new API +void ImGuiIO::AddInputCharacter(unsigned int c) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + if (c == 0) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Char; + e.Source = ImGuiInputSource_Keyboard; + e.Text.Char = c; + g.InputEventsQueue.push_back(e); +} + +// UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so +// we should save the high surrogate. +void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) +{ + if (c == 0 && InputQueueSurrogate == 0) + return; + + if ((c & 0xFC00) == 0xD800) // High surrogate, must save + { + if (InputQueueSurrogate != 0) + AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID); + InputQueueSurrogate = c; + return; + } + + ImWchar cp = c; + if (InputQueueSurrogate != 0) + { + if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate + { + AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID); + } + else + { +#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF + cp = IM_UNICODE_CODEPOINT_INVALID; // Codepoint will not fit in ImWchar +#else + cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000); +#endif + } + + InputQueueSurrogate = 0; + } + AddInputCharacter((unsigned)cp); +} + +void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) +{ + while (*utf8_chars != 0) + { + unsigned int c = 0; + utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL); + if (c != 0) + AddInputCharacter(c); + } +} + +void ImGuiIO::ClearInputCharacters() +{ + InputQueueCharacters.resize(0); +} + +void ImGuiIO::ClearInputKeys() +{ +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + memset(KeysDown, 0, sizeof(KeysDown)); +#endif + for (int n = 0; n < IM_ARRAYSIZE(KeysData); n++) + { + KeysData[n].Down = false; + KeysData[n].DownDuration = -1.0f; + KeysData[n].DownDurationPrev = -1.0f; + } + KeyCtrl = KeyShift = KeyAlt = KeySuper = false; + KeyMods = KeyModsPrev = ImGuiKeyModFlags_None; + for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++) + NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f; +} + +// Queue a new key down/up event. +// - ImGuiKey key: Translated key (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) +// - bool down: Is the key down? use false to signify a key release. +// - float analog_value: 0.0f..1.0f +void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value) +{ + //if (e->Down) { IMGUI_DEBUG_LOG("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); } + if (key == ImGuiKey_None) + return; + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + IM_ASSERT(ImGui::IsNamedKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API. + + // Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data. +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT((BackendUsingLegacyKeyArrays == -1 || BackendUsingLegacyKeyArrays == 0) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + if (BackendUsingLegacyKeyArrays == -1) + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++) + IM_ASSERT(KeyMap[n] == -1 && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + BackendUsingLegacyKeyArrays = 0; +#endif + if (ImGui::IsGamepadKey(key)) + BackendUsingLegacyNavInputArray = false; + + // Partial filter of duplicates (not strictly needed, but makes data neater in particular for key mods and gamepad values which are most commonly spmamed) + ImGuiKeyData* key_data = ImGui::GetKeyData(key); + if (key_data->Down == down && key_data->AnalogValue == analog_value) + { + bool found = false; + for (int n = g.InputEventsQueue.Size - 1; n >= 0 && !found; n--) + if (g.InputEventsQueue[n].Type == ImGuiInputEventType_Key && g.InputEventsQueue[n].Key.Key == key) + found = true; + if (!found) + return; + } + + // Add event + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Key; + e.Source = ImGui::IsGamepadKey(key) ? ImGuiInputSource_Gamepad : ImGuiInputSource_Keyboard; + e.Key.Key = key; + e.Key.Down = down; + e.Key.AnalogValue = analog_value; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down) +{ + AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f); +} + +// [Optional] Call after AddKeyEvent(). +// Specify native keycode, scancode + Specify index for legacy <1.87 IsKeyXXX() functions with native indices. +// If you are writing a backend in 2022 or don't use IsKeyXXX() with native values that are not ImGuiKey values, you can avoid calling this. +void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index) +{ + if (key == ImGuiKey_None) + return; + IM_ASSERT(ImGui::IsNamedKey(key)); // >= 512 + IM_ASSERT(native_legacy_index == -1 || ImGui::IsLegacyKey(native_legacy_index)); // >= 0 && <= 511 + IM_UNUSED(native_keycode); // Yet unused + IM_UNUSED(native_scancode); // Yet unused + + // Build native->imgui map so old user code can still call key functions with native 0..511 values. +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode; + if (ImGui::IsLegacyKey(legacy_key)) + KeyMap[legacy_key] = key; +#else + IM_UNUSED(key); + IM_UNUSED(native_legacy_index); +#endif +} + +// Queue a mouse move event +void ImGuiIO::AddMousePosEvent(float x, float y) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MousePos; + e.Source = ImGuiInputSource_Mouse; + e.MousePos.PosX = x; + e.MousePos.PosY = y; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT); + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MouseButton; + e.Source = ImGuiInputSource_Mouse; + e.MouseButton.Button = mouse_button; + e.MouseButton.Down = down; + g.InputEventsQueue.push_back(e); +} + +// Queue a mouse wheel event (most mouse/API will only have a Y component) +void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + if (wheel_x == 0.0f && wheel_y == 0.0f) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MouseWheel; + e.Source = ImGuiInputSource_Mouse; + e.MouseWheel.WheelX = wheel_x; + e.MouseWheel.WheelY = wheel_y; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddMouseViewportEvent(ImGuiID viewport_id) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + IM_ASSERT(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport); + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MouseViewport; + e.Source = ImGuiInputSource_Mouse; + e.MouseViewport.HoveredViewportID = viewport_id; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddFocusEvent(bool focused) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Focus; + e.AppFocused.Focused = focused; + g.InputEventsQueue.push_back(e); +} + +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (Geometry functions) +//----------------------------------------------------------------------------- + +ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments) +{ + IM_ASSERT(num_segments > 0); // Use ImBezierCubicClosestPointCasteljau() + ImVec2 p_last = p1; + ImVec2 p_closest; + float p_closest_dist2 = FLT_MAX; + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + { + ImVec2 p_current = ImBezierCubicCalc(p1, p2, p3, p4, t_step * i_step); + ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p); + float dist2 = ImLengthSqr(p - p_line); + if (dist2 < p_closest_dist2) + { + p_closest = p_line; + p_closest_dist2 = dist2; + } + p_last = p_current; + } + return p_closest; +} + +// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp +static void ImBezierCubicClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) +{ + float dx = x4 - x1; + float dy = y4 - y1; + float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); + float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); + d2 = (d2 >= 0) ? d2 : -d2; + d3 = (d3 >= 0) ? d3 : -d3; + if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) + { + ImVec2 p_current(x4, y4); + ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p); + float dist2 = ImLengthSqr(p - p_line); + if (dist2 < p_closest_dist2) + { + p_closest = p_line; + p_closest_dist2 = dist2; + } + p_last = p_current; + } + else if (level < 10) + { + float x12 = (x1 + x2)*0.5f, y12 = (y1 + y2)*0.5f; + float x23 = (x2 + x3)*0.5f, y23 = (y2 + y3)*0.5f; + float x34 = (x3 + x4)*0.5f, y34 = (y3 + y4)*0.5f; + float x123 = (x12 + x23)*0.5f, y123 = (y12 + y23)*0.5f; + float x234 = (x23 + x34)*0.5f, y234 = (y23 + y34)*0.5f; + float x1234 = (x123 + x234)*0.5f, y1234 = (y123 + y234)*0.5f; + ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); + ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + } +} + +// tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol +// Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically. +ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol) +{ + IM_ASSERT(tess_tol > 0.0f); + ImVec2 p_last = p1; + ImVec2 p_closest; + float p_closest_dist2 = FLT_MAX; + ImBezierCubicClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); + return p_closest; +} + +ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) +{ + ImVec2 ap = p - a; + ImVec2 ab_dir = b - a; + float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; + if (dot < 0.0f) + return a; + float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; + if (dot > ab_len_sqr) + return b; + return a + ab_dir * dot / ab_len_sqr; +} + +bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) +{ + bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; + bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; + bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f; + return ((b1 == b2) && (b2 == b3)); +} + +void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w) +{ + ImVec2 v0 = b - a; + ImVec2 v1 = c - a; + ImVec2 v2 = p - a; + const float denom = v0.x * v1.y - v1.x * v0.y; + out_v = (v2.x * v1.y - v1.x * v2.y) / denom; + out_w = (v0.x * v2.y - v2.x * v0.y) / denom; + out_u = 1.0f - out_v - out_w; +} + +ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) +{ + ImVec2 proj_ab = ImLineClosestPoint(a, b, p); + ImVec2 proj_bc = ImLineClosestPoint(b, c, p); + ImVec2 proj_ca = ImLineClosestPoint(c, a, p); + float dist2_ab = ImLengthSqr(p - proj_ab); + float dist2_bc = ImLengthSqr(p - proj_bc); + float dist2_ca = ImLengthSqr(p - proj_ca); + float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca)); + if (m == dist2_ab) + return proj_ab; + if (m == dist2_bc) + return proj_bc; + return proj_ca; +} + +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions) +//----------------------------------------------------------------------------- + +// Consider using _stricmp/_strnicmp under Windows or strcasecmp/strncasecmp. We don't actually use either ImStricmp/ImStrnicmp in the codebase any more. +int ImStricmp(const char* str1, const char* str2) +{ + int d; + while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } + return d; +} + +int ImStrnicmp(const char* str1, const char* str2, size_t count) +{ + int d = 0; + while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } + return d; +} + +void ImStrncpy(char* dst, const char* src, size_t count) +{ + if (count < 1) + return; + if (count > 1) + strncpy(dst, src, count - 1); + dst[count - 1] = 0; +} + +char* ImStrdup(const char* str) +{ + size_t len = strlen(str); + void* buf = IM_ALLOC(len + 1); + return (char*)memcpy(buf, (const void*)str, len + 1); +} + +char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) +{ + size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1; + size_t src_size = strlen(src) + 1; + if (dst_buf_size < src_size) + { + IM_FREE(dst); + dst = (char*)IM_ALLOC(src_size); + if (p_dst_size) + *p_dst_size = src_size; + } + return (char*)memcpy(dst, (const void*)src, src_size); +} + +const char* ImStrchrRange(const char* str, const char* str_end, char c) +{ + const char* p = (const char*)memchr(str, (int)c, str_end - str); + return p; +} + +int ImStrlenW(const ImWchar* str) +{ + //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bit + int n = 0; + while (*str++) n++; + return n; +} + +// Find end-of-line. Return pointer will point to either first \n, either str_end. +const char* ImStreolRange(const char* str, const char* str_end) +{ + const char* p = (const char*)memchr(str, '\n', str_end - str); + return p ? p : str_end; +} + +const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line +{ + while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') + buf_mid_line--; + return buf_mid_line; +} + +const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end) +{ + if (!needle_end) + needle_end = needle + strlen(needle); + + const char un0 = (char)toupper(*needle); + while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) + { + 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; +} + +// Trim str by offsetting contents when there's leading data + writing a \0 at the trailing position. We use this in situation where the cost is negligible. +void ImStrTrimBlanks(char* buf) +{ + char* p = buf; + while (p[0] == ' ' || p[0] == '\t') // Leading blanks + p++; + char* p_start = p; + while (*p != 0) // Find end of string + p++; + while (p > p_start && (p[-1] == ' ' || p[-1] == '\t')) // Trailing blanks + p--; + if (p_start != buf) // Copy memory if we had leading blanks + memmove(buf, p_start, p - p_start); + buf[p - p_start] = 0; // Zero terminate +} + +const char* ImStrSkipBlank(const char* str) +{ + while (str[0] == ' ' || str[0] == '\t') + str++; + return str; +} + +// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). +// Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +// B) When buf==NULL vsnprintf() will return the output size. +#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS + +// We support stb_sprintf which is much faster (see: https://github.com/nothings/stb/blob/master/stb_sprintf.h) +// You may set IMGUI_USE_STB_SPRINTF to use our default wrapper, or set IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS +// and setup the wrapper yourself. (FIXME-OPT: Some of our high-level operations such as ImGuiTextBuffer::appendfv() are +// designed using two-passes worst case, which probably could be improved using the stbsp_vsprintfcb() function.) +#ifdef IMGUI_USE_STB_SPRINTF +#define STB_SPRINTF_IMPLEMENTATION +#include "stb_sprintf.h" +#endif + +#if defined(_MSC_VER) && !defined(vsnprintf) +#define vsnprintf _vsnprintf +#endif + +int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); +#ifdef IMGUI_USE_STB_SPRINTF + int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args); +#else + int w = vsnprintf(buf, buf_size, fmt, args); +#endif + va_end(args); + if (buf == NULL) + return w; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; + buf[w] = 0; + return w; +} + +int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) +{ +#ifdef IMGUI_USE_STB_SPRINTF + int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args); +#else + int w = vsnprintf(buf, buf_size, fmt, args); +#endif + if (buf == NULL) + return w; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; + buf[w] = 0; + return w; +} +#endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS + +// CRC32 needs a 1KB lookup table (not cache friendly) +// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily: +// - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe. +static const ImU32 GCrc32LookupTable[256] = +{ + 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, + 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, + 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, + 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, + 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, + 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, + 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, + 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, + 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, + 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, + 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, + 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, + 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, + 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, + 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, + 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D, +}; + +// Known size hash +// It is ok to call ImHashData on a string with known length but the ### operator won't be supported. +// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. +ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed) +{ + ImU32 crc = ~seed; + const unsigned char* data = (const unsigned char*)data_p; + const ImU32* crc32_lut = GCrc32LookupTable; + while (data_size-- != 0) + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++]; + return ~crc; +} + +// Zero-terminated string hash, with support for ### to reset back to seed value +// 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/faster (measured ~10% diff in Debug build) +// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. +ImGuiID ImHashStr(const char* data_p, size_t data_size, ImU32 seed) +{ + seed = ~seed; + ImU32 crc = seed; + const unsigned char* data = (const unsigned char*)data_p; + const ImU32* crc32_lut = GCrc32LookupTable; + if (data_size != 0) + { + while (data_size-- != 0) + { + unsigned char c = *data++; + if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#') + crc = seed; + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; + } + } + else + { + while (unsigned char c = *data++) + { + if (c == '#' && data[0] == '#' && data[1] == '#') + crc = seed; + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; + } + } + return ~crc; +} + +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (File functions) +//----------------------------------------------------------------------------- + +// Default file functions +#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS + +ImFileHandle ImFileOpen(const char* filename, const char* mode) +{ +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__) + // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. + // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32! + const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); + const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0); + ImVector buf; + buf.resize(filename_wsize + mode_wsize); + ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize); + ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize); + return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]); +#else + return fopen(filename, mode); +#endif +} + +// We should in theory be using fseeko()/ftello() with off_t and _fseeki64()/_ftelli64() with __int64, waiting for the PR that does that in a very portable pre-C++11 zero-warnings way. +bool ImFileClose(ImFileHandle f) { return fclose(f) == 0; } +ImU64 ImFileGetSize(ImFileHandle f) { long off = 0, sz = 0; return ((off = ftell(f)) != -1 && !fseek(f, 0, SEEK_END) && (sz = ftell(f)) != -1 && !fseek(f, off, SEEK_SET)) ? (ImU64)sz : (ImU64)-1; } +ImU64 ImFileRead(void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fread(data, (size_t)sz, (size_t)count, f); } +ImU64 ImFileWrite(const void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fwrite(data, (size_t)sz, (size_t)count, f); } +#endif // #ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS + +// Helper: Load file content into memory +// Memory allocated with IM_ALLOC(), must be freed by user using IM_FREE() == ImGui::MemFree() +// This can't really be used with "rt" because fseek size won't match read size. +void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size, int padding_bytes) +{ + IM_ASSERT(filename && mode); + if (out_file_size) + *out_file_size = 0; + + ImFileHandle f; + if ((f = ImFileOpen(filename, mode)) == NULL) + return NULL; + + size_t file_size = (size_t)ImFileGetSize(f); + if (file_size == (size_t)-1) + { + ImFileClose(f); + return NULL; + } + + void* file_data = IM_ALLOC(file_size + padding_bytes); + if (file_data == NULL) + { + ImFileClose(f); + return NULL; + } + if (ImFileRead(file_data, 1, file_size, f) != file_size) + { + ImFileClose(f); + IM_FREE(file_data); + return NULL; + } + if (padding_bytes > 0) + memset((void*)(((char*)file_data) + file_size), 0, (size_t)padding_bytes); + + ImFileClose(f); + if (out_file_size) + *out_file_size = file_size; + + return file_data; +} + +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (ImText* functions) +//----------------------------------------------------------------------------- + +// Convert UTF-8 to 32-bit character, process single character input. +// A nearly-branchless UTF-8 decoder, based on work of Christopher Wellons (https://github.com/skeeto/branchless-utf8). +// We handle UTF-8 decoding error by skipping forward. +int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end) +{ + static const char lengths[32] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 }; + static const int masks[] = { 0x00, 0x7f, 0x1f, 0x0f, 0x07 }; + static const uint32_t mins[] = { 0x400000, 0, 0x80, 0x800, 0x10000 }; + static const int shiftc[] = { 0, 18, 12, 6, 0 }; + static const int shifte[] = { 0, 6, 4, 2, 0 }; + int len = lengths[*(const unsigned char*)in_text >> 3]; + int wanted = len + !len; + + if (in_text_end == NULL) + in_text_end = in_text + wanted; // Max length, nulls will be taken into account. + + // Copy at most 'len' bytes, stop copying at 0 or past in_text_end. Branch predictor does a good job here, + // so it is fast even with excessive branching. + unsigned char s[4]; + s[0] = in_text + 0 < in_text_end ? in_text[0] : 0; + s[1] = in_text + 1 < in_text_end ? in_text[1] : 0; + s[2] = in_text + 2 < in_text_end ? in_text[2] : 0; + s[3] = in_text + 3 < in_text_end ? in_text[3] : 0; + + // Assume a four-byte character and load four bytes. Unused bits are shifted out. + *out_char = (uint32_t)(s[0] & masks[len]) << 18; + *out_char |= (uint32_t)(s[1] & 0x3f) << 12; + *out_char |= (uint32_t)(s[2] & 0x3f) << 6; + *out_char |= (uint32_t)(s[3] & 0x3f) << 0; + *out_char >>= shiftc[len]; + + // Accumulate the various error conditions. + int e = 0; + e = (*out_char < mins[len]) << 6; // non-canonical encoding + e |= ((*out_char >> 11) == 0x1b) << 7; // surrogate half? + e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range? + e |= (s[1] & 0xc0) >> 2; + e |= (s[2] & 0xc0) >> 4; + e |= (s[3] ) >> 6; + e ^= 0x2a; // top two bits of each tail byte correct? + e >>= shifte[len]; + + if (e) + { + // No bytes are consumed when *in_text == 0 || in_text == in_text_end. + // One byte is consumed in case of invalid first byte of in_text. + // All available bytes (at most `len` bytes) are consumed on incomplete/invalid second to last bytes. + // Invalid or incomplete input may consume less bytes than wanted, therefore every byte has to be inspected in s. + wanted = ImMin(wanted, !!s[0] + !!s[1] + !!s[2] + !!s[3]); + *out_char = IM_UNICODE_CODEPOINT_INVALID; + } + + return wanted; +} + +int ImTextStrFromUtf8(ImWchar* buf, int 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; + *buf_out++ = (ImWchar)c; + } + *buf_out = 0; + if (in_text_remaining) + *in_text_remaining = in_text; + return (int)(buf_out - buf); +} + +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; + char_count++; + } + return char_count; +} + +// Based on stb_to_utf8() from github.com/nothings/stb/ +static inline int ImTextCharToUtf8_inline(char* buf, int buf_size, unsigned int c) +{ + if (c < 0x80) + { + buf[0] = (char)c; + return 1; + } + if (c < 0x800) + { + if (buf_size < 2) return 0; + buf[0] = (char)(0xc0 + (c >> 6)); + buf[1] = (char)(0x80 + (c & 0x3f)); + return 2; + } + if (c < 0x10000) + { + if (buf_size < 3) return 0; + buf[0] = (char)(0xe0 + (c >> 12)); + buf[1] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[2] = (char)(0x80 + ((c ) & 0x3f)); + return 3; + } + if (c <= 0x10FFFF) + { + if (buf_size < 4) return 0; + buf[0] = (char)(0xf0 + (c >> 18)); + buf[1] = (char)(0x80 + ((c >> 12) & 0x3f)); + buf[2] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[3] = (char)(0x80 + ((c ) & 0x3f)); + return 4; + } + // Invalid code point, the max unicode is 0x10FFFF + return 0; +} + +const char* ImTextCharToUtf8(char out_buf[5], unsigned int c) +{ + int count = ImTextCharToUtf8_inline(out_buf, 5, c); + out_buf[count] = 0; + return out_buf; +} + +// Not optimal but we very rarely use this function. +int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end) +{ + unsigned int unused = 0; + return ImTextCharFromUtf8(&unused, in_text, in_text_end); +} + +static inline int ImTextCountUtf8BytesFromChar(unsigned int c) +{ + if (c < 0x80) return 1; + if (c < 0x800) return 2; + if (c < 0x10000) return 3; + if (c <= 0x10FFFF) return 4; + return 3; +} + +int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end) +{ + char* buf_p = out_buf; + const char* buf_end = out_buf + out_buf_size; + while (buf_p < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + *buf_p++ = (char)c; + else + buf_p += ImTextCharToUtf8_inline(buf_p, (int)(buf_end - buf_p - 1), c); + } + *buf_p = 0; + return (int)(buf_p - out_buf); +} + +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) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + bytes_count++; + else + bytes_count += ImTextCountUtf8BytesFromChar(c); + } + return bytes_count; +} + +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (Color functions) +// Note: The Convert functions are early design which are not consistent with other API. +//----------------------------------------------------------------------------- + +IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b) +{ + float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f; + int r = ImLerp((int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_B_SHIFT) & 0xFF, t); + return IM_COL32(r, g, b, 0xFF); +} + +ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in) +{ + float s = 1.0f / 255.0f; + return ImVec4( + ((in >> IM_COL32_R_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_G_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_B_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_A_SHIFT) & 0xFF) * s); +} + +ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) +{ + ImU32 out; + out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT; + 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) + { + ImSwap(g, b); + K = -1.f; + } + if (r < g) + { + ImSwap(r, g); + K = -2.f / 6.f - K; + } + + const float chroma = r - (g < b ? g : b); + out_h = ImFabs(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 = ImFmod(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; + } +} + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiStorage +// Helper: Key->value storage +//----------------------------------------------------------------------------- + +// std::lower_bound but without the bullshit +static ImGuiStorage::ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID key) +{ + ImGuiStorage::ImGuiStoragePair* first = data.Data; + ImGuiStorage::ImGuiStoragePair* last = data.Data + data.Size; + size_t count = (size_t)(last - first); + while (count > 0) + { + size_t count2 = count >> 1; + ImGuiStorage::ImGuiStoragePair* mid = first + count2; + if (mid->key < key) + { + first = ++mid; + count -= count2 + 1; + } + else + { + count = count2; + } + } + return first; +} + +// For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. +void ImGuiStorage::BuildSortByKey() +{ + struct StaticFunc + { + static int IMGUI_CDECL PairComparerByID(const void* lhs, const void* rhs) + { + // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. + if (((const ImGuiStoragePair*)lhs)->key > ((const ImGuiStoragePair*)rhs)->key) return +1; + if (((const ImGuiStoragePair*)lhs)->key < ((const ImGuiStoragePair*)rhs)->key) return -1; + return 0; + } + }; + ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairComparerByID); +} + +int ImGuiStorage::GetInt(ImGuiID key, int default_val) const +{ + ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_i; +} + +bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const +{ + return GetInt(key, default_val ? 1 : 0) != 0; +} + +float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const +{ + ImGuiStoragePair* 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 +{ + ImGuiStoragePair* 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) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, ImGuiStoragePair(key, default_val)); + return &it->val_i; +} + +bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) +{ + return (bool*)GetIntRef(key, default_val ? 1 : 0); +} + +float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, ImGuiStoragePair(key, default_val)); + return &it->val_f; +} + +void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, ImGuiStoragePair(key, default_val)); + return &it->val_p; +} + +// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) +void ImGuiStorage::SetInt(ImGuiID key, int val) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, ImGuiStoragePair(key, val)); + return; + } + it->val_i = val; +} + +void ImGuiStorage::SetBool(ImGuiID key, bool val) +{ + SetInt(key, val ? 1 : 0); +} + +void ImGuiStorage::SetFloat(ImGuiID key, float val) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, ImGuiStoragePair(key, val)); + return; + } + it->val_f = val; +} + +void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) +{ + ImGuiStoragePair* it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, ImGuiStoragePair(key, val)); + return; + } + it->val_p = val; +} + +void ImGuiStorage::SetAllInt(int v) +{ + for (int i = 0; i < Data.Size; i++) + Data[i].val_i = v; +} + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiTextFilter +//----------------------------------------------------------------------------- + +// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) +{ + if (default_filter) + { + ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); + Build(); + } + else + { + InputBuf[0] = 0; + CountGrep = 0; + } +} + +bool ImGuiTextFilter::Draw(const char* label, float width) +{ + if (width != 0.0f) + ImGui::SetNextItemWidth(width); + bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); + if (value_changed) + Build(); + return value_changed; +} + +void ImGuiTextFilter::ImGuiTextRange::split(char separator, ImVector* out) const +{ + out->resize(0); + const char* wb = b; + const char* we = wb; + while (we < e) + { + if (*we == separator) + { + out->push_back(ImGuiTextRange(wb, we)); + wb = we + 1; + } + we++; + } + if (wb != we) + out->push_back(ImGuiTextRange(wb, we)); +} + +void ImGuiTextFilter::Build() +{ + Filters.resize(0); + ImGuiTextRange input_range(InputBuf, InputBuf + strlen(InputBuf)); + input_range.split(',', &Filters); + + CountGrep = 0; + for (int i = 0; i != Filters.Size; i++) + { + ImGuiTextRange& f = Filters[i]; + while (f.b < f.e && ImCharIsBlankA(f.b[0])) + f.b++; + while (f.e > f.b && ImCharIsBlankA(f.e[-1])) + f.e--; + if (f.empty()) + continue; + if (Filters[i].b[0] != '-') + CountGrep += 1; + } +} + +bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const +{ + if (Filters.empty()) + return true; + + if (text == NULL) + text = ""; + + for (int i = 0; i != Filters.Size; i++) + { + const ImGuiTextRange& f = Filters[i]; + if (f.empty()) + continue; + if (f.b[0] == '-') + { + // Subtract + if (ImStristr(text, text_end, f.b + 1, f.e) != NULL) + return false; + } + else + { + // Grep + if (ImStristr(text, text_end, f.b, f.e) != NULL) + return true; + } + } + + // Implicit * grep + if (CountGrep == 0) + return true; + + return false; +} + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiTextBuffer +//----------------------------------------------------------------------------- + +// 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 +#if defined(__GNUC__) || defined(__clang__) +#define va_copy(dest, src) __builtin_va_copy(dest, src) +#else +#define va_copy(dest, src) (dest = src) +#endif +#endif + +char ImGuiTextBuffer::EmptyString[1] = { 0 }; + +void ImGuiTextBuffer::append(const char* str, const char* str_end) +{ + int len = str_end ? (int)(str_end - str) : (int)strlen(str); + + // Add zero-terminator the first time + const int write_off = (Buf.Size != 0) ? Buf.Size : 1; + const int needed_sz = write_off + len; + if (write_off + len >= Buf.Capacity) + { + int new_capacity = Buf.Capacity * 2; + Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity); + } + + Buf.resize(needed_sz); + memcpy(&Buf[write_off - 1], str, (size_t)len); + Buf[write_off - 1 + len] = 0; +} + +void ImGuiTextBuffer::appendf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + appendfv(fmt, args); + va_end(args); +} + +// Helper: Text buffer for logging/accumulating text +void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) +{ + va_list args_copy; + va_copy(args_copy, args); + + int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + if (len <= 0) + { + va_end(args_copy); + return; + } + + // Add zero-terminator the first time + const int write_off = (Buf.Size != 0) ? Buf.Size : 1; + const int needed_sz = write_off + len; + if (write_off + len >= Buf.Capacity) + { + int new_capacity = Buf.Capacity * 2; + Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity); + } + + Buf.resize(needed_sz); + ImFormatStringV(&Buf[write_off - 1], (size_t)len + 1, fmt, args_copy); + va_end(args_copy); +} + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiListClipper +// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed +// the API mid-way through development and support two ways to using the clipper, needs some rework (see TODO) +//----------------------------------------------------------------------------- + +// FIXME-TABLE: This prevents us from using ImGuiListClipper _inside_ a table cell. +// The problem we have is that without a Begin/End scheme for rows using the clipper is ambiguous. +static bool GetSkipItemForListClipping() +{ + ImGuiContext& g = *GImGui; + return (g.CurrentTable ? g.CurrentTable->HostSkipItems : g.CurrentWindow->SkipItems); +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// Legacy helper to calculate coarse clipping of large list of evenly sized items. +// This legacy API is not ideal because it assume we will return a single contiguous rectangle. +// Prefer using ImGuiListClipper which can returns non-contiguous ranges. +void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + *out_items_display_start = 0; + *out_items_display_end = items_count; + return; + } + if (GetSkipItemForListClipping()) + { + *out_items_display_start = *out_items_display_end = 0; + return; + } + + // We create the union of the ClipRect and the scoring rect which at worst should be 1 page away from ClipRect + // We don't include g.NavId's rectangle in there (unless g.NavJustMovedToId is set) because the rectangle enlargement can get costly. + ImRect rect = window->ClipRect; + if (g.NavMoveScoringItems) + rect.Add(g.NavScoringNoClipRect); + if (g.NavJustMovedToId && window->NavLastIds[0] == g.NavJustMovedToId) + rect.Add(WindowRectRelToAbs(window, window->NavRectRel[0])); // Could store and use NavJustMovedToRectRel + + const ImVec2 pos = window->DC.CursorPos; + int start = (int)((rect.Min.y - pos.y) / items_height); + int end = (int)((rect.Max.y - pos.y) / items_height); + + // When performing a navigation request, ensure we have one item extra in the direction we are moving to + // FIXME: Verify this works with tabbing + const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) + start--; + if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) + end++; + + start = ImClamp(start, 0, items_count); + end = ImClamp(end + 1, start, items_count); + *out_items_display_start = start; + *out_items_display_end = end; +} +#endif + +static void ImGuiListClipper_SortAndFuseRanges(ImVector& ranges, int offset = 0) +{ + if (ranges.Size - offset <= 1) + return; + + // Helper to order ranges and fuse them together if possible (bubble sort is fine as we are only sorting 2-3 entries) + for (int sort_end = ranges.Size - offset - 1; sort_end > 0; --sort_end) + for (int i = offset; i < sort_end + offset; ++i) + if (ranges[i].Min > ranges[i + 1].Min) + ImSwap(ranges[i], ranges[i + 1]); + + // Now fuse ranges together as much as possible. + for (int i = 1 + offset; i < ranges.Size; i++) + { + IM_ASSERT(!ranges[i].PosToIndexConvert && !ranges[i - 1].PosToIndexConvert); + if (ranges[i - 1].Max < ranges[i].Min) + continue; + ranges[i - 1].Min = ImMin(ranges[i - 1].Min, ranges[i].Min); + ranges[i - 1].Max = ImMax(ranges[i - 1].Max, ranges[i].Max); + ranges.erase(ranges.Data + i); + i--; + } +} + +static void ImGuiListClipper_SeekCursorAndSetupPrevLine(float pos_y, float line_height) +{ + // Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor. + // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. + // The clipper should probably have a final step to display the last item in a regular manner, maybe with an opt-out flag for data sets which may have costly seek? + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + float off_y = pos_y - window->DC.CursorPos.y; + window->DC.CursorPos.y = pos_y; + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y - g.Style.ItemSpacing.y); + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage. + window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + if (ImGuiOldColumns* columns = window->DC.CurrentColumns) + columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly + if (ImGuiTable* table = g.CurrentTable) + { + if (table->IsInsideRow) + ImGui::TableEndRow(table); + table->RowPosY2 = window->DC.CursorPos.y; + const int row_increase = (int)((off_y / line_height) + 0.5f); + //table->CurrentRow += row_increase; // Can't do without fixing TableEndRow() + table->RowBgColorCounter += row_increase; + } +} + +static void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* clipper, int item_n) +{ + // StartPosY starts from ItemsFrozen hence the subtraction + // Perform the add and multiply with double to allow seeking through larger ranges + ImGuiListClipperData* data = (ImGuiListClipperData*)clipper->TempData; + float pos_y = (float)((double)clipper->StartPosY + data->LossynessOffset + (double)(item_n - data->ItemsFrozen) * clipper->ItemsHeight); + ImGuiListClipper_SeekCursorAndSetupPrevLine(pos_y, clipper->ItemsHeight); +} + +ImGuiListClipper::ImGuiListClipper() +{ + memset(this, 0, sizeof(*this)); + ItemsCount = -1; +} + +ImGuiListClipper::~ImGuiListClipper() +{ + End(); +} + +// Use case A: Begin() called from constructor with items_height<0, then called again from Step() in StepNo 1 +// Use case B: Begin() called from constructor with items_height>0 +// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style. +void ImGuiListClipper::Begin(int items_count, float items_height) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + if (ImGuiTable* table = g.CurrentTable) + if (table->IsInsideRow) + ImGui::TableEndRow(table); + + StartPosY = window->DC.CursorPos.y; + ItemsHeight = items_height; + ItemsCount = items_count; + DisplayStart = -1; + DisplayEnd = 0; + + // Acquire temporary buffer + if (++g.ClipperTempDataStacked > g.ClipperTempData.Size) + g.ClipperTempData.resize(g.ClipperTempDataStacked, ImGuiListClipperData()); + ImGuiListClipperData* data = &g.ClipperTempData[g.ClipperTempDataStacked - 1]; + data->Reset(this); + data->LossynessOffset = window->DC.CursorStartPosLossyness.y; + TempData = data; +} + +void ImGuiListClipper::End() +{ + // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user. + ImGuiContext& g = *GImGui; + if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0) + ImGuiListClipper_SeekCursorForItem(this, ItemsCount); + ItemsCount = -1; + + // Restore temporary buffer and fix back pointers which may be invalidated when nesting + if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData) + { + IM_ASSERT(data->ListClipper == this); + data->StepNo = data->Ranges.Size; + if (--g.ClipperTempDataStacked > 0) + { + data = &g.ClipperTempData[g.ClipperTempDataStacked - 1]; + data->ListClipper->TempData = data; + } + TempData = NULL; + } +} + +void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max) +{ + ImGuiListClipperData* data = (ImGuiListClipperData*)TempData; + IM_ASSERT(DisplayStart < 0); // Only allowed after Begin() and if there has not been a specified range yet. + IM_ASSERT(item_min <= item_max); + if (item_min < item_max) + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_min, item_max)); +} + +bool ImGuiListClipper::Step() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiListClipperData* data = (ImGuiListClipperData*)TempData; + + ImGuiTable* table = g.CurrentTable; + if (table && table->IsInsideRow) + ImGui::TableEndRow(table); + + // No items + if (ItemsCount == 0 || GetSkipItemForListClipping()) + return (void)End(), false; + + // While we are in frozen row state, keep displaying items one by one, unclipped + // FIXME: Could be stored as a table-agnostic state. + if (data->StepNo == 0 && table != NULL && !table->IsUnfrozenRows) + { + DisplayStart = data->ItemsFrozen; + DisplayEnd = data->ItemsFrozen + 1; + if (DisplayStart >= ItemsCount) + return (void)End(), false; + data->ItemsFrozen++; + return true; + } + + // Step 0: Let you process the first element (regardless of it being visible or not, so we can measure the element height) + bool calc_clipping = false; + if (data->StepNo == 0) + { + StartPosY = window->DC.CursorPos.y; + if (ItemsHeight <= 0.0f) + { + // Submit the first item (or range) so we can measure its height (generally the first range is 0..1) + data->Ranges.push_front(ImGuiListClipperRange::FromIndices(data->ItemsFrozen, data->ItemsFrozen + 1)); + DisplayStart = ImMax(data->Ranges[0].Min, data->ItemsFrozen); + DisplayEnd = ImMin(data->Ranges[0].Max, ItemsCount); + if (DisplayStart == DisplayEnd) + return (void)End(), false; + data->StepNo = 1; + return true; + } + calc_clipping = true; // If on the first step with known item height, calculate clipping. + } + + // Step 1: Let the clipper infer height from first range + if (ItemsHeight <= 0.0f) + { + IM_ASSERT(data->StepNo == 1); + if (table) + IM_ASSERT(table->RowPosY1 == StartPosY && table->RowPosY2 == window->DC.CursorPos.y); + + ItemsHeight = (window->DC.CursorPos.y - StartPosY) / (float)(DisplayEnd - DisplayStart); + bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y); + if (affected_by_floating_point_precision) + ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries. + + IM_ASSERT(ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!"); + calc_clipping = true; // If item height had to be calculated, calculate clipping afterwards. + } + + // Step 0 or 1: Calculate the actual ranges of visible elements. + const int already_submitted = DisplayEnd; + if (calc_clipping) + { + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(0, ItemsCount)); + } + else + { + // Add range selected to be included for navigation + const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (is_nav_request) + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0)); + if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && g.NavTabbingDir == -1) + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(ItemsCount - 1, ItemsCount)); + + // Add focused/active item + ImRect nav_rect_abs = ImGui::WindowRectRelToAbs(window, window->NavRectRel[0]); + if (g.NavId != 0 && window->NavLastIds[0] == g.NavId) + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0)); + + // Add visible range + const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; + const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(window->ClipRect.Min.y, window->ClipRect.Max.y, off_min, off_max)); + } + + // Convert position ranges to item index ranges + // - Very important: when a starting position is after our maximum item, we set Min to (ItemsCount - 1). This allows us to handle most forms of wrapping. + // - Due to how Selectable extra padding they tend to be "unaligned" with exact unit in the item list, + // which with the flooring/ceiling tend to lead to 2 items instead of one being submitted. + for (int i = 0; i < data->Ranges.Size; i++) + if (data->Ranges[i].PosToIndexConvert) + { + int m1 = (int)(((double)data->Ranges[i].Min - window->DC.CursorPos.y - data->LossynessOffset) / ItemsHeight); + int m2 = (int)((((double)data->Ranges[i].Max - window->DC.CursorPos.y - data->LossynessOffset) / ItemsHeight) + 0.999999f); + data->Ranges[i].Min = ImClamp(already_submitted + m1 + data->Ranges[i].PosToIndexOffsetMin, already_submitted, ItemsCount - 1); + data->Ranges[i].Max = ImClamp(already_submitted + m2 + data->Ranges[i].PosToIndexOffsetMax, data->Ranges[i].Min + 1, ItemsCount); + data->Ranges[i].PosToIndexConvert = false; + } + ImGuiListClipper_SortAndFuseRanges(data->Ranges, data->StepNo); + } + + // Step 0+ (if item height is given in advance) or 1+: Display the next range in line. + if (data->StepNo < data->Ranges.Size) + { + DisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted); + DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, ItemsCount); + if (DisplayStart > already_submitted) //-V1051 + ImGuiListClipper_SeekCursorForItem(this, DisplayStart); + data->StepNo++; + return true; + } + + // After the last step: Let the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), + // Advance the cursor to the end of the list and then returns 'false' to end the loop. + if (ItemsCount < INT_MAX) + ImGuiListClipper_SeekCursorForItem(this, ItemsCount); + ItemsCount = -1; + + return false; +} + +//----------------------------------------------------------------------------- +// [SECTION] STYLING +//----------------------------------------------------------------------------- + +ImGuiStyle& ImGui::GetStyle() +{ + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); + return GImGui->Style; +} + +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = style.Colors[idx]; + c.w *= style.Alpha * alpha_mul; + return ColorConvertFloat4ToU32(c); +} + +ImU32 ImGui::GetColorU32(const ImVec4& col) +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = col; + c.w *= style.Alpha; + return ColorConvertFloat4ToU32(c); +} + +const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx) +{ + ImGuiStyle& style = GImGui->Style; + return style.Colors[idx]; +} + +ImU32 ImGui::GetColorU32(ImU32 col) +{ + ImGuiStyle& style = GImGui->Style; + if (style.Alpha >= 1.0f) + return col; + ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; + a = (ImU32)(a * style.Alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. + return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); +} + +// FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32 +void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col) +{ + ImGuiContext& g = *GImGui; + ImGuiColorMod backup; + backup.Col = idx; + backup.BackupValue = g.Style.Colors[idx]; + g.ColorStack.push_back(backup); + g.Style.Colors[idx] = ColorConvertU32ToFloat4(col); +} + +void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) +{ + ImGuiContext& g = *GImGui; + ImGuiColorMod backup; + backup.Col = idx; + backup.BackupValue = g.Style.Colors[idx]; + g.ColorStack.push_back(backup); + g.Style.Colors[idx] = col; +} + +void ImGui::PopStyleColor(int count) +{ + ImGuiContext& g = *GImGui; + while (count > 0) + { + ImGuiColorMod& backup = g.ColorStack.back(); + g.Style.Colors[backup.Col] = backup.BackupValue; + g.ColorStack.pop_back(); + count--; + } +} + +struct ImGuiStyleVarInfo +{ + ImGuiDataType Type; + ImU32 Count; + ImU32 Offset; + void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } +}; + +static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] = +{ + ImGuiCol_Text, ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive +}; + +static const ImGuiStyleVarInfo GStyleVarInfo[] = +{ + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign +}; + +static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) +{ + IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT); + IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT); + return &GStyleVarInfo[idx]; +} + +void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) +{ + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1) + { + ImGuiContext& g = *GImGui; + float* pvar = (float*)var_info->GetVarPtr(&g.Style); + g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar)); + *pvar = val; + return; + } + IM_ASSERT(0 && "Called PushStyleVar() float variant but variable is not a float!"); +} + +void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) +{ + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2) + { + ImGuiContext& g = *GImGui; + ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); + g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar)); + *pvar = val; + return; + } + IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!"); +} + +void ImGui::PopStyleVar(int count) +{ + ImGuiContext& g = *GImGui; + while (count > 0) + { + // We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it. + ImGuiStyleMod& backup = g.StyleVarStack.back(); + const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); + void* data = info->GetVarPtr(&g.Style); + if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; } + else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; } + g.StyleVarStack.pop_back(); + count--; + } +} + +const char* ImGui::GetStyleColorName(ImGuiCol idx) +{ + // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; + switch (idx) + { + case ImGuiCol_Text: return "Text"; + case ImGuiCol_TextDisabled: return "TextDisabled"; + case ImGuiCol_WindowBg: return "WindowBg"; + case ImGuiCol_ChildBg: return "ChildBg"; + case ImGuiCol_PopupBg: return "PopupBg"; + 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_TitleBgActive: return "TitleBgActive"; + case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; + case ImGuiCol_MenuBarBg: return "MenuBarBg"; + case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; + case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; + case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; + case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; + 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_Separator: return "Separator"; + case ImGuiCol_SeparatorHovered: return "SeparatorHovered"; + case ImGuiCol_SeparatorActive: return "SeparatorActive"; + case ImGuiCol_ResizeGrip: return "ResizeGrip"; + case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; + case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; + case ImGuiCol_Tab: return "Tab"; + case ImGuiCol_TabHovered: return "TabHovered"; + case ImGuiCol_TabActive: return "TabActive"; + case ImGuiCol_TabUnfocused: return "TabUnfocused"; + case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive"; + case ImGuiCol_DockingPreview: return "DockingPreview"; + case ImGuiCol_DockingEmptyBg: return "DockingEmptyBg"; + case ImGuiCol_PlotLines: return "PlotLines"; + case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; + case ImGuiCol_PlotHistogram: return "PlotHistogram"; + case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; + case ImGuiCol_TableHeaderBg: return "TableHeaderBg"; + case ImGuiCol_TableBorderStrong: return "TableBorderStrong"; + case ImGuiCol_TableBorderLight: return "TableBorderLight"; + case ImGuiCol_TableRowBg: return "TableRowBg"; + case ImGuiCol_TableRowBgAlt: return "TableRowBgAlt"; + case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; + case ImGuiCol_DragDropTarget: return "DragDropTarget"; + case ImGuiCol_NavHighlight: return "NavHighlight"; + case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight"; + case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg"; + case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg"; + } + IM_ASSERT(0); + return "Unknown"; +} + + +//----------------------------------------------------------------------------- +// [SECTION] RENDER HELPERS +// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change, +// we need a nicer separation between low-level functions and high-level functions relying on the ImGui context. +// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: context. +//----------------------------------------------------------------------------- + +const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) +{ + const char* text_display_end = text; + if (!text_end) + text_end = (const char*)-1; + + 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; +} + +// Internal ImGui functions to render text +// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() +void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // Hide anything after a '##' string + const char* text_display_end; + if (hide_text_after_hash) + { + text_display_end = FindRenderedTextEnd(text, text_end); + } + else + { + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + text_display_end = text_end; + } + + if (text != text_display_end) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); + if (g.LogEnabled) + LogRenderedText(&pos, text, text_display_end); + } +} + +void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + + if (text != text_end) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); + if (g.LogEnabled) + LogRenderedText(&pos, text, text_end); + } +} + +// Default clip_rect uses (pos_min,pos_max) +// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) +void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) +{ + // Perform CPU side clipping for single clipped element to avoid using scissor state + ImVec2 pos = pos_min; + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); + + const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min; + const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max; + bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); + if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min + need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); + + // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. + if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); + if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); + + // Render + if (need_clipping) + { + ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); + draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); + } + else + { + draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); + } +} + +void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) +{ + // Hide anything after a '##' string + const char* text_display_end = FindRenderedTextEnd(text, text_end); + const int text_len = (int)(text_display_end - text); + if (text_len == 0) + return; + + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect); + if (g.LogEnabled) + LogRenderedText(&pos_min, text, text_display_end); +} + + +// Another overly complex function until we reorganize everything into a nice all-in-one helper. +// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display. +// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move. +void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known) +{ + ImGuiContext& g = *GImGui; + if (text_end_full == NULL) + text_end_full = FindRenderedTextEnd(text); + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f); + + //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255)); + //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255)); + //draw_list->AddLine(ImVec2(clip_max_x, pos_min.y), ImVec2(clip_max_x, pos_max.y), IM_COL32(255, 0, 0, 255)); + // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels. + if (text_size.x > pos_max.x - pos_min.x) + { + // Hello wo... + // | | | + // min max ellipsis_max + // <-> this is generally some padding value + + const ImFont* font = draw_list->_Data->Font; + const float font_size = draw_list->_Data->FontSize; + const char* text_end_ellipsis = NULL; + + ImWchar ellipsis_char = font->EllipsisChar; + int ellipsis_char_count = 1; + if (ellipsis_char == (ImWchar)-1) + { + ellipsis_char = font->DotChar; + ellipsis_char_count = 3; + } + const ImFontGlyph* glyph = font->FindGlyph(ellipsis_char); + + float ellipsis_glyph_width = glyph->X1; // Width of the glyph with no padding on either side + float ellipsis_total_width = ellipsis_glyph_width; // Full width of entire ellipsis + + if (ellipsis_char_count > 1) + { + // Full ellipsis size without free spacing after it. + const float spacing_between_dots = 1.0f * (draw_list->_Data->FontSize / font->FontSize); + ellipsis_glyph_width = glyph->X1 - glyph->X0 + spacing_between_dots; + ellipsis_total_width = ellipsis_glyph_width * (float)ellipsis_char_count - spacing_between_dots; + } + + // We can now claim the space between pos_max.x and ellipsis_max.x + const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f); + float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x; + if (text == text_end_ellipsis && text_end_ellipsis < text_end_full) + { + // Always display at least 1 character if there's no room for character + ellipsis + text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full); + text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x; + } + while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1])) + { + // Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text) + text_end_ellipsis--; + text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte + } + + // Render text, render ellipsis + RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f)); + float ellipsis_x = pos_min.x + text_size_clipped_x; + if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x) + for (int i = 0; i < ellipsis_char_count; i++) + { + font->RenderChar(draw_list, font_size, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char); + ellipsis_x += ellipsis_glyph_width; + } + } + else + { + RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f)); + } + + if (g.LogEnabled) + LogRenderedText(&pos_min, text, text_end_full); +} + +// Render a rectangle shaped with optional rounding and borders +void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) + { + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + } +} + +void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) + { + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + } +} + +void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags) +{ + ImGuiContext& g = *GImGui; + if (id != g.NavId) + return; + if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) + return; + ImGuiWindow* window = g.CurrentWindow; + if (window->DC.NavHideHighlightOneFrame) + return; + + float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding; + ImRect display_rect = bb; + display_rect.ClipWith(window->ClipRect); + if (flags & ImGuiNavHighlightFlags_TypeDefault) + { + const float THICKNESS = 2.0f; + const float DISTANCE = 3.0f + THICKNESS * 0.5f; + display_rect.Expand(ImVec2(DISTANCE, DISTANCE)); + bool fully_visible = window->ClipRect.Contains(display_rect); + if (!fully_visible) + window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); + window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS * 0.5f, THICKNESS * 0.5f), display_rect.Max - ImVec2(THICKNESS * 0.5f, THICKNESS * 0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, 0, THICKNESS); + if (!fully_visible) + window->DrawList->PopClipRect(); + } + if (flags & ImGuiNavHighlightFlags_TypeThin) + { + window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, 0, 1.0f); + } +} + +void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT); + ImFontAtlas* font_atlas = g.DrawListSharedData.Font->ContainerAtlas; + for (int n = 0; n < g.Viewports.Size; n++) + { + // We scale cursor with current viewport/monitor, however Windows 10 for its own hardware cursor seems to be using a different scale factor. + ImVec2 offset, size, uv[4]; + if (!font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2])) + continue; + ImGuiViewportP* viewport = g.Viewports[n]; + const ImVec2 pos = base_pos - offset; + const float scale = base_scale * viewport->DpiScale; + if (!viewport->GetMainRect().Overlaps(ImRect(pos, pos + ImVec2(size.x + 2, size.y + 2) * scale))) + continue; + ImDrawList* draw_list = GetForegroundDrawList(viewport); + ImTextureID tex_id = font_atlas->TexID; + draw_list->PushTextureID(tex_id); + draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow); + draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow); + draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border); + draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill); + draw_list->PopTextureID(); + } +} + + +//----------------------------------------------------------------------------- +// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) +//----------------------------------------------------------------------------- + +// ImGuiWindow is mostly a dumb struct. It merely has a constructor and a few helper methods +ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst(NULL) +{ + memset(this, 0, sizeof(*this)); + Name = ImStrdup(name); + NameBufLen = (int)strlen(name) + 1; + ID = ImHashStr(name); + IDStack.push_back(ID); + ViewportAllowPlatformMonitorExtend = -1; + ViewportPos = ImVec2(FLT_MAX, FLT_MAX); + MoveId = GetID("#MOVE"); + TabId = GetID("#TAB"); + ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); + AutoFitFramesX = AutoFitFramesY = -1; + AutoPosLastDirection = ImGuiDir_None; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; + SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); + LastFrameActive = -1; + LastFrameJustFocused = -1; + LastTimeActive = -1.0f; + FontWindowScale = FontDpiScale = 1.0f; + SettingsOffset = -1; + DockOrder = -1; + DrawList = &DrawListInst; + DrawList->_Data = &context->DrawListSharedData; + DrawList->_OwnerName = Name; + IM_PLACEMENT_NEW(&WindowClass) ImGuiWindowClass(); +} + +ImGuiWindow::~ImGuiWindow() +{ + IM_ASSERT(DrawList == &DrawListInst); + IM_DELETE(Name); + ColumnsStorage.clear_destruct(); +} + +ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); + ImGui::KeepAliveID(id); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); + return id; +} + +ImGuiID ImGuiWindow::GetID(const void* ptr) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); + ImGui::KeepAliveID(id); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); + return id; +} + +ImGuiID ImGuiWindow::GetID(int n) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&n, sizeof(n), seed); + ImGui::KeepAliveID(id); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); + return id; +} + +ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); + return id; +} + +ImGuiID ImGuiWindow::GetIDNoKeepAlive(const void* ptr) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); + return id; +} + +ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&n, sizeof(n), seed); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); + return id; +} + +// This is only used in rare/specific situations to manufacture an ID out of nowhere. +ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) +{ + ImGuiID seed = IDStack.back(); + ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs); + ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed); + ImGui::KeepAliveID(id); + return id; +} + +static void SetCurrentWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow = window; + g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL; + if (window) + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); +} + +void ImGui::GcCompactTransientMiscBuffers() +{ + ImGuiContext& g = *GImGui; + g.ItemFlagsStack.clear(); + g.GroupStack.clear(); + TableGcCompactSettings(); +} + +// Free up/compact internal window buffers, we can use this when a window becomes unused. +// Not freed: +// - ImGuiWindow, ImGuiWindowSettings, Name, StateStorage, ColumnsStorage (may hold useful data) +// This should have no noticeable visual effect. When the window reappear however, expect new allocation/buffer growth/copy cost. +void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window) +{ + window->MemoryCompacted = true; + window->MemoryDrawListIdxCapacity = window->DrawList->IdxBuffer.Capacity; + window->MemoryDrawListVtxCapacity = window->DrawList->VtxBuffer.Capacity; + window->IDStack.clear(); + window->DrawList->_ClearFreeMemory(); + window->DC.ChildWindows.clear(); + window->DC.ItemWidthStack.clear(); + window->DC.TextWrapPosStack.clear(); +} + +void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window) +{ + // We stored capacity of the ImDrawList buffer to reduce growth-caused allocation/copy when awakening. + // The other buffers tends to amortize much faster. + window->MemoryCompacted = false; + window->DrawList->IdxBuffer.reserve(window->MemoryDrawListIdxCapacity); + window->DrawList->VtxBuffer.reserve(window->MemoryDrawListVtxCapacity); + window->MemoryDrawListIdxCapacity = window->MemoryDrawListVtxCapacity = 0; +} + +void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + g.ActiveIdIsJustActivated = (g.ActiveId != id); + if (g.ActiveIdIsJustActivated) + { + g.ActiveIdTimer = 0.0f; + g.ActiveIdHasBeenPressedBefore = false; + g.ActiveIdHasBeenEditedBefore = false; + g.ActiveIdMouseButton = -1; + if (id != 0) + { + g.LastActiveId = id; + g.LastActiveIdTimer = 0.0f; + } + } + g.ActiveId = id; + g.ActiveIdAllowOverlap = false; + g.ActiveIdNoClearOnFocusLoss = false; + g.ActiveIdWindow = window; + g.ActiveIdHasBeenEditedThisFrame = false; + if (id) + { + g.ActiveIdIsAlive = id; + g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustMovedToId == id) ? (ImGuiInputSource)ImGuiInputSource_Nav : ImGuiInputSource_Mouse; + } + + // Clear declaration of inputs claimed by the widget + // (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet) + g.ActiveIdUsingMouseWheel = false; + g.ActiveIdUsingNavDirMask = 0x00; + g.ActiveIdUsingNavInputMask = 0x00; + g.ActiveIdUsingKeyInputMask.ClearAllBits(); +} + +void ImGui::ClearActiveID() +{ + SetActiveID(0, NULL); // g.ActiveId = 0; +} + +void ImGui::SetHoveredID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.HoveredId = id; + g.HoveredIdAllowOverlap = false; + g.HoveredIdUsingMouseWheel = false; + if (id != 0 && g.HoveredIdPreviousFrame != id) + g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f; +} + +ImGuiID ImGui::GetHoveredID() +{ + ImGuiContext& g = *GImGui; + return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame; +} + +void ImGui::KeepAliveID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId == id) + g.ActiveIdIsAlive = id; + if (g.ActiveIdPreviousFrame == id) + g.ActiveIdPreviousFrameIsAlive = true; +} + +void ImGui::MarkItemEdited(ImGuiID id) +{ + // This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit(). + // ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need need to fill the data. + ImGuiContext& g = *GImGui; + IM_ASSERT(g.ActiveId == id || g.ActiveId == 0 || g.DragDropActive); + IM_UNUSED(id); // Avoid unused variable warnings when asserts are compiled out. + //IM_ASSERT(g.CurrentWindow->DC.LastItemId == id); + g.ActiveIdHasBeenEditedThisFrame = true; + g.ActiveIdHasBeenEditedBefore = true; + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited; +} + +static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags) +{ + // An active popup disable hovering on other windows (apart from its own children) + // FIXME-OPT: This could be cached/stored within the window. + ImGuiContext& g = *GImGui; + if (g.NavWindow) + if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindowDockTree) + if (focused_root_window->WasActive && focused_root_window != window->RootWindowDockTree) + { + // For the purpose of those flags we differentiate "standard popup" from "modal popup" + // NB: The order of those two tests is important because Modal windows are also Popups. + if (focused_root_window->Flags & ImGuiWindowFlags_Modal) + return false; + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + return false; + } + + // Filter by viewport + if (window->Viewport != g.MouseViewport) + if (g.MovingWindow == NULL || window->RootWindowDockTree != g.MovingWindow->RootWindowDockTree) + return false; + + return true; +} + +// This is roughly matching the behavior of internal-facing ItemHoverable() +// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered() +// - this should work even for non-interactive items that have no ID, so we cannot use LastItemId +bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavDisableMouseHover && !g.NavDisableHighlight) + { + if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) + return false; + if (!IsItemFocused()) + return false; + } + else + { + // Test for bounding box overlap, as updated as ItemAdd() + ImGuiItemStatusFlags status_flags = g.LastItemData.StatusFlags; + if (!(status_flags & ImGuiItemStatusFlags_HoveredRect)) + return false; + IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy)) == 0); // Flags not supported by this function + + // Test if we are hovering the right window (our window could be behind another window) + // [2021/03/02] Reworked / reverted the revert, finally. Note we want e.g. BeginGroup/ItemAdd/EndGroup to work as well. (#3851) + // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable + // to use IsItemHovered() after EndChild() itself. Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was + // the test that has been running for a long while. + if (g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0) + if ((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0) + return false; + + // Test if another item is active (e.g. being dragged) + if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0) + if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap) + if (g.ActiveId != window->MoveId && g.ActiveId != window->TabId) + return false; + + // Test if interactions on this window are blocked by an active popup or modal. + // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here. + if (!IsWindowContentHoverable(window, flags)) + return false; + + // Test if the item is disabled + if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) + return false; + + // Special handling for calling after Begin() which represent the title bar or tab. + // When the window is skipped/collapsed (SkipItems==true) that last item (always ->MoveId submitted by Begin) + // will never be overwritten so we need to detect the case. + if (g.LastItemData.ID == window->MoveId && window->WriteAccessed) + return false; + } + + return true; +} + +// Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). +bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) +{ + ImGuiContext& g = *GImGui; + if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) + return false; + + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow != window) + return false; + if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) + return false; + if (!IsMouseHoveringRect(bb.Min, bb.Max)) + return false; + if (g.NavDisableMouseHover) + return false; + if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) + { + g.HoveredIdDisabled = true; + return false; + } + + // We exceptionally allow this function to be called with id==0 to allow using it for easy high-level + // hover test in widgets code. We could also decide to split this function is two. + if (id != 0) + SetHoveredID(id); + + // When disabled we'll return false but still set HoveredId + ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); + if (item_flags & ImGuiItemFlags_Disabled) + { + // Release active id if turning disabled + if (g.ActiveId == id) + ClearActiveID(); + g.HoveredIdDisabled = true; + return false; + } + + if (id != 0) + { + // [DEBUG] Item Picker tool! + // We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making + // the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered + // items if we perform the test in ItemAdd(), but that would incur a small runtime cost. + // #define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX in imconfig.h if you want this check to also be performed in ItemAdd(). + if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id) + GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255)); + if (g.DebugItemPickerBreakId == id) + IM_DEBUG_BREAK(); + } + + return true; +} + +bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!bb.Overlaps(window->ClipRect)) + if (id == 0 || (id != g.ActiveId && id != g.NavId)) + if (!g.LogEnabled) + return true; + return false; +} + +// This is also inlined in ItemAdd() +// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect! +void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect) +{ + ImGuiContext& g = *GImGui; + g.LastItemData.ID = item_id; + g.LastItemData.InFlags = in_flags; + g.LastItemData.StatusFlags = item_flags; + g.LastItemData.Rect = item_rect; +} + +float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) +{ + if (wrap_pos_x < 0.0f) + return 0.0f; + + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (wrap_pos_x == 0.0f) + { + // We could decide to setup a default wrapping max point for auto-resizing windows, + // or have auto-wrap (with unspecified wrapping pos) behave as a ContentSize extending function? + //if (window->Hidden && (window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) + // wrap_pos_x = ImMax(window->WorkRect.Min.x + g.FontSize * 10.0f, window->WorkRect.Max.x); + //else + wrap_pos_x = window->WorkRect.Max.x; + } + else if (wrap_pos_x > 0.0f) + { + wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space + } + + return ImMax(wrap_pos_x - pos.x, 1.0f); +} + +// IM_ALLOC() == ImGui::MemAlloc() +void* ImGui::MemAlloc(size_t size) +{ + if (ImGuiContext* ctx = GImGui) + ctx->IO.MetricsActiveAllocations++; + return (*GImAllocatorAllocFunc)(size, GImAllocatorUserData); +} + +// IM_FREE() == ImGui::MemFree() +void ImGui::MemFree(void* ptr) +{ + if (ptr) + if (ImGuiContext* ctx = GImGui) + ctx->IO.MetricsActiveAllocations--; + return (*GImAllocatorFreeFunc)(ptr, GImAllocatorUserData); +} + +const char* ImGui::GetClipboardText() +{ + ImGuiContext& g = *GImGui; + return g.IO.GetClipboardTextFn ? g.IO.GetClipboardTextFn(g.IO.ClipboardUserData) : ""; +} + +void ImGui::SetClipboardText(const char* text) +{ + ImGuiContext& g = *GImGui; + if (g.IO.SetClipboardTextFn) + g.IO.SetClipboardTextFn(g.IO.ClipboardUserData, text); +} + +const char* ImGui::GetVersion() +{ + return IMGUI_VERSION; +} + +// Internal state access - if you want to share Dear 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 +ImGuiContext* ImGui::GetCurrentContext() +{ + return GImGui; +} + +void ImGui::SetCurrentContext(ImGuiContext* ctx) +{ +#ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC + IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this. +#else + GImGui = ctx; +#endif +} + +void ImGui::SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data) +{ + GImAllocatorAllocFunc = alloc_func; + GImAllocatorFreeFunc = free_func; + GImAllocatorUserData = user_data; +} + +// This is provided to facilitate copying allocators from one static/DLL boundary to another (e.g. retrieve default allocator of your executable address space) +void ImGui::GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data) +{ + *p_alloc_func = GImAllocatorAllocFunc; + *p_free_func = GImAllocatorFreeFunc; + *p_user_data = GImAllocatorUserData; +} + +ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) +{ + ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); + if (GImGui == NULL) + SetCurrentContext(ctx); + Initialize(ctx); + return ctx; +} + +void ImGui::DestroyContext(ImGuiContext* ctx) +{ + if (ctx == NULL) + ctx = GImGui; + Shutdown(ctx); + if (GImGui == ctx) + SetCurrentContext(NULL); + IM_DELETE(ctx); +} + +// No specific ordering/dependency support, will see as needed +ImGuiID ImGui::AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook) +{ + ImGuiContext& g = *ctx; + IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_); + g.Hooks.push_back(*hook); + g.Hooks.back().HookId = ++g.HookIdNext; + return g.HookIdNext; +} + +// Deferred removal, avoiding issue with changing vector while iterating it +void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id) +{ + ImGuiContext& g = *ctx; + IM_ASSERT(hook_id != 0); + for (int n = 0; n < g.Hooks.Size; n++) + if (g.Hooks[n].HookId == hook_id) + g.Hooks[n].Type = ImGuiContextHookType_PendingRemoval_; +} + +// Call context hooks (used by e.g. test engine) +// We assume a small number of hooks so all stored in same array +void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type) +{ + ImGuiContext& g = *ctx; + for (int n = 0; n < g.Hooks.Size; n++) + if (g.Hooks[n].Type == hook_type) + g.Hooks[n].Callback(&g, &g.Hooks[n]); +} + +ImGuiIO& ImGui::GetIO() +{ + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); + return GImGui->IO; +} + +ImGuiPlatformIO& ImGui::GetPlatformIO() +{ + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); + return GImGui->PlatformIO; +} + +// Pass this to your backend rendering function! Valid after Render() and until the next call to NewFrame() +ImDrawData* ImGui::GetDrawData() +{ + ImGuiContext& g = *GImGui; + ImGuiViewportP* viewport = g.Viewports[0]; + return viewport->DrawDataP.Valid ? &viewport->DrawDataP : NULL; +} + +double ImGui::GetTime() +{ + return GImGui->Time; +} + +int ImGui::GetFrameCount() +{ + return GImGui->FrameCount; +} + +static ImDrawList* GetViewportDrawList(ImGuiViewportP* viewport, size_t drawlist_no, const char* drawlist_name) +{ + // Create the draw list on demand, because they are not frequently used for all viewports + ImGuiContext& g = *GImGui; + IM_ASSERT(drawlist_no < IM_ARRAYSIZE(viewport->DrawLists)); + ImDrawList* draw_list = viewport->DrawLists[drawlist_no]; + if (draw_list == NULL) + { + draw_list = IM_NEW(ImDrawList)(&g.DrawListSharedData); + draw_list->_OwnerName = drawlist_name; + viewport->DrawLists[drawlist_no] = draw_list; + } + + // Our ImDrawList system requires that there is always a command + if (viewport->DrawListsLastFrame[drawlist_no] != g.FrameCount) + { + draw_list->_ResetForNewFrame(); + draw_list->PushTextureID(g.IO.Fonts->TexID); + draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false); + viewport->DrawListsLastFrame[drawlist_no] = g.FrameCount; + } + return draw_list; +} + +ImDrawList* ImGui::GetBackgroundDrawList(ImGuiViewport* viewport) +{ + return GetViewportDrawList((ImGuiViewportP*)viewport, 0, "##Background"); +} + +ImDrawList* ImGui::GetBackgroundDrawList() +{ + ImGuiContext& g = *GImGui; + return GetBackgroundDrawList(g.CurrentWindow->Viewport); +} + +ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport) +{ + return GetViewportDrawList((ImGuiViewportP*)viewport, 1, "##Foreground"); +} + +ImDrawList* ImGui::GetForegroundDrawList() +{ + ImGuiContext& g = *GImGui; + return GetForegroundDrawList(g.CurrentWindow->Viewport); +} + +ImDrawListSharedData* ImGui::GetDrawListSharedData() +{ + return &GImGui->DrawListSharedData; +} + +void ImGui::StartMouseMovingWindow(ImGuiWindow* window) +{ + // Set ActiveId even if the _NoMove flag is set. Without it, dragging away from a window with _NoMove would activate hover on other windows. + // We _also_ call this when clicking in a window empty space when io.ConfigWindowsMoveFromTitleBarOnly is set, but clear g.MovingWindow afterward. + // This is because we want ActiveId to be set even when the window is not permitted to move. + ImGuiContext& g = *GImGui; + FocusWindow(window); + SetActiveID(window->MoveId, window); + g.NavDisableHighlight = true; + g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - window->RootWindowDockTree->Pos; + g.ActiveIdNoClearOnFocusLoss = true; + SetActiveIdUsingNavAndKeys(); + + bool can_move_window = true; + if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindowDockTree->Flags & ImGuiWindowFlags_NoMove)) + can_move_window = false; + if (ImGuiDockNode* node = window->DockNodeAsHost) + if (node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove)) + can_move_window = false; + if (can_move_window) + g.MovingWindow = window; +} + +// We use 'undock_floating_node == false' when dragging from title bar to allow moving groups of floating nodes without undocking them. +// - undock_floating_node == true: when dragging from a floating node within a hierarchy, always undock the node. +// - undock_floating_node == false: when dragging from a floating node within a hierarchy, move root window. +void ImGui::StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock_floating_node) +{ + ImGuiContext& g = *GImGui; + bool can_undock_node = false; + if (node != NULL && node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove) == 0) + { + // Can undock if: + // - part of a floating node hierarchy with more than one visible node (if only one is visible, we'll just move the whole hierarchy) + // - part of a dockspace node hierarchy (trivia: undocking from a fixed/central node will create a new node and copy windows) + ImGuiDockNode* root_node = DockNodeGetRootNode(node); + if (root_node->OnlyNodeWithWindows != node || root_node->CentralNode != NULL) // -V1051 PVS-Studio thinks node should be root_node and is wrong about that. + if (undock_floating_node || root_node->IsDockSpace()) + can_undock_node = true; + } + + const bool clicked = IsMouseClicked(0); + const bool dragging = IsMouseDragging(0, g.IO.MouseDragThreshold * 1.70f); + if (can_undock_node && dragging) + DockContextQueueUndockNode(&g, node); // Will lead to DockNodeStartMouseMovingWindow() -> StartMouseMovingWindow() being called next frame + else if (!can_undock_node && (clicked || dragging) && g.MovingWindow != window) + StartMouseMovingWindow(window); +} + +// Handle mouse moving window +// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing() +// FIXME: We don't have strong guarantee that g.MovingWindow stay synched with g.ActiveId == g.MovingWindow->MoveId. +// This is currently enforced by the fact that BeginDragDropSource() is setting all g.ActiveIdUsingXXXX flags to inhibit navigation inputs, +// but if we should more thoroughly test cases where g.ActiveId or g.MovingWindow gets changed and not the other. +void ImGui::UpdateMouseMovingWindowNewFrame() +{ + ImGuiContext& g = *GImGui; + if (g.MovingWindow != NULL) + { + // We actually want to move the root window. g.MovingWindow == window we clicked on (could be a child window). + // We track it to preserve Focus and so that generally ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. + KeepAliveID(g.ActiveId); + IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindowDockTree); + ImGuiWindow* moving_window = g.MovingWindow->RootWindowDockTree; + + // When a window stop being submitted while being dragged, it may will its viewport until next Begin() + const bool window_disappared = (!moving_window->WasActive || moving_window->Viewport == NULL); + if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos) && !window_disappared) + { + ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; + if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y) + { + MarkIniSettingsDirty(moving_window); + SetWindowPos(moving_window, pos, ImGuiCond_Always); + if (moving_window->ViewportOwned) // Synchronize viewport immediately because some overlays may relies on clipping rectangle before we Begin() into the window. + { + moving_window->Viewport->Pos = pos; + moving_window->Viewport->UpdateWorkRect(); + } + } + FocusWindow(g.MovingWindow); + } + else + { + if (!window_disappared) + { + // Try to merge the window back into the main viewport. + // This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports) + if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) + UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport); + + // Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button. + if (!IsDragDropPayloadBeingAccepted()) + g.MouseViewport = moving_window->Viewport; + + // Clear the NoInput window flag set by the Viewport system + moving_window->Viewport->Flags &= ~ImGuiViewportFlags_NoInputs; // FIXME-VIEWPORT: Test engine managed to crash here because Viewport was NULL. + } + + g.MovingWindow = NULL; + ClearActiveID(); + } + } + else + { + // When clicking/dragging from a window that has the _NoMove flag, we still set the ActiveId in order to prevent hovering others. + if (g.ActiveIdWindow && g.ActiveIdWindow->MoveId == g.ActiveId) + { + KeepAliveID(g.ActiveId); + if (!g.IO.MouseDown[0]) + ClearActiveID(); + } + } +} + +// Initiate moving window when clicking on empty space or title bar. +// Handle left-click and right-click focus. +void ImGui::UpdateMouseMovingWindowEndFrame() +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId != 0 || g.HoveredId != 0) + return; + + // Unless we just made a window/popup appear + if (g.NavWindow && g.NavWindow->Appearing) + return; + + // Click on empty space to focus window and start moving + // (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!) + if (g.IO.MouseClicked[0]) + { + // Handle the edge case of a popup being closed while clicking in its empty space. + // If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more. + ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; + const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(root_window->PopupId, ImGuiPopupFlags_AnyPopupLevel); + + if (root_window != NULL && !is_closed_popup) + { + StartMouseMovingWindow(g.HoveredWindow); //-V595 + + // Cancel moving if clicked outside of title bar + if (g.IO.ConfigWindowsMoveFromTitleBarOnly) + if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar) || root_window->DockIsActive) + if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) + g.MovingWindow = NULL; + + // Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already) + if (g.HoveredIdDisabled) + g.MovingWindow = NULL; + } + else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL) + { + // Clicking on void disable focus + FocusWindow(NULL); + } + } + + // With right mouse button we close popups without changing focus based on where the mouse is aimed + // Instead, focus will be restored to the window under the bottom-most closed popup. + // (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger) + if (g.IO.MouseClicked[1]) + { + // Find the top-most window between HoveredWindow and the top-most Modal Window. + // This is where we can trim the popup stack. + ImGuiWindow* modal = GetTopMostPopupModal(); + bool hovered_window_above_modal = g.HoveredWindow && (modal == NULL || IsWindowAbove(g.HoveredWindow, modal)); + ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal, true); + } +} + +static void TranslateWindow(ImGuiWindow* window, const ImVec2& delta) +{ + window->Pos += delta; + window->ClipRect.Translate(delta); + window->OuterRectClipped.Translate(delta); + window->InnerRect.Translate(delta); + window->DC.CursorPos += delta; + window->DC.CursorStartPos += delta; + window->DC.CursorMaxPos += delta; +} + +static void ScaleWindow(ImGuiWindow* window, float scale) +{ + ImVec2 origin = window->Viewport->Pos; + window->Pos = ImFloor((window->Pos - origin) * scale + origin); + window->Size = ImFloor(window->Size * scale); + window->SizeFull = ImFloor(window->SizeFull * scale); + window->ContentSize = ImFloor(window->ContentSize * scale); +} + +static bool IsWindowActiveAndVisible(ImGuiWindow* window) +{ + return (window->Active) && (!window->Hidden); +} + +static void ImGui::UpdateKeyboardInputs() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools + io.KeyMods = GetMergedKeyModFlags(); + + // Import legacy keys or verify they are not used +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + if (io.BackendUsingLegacyKeyArrays == 0) + { + // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written too. + for (int n = 0; n < IM_ARRAYSIZE(io.KeysDown); n++) + IM_ASSERT(io.KeysDown[n] == false && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + } + else + { + if (g.FrameCount == 0) + for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++) + IM_ASSERT(g.IO.KeyMap[n] == -1 && "Backend is not allowed to write to io.KeyMap[0..511]!"); + + // Build reverse KeyMap (Named -> Legacy) + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++) + if (io.KeyMap[n] != -1) + { + IM_ASSERT(IsLegacyKey((ImGuiKey)io.KeyMap[n])); + io.KeyMap[io.KeyMap[n]] = n; + } + + // Import legacy keys into new ones + for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++) + if (io.KeysDown[n] || io.BackendUsingLegacyKeyArrays == 1) + { + const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n); + IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key)); + io.KeysData[key].Down = io.KeysDown[n]; + io.BackendUsingLegacyKeyArrays = 1; + } + if (io.BackendUsingLegacyKeyArrays == 1) + { + io.KeysData[ImGuiKey_ModCtrl].Down = io.KeyCtrl; + io.KeysData[ImGuiKey_ModShift].Down = io.KeyShift; + io.KeysData[ImGuiKey_ModAlt].Down = io.KeyAlt; + io.KeysData[ImGuiKey_ModSuper].Down = io.KeySuper; + } + } +#endif + + // Clear gamepad data if disabled + if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0) + for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++) + { + io.KeysData[i - ImGuiKey_KeysData_OFFSET].Down = false; + io.KeysData[i - ImGuiKey_KeysData_OFFSET].AnalogValue = 0.0f; + } + + // Update keys + for (int i = 0; i < IM_ARRAYSIZE(io.KeysData); i++) + { + ImGuiKeyData& key_data = io.KeysData[i]; + key_data.DownDurationPrev = key_data.DownDuration; + key_data.DownDuration = key_data.Down ? (key_data.DownDuration < 0.0f ? 0.0f : key_data.DownDuration + io.DeltaTime) : -1.0f; + } +} + +static void ImGui::UpdateMouseInputs() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) + if (IsMousePosValid(&io.MousePos)) + io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos); + + // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta + if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev)) + io.MouseDelta = io.MousePos - io.MousePosPrev; + else + io.MouseDelta = ImVec2(0.0f, 0.0f); + + // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true. + if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) + g.NavDisableMouseHover = false; + + io.MousePosPrev = io.MousePos; + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + { + io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f; + io.MouseClickedCount[i] = 0; // Will be filled below + io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f; + io.MouseDownDurationPrev[i] = io.MouseDownDuration[i]; + io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f; + if (io.MouseClicked[i]) + { + bool is_repeated_click = false; + if ((float)(g.Time - io.MouseClickedTime[i]) < io.MouseDoubleClickTime) + { + ImVec2 delta_from_click_pos = IsMousePosValid(&io.MousePos) ? (io.MousePos - io.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); + if (ImLengthSqr(delta_from_click_pos) < io.MouseDoubleClickMaxDist * io.MouseDoubleClickMaxDist) + is_repeated_click = true; + } + if (is_repeated_click) + io.MouseClickedLastCount[i]++; + else + io.MouseClickedLastCount[i] = 1; + io.MouseClickedTime[i] = g.Time; + io.MouseClickedPos[i] = io.MousePos; + io.MouseClickedCount[i] = io.MouseClickedLastCount[i]; + io.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); + io.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (io.MouseDown[i]) + { + // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold + ImVec2 delta_from_click_pos = IsMousePosValid(&io.MousePos) ? (io.MousePos - io.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); + io.MouseDragMaxDistanceSqr[i] = ImMax(io.MouseDragMaxDistanceSqr[i], ImLengthSqr(delta_from_click_pos)); + io.MouseDragMaxDistanceAbs[i].x = ImMax(io.MouseDragMaxDistanceAbs[i].x, delta_from_click_pos.x < 0.0f ? -delta_from_click_pos.x : delta_from_click_pos.x); + io.MouseDragMaxDistanceAbs[i].y = ImMax(io.MouseDragMaxDistanceAbs[i].y, delta_from_click_pos.y < 0.0f ? -delta_from_click_pos.y : delta_from_click_pos.y); + } + + // We provide io.MouseDoubleClicked[] as a legacy service + io.MouseDoubleClicked[i] = (io.MouseClickedCount[i] == 2); + + // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation + if (io.MouseClicked[i]) + g.NavDisableMouseHover = false; + } +} + +static void StartLockWheelingWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.WheelingWindow == window) + return; + g.WheelingWindow = window; + g.WheelingWindowRefMousePos = g.IO.MousePos; + g.WheelingWindowTimer = WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER; +} + +void ImGui::UpdateMouseWheel() +{ + ImGuiContext& g = *GImGui; + + // Reset the locked window if we move the mouse or after the timer elapses + if (g.WheelingWindow != NULL) + { + g.WheelingWindowTimer -= g.IO.DeltaTime; + if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold) + g.WheelingWindowTimer = 0.0f; + if (g.WheelingWindowTimer <= 0.0f) + { + g.WheelingWindow = NULL; + g.WheelingWindowTimer = 0.0f; + } + } + + if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f) + return; + + if ((g.ActiveId != 0 && g.ActiveIdUsingMouseWheel) || (g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrameUsingMouseWheel)) + return; + + ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; + if (!window || window->Collapsed) + return; + + // Zoom / Scale window + // FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned. + if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling) + { + StartLockWheelingWindow(window); + const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + const float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; + if (window == window->RootWindow) + { + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + SetWindowPos(window, window->Pos + offset, 0); + window->Size = ImFloor(window->Size * scale); + window->SizeFull = ImFloor(window->SizeFull * scale); + } + return; + } + + // Mouse wheel scrolling + // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent + if (g.IO.KeyCtrl) + return; + + // As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead + // (we avoid doing it on OSX as it the OS input layer handles this already) + const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors; + const float wheel_y = swap_axis ? 0.0f : g.IO.MouseWheel; + const float wheel_x = swap_axis ? g.IO.MouseWheel : g.IO.MouseWheelH; + + // Vertical Mouse Wheel scrolling + if (wheel_y != 0.0f) + { + StartLockWheelingWindow(window); + while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) + window = window->ParentWindow; + if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) + { + float max_step = window->InnerRect.GetHeight() * 0.67f; + float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step)); + SetScrollY(window, window->Scroll.y - wheel_y * scroll_step); + } + } + + // Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held + if (wheel_x != 0.0f) + { + StartLockWheelingWindow(window); + while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) + window = window->ParentWindow; + if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) + { + float max_step = window->InnerRect.GetWidth() * 0.67f; + float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step)); + SetScrollX(window, window->Scroll.x - wheel_x * scroll_step); + } + } +} + +// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app) +void ImGui::UpdateHoveredWindowAndCaptureFlags() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING)); + + // Find the window hovered by mouse: + // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. + // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame. + // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. + bool clear_hovered_windows = false; + FindHoveredWindow(); + IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MouseViewport); + + // Modal windows prevents mouse from hovering behind them. + ImGuiWindow* modal_window = GetTopMostPopupModal(); + if (modal_window && g.HoveredWindow && !IsWindowWithinBeginStackOf(g.HoveredWindow->RootWindow, modal_window)) // FIXME-MERGE: RootWindowDockTree ? + clear_hovered_windows = true; + + // Disabled mouse? + if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) + clear_hovered_windows = true; + + // We track click ownership. When clicked outside of a window the click is owned by the application and + // won't report hovering nor request capture even while dragging over our windows afterward. + const bool has_open_popup = (g.OpenPopupStack.Size > 0); + const bool has_open_modal = (modal_window != NULL); + int mouse_earliest_down = -1; + bool mouse_any_down = false; + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + { + if (io.MouseClicked[i]) + { + io.MouseDownOwned[i] = (g.HoveredWindow != NULL) || has_open_popup; + io.MouseDownOwnedUnlessPopupClose[i] = (g.HoveredWindow != NULL) || has_open_modal; + } + mouse_any_down |= io.MouseDown[i]; + if (io.MouseDown[i]) + if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down]) + mouse_earliest_down = i; + } + const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down]; + const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down]; + + // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. + // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) + const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; + if (!mouse_avail && !mouse_dragging_extern_payload) + clear_hovered_windows = true; + + if (clear_hovered_windows) + g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; + + // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to Dear ImGui only, false = dispatch mouse to Dear ImGui + underlying app) + // Update io.WantCaptureMouseAllowPopupClose (experimental) to give a chance for app to react to popup closure with a drag + if (g.WantCaptureMouseNextFrame != -1) + { + io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (g.WantCaptureMouseNextFrame != 0); + } + else + { + io.WantCaptureMouse = (mouse_avail && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup; + io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal; + } + + // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to Dear ImGui only, false = dispatch keyboard info to Dear ImGui + underlying app) + if (g.WantCaptureKeyboardNextFrame != -1) + io.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); + else + io.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); + if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) + io.WantCaptureKeyboard = true; + + // Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible + io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; +} + +ImGuiKeyModFlags ImGui::GetMergedKeyModFlags() +{ + ImGuiContext& g = *GImGui; + ImGuiKeyModFlags key_mod_flags = ImGuiKeyModFlags_None; + if (g.IO.KeyCtrl) { key_mod_flags |= ImGuiKeyModFlags_Ctrl; } + if (g.IO.KeyShift) { key_mod_flags |= ImGuiKeyModFlags_Shift; } + if (g.IO.KeyAlt) { key_mod_flags |= ImGuiKeyModFlags_Alt; } + if (g.IO.KeySuper) { key_mod_flags |= ImGuiKeyModFlags_Super; } + return key_mod_flags; +} + +void ImGui::NewFrame() +{ + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); + ImGuiContext& g = *GImGui; + + // Remove pending delete hooks before frame start. + // This deferred removal avoid issues of removal while iterating the hook vector + for (int n = g.Hooks.Size - 1; n >= 0; n--) + if (g.Hooks[n].Type == ImGuiContextHookType_PendingRemoval_) + g.Hooks.erase(&g.Hooks[n]); + + CallContextHooks(&g, ImGuiContextHookType_NewFramePre); + + // Check and assert for various common IO and Configuration mistakes + g.ConfigFlagsLastFrame = g.ConfigFlagsCurrFrame; + ErrorCheckNewFrameSanityChecks(); + g.ConfigFlagsCurrFrame = g.IO.ConfigFlags; + + // Load settings on first frame, save settings when modified (after a delay) + UpdateSettings(); + + g.Time += g.IO.DeltaTime; + g.WithinFrameScope = true; + g.FrameCount += 1; + g.TooltipOverrideCount = 0; + g.WindowsActiveCount = 0; + g.MenusIdSubmittedThisFrame.resize(0); + + // 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.FramerateSecPerFrameCount = ImMin(g.FramerateSecPerFrameCount + 1, IM_ARRAYSIZE(g.FramerateSecPerFrame)); + g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)g.FramerateSecPerFrameCount)) : FLT_MAX; + + UpdateViewportsNewFrame(); + + // Setup current font and draw list shared data + // FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal! + g.IO.Fonts->Locked = true; + SetCurrentFont(GetDefaultFont()); + IM_ASSERT(g.Font->IsLoaded()); + ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); + for (int n = 0; n < g.Viewports.Size; n++) + virtual_space.Add(g.Viewports[n]->GetMainRect()); + g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4(); + g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; + g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError); + g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; + if (g.Style.AntiAliasedLines) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines; + if (g.Style.AntiAliasedLinesUseTex && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex; + if (g.Style.AntiAliasedFill) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; + if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; + + // Mark rendering data as invalid to prevent user who may have a handle on it to use it. + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + viewport->DrawData = NULL; + viewport->DrawDataP.Clear(); + } + + // Drag and drop keep the source ID alive so even if the source disappear our state is consistent + if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId) + KeepAliveID(g.DragDropPayload.SourceId); + + // Update HoveredId data + if (!g.HoveredIdPreviousFrame) + g.HoveredIdTimer = 0.0f; + if (!g.HoveredIdPreviousFrame || (g.HoveredId && g.ActiveId == g.HoveredId)) + g.HoveredIdNotActiveTimer = 0.0f; + if (g.HoveredId) + g.HoveredIdTimer += g.IO.DeltaTime; + if (g.HoveredId && g.ActiveId != g.HoveredId) + g.HoveredIdNotActiveTimer += g.IO.DeltaTime; + g.HoveredIdPreviousFrame = g.HoveredId; + g.HoveredIdPreviousFrameUsingMouseWheel = g.HoveredIdUsingMouseWheel; + g.HoveredId = 0; + g.HoveredIdAllowOverlap = false; + g.HoveredIdUsingMouseWheel = false; + g.HoveredIdDisabled = false; + + // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore) + if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + ClearActiveID(); + if (g.ActiveId) + g.ActiveIdTimer += g.IO.DeltaTime; + g.LastActiveIdTimer += g.IO.DeltaTime; + g.ActiveIdPreviousFrame = g.ActiveId; + g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow; + g.ActiveIdPreviousFrameHasBeenEditedBefore = g.ActiveIdHasBeenEditedBefore; + g.ActiveIdIsAlive = 0; + g.ActiveIdHasBeenEditedThisFrame = false; + g.ActiveIdPreviousFrameIsAlive = false; + g.ActiveIdIsJustActivated = false; + if (g.TempInputId != 0 && g.ActiveId != g.TempInputId) + g.TempInputId = 0; + if (g.ActiveId == 0) + { + g.ActiveIdUsingNavDirMask = 0x00; + g.ActiveIdUsingNavInputMask = 0x00; + g.ActiveIdUsingKeyInputMask.ClearAllBits(); + } + + // Drag and drop + g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; + g.DragDropAcceptIdCurr = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; + g.DragDropWithinSource = false; + g.DragDropWithinTarget = false; + g.DragDropHoldJustPressedId = 0; + + // Close popups on focus lost (currently wip/opt-in) + //if (g.IO.AppFocusLost) + // ClosePopupsExceptModals(); + + // Process input queue (trickle as many events as possible) + g.InputEventsTrail.resize(0); + UpdateInputEvents(g.IO.ConfigInputTrickleEventQueue); + + // Update keyboard input state + UpdateKeyboardInputs(); + + //IM_ASSERT(g.IO.KeyCtrl == IsKeyDown(ImGuiKey_LeftCtrl) || IsKeyDown(ImGuiKey_RightCtrl)); + //IM_ASSERT(g.IO.KeyShift == IsKeyDown(ImGuiKey_LeftShift) || IsKeyDown(ImGuiKey_RightShift)); + //IM_ASSERT(g.IO.KeyAlt == IsKeyDown(ImGuiKey_LeftAlt) || IsKeyDown(ImGuiKey_RightAlt)); + //IM_ASSERT(g.IO.KeySuper == IsKeyDown(ImGuiKey_LeftSuper) || IsKeyDown(ImGuiKey_RightSuper)); + + // Update gamepad/keyboard navigation + NavUpdate(); + + // Update mouse input state + UpdateMouseInputs(); + + // Undocking + // (needs to be before UpdateMouseMovingWindowNewFrame so the window is already offset and following the mouse on the detaching frame) + DockContextNewFrameUpdateUndocking(&g); + + // Find hovered window + // (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame) + UpdateHoveredWindowAndCaptureFlags(); + + // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) + UpdateMouseMovingWindowNewFrame(); + + // Background darkening/whitening + if (GetTopMostPopupModal() != NULL || (g.NavWindowingTarget != NULL && g.NavWindowingHighlightAlpha > 0.0f)) + g.DimBgRatio = ImMin(g.DimBgRatio + g.IO.DeltaTime * 6.0f, 1.0f); + else + g.DimBgRatio = ImMax(g.DimBgRatio - g.IO.DeltaTime * 10.0f, 0.0f); + + g.MouseCursor = ImGuiMouseCursor_Arrow; + g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; + + // Platform IME data: reset for the frame + g.PlatformImeDataPrev = g.PlatformImeData; + g.PlatformImeData.WantVisible = false; + + // Mouse wheel scrolling, scale + UpdateMouseWheel(); + + // Mark all windows as not visible and compact unused memory. + IM_ASSERT(g.WindowsFocusOrder.Size <= g.Windows.Size); + const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer; + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + window->WasActive = window->Active; + window->BeginCount = 0; + window->Active = false; + window->WriteAccessed = false; + + // Garbage collect transient buffers of recently unused windows + if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) + GcCompactTransientWindowBuffers(window); + } + + // Garbage collect transient buffers of recently unused tables + for (int i = 0; i < g.TablesLastTimeActive.Size; i++) + if (g.TablesLastTimeActive[i] >= 0.0f && g.TablesLastTimeActive[i] < memory_compact_start_time) + TableGcCompactTransientBuffers(g.Tables.GetByIndex(i)); + for (int i = 0; i < g.TablesTempData.Size; i++) + if (g.TablesTempData[i].LastTimeActive >= 0.0f && g.TablesTempData[i].LastTimeActive < memory_compact_start_time) + TableGcCompactTransientBuffers(&g.TablesTempData[i]); + if (g.GcCompactAll) + GcCompactTransientMiscBuffers(); + g.GcCompactAll = false; + + // Closing the focused window restore focus to the first active root window in descending z-order + if (g.NavWindow && !g.NavWindow->WasActive) + FocusTopMostWindowUnderOne(NULL, NULL); + + // 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); + g.BeginPopupStack.resize(0); + g.ItemFlagsStack.resize(0); + g.ItemFlagsStack.push_back(ImGuiItemFlags_None); + g.GroupStack.resize(0); + + // Docking + DockContextNewFrameUpdateDocking(&g); + + // [DEBUG] Update debug features + UpdateDebugToolItemPicker(); + UpdateDebugToolStackQueries(); + + // Create implicit/fallback window - which we will only render it if the user has added something to it. + // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. + // This fallback is particularly important as it avoid ImGui:: calls from crashing. + g.WithinFrameScopeWithImplicitWindow = true; + SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver); + Begin("Debug##Default"); + IM_ASSERT(g.CurrentWindow->IsFallbackWindow == true); + + CallContextHooks(&g, ImGuiContextHookType_NewFramePost); +} + +void ImGui::Initialize(ImGuiContext* context) +{ + ImGuiContext& g = *context; + IM_ASSERT(!g.Initialized && !g.SettingsLoaded); + + // Add .ini handle for ImGuiWindow type + { + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Window"; + ini_handler.TypeHash = ImHashStr("Window"); + ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll; + ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen; + ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine; + ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll; + ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll; + g.SettingsHandlers.push_back(ini_handler); + } + + // Add .ini handle for ImGuiTable type + TableSettingsInstallHandler(context); + + // Create default viewport + ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(); + viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID; + viewport->Idx = 0; + viewport->PlatformWindowCreated = true; + viewport->Flags = ImGuiViewportFlags_OwnedByApp; + g.Viewports.push_back(viewport); + g.PlatformIO.Viewports.push_back(g.Viewports[0]); + +#ifdef IMGUI_HAS_DOCK + // Initialize Docking + DockContextInitialize(&g); +#endif + + g.Initialized = true; +} + +// This function is merely here to free heap allocations. +void ImGui::Shutdown(ImGuiContext* context) +{ + // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + ImGuiContext& g = *context; + if (g.IO.Fonts && g.FontAtlasOwnedByContext) + { + g.IO.Fonts->Locked = false; + IM_DELETE(g.IO.Fonts); + } + g.IO.Fonts = NULL; + + // Cleanup of other data are conditional on actually having initialized Dear ImGui. + if (!g.Initialized) + return; + + // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file) + if (g.SettingsLoaded && g.IO.IniFilename != NULL) + { + ImGuiContext* backup_context = GImGui; + SetCurrentContext(&g); + SaveIniSettingsToDisk(g.IO.IniFilename); + SetCurrentContext(backup_context); + } + + // Destroy platform windows + ImGuiContext* backup_context = ImGui::GetCurrentContext(); + SetCurrentContext(context); + DestroyPlatformWindows(); + SetCurrentContext(backup_context); + + // Shutdown extensions + DockContextShutdown(&g); + + CallContextHooks(&g, ImGuiContextHookType_Shutdown); + + // Clear everything else + g.Windows.clear_delete(); + g.WindowsFocusOrder.clear(); + g.WindowsTempSortBuffer.clear(); + g.CurrentWindow = NULL; + g.CurrentWindowStack.clear(); + g.WindowsById.Clear(); + g.NavWindow = NULL; + g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; + g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL; + g.MovingWindow = NULL; + g.ColorStack.clear(); + g.StyleVarStack.clear(); + g.FontStack.clear(); + g.OpenPopupStack.clear(); + g.BeginPopupStack.clear(); + + g.CurrentViewport = g.MouseViewport = g.MouseLastHoveredViewport = NULL; + g.Viewports.clear_delete(); + + g.TabBars.Clear(); + g.CurrentTabBarStack.clear(); + g.ShrinkWidthBuffer.clear(); + + g.ClipperTempData.clear_destruct(); + + g.Tables.Clear(); + g.TablesTempData.clear_destruct(); + g.DrawChannelsTempMergeBuffer.clear(); + + g.ClipboardHandlerData.clear(); + g.MenusIdSubmittedThisFrame.clear(); + g.InputTextState.ClearFreeMemory(); + + g.SettingsWindows.clear(); + g.SettingsHandlers.clear(); + + if (g.LogFile) + { +#ifndef IMGUI_DISABLE_TTY_FUNCTIONS + if (g.LogFile != stdout) +#endif + ImFileClose(g.LogFile); + g.LogFile = NULL; + } + g.LogBuffer.clear(); + + g.Initialized = false; +} + +// FIXME: Add a more explicit sort order in the window structure. +static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) +{ + const ImGuiWindow* const a = *(const ImGuiWindow* const *)lhs; + const ImGuiWindow* const b = *(const ImGuiWindow* const *)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; + return (a->BeginOrderWithinParent - b->BeginOrderWithinParent); +} + +static void AddWindowToSortBuffer(ImVector* out_sorted_windows, ImGuiWindow* window) +{ + out_sorted_windows->push_back(window); + if (window->Active) + { + int count = window->DC.ChildWindows.Size; + ImQsort(window->DC.ChildWindows.Data, (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); + for (int i = 0; i < count; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Active) + AddWindowToSortBuffer(out_sorted_windows, child); + } + } +} + +static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list) +{ + if (draw_list->CmdBuffer.Size == 0) + return; + if (draw_list->CmdBuffer.Size == 1 && draw_list->CmdBuffer[0].ElemCount == 0 && draw_list->CmdBuffer[0].UserCallback == NULL) + return; + + // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. + // May trigger for you if you are using PrimXXX functions incorrectly. + IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size); + IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); + if (!(draw_list->Flags & ImDrawListFlags_AllowVtxOffset)) + IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); + + // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) + // If this assert triggers because you are drawing lots of stuff manually: + // - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds. + // Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics/Debugger window to inspect draw list contents. + // - If you want large meshes with more than 64K vertices, you can either: + // (A) Handle the ImDrawCmd::VtxOffset value in your renderer backend, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'. + // Most example backends already support this from 1.71. Pre-1.71 backends won't. + // Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them. + // (B) Or handle 32-bit indices in your renderer backend, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h. + // Most example backends already support this. For example, the OpenGL example code detect index size at compile-time: + // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + // Your own engine or render API may use different parameters or function calls to specify index sizes. + // 2 and 4 bytes indices are generally supported by most graphics API. + // - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching + // the 64K limit to split your draw commands in multiple draw lists. + if (sizeof(ImDrawIdx) == 2) + IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); + + out_list->push_back(draw_list); +} + +static void AddWindowToDrawData(ImGuiWindow* window, int layer) +{ + ImGuiContext& g = *GImGui; + ImGuiViewportP* viewport = window->Viewport; + g.IO.MetricsRenderWindows++; + if (window->Flags & ImGuiWindowFlags_DockNodeHost) + window->DrawList->ChannelsMerge(); + AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[layer], window->DrawList); + for (int i = 0; i < window->DC.ChildWindows.Size; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (IsWindowActiveAndVisible(child)) // Clipped children may have been marked not active + AddWindowToDrawData(child, layer); + } +} + +static inline int GetWindowDisplayLayer(ImGuiWindow* window) +{ + return (window->Flags & ImGuiWindowFlags_Tooltip) ? 1 : 0; +} + +// Layer is locked for the root window, however child windows may use a different viewport (e.g. extruding menu) +static inline void AddRootWindowToDrawData(ImGuiWindow* window) +{ + AddWindowToDrawData(window, GetWindowDisplayLayer(window)); +} + +void ImDrawDataBuilder::FlattenIntoSingleLayer() +{ + int n = Layers[0].Size; + int size = n; + for (int i = 1; i < IM_ARRAYSIZE(Layers); i++) + size += Layers[i].Size; + Layers[0].resize(size); + for (int layer_n = 1; layer_n < IM_ARRAYSIZE(Layers); layer_n++) + { + ImVector& layer = Layers[layer_n]; + if (layer.empty()) + continue; + memcpy(&Layers[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); + n += layer.Size; + layer.resize(0); + } +} + +static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVector* draw_lists) +{ + // When minimized, we report draw_data->DisplaySize as zero to be consistent with non-viewport mode, + // and to allow applications/backends to easily skip rendering. + // FIXME: Note that we however do NOT attempt to report "zero drawlist / vertices" into the ImDrawData structure. + // This is because the work has been done already, and its wasted! We should fix that and add optimizations for + // it earlier in the pipeline, rather than pretend to hide the data at the end of the pipeline. + const bool is_minimized = (viewport->Flags & ImGuiViewportFlags_Minimized) != 0; + + ImGuiIO& io = ImGui::GetIO(); + ImDrawData* draw_data = &viewport->DrawDataP; + viewport->DrawData = draw_data; // Make publicly accessible + draw_data->Valid = true; + draw_data->CmdLists = (draw_lists->Size > 0) ? draw_lists->Data : NULL; + draw_data->CmdListsCount = draw_lists->Size; + draw_data->TotalVtxCount = draw_data->TotalIdxCount = 0; + draw_data->DisplayPos = viewport->Pos; + draw_data->DisplaySize = is_minimized ? ImVec2(0.0f, 0.0f) : viewport->Size; + draw_data->FramebufferScale = io.DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis? + draw_data->OwnerViewport = viewport; + for (int n = 0; n < draw_lists->Size; n++) + { + ImDrawList* draw_list = draw_lists->Data[n]; + draw_list->_PopUnusedDrawCmd(); + draw_data->TotalVtxCount += draw_list->VtxBuffer.Size; + draw_data->TotalIdxCount += draw_list->IdxBuffer.Size; + } +} + +// Push a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering. +// - When using this function it is sane to ensure that float are perfectly rounded to integer values, +// so that e.g. (int)(max.x-min.x) in user's render produce correct result. +// - If the code here changes, may need to update code of functions like NextColumn() and PushColumnClipRect(): +// some frequently called functions which to modify both channels and clipping simultaneously tend to use the +// more specialized SetWindowClipRectBeforeSetChannel() to avoid extraneous updates of underlying ImDrawCmds. +void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); + window->ClipRect = window->DrawList->_ClipRectStack.back(); +} + +void ImGui::PopClipRect() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PopClipRect(); + window->ClipRect = window->DrawList->_ClipRectStack.back(); +} + +static ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* window) +{ + for (int n = window->DC.ChildWindows.Size - 1; n >= 0; n--) + if (IsWindowActiveAndVisible(window->DC.ChildWindows[n])) + return FindFrontMostVisibleChildWindow(window->DC.ChildWindows[n]); + return window; +} + +static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + ImGuiViewportP* viewport = window->Viewport; + ImRect viewport_rect = viewport->GetMainRect(); + + // Draw behind window by moving the draw command at the FRONT of the draw list + { + // We've already called AddWindowToDrawData() which called DrawList->ChannelsMerge() on DockNodeHost windows, + // and draw list have been trimmed already, hence the explicit recreation of a draw command if missing. + // FIXME: This is creating complication, might be simpler if we could inject a drawlist in drawdata at a given position and not attempt to manipulate ImDrawCmd order. + ImDrawList* draw_list = window->RootWindowDockTree->DrawList; + if (draw_list->CmdBuffer.Size == 0) + draw_list->AddDrawCmd(); + draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // Ensure ImDrawCmd are not merged + draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col); + ImDrawCmd cmd = draw_list->CmdBuffer.back(); + IM_ASSERT(cmd.ElemCount == 6); + draw_list->CmdBuffer.pop_back(); + draw_list->CmdBuffer.push_front(cmd); + draw_list->PopClipRect(); + draw_list->AddDrawCmd(); // We need to create a command as CmdBuffer.back().IdxOffset won't be correct if we append to same command. + } + + // Draw over sibling docking nodes in a same docking tree + if (window->RootWindow->DockIsActive) + { + ImDrawList* draw_list = FindFrontMostVisibleChildWindow(window->RootWindowDockTree)->DrawList; + if (draw_list->CmdBuffer.Size == 0) + draw_list->AddDrawCmd(); + draw_list->PushClipRect(viewport_rect.Min, viewport_rect.Max, false); + RenderRectFilledWithHole(draw_list, window->RootWindowDockTree->Rect(), window->RootWindow->Rect(), col, 0.0f);// window->RootWindowDockTree->WindowRounding); + draw_list->PopClipRect(); + } +} + +ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* parent_window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* bottom_most_visible_window = parent_window; + for (int i = FindWindowDisplayIndex(parent_window); i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_ChildWindow) + continue; + if (!IsWindowWithinBeginStackOf(window, parent_window)) + break; + if (IsWindowActiveAndVisible(window) && GetWindowDisplayLayer(window) <= GetWindowDisplayLayer(parent_window)) + bottom_most_visible_window = window; + } + return bottom_most_visible_window; +} + +static void ImGui::RenderDimmedBackgrounds() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* modal_window = GetTopMostAndVisiblePopupModal(); + if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f) + return; + const bool dim_bg_for_modal = (modal_window != NULL); + const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL && g.NavWindowingTargetAnim->Active); + if (!dim_bg_for_modal && !dim_bg_for_window_list) + return; + + ImGuiViewport* viewports_already_dimmed[2] = { NULL, NULL }; + if (dim_bg_for_modal) + { + // Draw dimming behind modal or a begin stack child, whichever comes first in draw order. + ImGuiWindow* dim_behind_window = FindBottomMostVisibleWindowWithinBeginStack(modal_window); + RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio)); + viewports_already_dimmed[0] = modal_window->Viewport; + } + else if (dim_bg_for_window_list) + { + // Draw dimming behind CTRL+Tab target window and behind CTRL+Tab UI window + RenderDimmedBackgroundBehindWindow(g.NavWindowingTargetAnim, GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio)); + if (g.NavWindowingListWindow != NULL && g.NavWindowingListWindow->Viewport && g.NavWindowingListWindow->Viewport != g.NavWindowingTargetAnim->Viewport) + RenderDimmedBackgroundBehindWindow(g.NavWindowingListWindow, GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio)); + viewports_already_dimmed[0] = g.NavWindowingTargetAnim->Viewport; + viewports_already_dimmed[1] = g.NavWindowingListWindow ? g.NavWindowingListWindow->Viewport : NULL; + + // Draw border around CTRL+Tab target window + ImGuiWindow* window = g.NavWindowingTargetAnim; + ImGuiViewport* viewport = window->Viewport; + float distance = g.FontSize; + ImRect bb = window->Rect(); + bb.Expand(distance); + if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y) + bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward + if (window->DrawList->CmdBuffer.Size == 0) + window->DrawList->AddDrawCmd(); + window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size); + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); + window->DrawList->PopClipRect(); + } + + // Draw dimming background on _other_ viewports than the ones our windows are in + for (int viewport_n = 0; viewport_n < g.Viewports.Size; viewport_n++) + { + ImGuiViewportP* viewport = g.Viewports[viewport_n]; + if (viewport == viewports_already_dimmed[0] || viewport == viewports_already_dimmed[1]) + continue; + if (modal_window && viewport->Window && IsWindowAbove(viewport->Window, modal_window)) + continue; + ImDrawList* draw_list = GetForegroundDrawList(viewport); + const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio); + draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col); + } +} + +// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal. +void ImGui::EndFrame() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); + + // Don't process EndFrame() multiple times. + if (g.FrameCountEnded == g.FrameCount) + return; + IM_ASSERT(g.WithinFrameScope && "Forgot to call ImGui::NewFrame()?"); + + CallContextHooks(&g, ImGuiContextHookType_EndFramePre); + + ErrorCheckEndFrameSanityChecks(); + + // Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) + if (g.IO.SetPlatformImeDataFn && memcmp(&g.PlatformImeData, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0) + { + ImGuiViewport* viewport = FindViewportByID(g.PlatformImeViewport); + g.IO.SetPlatformImeDataFn(viewport ? viewport : GetMainViewport(), &g.PlatformImeData); + } + + // Hide implicit/fallback "Debug" window if it hasn't been used + g.WithinFrameScopeWithImplicitWindow = false; + if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) + g.CurrentWindow->Active = false; + End(); + + // Update navigation: CTRL+Tab, wrap-around requests + NavEndFrame(); + + // Update docking + DockContextEndFrame(&g); + + SetCurrentViewport(NULL, NULL); + + // Drag and Drop: Elapse payload (if delivered, or if source stops being submitted) + if (g.DragDropActive) + { + bool is_delivered = g.DragDropPayload.Delivery; + bool is_elapsed = (g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton)); + if (is_delivered || is_elapsed) + ClearDragDrop(); + } + + // Drag and Drop: Fallback for source tooltip. This is not ideal but better than nothing. + if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + g.DragDropWithinSource = true; + SetTooltip("..."); + g.DragDropWithinSource = false; + } + + // End frame + g.WithinFrameScope = false; + g.FrameCountEnded = g.FrameCount; + + // Initiate moving window + handle left-click and right-click focus + UpdateMouseMovingWindowEndFrame(); + + // Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some) + UpdateViewportsEndFrame(); + + // Sort the window list so that all child windows are after their parent + // We cannot do that on FocusWindow() because children may not exist yet + g.WindowsTempSortBuffer.resize(0); + g.WindowsTempSortBuffer.reserve(g.Windows.Size); + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it + continue; + AddWindowToSortBuffer(&g.WindowsTempSortBuffer, window); + } + + // This usually assert if there is a mismatch between the ImGuiWindowFlags_ChildWindow / ParentWindow values and DC.ChildWindows[] in parents, aka we've done something wrong. + IM_ASSERT(g.Windows.Size == g.WindowsTempSortBuffer.Size); + g.Windows.swap(g.WindowsTempSortBuffer); + g.IO.MetricsActiveWindows = g.WindowsActiveCount; + + // Unlock font atlas + g.IO.Fonts->Locked = false; + + // Clear Input data for next frame + g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; + g.IO.InputQueueCharacters.resize(0); + g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it. + memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); + + CallContextHooks(&g, ImGuiContextHookType_EndFramePost); +} + +// Prepare the data for rendering so you can call GetDrawData() +// (As with anything within the ImGui:: namspace this doesn't touch your GPU or graphics API at all: +// it is the role of the ImGui_ImplXXXX_RenderDrawData() function provided by the renderer backend) +void ImGui::Render() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); + + if (g.FrameCountEnded != g.FrameCount) + EndFrame(); + const bool first_render_of_frame = (g.FrameCountRendered != g.FrameCount); + g.FrameCountRendered = g.FrameCount; + g.IO.MetricsRenderWindows = 0; + + CallContextHooks(&g, ImGuiContextHookType_RenderPre); + + // Add background ImDrawList (for each active viewport) + for (int n = 0; n != g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + viewport->DrawDataBuilder.Clear(); + if (viewport->DrawLists[0] != NULL) + AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport)); + } + + // Add ImDrawList to render + ImGuiWindow* windows_to_render_top_most[2]; + windows_to_render_top_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindowDockTree : NULL; + windows_to_render_top_most[1] = (g.NavWindowingTarget ? g.NavWindowingListWindow : NULL); + for (int n = 0; n != g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'" + if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_top_most[0] && window != windows_to_render_top_most[1]) + AddRootWindowToDrawData(window); + } + for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_top_most); n++) + if (windows_to_render_top_most[n] && IsWindowActiveAndVisible(windows_to_render_top_most[n])) // NavWindowingTarget is always temporarily displayed as the top-most window + AddRootWindowToDrawData(windows_to_render_top_most[n]); + + // Draw modal/window whitening backgrounds + if (first_render_of_frame) + RenderDimmedBackgrounds(); + + // Draw software mouse cursor if requested by io.MouseDrawCursor flag + if (g.IO.MouseDrawCursor && first_render_of_frame && g.MouseCursor != ImGuiMouseCursor_None) + RenderMouseCursor(g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32(0, 0, 0, 48)); + + // Setup ImDrawData structures for end-user + g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0; + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + viewport->DrawDataBuilder.FlattenIntoSingleLayer(); + + // Add foreground ImDrawList (for each active viewport) + if (viewport->DrawLists[1] != NULL) + AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport)); + + SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]); + ImDrawData* draw_data = viewport->DrawData; + g.IO.MetricsRenderVertices += draw_data->TotalVtxCount; + g.IO.MetricsRenderIndices += draw_data->TotalIdxCount; + } + + CallContextHooks(&g, ImGuiContextHookType_RenderPost); +} + +// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. +// CalcTextSize("") should return ImVec2(0.0f, g.FontSize) +ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) +{ + ImGuiContext& g = *GImGui; + + const char* text_display_end; + if (hide_text_after_double_hash) + text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string + else + text_display_end = text_end; + + ImFont* font = g.Font; + const float font_size = g.FontSize; + if (text == text_display_end) + return ImVec2(0.0f, font_size); + ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); + + // Round + // FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out. + // FIXME: Investigate using ceilf or e.g. + // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c + // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html + text_size.x = IM_FLOOR(text_size.x + 0.99999f); + + return text_size; +} + +// Find window given position, search front-to-back +// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically +// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is +// called, aka before the next Begin(). Moving window isn't affected. +static void FindHoveredWindow() +{ + ImGuiContext& g = *GImGui; + + // Special handling for the window being moved: Ignore the mouse viewport check (because it may reset/lose its viewport during the undocking frame) + ImGuiViewportP* moving_window_viewport = g.MovingWindow ? g.MovingWindow->Viewport : NULL; + if (g.MovingWindow) + g.MovingWindow->Viewport = g.MouseViewport; + + ImGuiWindow* hovered_window = NULL; + ImGuiWindow* hovered_window_ignoring_moving_window = NULL; + if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) + hovered_window = g.MovingWindow; + + ImVec2 padding_regular = g.Style.TouchExtraPadding; + ImVec2 padding_for_resize = g.IO.ConfigWindowsResizeFromEdges ? g.WindowsHoverPadding : padding_regular; + for (int i = g.Windows.Size - 1; i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. + if (!window->Active || window->Hidden) + continue; + if (window->Flags & ImGuiWindowFlags_NoMouseInputs) + continue; + IM_ASSERT(window->Viewport); + if (window->Viewport != g.MouseViewport) + continue; + + // Using the clipped AABB, a child window will typically be clipped by its parent (not always) + ImRect bb(window->OuterRectClipped); + if (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) + bb.Expand(padding_regular); + else + bb.Expand(padding_for_resize); + if (!bb.Contains(g.IO.MousePos)) + continue; + + // Support for one rectangular hole in any given window + // FIXME: Consider generalizing hit-testing override (with more generic data, callback, etc.) (#1512) + if (window->HitTestHoleSize.x != 0) + { + ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y); + ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y); + if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos)) + continue; + } + + if (hovered_window == NULL) + hovered_window = window; + IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. + if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindowDockTree != g.MovingWindow->RootWindowDockTree)) + hovered_window_ignoring_moving_window = window; + if (hovered_window && hovered_window_ignoring_moving_window) + break; + } + + g.HoveredWindow = hovered_window; + g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; + + if (g.MovingWindow) + g.MovingWindow->Viewport = moving_window_viewport; +} + +bool ImGui::IsItemActive() +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId) + return g.ActiveId == g.LastItemData.ID; + return false; +} + +bool ImGui::IsItemActivated() +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId) + if (g.ActiveId == g.LastItemData.ID && g.ActiveIdPreviousFrame != g.LastItemData.ID) + return true; + return false; +} + +bool ImGui::IsItemDeactivated() +{ + ImGuiContext& g = *GImGui; + if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDeactivated) + return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Deactivated) != 0; + return (g.ActiveIdPreviousFrame == g.LastItemData.ID && g.ActiveIdPreviousFrame != 0 && g.ActiveId != g.LastItemData.ID); +} + +bool ImGui::IsItemDeactivatedAfterEdit() +{ + ImGuiContext& g = *GImGui; + return IsItemDeactivated() && (g.ActiveIdPreviousFrameHasBeenEditedBefore || (g.ActiveId == 0 && g.ActiveIdHasBeenEditedBefore)); +} + +// == GetItemID() == GetFocusID() +bool ImGui::IsItemFocused() +{ + ImGuiContext& g = *GImGui; + if (g.NavId != g.LastItemData.ID || g.NavId == 0) + return false; + + // Special handling for the dummy item after Begin() which represent the title bar or tab. + // When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case. + ImGuiWindow* window = g.CurrentWindow; + if (g.LastItemData.ID == window->ID && window->WriteAccessed) + return false; + + return true; +} + +// Important: this can be useful but it is NOT equivalent to the behavior of e.g.Button()! +// Most widgets have specific reactions based on mouse-up/down state, mouse position etc. +bool ImGui::IsItemClicked(ImGuiMouseButton mouse_button) +{ + return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_None); +} + +bool ImGui::IsItemToggledOpen() +{ + ImGuiContext& g = *GImGui; + return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false; +} + +bool ImGui::IsItemToggledSelection() +{ + ImGuiContext& g = *GImGui; + return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false; +} + +bool ImGui::IsAnyItemHovered() +{ + ImGuiContext& g = *GImGui; + return g.HoveredId != 0 || g.HoveredIdPreviousFrame != 0; +} + +bool ImGui::IsAnyItemActive() +{ + ImGuiContext& g = *GImGui; + return g.ActiveId != 0; +} + +bool ImGui::IsAnyItemFocused() +{ + ImGuiContext& g = *GImGui; + return g.NavId != 0 && !g.NavDisableHighlight; +} + +bool ImGui::IsItemVisible() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->ClipRect.Overlaps(g.LastItemData.Rect); +} + +bool ImGui::IsItemEdited() +{ + ImGuiContext& g = *GImGui; + return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Edited) != 0; +} + +// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. +// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowItemOverlap flag are extremely confusing, need rework. +void ImGui::SetItemAllowOverlap() +{ + ImGuiContext& g = *GImGui; + ImGuiID id = g.LastItemData.ID; + if (g.HoveredId == id) + g.HoveredIdAllowOverlap = true; + if (g.ActiveId == id) + g.ActiveIdAllowOverlap = true; +} + +void ImGui::SetItemUsingMouseWheel() +{ + ImGuiContext& g = *GImGui; + ImGuiID id = g.LastItemData.ID; + if (g.HoveredId == id) + g.HoveredIdUsingMouseWheel = true; + if (g.ActiveId == id) + g.ActiveIdUsingMouseWheel = true; +} + +void ImGui::SetActiveIdUsingNavAndKeys() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.ActiveId != 0); + g.ActiveIdUsingNavDirMask = ~(ImU32)0; + g.ActiveIdUsingNavInputMask = ~(ImU32)0; + g.ActiveIdUsingKeyInputMask.SetAllBits(); + NavMoveRequestCancel(); +} + +ImVec2 ImGui::GetItemRectMin() +{ + ImGuiContext& g = *GImGui; + return g.LastItemData.Rect.Min; +} + +ImVec2 ImGui::GetItemRectMax() +{ + ImGuiContext& g = *GImGui; + return g.LastItemData.Rect.Max; +} + +ImVec2 ImGui::GetItemRectSize() +{ + ImGuiContext& g = *GImGui; + return g.LastItemData.Rect.GetSize(); +} + +bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* parent_window = g.CurrentWindow; + + flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking; + flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag + + // Size + const ImVec2 content_avail = GetContentRegionAvail(); + ImVec2 size = ImFloor(size_arg); + const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); + if (size.x <= 0.0f) + size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) + if (size.y <= 0.0f) + size.y = ImMax(content_avail.y + size.y, 4.0f); + SetNextWindowSize(size); + + // Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value. + if (name) + ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id); + else + ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id); + + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; + bool ret = Begin(g.TempBuffer, NULL, flags); + g.Style.ChildBorderSize = backup_border_size; + + ImGuiWindow* child_window = g.CurrentWindow; + child_window->ChildId = id; + child_window->AutoFitChildAxises = (ImS8)auto_fit_axises; + + // Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually. + // While this is not really documented/defined, it seems that the expected thing to do. + if (child_window->BeginCount == 1) + parent_window->DC.CursorPos = child_window->Pos; + + // Process navigation-in immediately so NavInit can run on first frame + if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavHasScroll)) + { + FocusWindow(child_window); + NavInitWindow(child_window, false); + SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item + g.ActiveIdSource = ImGuiInputSource_Nav; + } + return ret; +} + +bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags); +} + +bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) +{ + IM_ASSERT(id != 0); + return BeginChildEx(NULL, id, size_arg, border, extra_flags); +} + +void ImGui::EndChild() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + IM_ASSERT(g.WithinEndChild == false); + IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() calls + + g.WithinEndChild = true; + if (window->BeginCount > 1) + { + End(); + } + else + { + ImVec2 sz = window->Size; + if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + sz.x = ImMax(4.0f, sz.x); + if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) + sz.y = ImMax(4.0f, sz.y); + End(); + + ImGuiWindow* parent_window = g.CurrentWindow; + ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); + ItemSize(sz); + if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened)) + { + ItemAdd(bb, window->ChildId); + RenderNavHighlight(bb, window->ChildId); + + // When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying) + if (window->DC.NavLayersActiveMask == 0 && window == g.NavWindow) + RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin); + } + else + { + // Not navigable into + ItemAdd(bb, 0); + } + if (g.HoveredWindow == window) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; + } + g.WithinEndChild = false; + g.LogLinePosY = -FLT_MAX; // To enforce a carriage return +} + +// Helper to create a child window / scrolling region that looks like a normal widget frame. +bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + bool ret = BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + PopStyleVar(3); + PopStyleColor(); + return ret; +} + +void ImGui::EndChildFrame() +{ + EndChild(); +} + +static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) +{ + window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); + window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags); + window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags); + window->SetWindowDockAllowFlags = enabled ? (window->SetWindowDockAllowFlags | flags) : (window->SetWindowDockAllowFlags & ~flags); +} + +ImGuiWindow* ImGui::FindWindowByID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id); +} + +ImGuiWindow* ImGui::FindWindowByName(const char* name) +{ + ImGuiID id = ImHashStr(name); + return FindWindowByID(id); +} + +static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) +{ + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + window->ViewportPos = main_viewport->Pos; + if (settings->ViewportId) + { + window->ViewportId = settings->ViewportId; + window->ViewportPos = ImVec2(settings->ViewportPos.x, settings->ViewportPos.y); + } + window->Pos = ImFloor(ImVec2(settings->Pos.x + window->ViewportPos.x, settings->Pos.y + window->ViewportPos.y)); + if (settings->Size.x > 0 && settings->Size.y > 0) + window->Size = window->SizeFull = ImFloor(ImVec2(settings->Size.x, settings->Size.y)); + window->Collapsed = settings->Collapsed; + window->DockId = settings->DockId; + window->DockOrder = settings->DockOrder; +} + +static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags) +{ + ImGuiContext& g = *GImGui; + + const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0; + const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild; + if ((just_created || child_flag_changed) && !new_is_explicit_child) + { + IM_ASSERT(!g.WindowsFocusOrder.contains(window)); + g.WindowsFocusOrder.push_back(window); + window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1); + } + else if (!just_created && child_flag_changed && new_is_explicit_child) + { + IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window); + for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++) + g.WindowsFocusOrder[n]->FocusOrder--; + g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder); + window->FocusOrder = -1; + } + window->IsExplicitChild = new_is_explicit_child; +} + +static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + //IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags); + + // Create window the first time + ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); + window->Flags = flags; + g.WindowsById.SetVoidPtr(window->ID, window); + + // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + window->Pos = main_viewport->Pos + ImVec2(60, 60); + window->ViewportPos = main_viewport->Pos; + + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) + { + // Retrieve settings from .ini file + window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings); + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); + ApplyWindowSettings(window, settings); + } + window->DC.CursorStartPos = window->DC.CursorMaxPos = window->Pos; // So first call to CalcContentSize() doesn't return crazy values + + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + { + window->AutoFitFramesX = window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } + else + { + if (window->Size.x <= 0.0f) + window->AutoFitFramesX = 2; + if (window->Size.y <= 0.0f) + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); + } + + if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) + g.Windows.push_front(window); // Quite slow but rare and only once + else + g.Windows.push_back(window); + UpdateWindowInFocusOrderList(window, true, window->Flags); + + return window; +} + +static ImGuiWindow* GetWindowForTitleDisplay(ImGuiWindow* window) +{ + return window->DockNodeAsHost ? window->DockNodeAsHost->VisibleWindow : window; +} + +static ImGuiWindow* GetWindowForTitleAndMenuHeight(ImGuiWindow* window) +{ + return (window->DockNodeAsHost && window->DockNodeAsHost->VisibleWindow) ? window->DockNodeAsHost->VisibleWindow : window; +} + +static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& size_desired) +{ + ImGuiContext& g = *GImGui; + ImVec2 new_size = size_desired; + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) + { + // Using -1,-1 on either X/Y axis to preserve the current size. + ImRect cr = g.NextWindowData.SizeConstraintRect; + new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; + new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; + if (g.NextWindowData.SizeCallback) + { + ImGuiSizeCallbackData data; + data.UserData = g.NextWindowData.SizeCallbackUserData; + data.Pos = window->Pos; + data.CurrentSize = window->SizeFull; + data.DesiredSize = new_size; + g.NextWindowData.SizeCallback(&data); + new_size = data.DesiredSize; + } + new_size.x = IM_FLOOR(new_size.x); + new_size.y = IM_FLOOR(new_size.y); + } + + // Minimum size + if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) + { + ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window); + const float decoration_up_height = window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight(); + new_size = ImMax(new_size, g.Style.WindowMinSize); + new_size.y = ImMax(new_size.y, decoration_up_height + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows + } + return new_size; +} + +static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_current, ImVec2* content_size_ideal) +{ + bool preserve_old_content_sizes = false; + if (window->Collapsed && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + preserve_old_content_sizes = true; + else if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0) + preserve_old_content_sizes = true; + if (preserve_old_content_sizes) + { + *content_size_current = window->ContentSize; + *content_size_ideal = window->ContentSizeIdeal; + return; + } + + content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x); + content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y); + content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_FLOOR(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x); + content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_FLOOR(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y); +} + +static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); + ImVec2 size_pad = window->WindowPadding * 2.0f; + ImVec2 size_desired = size_contents + size_pad + ImVec2(0.0f, decoration_up_height); + if (window->Flags & ImGuiWindowFlags_Tooltip) + { + // Tooltip always resize + return size_desired; + } + else + { + // Maximum window size is determined by the viewport size or monitor size + const bool is_popup = (window->Flags & ImGuiWindowFlags_Popup) != 0; + const bool is_menu = (window->Flags & ImGuiWindowFlags_ChildMenu) != 0; + ImVec2 size_min = style.WindowMinSize; + if (is_popup || is_menu) // Popups and menus bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups) + size_min = ImMin(size_min, ImVec2(4.0f, 4.0f)); + + // FIXME-VIEWPORT-WORKAREA: May want to use GetWorkSize() instead of Size depending on the type of windows? + ImVec2 avail_size = window->Viewport->Size; + if (window->ViewportOwned) + avail_size = ImVec2(FLT_MAX, FLT_MAX); + const int monitor_idx = window->ViewportAllowPlatformMonitorExtend; + if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size) + avail_size = g.PlatformIO.Monitors[monitor_idx].WorkSize; + ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, avail_size - style.DisplaySafeAreaPadding * 2.0f)); + + // When the window cannot fit all contents (either because of constraints, either because screen is too small), + // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. + ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit); + bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - 0.0f < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); + bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_up_height < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar); + if (will_have_scrollbar_x) + size_auto_fit.y += style.ScrollbarSize; + if (will_have_scrollbar_y) + size_auto_fit.x += style.ScrollbarSize; + return size_auto_fit; + } +} + +ImVec2 ImGui::CalcWindowNextAutoFitSize(ImGuiWindow* window) +{ + ImVec2 size_contents_current; + ImVec2 size_contents_ideal; + CalcWindowContentSizes(window, &size_contents_current, &size_contents_ideal); + ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents_ideal); + ImVec2 size_final = CalcWindowSizeAfterConstraint(window, size_auto_fit); + return size_final; +} + +static ImGuiCol GetWindowBgColorIdx(ImGuiWindow* window) +{ + if (window->Flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + return ImGuiCol_PopupBg; + if ((window->Flags & ImGuiWindowFlags_ChildWindow) && !window->DockIsActive) + return ImGuiCol_ChildBg; + return ImGuiCol_WindowBg; +} + +static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size) +{ + ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left + ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right + ImVec2 size_expected = pos_max - pos_min; + ImVec2 size_constrained = CalcWindowSizeAfterConstraint(window, size_expected); + *out_pos = pos_min; + if (corner_norm.x == 0.0f) + out_pos->x -= (size_constrained.x - size_expected.x); + if (corner_norm.y == 0.0f) + out_pos->y -= (size_constrained.y - size_expected.y); + *out_size = size_constrained; +} + +// Data for resizing from corner +struct ImGuiResizeGripDef +{ + ImVec2 CornerPosN; + ImVec2 InnerDir; + int AngleMin12, AngleMax12; +}; +static const ImGuiResizeGripDef resize_grip_def[4] = +{ + { ImVec2(1, 1), ImVec2(-1, -1), 0, 3 }, // Lower-right + { ImVec2(0, 1), ImVec2(+1, -1), 3, 6 }, // Lower-left + { ImVec2(0, 0), ImVec2(+1, +1), 6, 9 }, // Upper-left (Unused) + { ImVec2(1, 0), ImVec2(-1, +1), 9, 12 } // Upper-right (Unused) +}; + +// Data for resizing from borders +struct ImGuiResizeBorderDef +{ + ImVec2 InnerDir; + ImVec2 SegmentN1, SegmentN2; + float OuterAngle; +}; +static const ImGuiResizeBorderDef resize_border_def[4] = +{ + { ImVec2(+1, 0), ImVec2(0, 1), ImVec2(0, 0), IM_PI * 1.00f }, // Left + { ImVec2(-1, 0), ImVec2(1, 0), ImVec2(1, 1), IM_PI * 0.00f }, // Right + { ImVec2(0, +1), ImVec2(0, 0), ImVec2(1, 0), IM_PI * 1.50f }, // Up + { ImVec2(0, -1), ImVec2(1, 1), ImVec2(0, 1), IM_PI * 0.50f } // Down +}; + +static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) +{ + ImRect rect = window->Rect(); + if (thickness == 0.0f) + rect.Max -= ImVec2(1, 1); + if (border_n == ImGuiDir_Left) { return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); } + if (border_n == ImGuiDir_Right) { return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); } + if (border_n == ImGuiDir_Up) { return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); } + if (border_n == ImGuiDir_Down) { return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); } + IM_ASSERT(0); + return ImRect(); +} + +// 0..3: corners (Lower-right, Lower-left, Unused, Unused) +ImGuiID ImGui::GetWindowResizeCornerID(ImGuiWindow* window, int n) +{ + IM_ASSERT(n >= 0 && n < 4); + ImGuiID id = window->DockIsActive ? window->DockNode->HostWindow->ID : window->ID; + id = ImHashStr("#RESIZE", 0, id); + id = ImHashData(&n, sizeof(int), id); + return id; +} + +// Borders (Left, Right, Up, Down) +ImGuiID ImGui::GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir) +{ + IM_ASSERT(dir >= 0 && dir < 4); + int n = (int)dir + 4; + ImGuiID id = window->DockIsActive ? window->DockNode->HostWindow->ID : window->ID; + id = ImHashStr("#RESIZE", 0, id); + id = ImHashData(&n, sizeof(int), id); + return id; +} + +// Handle resize for: Resize Grips, Borders, Gamepad +// Return true when using auto-fit (double click on resize grip) +static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect) +{ + ImGuiContext& g = *GImGui; + ImGuiWindowFlags flags = window->Flags; + + if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + return false; + if (window->WasActive == false) // Early out to avoid running this code for e.g. an hidden implicit/fallback Debug window. + return false; + + bool ret_auto_fit = false; + const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0; + const float grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); + const float grip_hover_inner_size = IM_FLOOR(grip_draw_size * 0.75f); + const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f; + + ImVec2 pos_target(FLT_MAX, FLT_MAX); + ImVec2 size_target(FLT_MAX, FLT_MAX); + + // Clip mouse interaction rectangles within the viewport rectangle (in practice the narrowing is going to happen most of the time). + // - Not narrowing would mostly benefit the situation where OS windows _without_ decoration have a threshold for hovering when outside their limits. + // This is however not the case with current backends under Win32, but a custom borderless window implementation would benefit from it. + // - When decoration are enabled we typically benefit from that distance, but then our resize elements would be conflicting with OS resize elements, so we also narrow. + // - Note that we are unable to tell if the platform setup allows hovering with a distance threshold (on Win32, decorated window have such threshold). + // We only clip interaction so we overwrite window->ClipRect, cannot call PushClipRect() yet as DrawList is not yet setup. + const bool clip_with_viewport_rect = !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) || (g.IO.MouseHoveredViewport != window->ViewportId) || !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration); + if (clip_with_viewport_rect) + window->ClipRect = window->Viewport->GetMainRect(); + + // Resize grips and borders are on layer 1 + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; + + // Manual resize grips + PushID("#RESIZE"); + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& def = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, def.CornerPosN); + + // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window + bool hovered, held; + ImRect resize_rect(corner - def.InnerDir * grip_hover_outer_size, corner + def.InnerDir * grip_hover_inner_size); + if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x); + if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); + ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID() + ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); + //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); + if (hovered || held) + g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; + + if (held && g.IO.MouseClickedCount[0] == 2 && resize_grip_n == 0) + { + // Manual auto-fit when double-clicking + size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit); + ret_auto_fit = true; + ClearActiveID(); + } + else if (held) + { + // Resize from any of the four corners + // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position + ImVec2 clamp_min = ImVec2(def.CornerPosN.x == 1.0f ? visibility_rect.Min.x : -FLT_MAX, def.CornerPosN.y == 1.0f ? visibility_rect.Min.y : -FLT_MAX); + ImVec2 clamp_max = ImVec2(def.CornerPosN.x == 0.0f ? visibility_rect.Max.x : +FLT_MAX, def.CornerPosN.y == 0.0f ? visibility_rect.Max.y : +FLT_MAX); + ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(def.InnerDir * grip_hover_outer_size, def.InnerDir * -grip_hover_inner_size, def.CornerPosN); // Corner of the window corresponding to our corner grip + corner_target = ImClamp(corner_target, clamp_min, clamp_max); + CalcResizePosSizeFromAnyCorner(window, corner_target, def.CornerPosN, &pos_target, &size_target); + } + + // Only lower-left grip is visible before hovering/activating + if (resize_grip_n == 0 || held || hovered) + resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + } + for (int border_n = 0; border_n < resize_border_count; border_n++) + { + const ImGuiResizeBorderDef& def = resize_border_def[border_n]; + const ImGuiAxis axis = (border_n == ImGuiDir_Left || border_n == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; + + bool hovered, held; + ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING); + ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID() + ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); + //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); + if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) + { + g.MouseCursor = (axis == ImGuiAxis_X) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; + if (held) + *border_held = border_n; + } + if (held) + { + ImVec2 clamp_min(border_n == ImGuiDir_Right ? visibility_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down ? visibility_rect.Min.y : -FLT_MAX); + ImVec2 clamp_max(border_n == ImGuiDir_Left ? visibility_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? visibility_rect.Max.y : +FLT_MAX); + ImVec2 border_target = window->Pos; + border_target[axis] = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING; + border_target = ImClamp(border_target, clamp_min, clamp_max); + CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target); + } + } + PopID(); + + // Restore nav layer + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + + // Navigation resize (keyboard/gamepad) + if (g.NavWindowingTarget && g.NavWindowingTarget->RootWindowDockTree == window) + { + ImVec2 nav_resize_delta; + if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift) + nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiInputReadMode_Down); + if (g.NavInputSource == ImGuiInputSource_Gamepad) + nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_Down); + if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f) + { + const float NAV_RESIZE_SPEED = 600.0f; + nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); + nav_resize_delta = ImMax(nav_resize_delta, visibility_rect.Min - window->Pos - window->Size); + g.NavWindowingToggleLayer = false; + g.NavDisableMouseHover = true; + resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); + // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. + size_target = CalcWindowSizeAfterConstraint(window, window->SizeFull + nav_resize_delta); + } + } + + // Apply back modified position/size to window + if (size_target.x != FLT_MAX) + { + window->SizeFull = size_target; + MarkIniSettingsDirty(window); + } + if (pos_target.x != FLT_MAX) + { + window->Pos = ImFloor(pos_target); + MarkIniSettingsDirty(window); + } + + window->Size = window->SizeFull; + return ret_auto_fit; +} + +static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility_rect) +{ + ImGuiContext& g = *GImGui; + ImVec2 size_for_clamping = window->Size; + if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) + size_for_clamping.y = window->TitleBarHeight(); + window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max); +} + +static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + float rounding = window->WindowRounding; + float border_size = window->WindowBorderSize; + if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground)) + window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + + int border_held = window->ResizeBorderHeld; + if (border_held != -1) + { + const ImGuiResizeBorderDef& def = resize_border_def[border_held]; + ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f); + window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle); + window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f); + window->DrawList->PathStroke(GetColorU32(ImGuiCol_SeparatorActive), 0, ImMax(2.0f, border_size)); // Thicker than usual + } + if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive) + { + float y = window->Pos.y + window->TitleBarHeight() - 1; + window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize); + } +} + +// Draw background and borders +// Draw and handle scrollbars +void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImGuiWindowFlags flags = window->Flags; + + // Ensure that ScrollBar doesn't read last frame's SkipItems + IM_ASSERT(window->BeginCount == 0); + window->SkipItems = false; + + // Draw window + handle manual resize + // As we highlight the title bar when want_focus is set, multiple reappearing windows will have have their title bar highlighted on their reappearing frame. + const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; + if (window->Collapsed) + { + // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; + ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed); + RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; + } + else + { + // Window background + if (!(flags & ImGuiWindowFlags_NoBackground)) + { + bool is_docking_transparent_payload = false; + if (g.DragDropActive && (g.FrameCount - g.DragDropAcceptFrameCount) <= 1 && g.IO.ConfigDockingTransparentPayload) + if (g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW) && *(ImGuiWindow**)g.DragDropPayload.Data == window) + is_docking_transparent_payload = true; + + ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window)); + if (window->ViewportOwned) + { + // No alpha + bg_col = (bg_col | IM_COL32_A_MASK); + if (is_docking_transparent_payload) + window->Viewport->Alpha *= DOCKING_TRANSPARENT_PAYLOAD_ALPHA; + } + else + { + // Adjust alpha. For docking + bool override_alpha = false; + float alpha = 1.0f; + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha) + { + alpha = g.NextWindowData.BgAlphaVal; + override_alpha = true; + } + if (is_docking_transparent_payload) + { + alpha *= DOCKING_TRANSPARENT_PAYLOAD_ALPHA; // FIXME-DOCK: Should that be an override? + override_alpha = true; + } + if (override_alpha) + bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT); + } + + // Render, for docked windows and host windows we ensure bg goes before decorations + ImDrawList* bg_draw_list = window->DockIsActive ? window->DockNode->HostWindow->DrawList : window->DrawList; + if (window->DockIsActive || (flags & ImGuiWindowFlags_DockNodeHost)) + bg_draw_list->ChannelsSetCurrent(0); + if (window->DockIsActive) + window->DockNode->LastBgColor = bg_col; + + bg_draw_list->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom); + + if (window->DockIsActive || (flags & ImGuiWindowFlags_DockNodeHost)) + bg_draw_list->ChannelsSetCurrent(1); + } + if (window->DockIsActive) + window->DockNode->IsBgDrawnThisFrame = true; + + // Title bar + // (when docked, DockNode are drawing their own title bar. Individual windows however do NOT set the _NoTitleBar flag, + // in order for their pos/size to be matching their undocking state.) + if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive) + { + ImU32 title_bar_col = GetColorU32(title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); + window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawFlags_RoundCornersTop); + } + + // Menu bar + if (flags & ImGuiWindowFlags_MenuBar) + { + ImRect menu_bar_rect = window->MenuBarRect(); + menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. + window->DrawList->AddRectFilled(menu_bar_rect.Min + ImVec2(window_border_size, 0), menu_bar_rect.Max - ImVec2(window_border_size, 0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop); + if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + } + + // Docking: Unhide tab bar (small triangle in the corner), drag from small triangle to quickly undock + ImGuiDockNode* node = window->DockNode; + if (window->DockIsActive && node->IsHiddenTabBar() && !node->IsNoTabBar()) + { + float unhide_sz_draw = ImFloor(g.FontSize * 0.70f); + float unhide_sz_hit = ImFloor(g.FontSize * 0.55f); + ImVec2 p = node->Pos; + ImRect r(p, p + ImVec2(unhide_sz_hit, unhide_sz_hit)); + bool hovered, held; + if (ButtonBehavior(r, window->GetID("#UNHIDE"), &hovered, &held, ImGuiButtonFlags_FlattenChildren)) + node->WantHiddenTabBarToggle = true; + else if (held && IsMouseDragging(0)) + StartMouseMovingWindowOrNode(window, node, true); + + // FIXME-DOCK: Ideally we'd use ImGuiCol_TitleBgActive/ImGuiCol_TitleBg here, but neither is guaranteed to be visible enough at this sort of size.. + ImU32 col = GetColorU32(((held && hovered) || (node->IsFocused && !hovered)) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + window->DrawList->AddTriangleFilled(p, p + ImVec2(unhide_sz_draw, 0.0f), p + ImVec2(0.0f, unhide_sz_draw), col); + } + + // Scrollbars + if (window->ScrollbarX) + Scrollbar(ImGuiAxis_X); + if (window->ScrollbarY) + Scrollbar(ImGuiAxis_Y); + + // Render resize grips (after their input handling so we don't have a frame of latency) + if (handle_borders_and_resize_grips && !(flags & ImGuiWindowFlags_NoResize)) + { + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size))); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size))); + window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); + window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); + } + } + + // Borders (for dock node host they will be rendered over after the tab bar) + if (handle_borders_and_resize_grips && !window->DockNodeAsHost) + RenderWindowOuterBorders(window); + } +} + +// Render title text, collapse button, close button +// When inside a dock node, this is handled in DockNodeCalcTabBarLayout() instead. +void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImGuiWindowFlags flags = window->Flags; + + const bool has_close_button = (p_open != NULL); + const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse) && (style.WindowMenuButtonPosition != ImGuiDir_None); + + // Close & Collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer) + // FIXME-NAV: Might want (or not?) to set the equivalent of ImGuiButtonFlags_NoNavFocus so that mouse clicks on standard title bar items don't necessarily set nav/keyboard ref? + const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags; + g.CurrentItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; + + // Layout buttons + // FIXME: Would be nice to generalize the subtleties expressed here into reusable code. + float pad_l = style.FramePadding.x; + float pad_r = style.FramePadding.x; + float button_sz = g.FontSize; + ImVec2 close_button_pos; + ImVec2 collapse_button_pos; + if (has_close_button) + { + pad_r += button_sz; + close_button_pos = ImVec2(title_bar_rect.Max.x - pad_r - style.FramePadding.x, title_bar_rect.Min.y); + } + if (has_collapse_button && style.WindowMenuButtonPosition == ImGuiDir_Right) + { + pad_r += button_sz; + collapse_button_pos = ImVec2(title_bar_rect.Max.x - pad_r - style.FramePadding.x, title_bar_rect.Min.y); + } + if (has_collapse_button && style.WindowMenuButtonPosition == ImGuiDir_Left) + { + collapse_button_pos = ImVec2(title_bar_rect.Min.x + pad_l - style.FramePadding.x, title_bar_rect.Min.y); + pad_l += button_sz; + } + + // Collapse button (submitting first so it gets priority when choosing a navigation init fallback) + if (has_collapse_button) + if (CollapseButton(window->GetID("#COLLAPSE"), collapse_button_pos, NULL)) + window->WantCollapseToggle = true; // Defer actual collapsing to next frame as we are too far in the Begin() function + + // Close button + if (has_close_button) + if (CloseButton(window->GetID("#CLOSE"), close_button_pos)) + *p_open = false; + + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + g.CurrentItemFlags = item_flags_backup; + + // Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker) + // FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code.. + const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? button_sz * 0.80f : 0.0f; + const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f); + + // As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button, + // while uncentered title text will still reach edges correctly. + if (pad_l > style.FramePadding.x) + pad_l += g.Style.ItemInnerSpacing.x; + if (pad_r > style.FramePadding.x) + pad_r += g.Style.ItemInnerSpacing.x; + if (style.WindowTitleAlign.x > 0.0f && style.WindowTitleAlign.x < 1.0f) + { + float centerness = ImSaturate(1.0f - ImFabs(style.WindowTitleAlign.x - 0.5f) * 2.0f); // 0.0f on either edges, 1.0f on center + float pad_extend = ImMin(ImMax(pad_l, pad_r), title_bar_rect.GetWidth() - pad_l - pad_r - text_size.x); + pad_l = ImMax(pad_l, pad_extend * centerness); + pad_r = ImMax(pad_r, pad_extend * centerness); + } + + ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y); + ImRect clip_r(layout_r.Min.x, layout_r.Min.y, ImMin(layout_r.Max.x + g.Style.ItemInnerSpacing.x, title_bar_rect.Max.x), layout_r.Max.y); + if (flags & ImGuiWindowFlags_UnsavedDocument) + { + ImVec2 marker_pos; + marker_pos.x = ImClamp(layout_r.Min.x + (layout_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x + text_size.x, layout_r.Min.x, layout_r.Max.x); + marker_pos.y = (layout_r.Min.y + layout_r.Max.y) * 0.5f; + if (marker_pos.x > layout_r.Min.x) + { + RenderBullet(window->DrawList, marker_pos, GetColorU32(ImGuiCol_Text)); + clip_r.Max.x = ImMin(clip_r.Max.x, marker_pos.x - (int)(marker_size_x * 0.5f)); + } + } + //if (g.IO.KeyShift) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG] + //if (g.IO.KeyCtrl) window->DrawList->AddRect(clip_r.Min, clip_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG] + RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r); +} + +void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window) +{ + window->ParentWindow = parent_window; + window->RootWindow = window->RootWindowPopupTree = window->RootWindowDockTree = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window; + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) + { + window->RootWindowDockTree = parent_window->RootWindowDockTree; + if (!window->DockIsActive && !(parent_window->Flags & ImGuiWindowFlags_DockNodeHost)) + window->RootWindow = parent_window->RootWindow; + } + if (parent_window && (flags & ImGuiWindowFlags_Popup)) + window->RootWindowPopupTree = parent_window->RootWindowPopupTree; + if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) + window->RootWindowForTitleBarHighlight = parent_window->RootWindowForTitleBarHighlight; + while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened) + { + IM_ASSERT(window->RootWindowForNav->ParentWindow != NULL); + window->RootWindowForNav = window->RootWindowForNav->ParentWindow; + } +} + +// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) +// should be positioned behind that modal window, unless the window was created inside the modal begin-stack. +// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. +// - Window // FindBlockingModal() returns Modal1 +// - Window // .. returns Modal1 +// - Modal1 // .. returns Modal2 +// - Window // .. returns Modal2 +// - Window // .. returns Modal2 +// - Modal2 // .. returns Modal2 +static ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= 0) + return NULL; + + // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. + for (int i = g.OpenPopupStack.Size - 1; i >= 0; i--) + { + ImGuiWindow* popup_window = g.OpenPopupStack.Data[i].Window; + if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal)) + continue; + if (!popup_window->Active && !popup_window->WasActive) // Check WasActive, because this code may run before popup renders on current frame, also check Active to handle newly created windows. + continue; + if (IsWindowWithinBeginStackOf(window, popup_window)) // Window is rendered over last modal, no render order change needed. + break; + for (ImGuiWindow* parent = popup_window->ParentWindowInBeginStack->RootWindow; parent != NULL; parent = parent->ParentWindowInBeginStack->RootWindow) + if (IsWindowWithinBeginStackOf(window, parent)) + return popup_window; // Place window above its begin stack parent. + } + return NULL; +} + +// Push a new Dear ImGui window to add widgets to. +// - 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_open' 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. +bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + IM_ASSERT(name != NULL && name[0] != '\0'); // Window name required + IM_ASSERT(g.WithinFrameScope); // Forgot to call ImGui::NewFrame() + IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet + + // Find or create + ImGuiWindow* window = FindWindowByName(name); + const bool window_just_created = (window == NULL); + if (window_just_created) + window = CreateNewWindow(name, flags); + else + UpdateWindowInFocusOrderList(window, window_just_created, flags); + + // Automatically disable manual moving/resizing when NoInputs is set + if ((flags & ImGuiWindowFlags_NoInputs) == ImGuiWindowFlags_NoInputs) + flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; + + if (flags & ImGuiWindowFlags_NavFlattened) + IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); + + const int current_frame = g.FrameCount; + const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); + window->IsFallbackWindow = (g.CurrentWindowStack.Size == 0 && g.WithinFrameScopeWithImplicitWindow); + + // Update the Appearing flag (note: the BeginDocked() path may also set this to true later) + bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; + window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed + window_just_activated_by_user |= (window != popup_ref.Window); + } + + // Update Flags, LastFrameActive, BeginOrderXXX fields + const bool window_was_appearing = window->Appearing; + if (first_begin_of_the_frame) + { + window->Appearing = window_just_activated_by_user; + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); + + window->FlagsPreviousFrame = window->Flags; + window->Flags = (ImGuiWindowFlags)flags; + window->LastFrameActive = current_frame; + window->LastTimeActive = (float)g.Time; + window->BeginOrderWithinParent = 0; + window->BeginOrderWithinContext = (short)(g.WindowsActiveCount++); + } + else + { + flags = window->Flags; + } + + // Docking + // (NB: during the frame dock nodes are created, it is possible that (window->DockIsActive == false) even though (window->DockNode->Windows.Size > 1) + IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL); // Cannot be both + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasDock) + SetWindowDock(window, g.NextWindowData.DockId, g.NextWindowData.DockCond); + if (first_begin_of_the_frame) + { + bool has_dock_node = (window->DockId != 0 || window->DockNode != NULL); + bool new_auto_dock_node = !has_dock_node && GetWindowAlwaysWantOwnTabBar(window); + bool dock_node_was_visible = window->DockNodeIsVisible; + bool dock_tab_was_visible = window->DockTabIsVisible; + if (has_dock_node || new_auto_dock_node) + { + BeginDocked(window, p_open); + flags = window->Flags; + if (window->DockIsActive) + { + IM_ASSERT(window->DockNode != NULL); + g.NextWindowData.Flags &= ~ImGuiNextWindowDataFlags_HasSizeConstraint; // Docking currently override constraints + } + + // Amend the Appearing flag + if (window->DockTabIsVisible && !dock_tab_was_visible && dock_node_was_visible && !window->Appearing && !window_was_appearing) + { + window->Appearing = true; + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); + } + } + else + { + window->DockIsActive = window->DockNodeIsVisible = window->DockTabIsVisible = false; + } + } + + // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack + ImGuiWindow* parent_window_in_stack = window->DockIsActive ? window->DockNode->HostWindow : g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back().Window; + ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow; + IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); + + // We allow window memory to be compacted so recreate the base stack when needed. + if (window->IDStack.Size == 0) + window->IDStack.push_back(window->ID); + + // Add to stack + // We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow() + g.CurrentWindow = window; + ImGuiWindowStackData window_stack_data; + window_stack_data.Window = window; + window_stack_data.ParentLastItemDataBackup = g.LastItemData; + window_stack_data.StackSizesOnBegin.SetToCurrentState(); + g.CurrentWindowStack.push_back(window_stack_data); + g.CurrentWindow = NULL; + if (flags & ImGuiWindowFlags_ChildMenu) + g.BeginMenuCount++; + + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; + popup_ref.Window = window; + g.BeginPopupStack.push_back(popup_ref); + window->PopupId = popup_ref.PopupId; + } + + // Update ->RootWindow and others pointers (before any possible call to FocusWindow) + if (first_begin_of_the_frame) + { + UpdateWindowParentAndRootLinks(window, flags, parent_window); + window->ParentWindowInBeginStack = parent_window_in_stack; + } + + // Process SetNextWindow***() calls + // (FIXME: Consider splitting the HasXXX flags into X/Y components + bool window_pos_set_by_api = false; + bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) + { + window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0; + if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f) + { + // May be processed on the next frame if this is our first frame and we are measuring size + // FIXME: Look into removing the branch so everything can go through this same code path for consistency. + window->SetWindowPosVal = g.NextWindowData.PosVal; + window->SetWindowPosPivot = g.NextWindowData.PosPivotVal; + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + } + else + { + SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); + } + } + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) + { + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); + SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); + } + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) + { + if (g.NextWindowData.ScrollVal.x >= 0.0f) + { + window->ScrollTarget.x = g.NextWindowData.ScrollVal.x; + window->ScrollTargetCenterRatio.x = 0.0f; + } + if (g.NextWindowData.ScrollVal.y >= 0.0f) + { + window->ScrollTarget.y = g.NextWindowData.ScrollVal.y; + window->ScrollTargetCenterRatio.y = 0.0f; + } + } + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize) + window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal; + else if (first_begin_of_the_frame) + window->ContentSizeExplicit = ImVec2(0.0f, 0.0f); + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasWindowClass) + window->WindowClass = g.NextWindowData.WindowClass; + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed) + SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasFocus) + FocusWindow(window); + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); + + // When reusing window again multiple times a frame, just append content (don't need to setup again) + if (first_begin_of_the_frame) + { + // Initialize + const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0); + window->Active = true; + window->HasCloseButton = (p_open != NULL); + window->ClipRect = ImVec4(-FLT_MAX, -FLT_MAX, +FLT_MAX, +FLT_MAX); + window->IDStack.resize(1); + window->DrawList->_ResetForNewFrame(); + window->DC.CurrentTableIdx = -1; + if (flags & ImGuiWindowFlags_DockNodeHost) + { + window->DrawList->ChannelsSplit(2); + window->DrawList->ChannelsSetCurrent(1); // Render decorations on channel 1 as we will render the backgrounds manually later + } + + // Restore buffer capacity when woken from a compacted state, to avoid + if (window->MemoryCompacted) + GcAwakeTransientWindowBuffers(window); + + // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged). + // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere. + bool window_title_visible_elsewhere = false; + if ((window->Viewport && window->Viewport->Window == window) || (window->DockIsActive)) + window_title_visible_elsewhere = true; + else if (g.NavWindowingListWindow != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB + window_title_visible_elsewhere = true; + if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0) + { + size_t buf_len = (size_t)window->NameBufLen; + window->Name = ImStrdupcpy(window->Name, &buf_len, name); + window->NameBufLen = (int)buf_len; + } + + // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS + + // Update contents size from last frame for auto-fitting (or use explicit size) + CalcWindowContentSizes(window, &window->ContentSize, &window->ContentSizeIdeal); + + // FIXME: These flags are decremented before they are used. This means that in order to have these fields produce their intended behaviors + // for one frame we must set them to at least 2, which is counter-intuitive. HiddenFramesCannotSkipItems is a more complicated case because + // it has a single usage before this code block and may be set below before it is finally checked. + if (window->HiddenFramesCanSkipItems > 0) + window->HiddenFramesCanSkipItems--; + if (window->HiddenFramesCannotSkipItems > 0) + window->HiddenFramesCannotSkipItems--; + if (window->HiddenFramesForRenderOnly > 0) + window->HiddenFramesForRenderOnly--; + + // Hide new windows for one frame until they calculate their size + if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api)) + window->HiddenFramesCannotSkipItems = 1; + + // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) + // We reset Size/ContentSize for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size. + if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0) + { + window->HiddenFramesCannotSkipItems = 1; + if (flags & ImGuiWindowFlags_AlwaysAutoResize) + { + if (!window_size_x_set_by_api) + window->Size.x = window->SizeFull.x = 0.f; + if (!window_size_y_set_by_api) + window->Size.y = window->SizeFull.y = 0.f; + window->ContentSize = window->ContentSizeIdeal = ImVec2(0.f, 0.f); + } + } + + // SELECT VIEWPORT + // We need to do this before using any style/font sizes, as viewport with a different DPI may affect font sizes. + + WindowSelectViewport(window); + SetCurrentViewport(window, window->Viewport); + window->FontDpiScale = (g.IO.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ? window->Viewport->DpiScale : 1.0f; + SetCurrentWindow(window); + flags = window->Flags; + + // LOCK BORDER SIZE AND PADDING FOR THE FRAME (so that altering them doesn't cause inconsistencies) + // We read Style data after the call to UpdateSelectWindowViewport() which might be swapping the style. + + if (flags & ImGuiWindowFlags_ChildWindow) + window->WindowBorderSize = style.ChildBorderSize; + else + window->WindowBorderSize = ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + if (!window->DockIsActive && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) + window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + else + window->WindowPadding = style.WindowPadding; + + // Lock menu offset so size calculation can use it as menu-bar windows need a minimum size. + window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x); + window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y; + + // Collapse window by double-clicking on title bar + // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing + if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse) && !window->DockIsActive) + { + // We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar. + ImRect title_bar_rect = window->TitleBarRect(); + if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseClickedCount[0] == 2) + window->WantCollapseToggle = true; + if (window->WantCollapseToggle) + { + window->Collapsed = !window->Collapsed; + MarkIniSettingsDirty(window); + } + } + else + { + window->Collapsed = false; + } + window->WantCollapseToggle = false; + + // SIZE + + // Calculate auto-fit size, handle automatic resize + const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSizeIdeal); + bool use_current_size_for_scrollbar_x = window_just_created; + bool use_current_size_for_scrollbar_y = window_just_created; + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed) + { + // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. + if (!window_size_x_set_by_api) + { + window->SizeFull.x = size_auto_fit.x; + use_current_size_for_scrollbar_x = true; + } + if (!window_size_y_set_by_api) + { + window->SizeFull.y = size_auto_fit.y; + use_current_size_for_scrollbar_y = true; + } + } + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + { + // Auto-fit may only grow window during the first few frames + // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. + if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) + { + window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + use_current_size_for_scrollbar_x = true; + } + if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) + { + window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + use_current_size_for_scrollbar_y = true; + } + if (!window->Collapsed) + MarkIniSettingsDirty(window); + } + + // Apply minimum/maximum window size constraints and final size + window->SizeFull = CalcWindowSizeAfterConstraint(window, window->SizeFull); + window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; + + // Decoration size + const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); + + // POSITION + + // Popup latch its initial position, will position itself when it appears next frame + if (window_just_activated_by_user) + { + window->AutoPosLastDirection = ImGuiDir_None; + if ((flags & ImGuiWindowFlags_Popup) != 0 && !(flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api) // FIXME: BeginPopup() could use SetNextWindowPos() + window->Pos = g.BeginPopupStack.back().OpenPopupPos; + } + + // Position child window + if (flags & ImGuiWindowFlags_ChildWindow) + { + IM_ASSERT(parent_window && parent_window->Active); + window->BeginOrderWithinParent = (short)parent_window->DC.ChildWindows.Size; + parent_window->DC.ChildWindows.push_back(window); + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) + window->Pos = parent_window->DC.CursorPos; + } + + const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFramesCannotSkipItems == 0); + if (window_pos_with_pivot) + SetWindowPos(window, window->SetWindowPosVal - window->Size * window->SetWindowPosPivot, 0); // Position given a pivot (e.g. for centering) + else if ((flags & ImGuiWindowFlags_ChildMenu) != 0) + window->Pos = FindBestWindowPosForPopup(window); + else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) + window->Pos = FindBestWindowPosForPopup(window); + else if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) + window->Pos = FindBestWindowPosForPopup(window); + + // Late create viewport if we don't fit within our current host viewport. + if (window->ViewportAllowPlatformMonitorExtend >= 0 && !window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_Minimized)) + if (!window->Viewport->GetMainRect().Contains(window->Rect())) + { + // This is based on the assumption that the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport) + //ImGuiViewport* old_viewport = window->Viewport; + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing); + + // FIXME-DPI + //IM_ASSERT(old_viewport->DpiScale == window->Viewport->DpiScale); // FIXME-DPI: Something went wrong + SetCurrentViewport(window, window->Viewport); + window->FontDpiScale = (g.IO.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ? window->Viewport->DpiScale : 1.0f; + SetCurrentWindow(window); + } + + if (window->ViewportOwned) + WindowSyncOwnedViewport(window, parent_window_in_stack); + + // Calculate the range of allowed position for that window (to be movable and visible past safe area padding) + // When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect. + ImRect viewport_rect(window->Viewport->GetMainRect()); + ImRect viewport_work_rect(window->Viewport->GetWorkRect()); + ImVec2 visibility_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); + ImRect visibility_rect(viewport_work_rect.Min + visibility_padding, viewport_work_rect.Max - visibility_padding); + + // Clamp position/size so window stays visible within its viewport or monitor + // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. + // FIXME: Similar to code in GetWindowAllowedExtentRect() + if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + { + if (!window->ViewportOwned && viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f) + { + ClampWindowRect(window, visibility_rect); + } + else if (window->ViewportOwned && g.PlatformIO.Monitors.Size > 0) + { + // Lost windows (e.g. a monitor disconnected) will naturally moved to the fallback/dummy monitor aka the main viewport. + const ImGuiPlatformMonitor* monitor = GetViewportPlatformMonitor(window->Viewport); + visibility_rect.Min = monitor->WorkPos + visibility_padding; + visibility_rect.Max = monitor->WorkPos + monitor->WorkSize - visibility_padding; + ClampWindowRect(window, visibility_rect); + } + } + window->Pos = ImFloor(window->Pos); + + // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) + // Large values tend to lead to variety of artifacts and are not recommended. + if (window->ViewportOwned || window->DockIsActive) + window->WindowRounding = 0.0f; + else + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + + // For windows with title bar or menu bar, we clamp to FrameHeight(FontSize + FramePadding.y * 2.0f) to completely hide artifacts. + //if ((window->Flags & ImGuiWindowFlags_MenuBar) || !(window->Flags & ImGuiWindowFlags_NoTitleBar)) + // window->WindowRounding = ImMin(window->WindowRounding, g.FontSize + style.FramePadding.y * 2.0f); + + // Apply window focus (new and reactivated windows are moved to front) + bool want_focus = false; + if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + { + if (flags & ImGuiWindowFlags_Popup) + want_focus = true; + else if ((window->DockIsActive || (flags & ImGuiWindowFlags_ChildWindow) == 0) && !(flags & ImGuiWindowFlags_Tooltip)) + want_focus = true; + + ImGuiWindow* modal = GetTopMostPopupModal(); + if (modal != NULL && !IsWindowWithinBeginStackOf(window, modal)) + { + // Avoid focusing a window that is created outside of active modal. This will prevent active modal from being closed. + // Since window is not focused it would reappear at the same display position like the last time it was visible. + // In case of completely new windows it would go to the top (over current modal), but input to such window would still be blocked by modal. + // Position window behind a modal that is not a begin-parent of this window. + want_focus = false; + if (window == window->RootWindow) + { + ImGuiWindow* blocking_modal = FindBlockingModal(window); + IM_ASSERT(blocking_modal != NULL); + BringWindowToDisplayBehind(window, blocking_modal); + } + } + } + + // [Test Engine] Register whole window in the item system +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (g.TestEngineHookItems) + { + IM_ASSERT(window->IDStack.Size == 1); + window->IDStack.Size = 0; + IMGUI_TEST_ENGINE_ITEM_ADD(window->Rect(), window->ID); + IMGUI_TEST_ENGINE_ITEM_INFO(window->ID, window->Name, (g.HoveredWindow == window) ? ImGuiItemStatusFlags_HoveredRect : 0); + window->IDStack.Size = 1; + } +#endif + + // Decide if we are going to handle borders and resize grips + const bool handle_borders_and_resize_grips = (window->DockNodeAsHost || !window->DockIsActive); + + // Handle manual resize: Resize Grips, Borders, Gamepad + int border_held = -1; + ImU32 resize_grip_col[4] = {}; + const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it. + const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); + if (handle_borders_and_resize_grips && !window->Collapsed) + if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect)) + use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true; + window->ResizeBorderHeld = (signed char)border_held; + + // Synchronize window --> viewport again and one last time (clamping and manual resize may have affected either) + if (window->ViewportOwned) + { + if (!window->Viewport->PlatformRequestMove) + window->Viewport->Pos = window->Pos; + if (!window->Viewport->PlatformRequestResize) + window->Viewport->Size = window->Size; + window->Viewport->UpdateWorkRect(); + viewport_rect = window->Viewport->GetMainRect(); + } + + // Save last known viewport position within the window itself (so it can be saved in .ini file and restored) + window->ViewportPos = window->Viewport->Pos; + + // SCROLLBAR VISIBILITY + + // Update scrollbar visibility (based on the Size that was effective during last frame or the auto-resized Size). + if (!window->Collapsed) + { + // When reading the current size we need to read it after size constraints have been applied. + // When we use InnerRect here we are intentionally reading last frame size, same for ScrollbarSizes values before we set them again. + ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - decoration_up_height); + ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + window->ScrollbarSizes; + ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0, 0) : window->ContentSize + window->WindowPadding * 2.0f; + float size_x_for_scrollbars = use_current_size_for_scrollbar_x ? avail_size_from_current_frame.x : avail_size_from_last_frame.x; + float size_y_for_scrollbars = use_current_size_for_scrollbar_y ? avail_size_from_current_frame.y : avail_size_from_last_frame.y; + //bool scrollbar_y_from_last_frame = window->ScrollbarY; // FIXME: May want to use that in the ScrollbarX expression? How many pros vs cons? + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + if (window->ScrollbarX && !window->ScrollbarY) + window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + } + + // UPDATE RECTANGLES (1- THOSE NOT AFFECTED BY SCROLLING) + // Update various regions. Variables they depends on should be set above in this function. + // We set this up after processing the resize grip so that our rectangles doesn't lag by a frame. + + // Outer rectangle + // Not affected by window border size. Used by: + // - FindHoveredWindow() (w/ extra padding when border resize is enabled) + // - Begin() initial clipping rect for drawing window background and borders. + // - Begin() clipping whole child + const ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect; + const ImRect outer_rect = window->Rect(); + const ImRect title_bar_rect = window->TitleBarRect(); + window->OuterRectClipped = outer_rect; + if (window->DockIsActive) + window->OuterRectClipped.Min.y += window->TitleBarHeight(); + window->OuterRectClipped.ClipWith(host_rect); + + // Inner rectangle + // Not affected by window border size. Used by: + // - InnerClipRect + // - ScrollToRectEx() + // - NavUpdatePageUpPageDown() + // - Scrollbar() + window->InnerRect.Min.x = window->Pos.x; + window->InnerRect.Min.y = window->Pos.y + decoration_up_height; + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; + + // Inner clipping rectangle. + // Will extend a little bit outside the normal work region. + // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space. + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior. + // Affected by window/frame border size. Used by: + // - Begin() initial clip rect + float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); + window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); + window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size); + window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); + window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize); + window->InnerClipRect.ClipWithFull(host_rect); + + // Default item width. Make it proportional to window size if window manually resizes + if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) + window->ItemWidthDefault = ImFloor(window->Size.x * 0.65f); + else + window->ItemWidthDefault = ImFloor(g.FontSize * 16.0f); + + // SCROLLING + + // Lock down maximum scrolling + // The value of ScrollMax are ahead from ScrollbarX/ScrollbarY which is intentionally using InnerRect from previous rect in order to accommodate + // for right/bottom aligned items without creating a scrollbar. + window->ScrollMax.x = ImMax(0.0f, window->ContentSize.x + window->WindowPadding.x * 2.0f - window->InnerRect.GetWidth()); + window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight()); + + // Apply scrolling + window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); + window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + + // DRAWING + + // Setup draw list and outer clipping rectangle + IM_ASSERT(window->DrawList->CmdBuffer.Size == 1 && window->DrawList->CmdBuffer[0].ElemCount == 0); + window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); + PushClipRect(host_rect.Min, host_rect.Max, false); + + // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71) + // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order. + // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493) + const bool is_undocked_or_docked_visible = !window->DockIsActive || window->DockTabIsVisible; + if (is_undocked_or_docked_visible) + { + bool render_decorations_in_parent = false; + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) + { + // - We test overlap with the previous child window only (testing all would end up being O(log N) not a good investment here) + // - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs + ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL; + bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false; + bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0; + if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping) + render_decorations_in_parent = true; + } + if (render_decorations_in_parent) + window->DrawList = parent_window->DrawList; + + // Handle title bar, scrollbar, resize grips and resize borders + const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow; + const bool title_bar_is_highlight = want_focus || (window_to_highlight && (window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight || (window->DockNode && window->DockNode == window_to_highlight->DockNode))); + RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size); + + if (render_decorations_in_parent) + window->DrawList = &window->DrawListInst; + } + + // UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING) + + // Work rectangle. + // Affected by window padding and border size. Used by: + // - Columns() for right-most edge + // - TreeNode(), CollapsingHeader() for right-most edge + // - BeginTabBar() for right-most edge + const bool allow_scrollbar_x = !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar); + const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar); + const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x)); + const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y)); + window->WorkRect.Min.x = ImFloor(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize)); + window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize)); + window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x; + window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y; + window->ParentWorkRect = window->WorkRect; + + // [LEGACY] Content Region + // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. + // Used by: + // - Mouse wheel scrolling + many other things + window->ContentRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x; + window->ContentRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height; + window->ContentRegionRect.Max.x = window->ContentRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x)); + window->ContentRegionRect.Max.y = window->ContentRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y)); + + // Setup drawing context + // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) + window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.GroupOffset.x = 0.0f; + window->DC.ColumnsOffset.x = 0.0f; + + // Record the loss of precision of CursorStartPos which can happen due to really large scrolling amount. + // This is used by clipper to compensate and fix the most common use case of large scroll area. Easy and cheap, next best thing compared to switching everything to double or ImU64. + double start_pos_highp_x = (double)window->Pos.x + window->WindowPadding.x - (double)window->Scroll.x + window->DC.ColumnsOffset.x; + double start_pos_highp_y = (double)window->Pos.y + window->WindowPadding.y - (double)window->Scroll.y + decoration_up_height; + window->DC.CursorStartPos = ImVec2((float)start_pos_highp_x, (float)start_pos_highp_y); + window->DC.CursorStartPosLossyness = ImVec2((float)(start_pos_highp_x - window->DC.CursorStartPos.x), (float)(start_pos_highp_y - window->DC.CursorStartPos.y)); + window->DC.CursorPos = window->DC.CursorStartPos; + window->DC.CursorPosPrevLine = window->DC.CursorPos; + window->DC.CursorMaxPos = window->DC.CursorStartPos; + window->DC.IdealMaxPos = window->DC.CursorStartPos; + window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); + window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; + + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + window->DC.NavLayersActiveMask = window->DC.NavLayersActiveMaskNext; + window->DC.NavHideHighlightOneFrame = false; + window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f); + + window->DC.MenuBarAppending = false; + window->DC.MenuColumns.Update(style.ItemSpacing.x, window_just_activated_by_user); + window->DC.TreeDepth = 0; + window->DC.TreeJumpToParentOnPopMask = 0x00; + window->DC.ChildWindows.resize(0); + window->DC.StateStorage = &window->StateStorage; + window->DC.CurrentColumns = NULL; + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; + + window->DC.ItemWidth = window->ItemWidthDefault; + window->DC.TextWrapPos = -1.0f; // disabled + window->DC.ItemWidthStack.resize(0); + window->DC.TextWrapPosStack.resize(0); + + if (window->AutoFitFramesX > 0) + window->AutoFitFramesX--; + if (window->AutoFitFramesY > 0) + window->AutoFitFramesY--; + + // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (want_focus) + { + FocusWindow(window); + NavInitWindow(window, false); // <-- this is in the way for us to be able to defer and sort reappearing FocusWindow() calls + } + + // Close requested by platform window + if (p_open != NULL && window->Viewport->PlatformRequestClose && window->Viewport != GetMainViewport()) + { + if (!window->DockIsActive || window->DockTabIsVisible) + { + window->Viewport->PlatformRequestClose = false; + g.NavWindowingToggleLayer = false; // Assume user mapped PlatformRequestClose on ALT-F4 so we disable ALT for menu toggle. False positive not an issue. + IMGUI_DEBUG_LOG_VIEWPORT("Window '%s' PlatformRequestClose\n", window->Name); + *p_open = false; + } + } + + // Title bar + if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive) + RenderWindowTitleBarContents(window, ImRect(title_bar_rect.Min.x + window->WindowBorderSize, title_bar_rect.Min.y, title_bar_rect.Max.x - window->WindowBorderSize, title_bar_rect.Max.y), name, p_open); + + // Clear hit test shape every frame + window->HitTestHoleSize.x = window->HitTestHoleSize.y = 0; + + // 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.NavWindow == window && g.ActiveId == 0) + if (g.ActiveId == window->MoveId) + if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) + LogToClipboard(); + */ + + if (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable) + { + // Docking: Dragging a dockable window (or any of its child) turns it into a drag and drop source. + // We need to do this _before_ we overwrite window->DC.LastItemId below because BeginDockableDragDropSource() also overwrites it. + if ((g.MovingWindow == window) && (g.IO.ConfigDockingWithShift == g.IO.KeyShift)) + if ((window->RootWindowDockTree->Flags & ImGuiWindowFlags_NoDocking) == 0) + BeginDockableDragDropSource(window); + + // Docking: Any dockable window can act as a target. For dock node hosts we call BeginDockableDragDropTarget() in DockNodeUpdate() instead. + if (g.DragDropActive && !(flags & ImGuiWindowFlags_NoDocking)) + if (g.MovingWindow == NULL || g.MovingWindow->RootWindowDockTree != window) + if ((window == window->RootWindowDockTree) && !(window->Flags & ImGuiWindowFlags_DockNodeHost)) + BeginDockableDragDropTarget(window); + } + + // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). + // This is useful to allow creating context menus on title bar only, etc. + if (window->DockIsActive) + SetLastItemData(window->MoveId, g.CurrentItemFlags, window->DockTabItemStatusFlags, window->DockTabItemRect); + else + SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect); + + // [Test Engine] Register title bar / tab + if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + IMGUI_TEST_ENGINE_ITEM_ADD(g.LastItemData.Rect, g.LastItemData.ID); + } + else + { + // Append + SetCurrentViewport(window, window->Viewport); + SetCurrentWindow(window); + } + + // Pull/inherit current state + window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetID("#FOCUSSCOPE"); // Inherit from parent only // -V595 + + if (!(flags & ImGuiWindowFlags_DockNodeHost)) + PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); + + // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) + window->WriteAccessed = false; + window->BeginCount++; + g.NextWindowData.ClearFlags(); + + // Update visibility + if (first_begin_of_the_frame) + { + // When we are about to select this tab (which will only be visible on the _next frame_), flag it with a non-zero HiddenFramesCannotSkipItems. + // This will have the important effect of actually returning true in Begin() and not setting SkipItems, allowing an earlier submission of the window contents. + // This is analogous to regular windows being hidden from one frame. + // It is especially important as e.g. nested TabBars would otherwise generate flicker in the form of one empty frame, or focus requests won't be processed. + if (window->DockIsActive && !window->DockTabIsVisible) + { + if (window->LastFrameJustFocused == g.FrameCount) + window->HiddenFramesCannotSkipItems = 1; + else + window->HiddenFramesCanSkipItems = 1; + } + + if (flags & ImGuiWindowFlags_ChildWindow) + { + // 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 them because they have no title bar). + IM_ASSERT((flags& ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive)); + if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) // FIXME: Doesn't make sense for ChildWindow?? + { + const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (!g.LogEnabled && !nav_request) + if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y) + window->HiddenFramesCanSkipItems = 1; + } + + // Hide along with parent or if parent is collapsed + if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0)) + window->HiddenFramesCanSkipItems = 1; + if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCannotSkipItems > 0)) + window->HiddenFramesCannotSkipItems = 1; + } + + // Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point) + if (style.Alpha <= 0.0f) + window->HiddenFramesCanSkipItems = 1; + + // Update the Hidden flag + bool hidden_regular = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0); + window->Hidden = hidden_regular || (window->HiddenFramesForRenderOnly > 0); + + // Disable inputs for requested number of frames + if (window->DisableInputsFrames > 0) + { + window->DisableInputsFrames--; + window->Flags |= ImGuiWindowFlags_NoInputs; + } + + // Update the SkipItems flag, used to early out of all items functions (no layout required) + bool skip_items = false; + if (window->Collapsed || !window->Active || hidden_regular) + if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0) + skip_items = true; + window->SkipItems = skip_items; + + // Only clear NavLayersActiveMaskNext when marked as visible, so a CTRL+Tab back can use a safe value. + if (!window->SkipItems) + window->DC.NavLayersActiveMaskNext = 0x00; + + // Sanity check: there are two spots which can set Appearing = true + // - when 'window_just_activated_by_user' is set -> HiddenFramesCannotSkipItems is set -> SkipItems always false + // - in BeginDocked() path when DockNodeIsVisible == DockTabIsVisible == true -> hidden _should_ be all zero // FIXME: Not formally proven, hence the assert. + if (window->SkipItems && !window->Appearing) + IM_ASSERT(window->Appearing == false); // Please report on GitHub if this triggers: https://github.com/ocornut/imgui/issues/4177 + } + + return !window->SkipItems; +} + +void ImGui::End() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // Error checking: verify that user hasn't called End() too many times! + if (g.CurrentWindowStack.Size <= 1 && g.WithinFrameScopeWithImplicitWindow) + { + IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size > 1, "Calling End() too many times!"); + return; + } + IM_ASSERT(g.CurrentWindowStack.Size > 0); + + // Error checking: verify that user doesn't directly call End() on a child window. + if ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_DockNodeHost) && !window->DockIsActive) + IM_ASSERT_USER_ERROR(g.WithinEndChild, "Must call EndChild() and not End()!"); + + // Close anything that is open + if (window->DC.CurrentColumns) + EndColumns(); + if (!(window->Flags & ImGuiWindowFlags_DockNodeHost)) // Pop inner window clip rectangle + PopClipRect(); + + // Stop logging + if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging + LogFinish(); + + // Docking: report contents sizes to parent to allow for auto-resize + if (window->DockNode && window->DockTabIsVisible) + if (ImGuiWindow* host_window = window->DockNode->HostWindow) // FIXME-DOCK + host_window->DC.CursorMaxPos = window->DC.CursorMaxPos + window->WindowPadding - host_window->WindowPadding; + + // Pop from window stack + g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup; + if (window->Flags & ImGuiWindowFlags_ChildMenu) + g.BeginMenuCount--; + if (window->Flags & ImGuiWindowFlags_Popup) + g.BeginPopupStack.pop_back(); + g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithCurrentState(); + g.CurrentWindowStack.pop_back(); + SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window); + if (g.CurrentWindow) + SetCurrentViewport(g.CurrentWindow, g.CurrentWindow->Viewport); +} + +void ImGui::BringWindowToFocusFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(window == window->RootWindow); + + const int cur_order = window->FocusOrder; + IM_ASSERT(g.WindowsFocusOrder[cur_order] == window); + if (g.WindowsFocusOrder.back() == window) + return; + + const int new_order = g.WindowsFocusOrder.Size - 1; + for (int n = cur_order; n < new_order; n++) + { + g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1]; + g.WindowsFocusOrder[n]->FocusOrder--; + IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n); + } + g.WindowsFocusOrder[new_order] = window; + window->FocusOrder = (short)new_order; +} + +void ImGui::BringWindowToDisplayFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* current_front_window = g.Windows.back(); + if (current_front_window == window || current_front_window->RootWindowDockTree == window) // Cheap early out (could be better) + return; + for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window + if (g.Windows[i] == window) + { + memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*)); + g.Windows[g.Windows.Size - 1] = window; + break; + } +} + +void ImGui::BringWindowToDisplayBack(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows[0] == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); + g.Windows[0] = window; + break; + } +} + +void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window) +{ + IM_ASSERT(window != NULL && behind_window != NULL); + ImGuiContext& g = *GImGui; + window = window->RootWindow; + behind_window = behind_window->RootWindow; + int pos_wnd = FindWindowDisplayIndex(window); + int pos_beh = FindWindowDisplayIndex(behind_window); + if (pos_wnd < pos_beh) + { + size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes); + g.Windows[pos_beh - 1] = window; + } + else + { + size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes); + g.Windows[pos_beh] = window; + } +} + +int ImGui::FindWindowDisplayIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + return g.Windows.index_from_ptr(g.Windows.find(window)); +} + +// Moving window to front of display and set focus (which happens to be back of our sorted list) +void ImGui::FocusWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + + if (g.NavWindow != window) + { + g.NavWindow = window; + if (window && g.NavDisableMouseHover) + g.NavMousePosDirty = true; + g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId + g.NavFocusScopeId = 0; + g.NavIdIsAlive = false; + g.NavLayer = ImGuiNavLayer_Main; + g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); + //IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL); + } + + // Close popups if any + ClosePopupsOverWindow(window, false); + + // Move the root window to the top of the pile + IM_ASSERT(window == NULL || window->RootWindowDockTree != NULL); + ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; + ImGuiWindow* display_front_window = window ? window->RootWindowDockTree : NULL; + ImGuiDockNode* dock_node = window ? window->DockNode : NULL; + bool active_id_window_is_dock_node_host = (g.ActiveIdWindow && dock_node && dock_node->HostWindow == g.ActiveIdWindow); + + // Steal active widgets. Some of the cases it triggers includes: + // - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run. + // - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId) + // - Using dock host items (tab, collapse button) can trigger this before we redirect the ActiveIdWindow toward the child window. + if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window) + if (!g.ActiveIdNoClearOnFocusLoss && !active_id_window_is_dock_node_host) + ClearActiveID(); + + // Passing NULL allow to disable keyboard focus + if (!window) + return; + window->LastFrameJustFocused = g.FrameCount; + + // Select in dock node + if (dock_node && dock_node->TabBar) + dock_node->TabBar->SelectedTabId = dock_node->TabBar->NextSelectedTabId = window->TabId; + + // Bring to front + BringWindowToFocusFront(focus_front_window); + if (((window->Flags | focus_front_window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayFront(display_front_window); +} + +void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window) +{ + ImGuiContext& g = *GImGui; + int start_idx = g.WindowsFocusOrder.Size - 1; + if (under_this_window != NULL) + { + // Aim at root window behind us, if we are in a child window that's our own root (see #4640) + int offset = -1; + while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow) + { + under_this_window = under_this_window->ParentWindow; + offset = 0; + } + start_idx = FindWindowFocusIndex(under_this_window) + offset; + } + for (int i = start_idx; i >= 0; i--) + { + // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. + ImGuiWindow* window = g.WindowsFocusOrder[i]; + IM_ASSERT(window == window->RootWindow); + if (window != ignore_window && window->WasActive) + if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) + { + // FIXME-DOCK: This is failing (lagging by one frame) for docked windows. + // If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B. + // We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update) + // to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself? + ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window); + FocusWindow(focus_window); + return; + } + } + FocusWindow(NULL); +} + +// Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only. +void ImGui::SetCurrentFont(ImFont* font) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(font->Scale > 0.0f); + g.Font = font; + g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale); + g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; + + ImFontAtlas* atlas = g.Font->ContainerAtlas; + g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; + g.DrawListSharedData.TexUvLines = atlas->TexUvLines; + g.DrawListSharedData.Font = g.Font; + g.DrawListSharedData.FontSize = g.FontSize; +} + +void ImGui::PushFont(ImFont* font) +{ + ImGuiContext& g = *GImGui; + if (!font) + font = GetDefaultFont(); + SetCurrentFont(font); + g.FontStack.push_back(font); + g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); +} + +void ImGui::PopFont() +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow->DrawList->PopTextureID(); + g.FontStack.pop_back(); + SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back()); +} + +void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled) +{ + ImGuiContext& g = *GImGui; + ImGuiItemFlags item_flags = g.CurrentItemFlags; + IM_ASSERT(item_flags == g.ItemFlagsStack.back()); + if (enabled) + item_flags |= option; + else + item_flags &= ~option; + g.CurrentItemFlags = item_flags; + g.ItemFlagsStack.push_back(item_flags); +} + +void ImGui::PopItemFlag() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.ItemFlagsStack.Size > 1); // Too many calls to PopItemFlag() - we always leave a 0 at the bottom of the stack. + g.ItemFlagsStack.pop_back(); + g.CurrentItemFlags = g.ItemFlagsStack.back(); +} + +// BeginDisabled()/EndDisabled() +// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) +// - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently. +// - Feedback welcome at https://github.com/ocornut/imgui/issues/211 +// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. +// - Optimized shortcuts instead of PushStyleVar() + PushItemFlag() +void ImGui::BeginDisabled(bool disabled) +{ + ImGuiContext& g = *GImGui; + bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; + if (!was_disabled && disabled) + { + g.DisabledAlphaBackup = g.Style.Alpha; + g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha); + } + if (was_disabled || disabled) + g.CurrentItemFlags |= ImGuiItemFlags_Disabled; + g.ItemFlagsStack.push_back(g.CurrentItemFlags); + g.DisabledStackSize++; +} + +void ImGui::EndDisabled() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DisabledStackSize > 0); + g.DisabledStackSize--; + bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; + //PopItemFlag(); + g.ItemFlagsStack.pop_back(); + g.CurrentItemFlags = g.ItemFlagsStack.back(); + if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0) + g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); +} + +// FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system. +void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +{ + PushItemFlag(ImGuiItemFlags_NoTabStop, !allow_keyboard_focus); +} + +void ImGui::PopAllowKeyboardFocus() +{ + PopItemFlag(); +} + +void ImGui::PushButtonRepeat(bool repeat) +{ + PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); +} + +void ImGui::PopButtonRepeat() +{ + PopItemFlag(); +} + +void ImGui::PushTextWrapPos(float wrap_pos_x) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPosStack.push_back(window->DC.TextWrapPos); + window->DC.TextWrapPos = wrap_pos_x; +} + +void ImGui::PopTextWrapPos() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPos = window->DC.TextWrapPosStack.back(); + window->DC.TextWrapPosStack.pop_back(); +} + +static ImGuiWindow* GetCombinedRootWindow(ImGuiWindow* window, bool popup_hierarchy, bool dock_hierarchy) +{ + ImGuiWindow* last_window = NULL; + while (last_window != window) + { + last_window = window; + window = window->RootWindow; + if (popup_hierarchy) + window = window->RootWindowPopupTree; + if (dock_hierarchy) + window = window->RootWindowDockTree; + } + return window; +} + +bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy, bool dock_hierarchy) +{ + ImGuiWindow* window_root = GetCombinedRootWindow(window, popup_hierarchy, dock_hierarchy); + if (window_root == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + if (window == window_root) // end of chain + return false; + window = window->ParentWindow; + } + return false; +} + +bool ImGui::IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent) +{ + if (window->RootWindow == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + window = window->ParentWindowInBeginStack; + } + return false; +} + +bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below) +{ + ImGuiContext& g = *GImGui; + + // It would be saner to ensure that display layer is always reflected in the g.Windows[] order, which would likely requires altering all manipulations of that array + const int display_layer_delta = GetWindowDisplayLayer(potential_above) - GetWindowDisplayLayer(potential_below); + if (display_layer_delta != 0) + return display_layer_delta > 0; + + for (int i = g.Windows.Size - 1; i >= 0; i--) + { + ImGuiWindow* candidate_window = g.Windows[i]; + if (candidate_window == potential_above) + return true; + if (candidate_window == potential_below) + return false; + } + return false; +} + +bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) +{ + IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled)) == 0); // Flags not supported by this function + ImGuiContext& g = *GImGui; + ImGuiWindow* ref_window = g.HoveredWindow; + ImGuiWindow* cur_window = g.CurrentWindow; + if (ref_window == NULL) + return false; + + if ((flags & ImGuiHoveredFlags_AnyWindow) == 0) + { + IM_ASSERT(cur_window); // Not inside a Begin()/End() + const bool popup_hierarchy = (flags & ImGuiHoveredFlags_NoPopupHierarchy) == 0; + const bool dock_hierarchy = (flags & ImGuiHoveredFlags_DockHierarchy) != 0; + if (flags & ImGuiHoveredFlags_RootWindow) + cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy, dock_hierarchy); + + bool result; + if (flags & ImGuiHoveredFlags_ChildWindows) + result = IsWindowChildOf(ref_window, cur_window, popup_hierarchy, dock_hierarchy); + else + result = (ref_window == cur_window); + if (!result) + return false; + } + + if (!IsWindowContentHoverable(ref_window, flags)) + return false; + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != ref_window->MoveId) + return false; + return true; +} + +bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* ref_window = g.NavWindow; + ImGuiWindow* cur_window = g.CurrentWindow; + + if (ref_window == NULL) + return false; + if (flags & ImGuiFocusedFlags_AnyWindow) + return true; + + IM_ASSERT(cur_window); // Not inside a Begin()/End() + const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0; + const bool dock_hierarchy = (flags & ImGuiFocusedFlags_DockHierarchy) != 0; + if (flags & ImGuiHoveredFlags_RootWindow) + cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy, dock_hierarchy); + + if (flags & ImGuiHoveredFlags_ChildWindows) + return IsWindowChildOf(ref_window, cur_window, popup_hierarchy, dock_hierarchy); + else + return (ref_window == cur_window); +} + +ImGuiID ImGui::GetWindowDockID() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DockId; +} + +bool ImGui::IsWindowDocked() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DockIsActive; +} + +// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) +// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically. +// If you want a window to never be focused, you may use the e.g. NoInputs flag. +bool ImGui::IsWindowNavFocusable(ImGuiWindow* window) +{ + return window->WasActive && window == window->RootWindow && !(window->Flags & ImGuiWindowFlags_NoNavFocus); +} + +float ImGui::GetWindowWidth() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.x; +} + +float ImGui::GetWindowHeight() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.y; +} + +ImVec2 ImGui::GetWindowPos() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + return window->Pos; +} + +void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowPosAllowFlags & cond) == 0) + return; + + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); + + // Set + const ImVec2 old_pos = window->Pos; + window->Pos = ImFloor(pos); + ImVec2 offset = window->Pos - old_pos; + window->DC.CursorPos += offset; // 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 += offset; // And more importantly we need to offset CursorMaxPos/CursorStartPos this so ContentSize calculation doesn't get affected. + window->DC.IdealMaxPos += offset; + window->DC.CursorStartPos += offset; +} + +void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + SetWindowPos(window, pos, cond); +} + +void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond) +{ + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowPos(window, pos, cond); +} + +ImVec2 ImGui::GetWindowSize() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Size; +} + +void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) + return; + + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. + window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + + // Set + if (size.x > 0.0f) + { + window->AutoFitFramesX = 0; + window->SizeFull.x = IM_FLOOR(size.x); + } + else + { + window->AutoFitFramesX = 2; + window->AutoFitOnlyGrows = false; + } + if (size.y > 0.0f) + { + window->AutoFitFramesY = 0; + window->SizeFull.y = IM_FLOOR(size.y); + } + else + { + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } +} + +void ImGui::SetWindowSize(const ImVec2& size, ImGuiCond cond) +{ + SetWindowSize(GImGui->CurrentWindow, size, cond); +} + +void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) +{ + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowSize(window, size, cond); +} + +void ImGui::SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) + return; + window->SetWindowCollapsedAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + + // Set + window->Collapsed = collapsed; +} + +void ImGui::SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size) +{ + IM_ASSERT(window->HitTestHoleSize.x == 0); // We don't support multiple holes/hit test filters + window->HitTestHoleSize = ImVec2ih(size); + window->HitTestHoleOffset = ImVec2ih(pos - window->Pos); +} + +void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond) +{ + SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); +} + +bool ImGui::IsWindowCollapsed() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Collapsed; +} + +bool ImGui::IsWindowAppearing() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Appearing; +} + +void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) +{ + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowCollapsed(window, collapsed, cond); +} + +void ImGui::SetWindowFocus() +{ + FocusWindow(GImGui->CurrentWindow); +} + +void ImGui::SetWindowFocus(const char* name) +{ + if (name) + { + if (ImGuiWindow* window = FindWindowByName(name)) + FocusWindow(window); + } + else + { + FocusWindow(NULL); + } +} + +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasPos; + g.NextWindowData.PosVal = pos; + g.NextWindowData.PosPivotVal = pivot; + g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; + g.NextWindowData.PosUndock = true; +} + +void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSize; + g.NextWindowData.SizeVal = size; + g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; +} + +void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_user_data) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSizeConstraint; + g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); + g.NextWindowData.SizeCallback = custom_callback; + g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; +} + +// Content size = inner scrollable rectangle, padded with WindowPadding. +// SetNextWindowContentSize(ImVec2(100,100) + ImGuiWindowFlags_AlwaysAutoResize will always allow submitting a 100x100 item. +void ImGui::SetNextWindowContentSize(const ImVec2& size) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize; + g.NextWindowData.ContentSizeVal = ImFloor(size); +} + +void ImGui::SetNextWindowScroll(const ImVec2& scroll) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasScroll; + g.NextWindowData.ScrollVal = scroll; +} + +void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags. + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasCollapsed; + g.NextWindowData.CollapsedVal = collapsed; + g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; +} + +void ImGui::SetNextWindowFocus() +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus; +} + +void ImGui::SetNextWindowBgAlpha(float alpha) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasBgAlpha; + g.NextWindowData.BgAlphaVal = alpha; +} + +void ImGui::SetNextWindowViewport(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasViewport; + g.NextWindowData.ViewportId = id; +} + +void ImGui::SetNextWindowDockID(ImGuiID id, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasDock; + g.NextWindowData.DockCond = cond ? cond : ImGuiCond_Always; + g.NextWindowData.DockId = id; +} + +void ImGui::SetNextWindowClass(const ImGuiWindowClass* window_class) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT((window_class->ViewportFlagsOverrideSet & window_class->ViewportFlagsOverrideClear) == 0); // Cannot set both set and clear for the same bit + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasWindowClass; + g.NextWindowData.WindowClass = *window_class; +} + +ImDrawList* ImGui::GetWindowDrawList() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DrawList; +} + +float ImGui::GetWindowDpiScale() +{ + ImGuiContext& g = *GImGui; + return g.CurrentDpiScale; +} + +ImGuiViewport* ImGui::GetWindowViewport() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentViewport != NULL && g.CurrentViewport == g.CurrentWindow->Viewport); + return g.CurrentViewport; +} + +ImFont* ImGui::GetFont() +{ + return GImGui->Font; +} + +float ImGui::GetFontSize() +{ + return GImGui->FontSize; +} + +ImVec2 ImGui::GetFontTexUvWhitePixel() +{ + return GImGui->DrawListSharedData.TexUvWhitePixel; +} + +void ImGui::SetWindowFontScale(float scale) +{ + IM_ASSERT(scale > 0.0f); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->FontWindowScale = scale; + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); +} + +void ImGui::ActivateItem(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; + g.NavNextActivateFlags = ImGuiActivateFlags_None; +} + +void ImGui::PushFocusScope(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + g.FocusScopeStack.push_back(window->DC.NavFocusScopeIdCurrent); + window->DC.NavFocusScopeIdCurrent = id; +} + +void ImGui::PopFocusScope() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(g.FocusScopeStack.Size > 0); // Too many PopFocusScope() ? + window->DC.NavFocusScopeIdCurrent = g.FocusScopeStack.back(); + g.FocusScopeStack.pop_back(); +} + +void ImGui::SetKeyboardFocusHere(int offset) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(offset >= -1); // -1 is allowed but not below + g.NavWindow = window; + ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; + NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. + if (offset == -1) + { + NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal); + } + else + { + g.NavTabbingDir = 1; + g.NavTabbingCounter = offset + 1; + } +} + +void ImGui::SetItemDefaultFocus() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!window->Appearing) + return; + if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResultId == 0) || g.NavLayer != window->DC.NavLayerCurrent) + return; + + g.NavInitRequest = false; + g.NavInitResultId = g.LastItemData.ID; + g.NavInitResultRectRel = WindowRectAbsToRel(window, g.LastItemData.Rect); + NavUpdateAnyRequestFlag(); + + // Scroll could be done in NavInitRequestApplyResult() via a opt-in flag (we however don't want regular init requests to scroll) + if (!IsItemVisible()) + ScrollToRectEx(window, g.LastItemData.Rect, ImGuiScrollFlags_None); +} + +void ImGui::SetStateStorage(ImGuiStorage* tree) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + window->DC.StateStorage = tree ? tree : &window->StateStorage; +} + +ImGuiStorage* ImGui::GetStateStorage() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->DC.StateStorage; +} + +void ImGui::PushID(const char* str_id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetIDNoKeepAlive(str_id); + window->IDStack.push_back(id); +} + +void ImGui::PushID(const char* str_id_begin, const char* str_id_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetIDNoKeepAlive(str_id_begin, str_id_end); + window->IDStack.push_back(id); +} + +void ImGui::PushID(const void* ptr_id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetIDNoKeepAlive(ptr_id); + window->IDStack.push_back(id); +} + +void ImGui::PushID(int int_id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetIDNoKeepAlive(int_id); + window->IDStack.push_back(id); +} + +// Push a given id value ignoring the ID stack as a seed. +void ImGui::PushOverrideID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.DebugHookIdInfo == id) + DebugHookIdInfo(id, ImGuiDataType_ID, NULL, NULL); + window->IDStack.push_back(id); +} + +// Helper to avoid a common series of PushOverrideID -> GetID() -> PopID() call +// (note that when using this pattern, TestEngine's "Stack Tool" will tend to not display the intermediate stack level. +// for that to work we would need to do PushOverrideID() -> ItemAdd() -> PopID() which would alter widget code a little more) +ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed) +{ + ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); + KeepAliveID(id); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); + return id; +} + +void ImGui::PopID() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + IM_ASSERT(window->IDStack.Size > 1); // Too many PopID(), or could be popping in a wrong/different window? + window->IDStack.pop_back(); +} + +ImGuiID ImGui::GetID(const char* str_id) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->GetID(str_id); +} + +ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->GetID(str_id_begin, str_id_end); +} + +ImGuiID ImGui::GetID(const void* ptr_id) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->GetID(ptr_id); +} + +bool ImGui::IsRectVisible(const ImVec2& size) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); +} + +bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); +} + + +//----------------------------------------------------------------------------- +// [SECTION] INPUTS +//----------------------------------------------------------------------------- + +// 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) +bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) +{ + ImGuiContext& g = *GImGui; + + // Clip + ImRect rect_clipped(r_min, r_max); + if (clip) + rect_clipped.ClipWith(g.CurrentWindow->ClipRect); + + // Expand for touch input + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + if (!rect_for_touch.Contains(g.IO.MousePos)) + return false; + if (!g.MouseViewport->GetMainRect().Overlaps(rect_clipped)) + return false; + return true; +} + +ImGuiKeyData* ImGui::GetKeyData(ImGuiKey key) +{ + ImGuiContext& g = *GImGui; + int index; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT(key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_NamedKey_END); + if (IsLegacyKey(key)) + index = (g.IO.KeyMap[key] != -1) ? g.IO.KeyMap[key] : key; // Remap native->imgui or imgui->native + else + index = key; +#else + IM_ASSERT(IsNamedKey(key) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend & user code."); + index = key - ImGuiKey_NamedKey_BEGIN; +#endif + return &g.IO.KeysData[index]; +} + +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO +int ImGui::GetKeyIndex(ImGuiKey key) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(IsNamedKey(key)); + const ImGuiKeyData* key_data = GetKeyData(key); + return (int)(key_data - g.IO.KeysData); +} +#endif + +// Those names a provided for debugging purpose and are not meant to be saved persistently not compared. +static const char* const GKeyNames[] = +{ + "Tab", "LeftArrow", "RightArrow", "UpArrow", "DownArrow", "PageUp", "PageDown", + "Home", "End", "Insert", "Delete", "Backspace", "Space", "Enter", "Escape", + "LeftCtrl", "LeftShift", "LeftAlt", "LeftSuper", "RightCtrl", "RightShift", "RightAlt", "RightSuper", "Menu", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", + "Apostrophe", "Comma", "Minus", "Period", "Slash", "Semicolon", "Equal", "LeftBracket", + "Backslash", "RightBracket", "GraveAccent", "CapsLock", "ScrollLock", "NumLock", "PrintScreen", + "Pause", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", + "Keypad7", "Keypad8", "Keypad9", "KeypadDecimal", "KeypadDivide", "KeypadMultiply", + "KeypadSubtract", "KeypadAdd", "KeypadEnter", "KeypadEqual", + "GamepadStart", "GamepadBack", "GamepadFaceUp", "GamepadFaceDown", "GamepadFaceLeft", "GamepadFaceRight", + "GamepadDpadUp", "GamepadDpadDown", "GamepadDpadLeft", "GamepadDpadRight", + "GamepadL1", "GamepadR1", "GamepadL2", "GamepadR2", "GamepadL3", "GamepadR3", + "GamepadLStickUp", "GamepadLStickDown", "GamepadLStickLeft", "GamepadLStickRight", + "GamepadRStickUp", "GamepadRStickDown", "GamepadRStickLeft", "GamepadRStickRight", + "ModCtrl", "ModShift", "ModAlt", "ModSuper" +}; +IM_STATIC_ASSERT(ImGuiKey_NamedKey_COUNT == IM_ARRAYSIZE(GKeyNames)); + +const char* ImGui::GetKeyName(ImGuiKey key) +{ +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT((IsNamedKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code."); +#else + if (IsLegacyKey(key)) + { + ImGuiIO& io = GetIO(); + if (io.KeyMap[key] == -1) + return "N/A"; + IM_ASSERT(IsNamedKey((ImGuiKey)io.KeyMap[key])); + key = (ImGuiKey)io.KeyMap[key]; + } +#endif + if (key == ImGuiKey_None) + return "None"; + if (!IsNamedKey(key)) + return "Unknown"; + + return GKeyNames[key - ImGuiKey_NamedKey_BEGIN]; +} + +// Note that Dear ImGui doesn't know the meaning/semantic of ImGuiKey from 0..511: they are legacy native keycodes. +// Consider transitioning from 'IsKeyDown(MY_ENGINE_KEY_A)' (<1.87) to IsKeyDown(ImGuiKey_A) (>= 1.87) +bool ImGui::IsKeyDown(ImGuiKey key) +{ + const ImGuiKeyData* key_data = GetKeyData(key); + return key_data->Down; +} + +// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime) +// t1 = current time (e.g.: g.Time) +// An event is triggered at: +// t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N +int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate) +{ + if (t1 == 0.0f) + return 1; + if (t0 >= t1) + return 0; + if (repeat_rate <= 0.0f) + return (t0 < repeat_delay) && (t1 >= repeat_delay); + const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate); + const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate); + const int count = count_t1 - count_t0; + return count; +} + +int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_rate) +{ + ImGuiContext& g = *GImGui; + const ImGuiKeyData* key_data = GetKeyData(key); + const float t = key_data->DownDuration; + return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate); +} + +bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat) +{ + ImGuiContext& g = *GImGui; + const ImGuiKeyData* key_data = GetKeyData(key); + const float t = key_data->DownDuration; + if (t == 0.0f) + return true; + if (repeat && t > g.IO.KeyRepeatDelay) + return GetKeyPressedAmount(key, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; + return false; +} + +bool ImGui::IsKeyReleased(ImGuiKey key) +{ + const ImGuiKeyData* key_data = GetKeyData(key); + return key_data->DownDurationPrev >= 0.0f && !key_data->Down; +} + +bool ImGui::IsMouseDown(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDown[button]; +} + +bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + const float t = g.IO.MouseDownDuration[button]; + if (t == 0.0f) + return true; + + if (repeat && t > g.IO.KeyRepeatDelay) + { + // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold. + int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f); + if (amount > 0) + return true; + } + return false; +} + +bool ImGui::IsMouseReleased(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseReleased[button]; +} + +bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseClickedCount[button] == 2; +} + +int ImGui::GetMouseClickedCount(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseClickedCount[button]; +} + +// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame. +// [Internal] This doesn't test if the button is pressed +bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& 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; +} + +bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (!g.IO.MouseDown[button]) + return false; + return IsMouseDragPastThreshold(button, lock_threshold); +} + +ImVec2 ImGui::GetMousePos() +{ + ImGuiContext& g = *GImGui; + return g.IO.MousePos; +} + +// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! +ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() +{ + ImGuiContext& g = *GImGui; + if (g.BeginPopupStack.Size > 0) + return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos; + return g.IO.MousePos; +} + +// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position. +bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) +{ + // The assert is only to silence a false-positive in XCode Static Analysis. + // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions). + IM_ASSERT(GImGui != NULL); + const float MOUSE_INVALID = -256000.0f; + ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos; + return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID; +} + +// [WILL OBSOLETE] This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid. +bool ImGui::IsAnyMouseDown() +{ + ImGuiContext& g = *GImGui; + for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++) + if (g.IO.MouseDown[n]) + return true; + return false; +} + +// Return the delta from the initial clicking position while the mouse button is clicked or was just released. +// This is locked and return 0.0f until the mouse moves past a distance threshold at least once. +// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window. +ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& 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] || g.IO.MouseReleased[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button])) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; + return ImVec2(0.0f, 0.0f); +} + +void ImGui::ResetMouseDragDelta(ImGuiMouseButton button) +{ + ImGuiContext& 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() +{ + ImGuiContext& g = *GImGui; + return g.MouseCursor; +} + +void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) +{ + ImGuiContext& g = *GImGui; + g.MouseCursor = cursor_type; +} + +void ImGui::CaptureKeyboardFromApp(bool capture) +{ + ImGuiContext& g = *GImGui; + g.WantCaptureKeyboardNextFrame = capture ? 1 : 0; +} + +void ImGui::CaptureMouseFromApp(bool capture) +{ + ImGuiContext& g = *GImGui; + g.WantCaptureMouseNextFrame = capture ? 1 : 0; +} + +static const char* GetInputSourceName(ImGuiInputSource source) +{ + const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" }; + IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT); + return input_source_names[source]; +} + + +// Process input queue +// - trickle_fast_inputs = false : process all events, turn into flattened input state (e.g. successive down/up/down/up will be lost) +// - trickle_fast_inputs = true : process as many events as possible (successive down/up/down/up will be trickled over several frames so nothing is lost) (new feature in 1.87) +void ImGui::UpdateInputEvents(bool trickle_fast_inputs) +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputed = false; + int mouse_button_changed = 0x00; + ImBitArray key_changed_mask; + + int event_n = 0; + for (; event_n < g.InputEventsQueue.Size; event_n++) + { + const ImGuiInputEvent* e = &g.InputEventsQueue[event_n]; + if (e->Type == ImGuiInputEventType_MousePos) + { + ImVec2 event_pos(e->MousePos.PosX, e->MousePos.PosY); + if (IsMousePosValid(&event_pos)) + event_pos = ImVec2(ImFloorSigned(event_pos.x), ImFloorSigned(event_pos.y)); // Apply same flooring as UpdateMouseInputs() + if (io.MousePos.x != event_pos.x || io.MousePos.y != event_pos.y) + { + // Trickling Rule: Stop processing queued events if we already handled a mouse button change + if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputed)) + break; + io.MousePos = event_pos; + mouse_moved = true; + } + } + else if (e->Type == ImGuiInputEventType_MouseButton) + { + const ImGuiMouseButton button = e->MouseButton.Button; + IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); + if (io.MouseDown[button] != e->MouseButton.Down) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the same button + if (trickle_fast_inputs && ((mouse_button_changed & (1 << button)) || mouse_wheeled)) + break; + io.MouseDown[button] = e->MouseButton.Down; + mouse_button_changed |= (1 << button); + } + } + else if (e->Type == ImGuiInputEventType_MouseWheel) + { + if (e->MouseWheel.WheelX != 0.0f || e->MouseWheel.WheelY != 0.0f) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the event + if (trickle_fast_inputs && (mouse_wheeled || mouse_button_changed != 0)) + break; + io.MouseWheelH += e->MouseWheel.WheelX; + io.MouseWheel += e->MouseWheel.WheelY; + mouse_wheeled = true; + } + } + else if (e->Type == ImGuiInputEventType_MouseViewport) + { + io.MouseHoveredViewport = e->MouseViewport.HoveredViewportID; + } + else if (e->Type == ImGuiInputEventType_Key) + { + ImGuiKey key = e->Key.Key; + IM_ASSERT(key != ImGuiKey_None); + const int keydata_index = (key - ImGuiKey_KeysData_OFFSET); + ImGuiKeyData* keydata = &io.KeysData[keydata_index]; + if (keydata->Down != e->Key.Down || keydata->AnalogValue != e->Key.AnalogValue) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the same button + if (trickle_fast_inputs && keydata->Down != e->Key.Down && (key_changed_mask.TestBit(keydata_index) || text_inputed || mouse_button_changed != 0)) + break; + keydata->Down = e->Key.Down; + keydata->AnalogValue = e->Key.AnalogValue; + key_changed = true; + key_changed_mask.SetBit(keydata_index); + + if (key == ImGuiKey_ModCtrl || key == ImGuiKey_ModShift || key == ImGuiKey_ModAlt || key == ImGuiKey_ModSuper) + { + if (key == ImGuiKey_ModCtrl) { io.KeyCtrl = keydata->Down; } + if (key == ImGuiKey_ModShift) { io.KeyShift = keydata->Down; } + if (key == ImGuiKey_ModAlt) { io.KeyAlt = keydata->Down; } + if (key == ImGuiKey_ModSuper) { io.KeySuper = keydata->Down; } + io.KeyMods = GetMergedKeyModFlags(); + } + } + } + else if (e->Type == ImGuiInputEventType_Char) + { + // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with + if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled)) + break; + unsigned int c = e->Text.Char; + io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); + text_inputed = true; + } + else if (e->Type == ImGuiInputEventType_Focus) + { + // We intentionally overwrite this and process lower, in order to give a chance + // to multi-viewports backends to queue AddFocusEvent(false) + AddFocusEvent(true) in same frame. + io.AppFocusLost = !e->AppFocused.Focused; + } + else + { + IM_ASSERT(0 && "Unknown event!"); + } + } + + // Record trail (for domain-specific applications wanting to access a precise trail) + //if (event_n != 0) IMGUI_DEBUG_LOG("Processed: %d / Remaining: %d\n", event_n, g.InputEventsQueue.Size - event_n); + for (int n = 0; n < event_n; n++) + g.InputEventsTrail.push_back(g.InputEventsQueue[n]); + + // Remaining events will be processed on the next frame + if (event_n == g.InputEventsQueue.Size) + g.InputEventsQueue.resize(0); + else + g.InputEventsQueue.erase(g.InputEventsQueue.Data, g.InputEventsQueue.Data + event_n); + + // Clear buttons state when focus is lost + // (this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle) + if (g.IO.AppFocusLost) + { + g.IO.ClearInputKeys(); + g.IO.AppFocusLost = false; + } +} + + +//----------------------------------------------------------------------------- +// [SECTION] ERROR CHECKING +//----------------------------------------------------------------------------- + +// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. +// Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit +// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. your user code +// may see different structures than what imgui.cpp sees, which is problematic. +// We usually require settings to be in imconfig.h to make sure that they are accessible to all compilation units involved with Dear ImGui. +bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx) +{ + bool error = false; + if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); } + if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } + if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } + if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } + if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } + if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } + if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } + return !error; +} + +static void ImGui::ErrorCheckNewFrameSanityChecks() +{ + ImGuiContext& g = *GImGui; + + // Check user IM_ASSERT macro + // (IF YOU GET A WARNING OR COMPILE ERROR HERE: it means your assert macro is incorrectly defined! + // If your macro uses multiple statements, it NEEDS to be surrounded by a 'do { ... } while (0)' block. + // This is a common C/C++ idiom to allow multiple statements macros to be used in control flow blocks.) + // #define IM_ASSERT(EXPR) if (SomeCode(EXPR)) SomeMoreCode(); // Wrong! + // #define IM_ASSERT(EXPR) do { if (SomeCode(EXPR)) SomeMoreCode(); } while (0) // Correct! + if (true) IM_ASSERT(1); else IM_ASSERT(0); + + // Check user data + // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument) + IM_ASSERT(g.Initialized); + IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!"); + IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); + IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!"); + IM_ASSERT(g.IO.Fonts->IsBuilt() && "Font Atlas not built! Make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()"); + IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); + IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); + IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations + IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting."); + IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right); +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_COUNT; n++) + IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..511, or -1 for unmapped key)"); + + // Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP) + if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1) + IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); +#endif + + // Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly. + if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors)) + g.IO.ConfigWindowsResizeFromEdges = false; + + // Perform simple check: error if Docking or Viewport are enabled _exactly_ on frame 1 (instead of frame 0 or later), which is a common error leading to loss of .ini data. + if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable) && (g.ConfigFlagsLastFrame & ImGuiConfigFlags_DockingEnable) == 0) + IM_ASSERT(0 && "Please set DockingEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!"); + if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (g.ConfigFlagsLastFrame & ImGuiConfigFlags_ViewportsEnable) == 0) + IM_ASSERT(0 && "Please set ViewportsEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!"); + + // Perform simple checks: multi-viewport and platform windows support + if (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + if ((g.IO.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) && (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasViewports)) + { + IM_ASSERT((g.FrameCount == 0 || g.FrameCount == g.FrameCountPlatformEnded) && "Forgot to call UpdatePlatformWindows() in main loop after EndFrame()? Check examples/ applications for reference."); + IM_ASSERT(g.PlatformIO.Platform_CreateWindow != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Platform_DestroyWindow != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Platform_GetWindowPos != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Platform_SetWindowPos != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Platform_GetWindowSize != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Platform_SetWindowSize != NULL && "Platform init didn't install handlers?"); + IM_ASSERT(g.PlatformIO.Monitors.Size > 0 && "Platform init didn't setup Monitors list?"); + IM_ASSERT((g.Viewports[0]->PlatformUserData != NULL || g.Viewports[0]->PlatformHandle != NULL) && "Platform init didn't setup main viewport."); + if (g.IO.ConfigDockingTransparentPayload && (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) + IM_ASSERT(g.PlatformIO.Platform_SetWindowAlpha != NULL && "Platform_SetWindowAlpha handler is required to use io.ConfigDockingTransparent!"); + } + else + { + // Disable feature, our backends do not support it + g.IO.ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable; + } + + // Perform simple checks on platform monitor data + compute a total bounding box for quick early outs + for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++) + { + ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[monitor_n]; + IM_UNUSED(mon); + IM_ASSERT(mon.MainSize.x > 0.0f && mon.MainSize.y > 0.0f && "Monitor main bounds not setup properly."); + IM_ASSERT(ImRect(mon.MainPos, mon.MainPos + mon.MainSize).Contains(ImRect(mon.WorkPos, mon.WorkPos + mon.WorkSize)) && "Monitor work bounds not setup properly. If you don't have work area information, just copy MainPos/MainSize into them."); + IM_ASSERT(mon.DpiScale != 0.0f); + } + } +} + +static void ImGui::ErrorCheckEndFrameSanityChecks() +{ + ImGuiContext& g = *GImGui; + + // Verify that io.KeyXXX fields haven't been tampered with. Key mods should not be modified between NewFrame() and EndFrame() + // One possible reason leading to this assert is that your backends update inputs _AFTER_ NewFrame(). + // It is known that when some modal native windows called mid-frame takes focus away, some backends such as GLFW will + // send key release events mid-frame. This would normally trigger this assertion and lead to sheared inputs. + // We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0), + // while still correctly asserting on mid-frame key press events. + const ImGuiKeyModFlags key_mod_flags = GetMergedKeyModFlags(); + IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); + IM_UNUSED(key_mod_flags); + + // Recover from errors + //ErrorCheckEndFrameRecover(); + + // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you + // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API). + if (g.CurrentWindowStack.Size != 1) + { + if (g.CurrentWindowStack.Size > 1) + { + IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?"); + while (g.CurrentWindowStack.Size > 1) + End(); + } + else + { + IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?"); + } + } + + IM_ASSERT_USER_ERROR(g.GroupStack.Size == 0, "Missing EndGroup call!"); +} + +// Experimental recovery from incorrect usage of BeginXXX/EndXXX/PushXXX/PopXXX calls. +// Must be called during or before EndFrame(). +// This is generally flawed as we are not necessarily End/Popping things in the right order. +// FIXME: Can't recover from inside BeginTabItem/EndTabItem yet. +// FIXME: Can't recover from interleaved BeginTabBar/Begin +void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data) +{ + // PVS-Studio V1044 is "Loop break conditions do not depend on the number of iterations" + ImGuiContext& g = *GImGui; + while (g.CurrentWindowStack.Size > 0) //-V1044 + { + ErrorCheckEndWindowRecover(log_callback, user_data); + ImGuiWindow* window = g.CurrentWindow; + if (g.CurrentWindowStack.Size == 1) + { + IM_ASSERT(window->IsFallbackWindow); + break; + } + IM_ASSERT(window == g.CurrentWindow); + if (window->Flags & ImGuiWindowFlags_ChildWindow) + { + if (log_callback) log_callback(user_data, "Recovered from missing EndChild() for '%s'", window->Name); + EndChild(); + } + else + { + if (log_callback) log_callback(user_data, "Recovered from missing End() for '%s'", window->Name); + End(); + } + } +} + +// Must be called before End()/EndChild() +void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data) +{ + ImGuiContext& g = *GImGui; + while (g.CurrentTable && (g.CurrentTable->OuterWindow == g.CurrentWindow || g.CurrentTable->InnerWindow == g.CurrentWindow)) + { + if (log_callback) log_callback(user_data, "Recovered from missing EndTable() in '%s'", g.CurrentTable->OuterWindow->Name); + EndTable(); + } + + ImGuiWindow* window = g.CurrentWindow; + ImGuiStackSizes* stack_sizes = &g.CurrentWindowStack.back().StackSizesOnBegin; + IM_ASSERT(window != NULL); + while (g.CurrentTabBar != NULL) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name); + EndTabBar(); + } + while (window->DC.TreeDepth > 0) + { + if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name); + TreePop(); + } + while (g.GroupStack.Size > stack_sizes->SizeOfGroupStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing EndGroup() in '%s'", window->Name); + EndGroup(); + } + while (window->IDStack.Size > 1) + { + if (log_callback) log_callback(user_data, "Recovered from missing PopID() in '%s'", window->Name); + PopID(); + } + while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name); + EndDisabled(); + } + while (g.ColorStack.Size > stack_sizes->SizeOfColorStack) + { + if (log_callback) log_callback(user_data, "Recovered from missing PopStyleColor() in '%s' for ImGuiCol_%s", window->Name, GetStyleColorName(g.ColorStack.back().Col)); + PopStyleColor(); + } + while (g.ItemFlagsStack.Size > stack_sizes->SizeOfItemFlagsStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing PopItemFlag() in '%s'", window->Name); + PopItemFlag(); + } + while (g.StyleVarStack.Size > stack_sizes->SizeOfStyleVarStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name); + PopStyleVar(); + } + while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name); + PopFocusScope(); + } +} + +// Save current stack sizes for later compare +void ImGuiStackSizes::SetToCurrentState() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + SizeOfIDStack = (short)window->IDStack.Size; + SizeOfColorStack = (short)g.ColorStack.Size; + SizeOfStyleVarStack = (short)g.StyleVarStack.Size; + SizeOfFontStack = (short)g.FontStack.Size; + SizeOfFocusScopeStack = (short)g.FocusScopeStack.Size; + SizeOfGroupStack = (short)g.GroupStack.Size; + SizeOfItemFlagsStack = (short)g.ItemFlagsStack.Size; + SizeOfBeginPopupStack = (short)g.BeginPopupStack.Size; + SizeOfDisabledStack = (short)g.DisabledStackSize; +} + +// Compare to detect usage errors +void ImGuiStackSizes::CompareWithCurrentState() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_UNUSED(window); + + // Window stacks + // NOT checking: DC.ItemWidth, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) + IM_ASSERT(SizeOfIDStack == window->IDStack.Size && "PushID/PopID or TreeNode/TreePop Mismatch!"); + + // Global stacks + // For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them. + IM_ASSERT(SizeOfGroupStack == g.GroupStack.Size && "BeginGroup/EndGroup Mismatch!"); + IM_ASSERT(SizeOfBeginPopupStack == g.BeginPopupStack.Size && "BeginPopup/EndPopup or BeginMenu/EndMenu Mismatch!"); + IM_ASSERT(SizeOfDisabledStack == g.DisabledStackSize && "BeginDisabled/EndDisabled Mismatch!"); + IM_ASSERT(SizeOfItemFlagsStack >= g.ItemFlagsStack.Size && "PushItemFlag/PopItemFlag Mismatch!"); + IM_ASSERT(SizeOfColorStack >= g.ColorStack.Size && "PushStyleColor/PopStyleColor Mismatch!"); + IM_ASSERT(SizeOfStyleVarStack >= g.StyleVarStack.Size && "PushStyleVar/PopStyleVar Mismatch!"); + IM_ASSERT(SizeOfFontStack >= g.FontStack.Size && "PushFont/PopFont Mismatch!"); + IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!"); +} + + +//----------------------------------------------------------------------------- +// [SECTION] LAYOUT +//----------------------------------------------------------------------------- +// - ItemSize() +// - ItemAdd() +// - SameLine() +// - GetCursorScreenPos() +// - SetCursorScreenPos() +// - GetCursorPos(), GetCursorPosX(), GetCursorPosY() +// - SetCursorPos(), SetCursorPosX(), SetCursorPosY() +// - GetCursorStartPos() +// - Indent() +// - Unindent() +// - SetNextItemWidth() +// - PushItemWidth() +// - PushMultiItemsWidths() +// - PopItemWidth() +// - CalcItemWidth() +// - CalcItemSize() +// - GetTextLineHeight() +// - GetTextLineHeightWithSpacing() +// - GetFrameHeight() +// - GetFrameHeightWithSpacing() +// - GetContentRegionMax() +// - GetContentRegionMaxAbs() [Internal] +// - GetContentRegionAvail(), +// - GetWindowContentRegionMin(), GetWindowContentRegionMax() +// - BeginGroup() +// - EndGroup() +// Also see in imgui_widgets: tab bars, columns. +//----------------------------------------------------------------------------- + +// Advance cursor given item size for layout. +// Register minimum needed size so it can extend the bounding box used for auto-fit calculation. +// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different. +void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + // We increase the height in this function to accommodate for baseline offset. + // In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor, + // but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect. + const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f; + const float line_height = ImMax(window->DC.CurrLineSize.y, size.y + offset_to_match_baseline_y); + + // Always align ourselves on pixel boundaries + //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] + window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x; + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y; + window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line + window->DC.CursorPos.y = IM_FLOOR(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y); // Next line + 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 - g.Style.ItemSpacing.y); + //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] + + window->DC.PrevLineSize.y = line_height; + window->DC.CurrLineSize.y = 0.0f; + window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y); + window->DC.CurrLineTextBaseOffset = 0.0f; + + // Horizontal layout mode + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + SameLine(); +} + +void ImGui::ItemSize(const ImRect& bb, float text_baseline_y) +{ + ItemSize(bb.GetSize(), text_baseline_y); +} + +// Declare item bounding box for clipping and interaction. +// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface +// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction. +bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemFlags extra_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // Set item data + // (DisplayRect is left untouched, made valid when ImGuiItemStatusFlags_HasDisplayRect is set) + g.LastItemData.ID = id; + g.LastItemData.Rect = bb; + g.LastItemData.NavRect = nav_bb_arg ? *nav_bb_arg : bb; + g.LastItemData.InFlags = g.CurrentItemFlags | extra_flags; + g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None; + + // Directional navigation processing + if (id != 0) + { + // Runs prior to clipping early-out + // (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget + // (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests + // unfortunately, but it is still limited to one window. It may not scale very well for windows with ten of + // thousands of item, but at least NavMoveRequest is only set on user interaction, aka maximum once a frame. + // We could early out with "if (is_clipped && !g.NavInitRequest) return false;" but when we wouldn't be able + // to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick). + // We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null. + // If we crash on a NULL g.NavWindow we need to fix the bug elsewhere. + window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent); + if (g.NavId == id || g.NavAnyRequest) + if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) + if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) + NavProcessItem(); + + // [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something". + // Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something". + // READ THE FAQ: https://dearimgui.org/faq + IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!"); + + // [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd() +#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX + if (id == g.DebugItemPickerBreakId) + { + IM_DEBUG_BREAK(); + g.DebugItemPickerBreakId = 0; + } +#endif + } + g.NextItemData.Flags = ImGuiNextItemDataFlags_None; + +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (id != 0) + IMGUI_TEST_ENGINE_ITEM_ADD(nav_bb_arg ? *nav_bb_arg : bb, id); +#endif + + // Clipping test + const bool is_clipped = IsClippedEx(bb, id); + if (is_clipped) + return false; + //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + + // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) + if (IsMouseHoveringRect(bb.Min, bb.Max)) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; + return true; +} + +// Gets back to previous line and continue with horizontal layout +// offset_from_start_x == 0 : follow right after previous item +// offset_from_start_x != 0 : align to specified x position (relative to window/group left) +// spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0 +// spacing_w >= 0 : enforce spacing amount +void ImGui::SameLine(float offset_from_start_x, float spacing_w) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + if (offset_from_start_x != 0.0f) + { + if (spacing_w < 0.0f) spacing_w = 0.0f; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + offset_from_start_x + spacing_w + window->DC.GroupOffset.x + window->DC.ColumnsOffset.x; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + else + { + if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; + window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + window->DC.CurrLineSize = window->DC.PrevLineSize; + window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; +} + +ImVec2 ImGui::GetCursorScreenPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos; +} + +void ImGui::SetCursorScreenPos(const ImVec2& pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); +} + +// User generally sees positions in window coordinates. 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 confusing because GetCursorPos() == (DC.CursorPos - window.Pos). May want to rename 'DC.CursorPos'. +ImVec2 ImGui::GetCursorPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos - window->Pos + window->Scroll; +} + +float ImGui::GetCursorPosX() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; +} + +float ImGui::GetCursorPosY() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; +} + +void ImGui::SetCursorPos(const ImVec2& local_pos) +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = window->Pos - window->Scroll + local_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 - window->Scroll.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 - window->Scroll.y + y; + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); +} + +ImVec2 ImGui::GetCursorStartPos() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorStartPos - window->Pos; +} + +void ImGui::Indent(float indent_w) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.Indent.x += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x; +} + +void ImGui::Unindent(float indent_w) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.Indent.x -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x; +} + +// Affect large frame+labels widgets only. +void ImGui::SetNextItemWidth(float item_width) +{ + ImGuiContext& g = *GImGui; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasWidth; + g.NextItemData.Width = item_width; +} + +// FIXME: Remove the == 0.0f behavior? +void ImGui::PushItemWidth(float item_width) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width + window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width); + g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth; +} + +void ImGui::PushMultiItemsWidths(int components, float w_full) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiStyle& style = g.Style; + const float w_item_one = ImMax(1.0f, IM_FLOOR((w_full - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); + const float w_item_last = ImMax(1.0f, IM_FLOOR(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); + window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width + window->DC.ItemWidthStack.push_back(w_item_last); + for (int i = 0; i < components - 2; i++) + window->DC.ItemWidthStack.push_back(w_item_one); + window->DC.ItemWidth = (components == 1) ? w_item_last : w_item_one; + g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth; +} + +void ImGui::PopItemWidth() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidth = window->DC.ItemWidthStack.back(); + window->DC.ItemWidthStack.pop_back(); +} + +// Calculate default item width given value passed to PushItemWidth() or SetNextItemWidth(). +// The SetNextItemWidth() data is generally cleared/consumed by ItemAdd() or NextItemData.ClearFlags() +float ImGui::CalcItemWidth() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + float w; + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth) + w = g.NextItemData.Width; + else + w = window->DC.ItemWidth; + if (w < 0.0f) + { + float region_max_x = GetContentRegionMaxAbs().x; + w = ImMax(1.0f, region_max_x - window->DC.CursorPos.x + w); + } + w = IM_FLOOR(w); + return w; +} + +// [Internal] Calculate full item size given user provided 'size' parameter and default width/height. Default width is often == CalcItemWidth(). +// Those two functions CalcItemWidth vs CalcItemSize are awkwardly named because they are not fully symmetrical. +// Note that only CalcItemWidth() is publicly exposed. +// The 4.0f here may be changed to match CalcItemWidth() and/or BeginChild() (right now we have a mismatch which is harmless but undesirable) +ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_w, float default_h) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + + ImVec2 region_max; + if (size.x < 0.0f || size.y < 0.0f) + region_max = GetContentRegionMaxAbs(); + + if (size.x == 0.0f) + size.x = default_w; + else if (size.x < 0.0f) + size.x = ImMax(4.0f, region_max.x - window->DC.CursorPos.x + size.x); + + if (size.y == 0.0f) + size.y = default_h; + else if (size.y < 0.0f) + size.y = ImMax(4.0f, region_max.y - window->DC.CursorPos.y + size.y); + + return size; +} + +float ImGui::GetTextLineHeight() +{ + ImGuiContext& g = *GImGui; + return g.FontSize; +} + +float ImGui::GetTextLineHeightWithSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.ItemSpacing.y; +} + +float ImGui::GetFrameHeight() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f; +} + +float ImGui::GetFrameHeightWithSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; +} + +// FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience! + +// FIXME: This is in window space (not screen space!). +ImVec2 ImGui::GetContentRegionMax() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImVec2 mx = window->ContentRegionRect.Max - window->Pos; + if (window->DC.CurrentColumns || g.CurrentTable) + mx.x = window->WorkRect.Max.x - window->Pos.x; + return mx; +} + +// [Internal] Absolute coordinate. Saner. This is not exposed until we finishing refactoring work rect features. +ImVec2 ImGui::GetContentRegionMaxAbs() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImVec2 mx = window->ContentRegionRect.Max; + if (window->DC.CurrentColumns || g.CurrentTable) + mx.x = window->WorkRect.Max.x; + return mx; +} + +ImVec2 ImGui::GetContentRegionAvail() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return GetContentRegionMaxAbs() - window->DC.CursorPos; +} + +// In window space (not screen space!) +ImVec2 ImGui::GetWindowContentRegionMin() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ContentRegionRect.Min - window->Pos; +} + +ImVec2 ImGui::GetWindowContentRegionMax() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ContentRegionRect.Max - window->Pos; +} + +// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) +// Groups are currently a mishmash of functionalities which should perhaps be clarified and separated. +// FIXME-OPT: Could we safely early out on ->SkipItems? +void ImGui::BeginGroup() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + g.GroupStack.resize(g.GroupStack.Size + 1); + ImGuiGroupData& group_data = g.GroupStack.back(); + group_data.WindowID = window->ID; + group_data.BackupCursorPos = window->DC.CursorPos; + group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; + group_data.BackupIndent = window->DC.Indent; + group_data.BackupGroupOffset = window->DC.GroupOffset; + group_data.BackupCurrLineSize = window->DC.CurrLineSize; + group_data.BackupCurrLineTextBaseOffset = window->DC.CurrLineTextBaseOffset; + group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive; + group_data.BackupHoveredIdIsAlive = g.HoveredId != 0; + group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive; + group_data.EmitItem = true; + + window->DC.GroupOffset.x = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffset.x; + window->DC.Indent = window->DC.GroupOffset; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + if (g.LogEnabled) + g.LogLinePosY = -FLT_MAX; // To enforce a carriage return +} + +void ImGui::EndGroup() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(g.GroupStack.Size > 0); // Mismatched BeginGroup()/EndGroup() calls + + ImGuiGroupData& group_data = g.GroupStack.back(); + IM_ASSERT(group_data.WindowID == window->ID); // EndGroup() in wrong window? + + ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos)); + + window->DC.CursorPos = group_data.BackupCursorPos; + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.Indent = group_data.BackupIndent; + window->DC.GroupOffset = group_data.BackupGroupOffset; + window->DC.CurrLineSize = group_data.BackupCurrLineSize; + window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset; + if (g.LogEnabled) + g.LogLinePosY = -FLT_MAX; // To enforce a carriage return + + if (!group_data.EmitItem) + { + g.GroupStack.pop_back(); + return; + } + + window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. + ItemSize(group_bb.GetSize()); + ItemAdd(group_bb, 0, NULL, ImGuiItemFlags_NoTabStop); + + // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group. + // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets. + // Also if you grep for LastItemId you'll notice it is only used in that context. + // (The two tests not the same because ActiveIdIsAlive is an ID itself, in order to be able to handle ActiveId being overwritten during the frame.) + const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId; + const bool group_contains_prev_active_id = (group_data.BackupActiveIdPreviousFrameIsAlive == false) && (g.ActiveIdPreviousFrameIsAlive == true); + if (group_contains_curr_active_id) + g.LastItemData.ID = g.ActiveId; + else if (group_contains_prev_active_id) + g.LastItemData.ID = g.ActiveIdPreviousFrame; + g.LastItemData.Rect = group_bb; + + // Forward Hovered flag + const bool group_contains_curr_hovered_id = (group_data.BackupHoveredIdIsAlive == false) && g.HoveredId != 0; + if (group_contains_curr_hovered_id) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; + + // Forward Edited flag + if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited; + + // Forward Deactivated flag + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDeactivated; + if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Deactivated; + + g.GroupStack.pop_back(); + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug] +} + + +//----------------------------------------------------------------------------- +// [SECTION] SCROLLING +//----------------------------------------------------------------------------- + +// Helper to snap on edges when aiming at an item very close to the edge, +// So the difference between WindowPadding and ItemSpacing will be in the visible area after scrolling. +// When we refactor the scrolling API this may be configurable with a flag? +// Note that the effect for this won't be visible on X axis with default Style settings as WindowPadding.x == ItemSpacing.x by default. +static float CalcScrollEdgeSnap(float target, float snap_min, float snap_max, float snap_threshold, float center_ratio) +{ + if (target <= snap_min + snap_threshold) + return ImLerp(snap_min, target, center_ratio); + if (target >= snap_max - snap_threshold) + return ImLerp(target, snap_max, center_ratio); + return target; +} + +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) +{ + ImVec2 scroll = window->Scroll; + if (window->ScrollTarget.x < FLT_MAX) + { + float decoration_total_width = window->ScrollbarSizes.x; + float center_x_ratio = window->ScrollTargetCenterRatio.x; + float scroll_target_x = window->ScrollTarget.x; + if (window->ScrollTargetEdgeSnapDist.x > 0.0f) + { + float snap_x_min = 0.0f; + float snap_x_max = window->ScrollMax.x + window->SizeFull.x - decoration_total_width; + scroll_target_x = CalcScrollEdgeSnap(scroll_target_x, snap_x_min, snap_x_max, window->ScrollTargetEdgeSnapDist.x, center_x_ratio); + } + scroll.x = scroll_target_x - center_x_ratio * (window->SizeFull.x - decoration_total_width); + } + if (window->ScrollTarget.y < FLT_MAX) + { + float decoration_total_height = window->TitleBarHeight() + window->MenuBarHeight() + window->ScrollbarSizes.y; + float center_y_ratio = window->ScrollTargetCenterRatio.y; + float scroll_target_y = window->ScrollTarget.y; + if (window->ScrollTargetEdgeSnapDist.y > 0.0f) + { + float snap_y_min = 0.0f; + float snap_y_max = window->ScrollMax.y + window->SizeFull.y - decoration_total_height; + scroll_target_y = CalcScrollEdgeSnap(scroll_target_y, snap_y_min, snap_y_max, window->ScrollTargetEdgeSnapDist.y, center_y_ratio); + } + scroll.y = scroll_target_y - center_y_ratio * (window->SizeFull.y - decoration_total_height); + } + scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f)); + scroll.y = IM_FLOOR(ImMax(scroll.y, 0.0f)); + if (!window->Collapsed && !window->SkipItems) + { + scroll.x = ImMin(scroll.x, window->ScrollMax.x); + scroll.y = ImMin(scroll.y, window->ScrollMax.y); + } + return scroll; +} + +void ImGui::ScrollToItem(ImGuiScrollFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ScrollToRectEx(window, g.LastItemData.NavRect, flags); +} + +void ImGui::ScrollToRect(ImGuiWindow* window, const ImRect& item_rect, ImGuiScrollFlags flags) +{ + ScrollToRectEx(window, item_rect, flags); +} + +// Scroll to keep newly navigated item fully into view +ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGuiScrollFlags flags) +{ + ImGuiContext& g = *GImGui; + ImRect window_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1)); + //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG] + + // Check that only one behavior is selected per axis + IM_ASSERT((flags & ImGuiScrollFlags_MaskX_) == 0 || ImIsPowerOfTwo(flags & ImGuiScrollFlags_MaskX_)); + IM_ASSERT((flags & ImGuiScrollFlags_MaskY_) == 0 || ImIsPowerOfTwo(flags & ImGuiScrollFlags_MaskY_)); + + // Defaults + ImGuiScrollFlags in_flags = flags; + if ((flags & ImGuiScrollFlags_MaskX_) == 0 && window->ScrollbarX) + flags |= ImGuiScrollFlags_KeepVisibleEdgeX; + if ((flags & ImGuiScrollFlags_MaskY_) == 0) + flags |= window->Appearing ? ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeY; + + const bool fully_visible_x = item_rect.Min.x >= window_rect.Min.x && item_rect.Max.x <= window_rect.Max.x; + const bool fully_visible_y = item_rect.Min.y >= window_rect.Min.y && item_rect.Max.y <= window_rect.Max.y; + const bool can_be_fully_visible_x = (item_rect.GetWidth() + g.Style.ItemSpacing.x * 2.0f) <= window_rect.GetWidth(); + const bool can_be_fully_visible_y = (item_rect.GetHeight() + g.Style.ItemSpacing.y * 2.0f) <= window_rect.GetHeight(); + + if ((flags & ImGuiScrollFlags_KeepVisibleEdgeX) && !fully_visible_x) + { + if (item_rect.Min.x < window_rect.Min.x || !can_be_fully_visible_x) + SetScrollFromPosX(window, item_rect.Min.x - g.Style.ItemSpacing.x - window->Pos.x, 0.0f); + else if (item_rect.Max.x >= window_rect.Max.x) + SetScrollFromPosX(window, item_rect.Max.x + g.Style.ItemSpacing.x - window->Pos.x, 1.0f); + } + else if (((flags & ImGuiScrollFlags_KeepVisibleCenterX) && !fully_visible_x) || (flags & ImGuiScrollFlags_AlwaysCenterX)) + { + float target_x = can_be_fully_visible_x ? ImFloor((item_rect.Min.x + item_rect.Max.x - window->InnerRect.GetWidth()) * 0.5f) : item_rect.Min.x; + SetScrollFromPosX(window, target_x - window->Pos.x, 0.0f); + } + + if ((flags & ImGuiScrollFlags_KeepVisibleEdgeY) && !fully_visible_y) + { + if (item_rect.Min.y < window_rect.Min.y || !can_be_fully_visible_y) + SetScrollFromPosY(window, item_rect.Min.y - g.Style.ItemSpacing.y - window->Pos.y, 0.0f); + else if (item_rect.Max.y >= window_rect.Max.y) + SetScrollFromPosY(window, item_rect.Max.y + g.Style.ItemSpacing.y - window->Pos.y, 1.0f); + } + else if (((flags & ImGuiScrollFlags_KeepVisibleCenterY) && !fully_visible_y) || (flags & ImGuiScrollFlags_AlwaysCenterY)) + { + float target_y = can_be_fully_visible_y ? ImFloor((item_rect.Min.y + item_rect.Max.y - window->InnerRect.GetHeight()) * 0.5f) : item_rect.Min.y; + SetScrollFromPosY(window, target_y - window->Pos.y, 0.0f); + } + + ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); + ImVec2 delta_scroll = next_scroll - window->Scroll; + + // Also scroll parent window to keep us into view if necessary + if (!(flags & ImGuiScrollFlags_NoScrollParent) && (window->Flags & ImGuiWindowFlags_ChildWindow)) + { + // FIXME-SCROLL: May be an option? + if ((in_flags & (ImGuiScrollFlags_AlwaysCenterX | ImGuiScrollFlags_KeepVisibleCenterX)) != 0) + in_flags = (in_flags & ~ImGuiScrollFlags_MaskX_) | ImGuiScrollFlags_KeepVisibleEdgeX; + if ((in_flags & (ImGuiScrollFlags_AlwaysCenterY | ImGuiScrollFlags_KeepVisibleCenterY)) != 0) + in_flags = (in_flags & ~ImGuiScrollFlags_MaskY_) | ImGuiScrollFlags_KeepVisibleEdgeY; + delta_scroll += ScrollToRectEx(window->ParentWindow, ImRect(item_rect.Min - delta_scroll, item_rect.Max - delta_scroll), in_flags); + } + + return delta_scroll; +} + +float ImGui::GetScrollX() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Scroll.x; +} + +float ImGui::GetScrollY() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Scroll.y; +} + +float ImGui::GetScrollMaxX() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ScrollMax.x; +} + +float ImGui::GetScrollMaxY() +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ScrollMax.y; +} + +void ImGui::SetScrollX(ImGuiWindow* window, float scroll_x) +{ + window->ScrollTarget.x = scroll_x; + window->ScrollTargetCenterRatio.x = 0.0f; + window->ScrollTargetEdgeSnapDist.x = 0.0f; +} + +void ImGui::SetScrollY(ImGuiWindow* window, float scroll_y) +{ + window->ScrollTarget.y = scroll_y; + window->ScrollTargetCenterRatio.y = 0.0f; + window->ScrollTargetEdgeSnapDist.y = 0.0f; +} + +void ImGui::SetScrollX(float scroll_x) +{ + ImGuiContext& g = *GImGui; + SetScrollX(g.CurrentWindow, scroll_x); +} + +void ImGui::SetScrollY(float scroll_y) +{ + ImGuiContext& g = *GImGui; + SetScrollY(g.CurrentWindow, scroll_y); +} + +// Note that a local position will vary depending on initial scroll value, +// This is a little bit confusing so bear with us: +// - local_pos = (absolution_pos - window->Pos) +// - So local_x/local_y are 0.0f for a position at the upper-left corner of a window, +// and generally local_x/local_y are >(padding+decoration) && <(size-padding-decoration) when in the visible area. +// - They mostly exists because of legacy API. +// Following the rules above, when trying to work with scrolling code, consider that: +// - SetScrollFromPosY(0.0f) == SetScrollY(0.0f + scroll.y) == has no effect! +// - SetScrollFromPosY(-scroll.y) == SetScrollY(-scroll.y + scroll.y) == SetScrollY(0.0f) == reset scroll. Of course writing SetScrollY(0.0f) directly then makes more sense +// We store a target position so centering and clamping can occur on the next frame when we are guaranteed to have a known window size +void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio) +{ + IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f); + window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x); // Convert local position to scroll offset + window->ScrollTargetCenterRatio.x = center_x_ratio; + window->ScrollTargetEdgeSnapDist.x = 0.0f; +} + +void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio) +{ + IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); + const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect; + local_y -= decoration_up_height; + window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y); // Convert local position to scroll offset + window->ScrollTargetCenterRatio.y = center_y_ratio; + window->ScrollTargetEdgeSnapDist.y = 0.0f; +} + +void ImGui::SetScrollFromPosX(float local_x, float center_x_ratio) +{ + ImGuiContext& g = *GImGui; + SetScrollFromPosX(g.CurrentWindow, local_x, center_x_ratio); +} + +void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio) +{ + ImGuiContext& g = *GImGui; + SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio); +} + +// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item. +void ImGui::SetScrollHereX(float center_x_ratio) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + float spacing_x = ImMax(window->WindowPadding.x, g.Style.ItemSpacing.x); + float target_pos_x = ImLerp(g.LastItemData.Rect.Min.x - spacing_x, g.LastItemData.Rect.Max.x + spacing_x, center_x_ratio); + SetScrollFromPosX(window, target_pos_x - window->Pos.x, center_x_ratio); // Convert from absolute to local pos + + // Tweak: snap on edges when aiming at an item very close to the edge + window->ScrollTargetEdgeSnapDist.x = ImMax(0.0f, window->WindowPadding.x - spacing_x); +} + +// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. +void ImGui::SetScrollHereY(float center_y_ratio) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + float spacing_y = ImMax(window->WindowPadding.y, g.Style.ItemSpacing.y); + float target_pos_y = ImLerp(window->DC.CursorPosPrevLine.y - spacing_y, window->DC.CursorPosPrevLine.y + window->DC.PrevLineSize.y + spacing_y, center_y_ratio); + SetScrollFromPosY(window, target_pos_y - window->Pos.y, center_y_ratio); // Convert from absolute to local pos + + // Tweak: snap on edges when aiming at an item very close to the edge + window->ScrollTargetEdgeSnapDist.y = ImMax(0.0f, window->WindowPadding.y - spacing_y); +} + +//----------------------------------------------------------------------------- +// [SECTION] TOOLTIPS +//----------------------------------------------------------------------------- + +void ImGui::BeginTooltip() +{ + BeginTooltipEx(ImGuiTooltipFlags_None, ImGuiWindowFlags_None); +} + +void ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags) +{ + ImGuiContext& g = *GImGui; + + if (g.DragDropWithinSource || g.DragDropWithinTarget) + { + // The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor) + // In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor. + // Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do. + //ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding; + ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale); + SetNextWindowPos(tooltip_pos); + SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f); + //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :( + tooltip_flags |= ImGuiTooltipFlags_OverridePreviousTooltip; + } + + char window_name[16]; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); + if (tooltip_flags & ImGuiTooltipFlags_OverridePreviousTooltip) + if (ImGuiWindow* window = FindWindowByName(window_name)) + if (window->Active) + { + // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one. + window->Hidden = true; + window->HiddenFramesCanSkipItems = 1; // FIXME: This may not be necessary? + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); + } + ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking; + Begin(window_name, NULL, flags | extra_window_flags); +} + +void ImGui::EndTooltip() +{ + IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls + End(); +} + +void ImGui::SetTooltipV(const char* fmt, va_list args) +{ + BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None); + TextV(fmt, args); + EndTooltip(); +} + +void ImGui::SetTooltip(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + SetTooltipV(fmt, args); + va_end(args); +} + +//----------------------------------------------------------------------------- +// [SECTION] POPUPS +//----------------------------------------------------------------------------- + +// Supported flags: ImGuiPopupFlags_AnyPopupId, ImGuiPopupFlags_AnyPopupLevel +bool ImGui::IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + if (popup_flags & ImGuiPopupFlags_AnyPopupId) + { + // Return true if any popup is open at the current BeginPopup() level of the popup stack + // This may be used to e.g. test for another popups already opened to handle popups priorities at the same level. + IM_ASSERT(id == 0); + if (popup_flags & ImGuiPopupFlags_AnyPopupLevel) + return g.OpenPopupStack.Size > 0; + else + return g.OpenPopupStack.Size > g.BeginPopupStack.Size; + } + else + { + if (popup_flags & ImGuiPopupFlags_AnyPopupLevel) + { + // Return true if the popup is open anywhere in the popup stack + for (int n = 0; n < g.OpenPopupStack.Size; n++) + if (g.OpenPopupStack[n].PopupId == id) + return true; + return false; + } + else + { + // Return true if the popup is open at the current BeginPopup() level of the popup stack (this is the most-common query) + return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id; + } + } +} + +bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiID id = (popup_flags & ImGuiPopupFlags_AnyPopupId) ? 0 : g.CurrentWindow->GetID(str_id); + if ((popup_flags & ImGuiPopupFlags_AnyPopupLevel) && id != 0) + IM_ASSERT(0 && "Cannot use IsPopupOpen() with a string id and ImGuiPopupFlags_AnyPopupLevel."); // But non-string version is legal and used internally + return IsPopupOpen(id, popup_flags); +} + +ImGuiWindow* ImGui::GetTopMostPopupModal() +{ + ImGuiContext& g = *GImGui; + for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--) + if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) + if (popup->Flags & ImGuiWindowFlags_Modal) + return popup; + return NULL; +} + +ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal() +{ + ImGuiContext& g = *GImGui; + for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--) + if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) + if ((popup->Flags & ImGuiWindowFlags_Modal) && IsWindowActiveAndVisible(popup)) + return popup; + return NULL; +} + +void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags); +} + +void ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags) +{ + OpenPopupEx(id, popup_flags); +} + +// Mark popup as open (toggle toward open state). +// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. +// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). +// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) +void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* parent_window = g.CurrentWindow; + const int current_stack_size = g.BeginPopupStack.Size; + + if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup) + if (IsPopupOpen(0u, ImGuiPopupFlags_AnyPopupId)) + return; + + ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. + popup_ref.PopupId = id; + popup_ref.Window = NULL; + popup_ref.SourceWindow = g.NavWindow; + popup_ref.OpenFrameCount = g.FrameCount; + popup_ref.OpenParentId = parent_window->IDStack.back(); + popup_ref.OpenPopupPos = NavCalcPreferredRefPos(); + popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos; + + IMGUI_DEBUG_LOG_POPUP("OpenPopupEx(0x%08X)\n", id); + if (g.OpenPopupStack.Size < current_stack_size + 1) + { + g.OpenPopupStack.push_back(popup_ref); + } + else + { + // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui + // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing + // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand. + if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1) + { + g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount; + } + else + { + // Close child popups if any, then flag popup for open/reopen + ClosePopupToLevel(current_stack_size, false); + g.OpenPopupStack.push_back(popup_ref); + } + + // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow(). + // This is equivalent to what ClosePopupToLevel() does. + //if (g.OpenPopupStack[current_stack_size].PopupId == id) + // FocusWindow(parent_window); + } +} + +// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. +// This function closes any popups that are over 'ref_window'. +void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size == 0) + return; + + // Don't close our own child popup windows. + int popup_count_to_keep = 0; + if (ref_window) + { + // Find the highest popup which is a descendant of the reference window (generally reference window = NavWindow) + for (; popup_count_to_keep < g.OpenPopupStack.Size; popup_count_to_keep++) + { + ImGuiPopupData& popup = g.OpenPopupStack[popup_count_to_keep]; + if (!popup.Window) + continue; + IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); + if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow) + continue; + + // Trim the stack unless the popup is a direct parent of the reference window (the reference window is often the NavWindow) + // - With this stack of window, clicking/focusing Popup1 will close Popup2 and Popup3: + // Window -> Popup1 -> Popup2 -> Popup3 + // - Each popups may contain child windows, which is why we compare ->RootWindowDockTree! + // Window -> Popup1 -> Popup1_Child -> Popup2 -> Popup2_Child + bool ref_window_is_descendent_of_popup = false; + for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++) + if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window) + //if (popup_window->RootWindowDockTree == ref_window->RootWindowDockTree) // FIXME-MERGE + if (IsWindowWithinBeginStackOf(ref_window, popup_window)) + { + ref_window_is_descendent_of_popup = true; + break; + } + if (!ref_window_is_descendent_of_popup) + break; + } + } + if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below + { + IMGUI_DEBUG_LOG_POPUP("ClosePopupsOverWindow(\"%s\") -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep); + ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup); + } +} + +void ImGui::ClosePopupsExceptModals() +{ + ImGuiContext& g = *GImGui; + + int popup_count_to_keep; + for (popup_count_to_keep = g.OpenPopupStack.Size; popup_count_to_keep > 0; popup_count_to_keep--) + { + ImGuiWindow* window = g.OpenPopupStack[popup_count_to_keep - 1].Window; + if (!window || window->Flags & ImGuiWindowFlags_Modal) + break; + } + if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below + ClosePopupToLevel(popup_count_to_keep, true); +} + +void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup) +{ + ImGuiContext& g = *GImGui; + IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup); + IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size); + + // Trim open popup stack + ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow; + ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window; + g.OpenPopupStack.resize(remaining); + + if (restore_focus_to_window_under_popup) + { + if (focus_window && !focus_window->WasActive && popup_window) + { + // Fallback + FocusTopMostWindowUnderOne(popup_window, NULL); + } + else + { + if (g.NavLayer == ImGuiNavLayer_Main && focus_window) + focus_window = NavRestoreLastChildNavWindow(focus_window); + FocusWindow(focus_window); + } + } +} + +// Close the popup we have begin-ed into. +void ImGui::CloseCurrentPopup() +{ + ImGuiContext& g = *GImGui; + int popup_idx = g.BeginPopupStack.Size - 1; + if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.BeginPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) + return; + + // Closing a menu closes its top-most parent popup (unless a modal) + while (popup_idx > 0) + { + ImGuiWindow* popup_window = g.OpenPopupStack[popup_idx].Window; + ImGuiWindow* parent_popup_window = g.OpenPopupStack[popup_idx - 1].Window; + bool close_parent = false; + if (popup_window && (popup_window->Flags & ImGuiWindowFlags_ChildMenu)) + if (parent_popup_window && !(parent_popup_window->Flags & ImGuiWindowFlags_MenuBar)) + close_parent = true; + if (!close_parent) + break; + popup_idx--; + } + IMGUI_DEBUG_LOG_POPUP("CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx); + ClosePopupToLevel(popup_idx, true); + + // A common pattern is to close a popup when selecting a menu item/selectable that will open another window. + // To improve this usage pattern, we avoid nav highlight for a single frame in the parent window. + // Similarly, we could avoid mouse hover highlight in this window but it is less visually problematic. + if (ImGuiWindow* window = g.NavWindow) + window->DC.NavHideHighlightOneFrame = true; +} + +// Attention! BeginPopup() adds default flags which BeginPopupEx()! +bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + if (!IsPopupOpen(id, ImGuiPopupFlags_None)) + { + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + return false; + } + + char name[20]; + if (flags & ImGuiWindowFlags_ChildMenu) + ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuCount); // Recycle windows based on depth + else + ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame + + flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoDocking; + bool is_open = Begin(name, NULL, flags); + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) + EndPopup(); + + return is_open; +} + +bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= g.BeginPopupStack.Size) // Early out for performance + { + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + return false; + } + flags |= ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings; + ImGuiID id = g.CurrentWindow->GetID(str_id); + return BeginPopupEx(id, flags); +} + +// If 'p_open' is specified for a modal popup window, the popup will have a regular close button which will close the popup. +// Note that popup visibility status is owned by Dear ImGui (and manipulated with e.g. OpenPopup) so the actual value of *p_open is meaningless here. +bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = window->GetID(name); + if (!IsPopupOpen(id, ImGuiPopupFlags_None)) + { + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + return false; + } + + // Center modal windows by default for increased visibility + // (this won't really last as settings will kick in, and is mostly for backward compatibility. user may do the same themselves) + // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. + if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0) + { + const ImGuiViewport* viewport = window->WasActive ? window->Viewport : GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport? + SetNextWindowPos(viewport->GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f)); + } + + flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking; + const bool is_open = Begin(name, p_open, flags); + if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + { + EndPopup(); + if (is_open) + ClosePopupToLevel(g.BeginPopupStack.Size, true); + return false; + } + return is_open; +} + +void ImGui::EndPopup() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls + IM_ASSERT(g.BeginPopupStack.Size > 0); + + // Make all menus and popups wrap around for now, may need to expose that policy (e.g. focus scope could include wrap/loop policy flags used by new move requests) + if (g.NavWindow == window) + NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY); + + // Child-popups don't need to be laid out + IM_ASSERT(g.WithinEndChild == false); + if (window->Flags & ImGuiWindowFlags_ChildWindow) + g.WithinEndChild = true; + End(); + g.WithinEndChild = false; +} + +// Helper to open a popup if mouse button is released over the item +// - This is essentially the same as BeginPopupContextItem() but without the trailing BeginPopup() +void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + { + ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + OpenPopupEx(id, popup_flags); + } +} + +// This is a helper to handle the simplest case of associating one named popup to one given widget. +// - To create a popup associated to the last item, you generally want to pass a NULL value to str_id. +// - To create a popup with a specific identifier, pass it in str_id. +// - This is useful when using using BeginPopupContextItem() on an item which doesn't have an identifier, e.g. a Text() call. +// - This is useful when multiple code locations may want to manipulate/open the same popup, given an explicit id. +// - You may want to handle the whole on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). +// This is essentially the same as: +// id = str_id ? GetID(str_id) : GetItemID(); +// OpenPopupOnItemClick(str_id, ImGuiPopupFlags_MouseButtonRight); +// return BeginPopup(id); +// Which is essentially the same as: +// id = str_id ? GetID(str_id) : GetItemID(); +// if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right)) +// OpenPopup(id); +// return BeginPopup(id); +// The main difference being that this is tweaked to avoid computing the ID twice. +bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id, popup_flags); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); +} + +bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!str_id) + str_id = "window_context"; + ImGuiID id = window->GetID(str_id); + int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); + if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + if (!(popup_flags & ImGuiPopupFlags_NoOpenOverItems) || !IsAnyItemHovered()) + OpenPopupEx(id, popup_flags); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); +} + +bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!str_id) + str_id = "void_context"; + ImGuiID id = window->GetID(str_id); + int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); + if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) + if (GetTopMostPopupModal() == NULL) + OpenPopupEx(id, popup_flags); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); +} + +// r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) +// r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. +// (r_outer is usually equivalent to the viewport rectangle minus padding, but when multi-viewports are enabled and monitor +// information are available, it may represent the entire platform monitor from the frame of reference of the current viewport. +// this allows us to have tooltips/popups displayed out of the parent viewport.) +ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy) +{ + ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); + //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); + //GetForegroundDrawList()->AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); + + // Combo Box policy (we want a connecting edge) + if (policy == ImGuiPopupPositionPolicy_ComboBox) + { + const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++) + { + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; + ImVec2 pos; + if (dir == ImGuiDir_Down) pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y); // Below, Toward Right (default) + if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right + if (dir == ImGuiDir_Left) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left + if (dir == ImGuiDir_Up) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left + if (!r_outer.Contains(ImRect(pos, pos + size))) + continue; + *last_dir = dir; + return pos; + } + } + + // Tooltip and Default popup policy + // (Always first try the direction we used on the last frame, if any) + if (policy == ImGuiPopupPositionPolicy_Tooltip || policy == ImGuiPopupPositionPolicy_Default) + { + const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++) + { + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; + + const float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); + const float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); + + // If there not enough room on one axis, there's no point in positioning on a side on this axis (e.g. when not enough width, use a top/bottom position to maximize available width) + if (avail_w < size.x && (dir == ImGuiDir_Left || dir == ImGuiDir_Right)) + continue; + if (avail_h < size.y && (dir == ImGuiDir_Up || dir == ImGuiDir_Down)) + continue; + + ImVec2 pos; + pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x; + pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y; + + // Clamp top-left corner of popup + pos.x = ImMax(pos.x, r_outer.Min.x); + pos.y = ImMax(pos.y, r_outer.Min.y); + + *last_dir = dir; + return pos; + } + } + + // Fallback when not enough room: + *last_dir = ImGuiDir_None; + + // For tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. + if (policy == ImGuiPopupPositionPolicy_Tooltip) + return ref_pos + ImVec2(2, 2); + + // Otherwise try to keep within display + ImVec2 pos = ref_pos; + pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); + pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); + return pos; +} + +// Note that this is used for popups, which can overlap the non work-area of individual viewports. +ImRect ImGui::GetPopupAllowedExtentRect(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImRect r_screen; + if (window->ViewportAllowPlatformMonitorExtend >= 0) + { + // Extent with be in the frame of reference of the given viewport (so Min is likely to be negative here) + const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->ViewportAllowPlatformMonitorExtend]; + r_screen.Min = monitor.WorkPos; + r_screen.Max = monitor.WorkPos + monitor.WorkSize; + } + else + { + // Use the full viewport area (not work area) for popups + r_screen = window->Viewport->GetMainRect(); + } + ImVec2 padding = g.Style.DisplaySafeAreaPadding; + r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f)); + return r_screen; +} + +ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + + ImRect r_outer = GetPopupAllowedExtentRect(window); + if (window->Flags & ImGuiWindowFlags_ChildMenu) + { + // Child menus typically request _any_ position within the parent menu item, and then we move the new menu outside the parent bounds. + // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. + ImGuiWindow* parent_window = window->ParentWindow; + float horizontal_overlap = g.Style.ItemInnerSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x). + ImRect r_avoid; + if (parent_window->DC.MenuBarAppending) + r_avoid = ImRect(-FLT_MAX, parent_window->ClipRect.Min.y, FLT_MAX, parent_window->ClipRect.Max.y); // Avoid parent menu-bar. If we wanted multi-line menu-bar, we may instead want to have the calling window setup e.g. a NextWindowData.PosConstraintAvoidRect field + else + r_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); + return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default); + } + if (window->Flags & ImGuiWindowFlags_Popup) + { + return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, ImRect(window->Pos, window->Pos), ImGuiPopupPositionPolicy_Default); // Ideally we'd disable r_avoid here + } + if (window->Flags & ImGuiWindowFlags_Tooltip) + { + // Position tooltip (always follows mouse) + float sc = g.Style.MouseCursorScale; + ImVec2 ref_pos = NavCalcPreferredRefPos(); + ImRect r_avoid; + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)) + r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); + else + r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. + return FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip); + } + IM_ASSERT(0); + return window->Pos; +} + +//----------------------------------------------------------------------------- +// [SECTION] KEYBOARD/GAMEPAD NAVIGATION +//----------------------------------------------------------------------------- + +// FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked. +// In our terminology those should be interchangeable. Those two functions are merely a legacy artifact, so at minimum naming should be clarified. +void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindow != NULL); + IM_ASSERT(nav_layer == ImGuiNavLayer_Main || nav_layer == ImGuiNavLayer_Menu); + g.NavId = id; + g.NavLayer = nav_layer; + g.NavFocusScopeId = focus_scope_id; + g.NavWindow->NavLastIds[nav_layer] = id; + g.NavWindow->NavRectRel[nav_layer] = rect_rel; +} + +void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(id != 0); + + // Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and window->DC.NavFocusScopeIdCurrent are valid. + // Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text) + const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent; + if (g.NavWindow != window) + g.NavInitRequest = false; + g.NavWindow = window; + g.NavId = id; + g.NavLayer = nav_layer; + g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; + window->NavLastIds[nav_layer] = id; + if (g.LastItemData.ID == id) + window->NavRectRel[nav_layer] = WindowRectAbsToRel(window, g.LastItemData.NavRect); + + if (g.ActiveIdSource == ImGuiInputSource_Nav) + g.NavDisableMouseHover = true; + else + g.NavDisableHighlight = true; +} + +ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) +{ + if (ImFabs(dx) > ImFabs(dy)) + return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; + return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up; +} + +static float inline NavScoreItemDistInterval(float a0, float a1, float b0, float b1) +{ + if (a1 < b0) + return a1 - b0; + if (b1 < a0) + return a0 - b1; + return 0.0f; +} + +static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect& r, const ImRect& clip_rect) +{ + if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) + { + r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y); + r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y); + } + else // FIXME: PageUp/PageDown are leaving move_dir == None + { + r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x); + r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x); + } +} + +// Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057 +static bool ImGui::NavScoreItem(ImGuiNavItemData* result) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavLayer != window->DC.NavLayerCurrent) + return false; + + // FIXME: Those are not good variables names + ImRect cand = g.LastItemData.NavRect; // Current item nav rectangle + const ImRect curr = g.NavScoringRect; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width) + g.NavScoringDebugCount++; + + // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring + if (window->ParentWindow == g.NavWindow) + { + IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened); + if (!window->ClipRect.Overlaps(cand)) + return false; + cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window + } + + // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items) + // For example, this ensure that items in one column are not reached when moving vertically from items in another column. + NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect); + + // Compute distance between boxes + // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. + float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x); + float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items + if (dby != 0.0f && dbx != 0.0f) + dbx = (dbx / 1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f); + float dist_box = ImFabs(dbx) + ImFabs(dby); + + // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter) + float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x); + float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y); + float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee) + + // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance + ImGuiDir quadrant; + float dax = 0.0f, day = 0.0f, dist_axial = 0.0f; + if (dbx != 0.0f || dby != 0.0f) + { + // For non-overlapping boxes, use distance between boxes + dax = dbx; + day = dby; + dist_axial = dist_box; + quadrant = ImGetDirQuadrantFromDelta(dbx, dby); + } + else if (dcx != 0.0f || dcy != 0.0f) + { + // For overlapping boxes with different centers, use distance between centers + dax = dcx; + day = dcy; + dist_axial = dist_center; + quadrant = ImGetDirQuadrantFromDelta(dcx, dcy); + } + else + { + // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter) + quadrant = (g.LastItemData.ID < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right; + } + +#if IMGUI_DEBUG_NAV_SCORING + char buf[128]; + if (IsMouseHoveringRect(cand.Min, cand.Max)) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); + ImDrawList* draw_list = GetForegroundDrawList(window); + draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100)); + draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); + draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,150)); + draw_list->AddText(cand.Max, ~0U, buf); + } + else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate. + { + if (quadrant == g.NavMoveDir) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); + ImDrawList* draw_list = GetForegroundDrawList(window); + draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); + draw_list->AddText(cand.Min, IM_COL32(255, 255, 255, 255), buf); + } + } +#endif + + // Is it in the quadrant we're interesting in moving to? + bool new_best = false; + const ImGuiDir move_dir = g.NavMoveDir; + if (quadrant == move_dir) + { + // Does it beat the current best candidate? + if (dist_box < result->DistBox) + { + result->DistBox = dist_box; + result->DistCenter = dist_center; + return true; + } + if (dist_box == result->DistBox) + { + // Try using distance between center points to break ties + if (dist_center < result->DistCenter) + { + result->DistCenter = dist_center; + new_best = true; + } + else if (dist_center == result->DistCenter) + { + // Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items + // (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index), + // this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis. + if (((move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance + new_best = true; + } + } + } + + // Axial check: if 'curr' has no link at all in some direction and 'cand' lies roughly in that direction, add a tentative link. This will only be kept if no "real" matches + // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness) + // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too. + // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward. + // Disabling it may lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option? + if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match + if (g.NavLayer == ImGuiNavLayer_Menu && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) + if ((move_dir == ImGuiDir_Left && dax < 0.0f) || (move_dir == ImGuiDir_Right && dax > 0.0f) || (move_dir == ImGuiDir_Up && day < 0.0f) || (move_dir == ImGuiDir_Down && day > 0.0f)) + { + result->DistAxial = dist_axial; + new_best = true; + } + + return new_best; +} + +static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + result->Window = window; + result->ID = g.LastItemData.ID; + result->FocusScopeId = window->DC.NavFocusScopeIdCurrent; + result->InFlags = g.LastItemData.InFlags; + result->RectRel = WindowRectAbsToRel(window, g.LastItemData.NavRect); +} + +// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above) +// This is called after LastItemData is set. +static void ImGui::NavProcessItem() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = g.LastItemData.ID; + const ImRect nav_bb = g.LastItemData.NavRect; + const ImGuiItemFlags item_flags = g.LastItemData.InFlags; + + // Process Init Request + if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) + { + // Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback + const bool candidate_for_nav_default_focus = (item_flags & (ImGuiItemFlags_NoNavDefaultFocus | ImGuiItemFlags_Disabled)) == 0; + if (candidate_for_nav_default_focus || g.NavInitResultId == 0) + { + g.NavInitResultId = id; + g.NavInitResultRectRel = WindowRectAbsToRel(window, nav_bb); + } + if (candidate_for_nav_default_focus) + { + g.NavInitRequest = false; // Found a match, clear request + NavUpdateAnyRequestFlag(); + } + } + + // Process Move Request (scoring for navigation) + // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) + if (g.NavMoveScoringItems) + { + const bool is_tab_stop = (item_flags & ImGuiItemFlags_Inputable) && (item_flags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; + const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; + if (is_tabbing) + { + if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi)) + NavProcessItemForTabbingRequest(id); + } + else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) + { + ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; + if (!is_tabbing) + { + if (NavScoreItem(result)) + NavApplyItemToResult(result); + + // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. + const float VISIBLE_RATIO = 0.70f; + if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) + if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) + if (NavScoreItem(&g.NavMoveResultLocalVisible)) + NavApplyItemToResult(&g.NavMoveResultLocalVisible); + } + } + } + + // Update window-relative bounding box of navigated item + if (g.NavId == id) + { + g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. + g.NavLayer = window->DC.NavLayerCurrent; + g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; + g.NavIdIsAlive = true; + window->NavRectRel[window->DC.NavLayerCurrent] = WindowRectAbsToRel(window, nav_bb); // Store item bounding box (relative to window position) + } +} + +// Handle "scoring" of an item for a tabbing/focusing request initiated by NavUpdateCreateTabbingRequest(). +// Note that SetKeyboardFocusHere() API calls are considered tabbing requests! +// - Case 1: no nav/active id: set result to first eligible item, stop storing. +// - Case 2: tab forward: on ref id set counter, on counter elapse store result +// - Case 3: tab forward wrap: set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request +// - Case 4: tab backward: store all results, on ref id pick prev, stop storing +// - Case 5: tab backward wrap: store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested +void ImGui::NavProcessItemForTabbingRequest(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + + // Always store in NavMoveResultLocal (unlike directional request which uses NavMoveResultOther on sibling/flattened windows) + ImGuiNavItemData* result = &g.NavMoveResultLocal; + if (g.NavTabbingDir == +1) + { + // Tab Forward or SetKeyboardFocusHere() with >= 0 + if (g.NavTabbingResultFirst.ID == 0) + NavApplyItemToResult(&g.NavTabbingResultFirst); + if (--g.NavTabbingCounter == 0) + NavMoveRequestResolveWithLastItem(result); + else if (g.NavId == id) + g.NavTabbingCounter = 1; + } + else if (g.NavTabbingDir == -1) + { + // Tab Backward + if (g.NavId == id) + { + if (result->ID) + { + g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); + } + } + else + { + NavApplyItemToResult(result); + } + } + else if (g.NavTabbingDir == 0) + { + // Tab Init + if (g.NavTabbingResultFirst.ID == 0) + NavMoveRequestResolveWithLastItem(&g.NavTabbingResultFirst); + } +} + +bool ImGui::NavMoveRequestButNoResultYet() +{ + ImGuiContext& g = *GImGui; + return g.NavMoveScoringItems && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; +} + +// FIXME: ScoringRect is not set +void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindow != NULL); + + if (move_flags & ImGuiNavMoveFlags_Tabbing) + move_flags |= ImGuiNavMoveFlags_AllowCurrentNavId; + + g.NavMoveSubmitted = g.NavMoveScoringItems = true; + g.NavMoveDir = move_dir; + g.NavMoveDirForDebug = move_dir; + g.NavMoveClipDir = clip_dir; + g.NavMoveFlags = move_flags; + g.NavMoveScrollFlags = scroll_flags; + g.NavMoveForwardToNextFrame = false; + g.NavMoveKeyMods = g.IO.KeyMods; + g.NavTabbingCounter = 0; + g.NavMoveResultLocal.Clear(); + g.NavMoveResultLocalVisible.Clear(); + g.NavMoveResultOther.Clear(); + NavUpdateAnyRequestFlag(); +} + +void ImGui::NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result) +{ + ImGuiContext& g = *GImGui; + g.NavMoveScoringItems = false; // Ensure request doesn't need more processing + NavApplyItemToResult(result); + NavUpdateAnyRequestFlag(); +} + +void ImGui::NavMoveRequestCancel() +{ + ImGuiContext& g = *GImGui; + g.NavMoveSubmitted = g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); +} + +// Forward will reuse the move request again on the next frame (generally with modifications done to it) +void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavMoveForwardToNextFrame == false); + NavMoveRequestCancel(); + g.NavMoveForwardToNextFrame = true; + g.NavMoveDir = move_dir; + g.NavMoveClipDir = clip_dir; + g.NavMoveFlags = move_flags | ImGuiNavMoveFlags_Forwarded; + g.NavMoveScrollFlags = scroll_flags; +} + +// Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire +// popup is assembled and in case of appended popups it is not clear which EndPopup() call is final. +void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY + // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test + if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main) + g.NavMoveFlags |= wrap_flags; +} + +// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0). +// This way we could find the last focused window among our children. It would be much less confusing this way? +static void ImGui::NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window) +{ + ImGuiWindow* parent = nav_window; + while (parent && parent->RootWindow != parent && (parent->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) + parent = parent->ParentWindow; + if (parent && parent != nav_window) + parent->NavLastChildNavWindow = nav_window; +} + +// Restore the last focused child. +// Call when we are expected to land on the Main Layer (0) after FocusWindow() +static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window) +{ + if (window->NavLastChildNavWindow && window->NavLastChildNavWindow->WasActive) + return window->NavLastChildNavWindow; + if (window->DockNodeAsHost && window->DockNodeAsHost->TabBar) + if (ImGuiTabItem* tab = TabBarFindMostRecentlySelectedTabForActiveWindow(window->DockNodeAsHost->TabBar)) + return tab->Window; + return window; +} + +void ImGui::NavRestoreLayer(ImGuiNavLayer layer) +{ + ImGuiContext& g = *GImGui; + if (layer == ImGuiNavLayer_Main) + g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); + ImGuiWindow* window = g.NavWindow; + if (window->NavLastIds[layer] != 0) + { + SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); + } + else + { + g.NavLayer = layer; + NavInitWindow(window, true); + } +} + +void ImGui::NavRestoreHighlightAfterMove() +{ + ImGuiContext& g = *GImGui; + g.NavDisableHighlight = false; + g.NavDisableMouseHover = g.NavMousePosDirty = true; +} + +static inline void ImGui::NavUpdateAnyRequestFlag() +{ + ImGuiContext& g = *GImGui; + g.NavAnyRequest = g.NavMoveScoringItems || g.NavInitRequest || (IMGUI_DEBUG_NAV_SCORING && g.NavWindow != NULL); + if (g.NavAnyRequest) + IM_ASSERT(g.NavWindow != NULL); +} + +// This needs to be called before we submit any widget (aka in or before Begin) +void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) +{ + // FIXME: ChildWindow test here is wrong for docking + ImGuiContext& g = *GImGui; + IM_ASSERT(window == g.NavWindow); + + if (window->Flags & ImGuiWindowFlags_NoNavInputs) + { + g.NavId = g.NavFocusScopeId = 0; + return; + } + + bool init_for_nav = false; + if (window == window->RootWindow || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit) + init_for_nav = true; + IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer); + if (init_for_nav) + { + SetNavID(0, g.NavLayer, 0, ImRect()); + g.NavInitRequest = true; + g.NavInitRequestFromMove = false; + g.NavInitResultId = 0; + g.NavInitResultRectRel = ImRect(); + NavUpdateAnyRequestFlag(); + } + else + { + g.NavId = window->NavLastIds[0]; + g.NavFocusScopeId = 0; + } +} + +static ImVec2 ImGui::NavCalcPreferredRefPos() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + if (g.NavDisableHighlight || !g.NavDisableMouseHover || !window) + { + // Mouse (we need a fallback in case the mouse becomes invalid after being used) + // The +1.0f offset when stored by OpenPopupEx() allows reopening this or another popup (same or another mouse button) while not moving the mouse, it is pretty standard. + // In theory we could move that +1.0f offset in OpenPopupEx() + ImVec2 p = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : g.MouseLastValidPos; + return ImVec2(p.x + 1.0f, p.y); + } + else + { + // When navigation is active and mouse is disabled, pick a position around the bottom left of the currently navigated item + // Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?) + ImRect rect_rel = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]); + if (window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX)) + { + ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); + rect_rel.Translate(window->Scroll - next_scroll); + } + ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); + ImGuiViewport* viewport = window->Viewport; + return ImFloor(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta. + } +} + +const char* ImGui::GetNavInputName(ImGuiNavInput n) +{ + static const char* names[] = + { + "Activate", "Cancel", "Input", "Menu", "DpadLeft", "DpadRight", "DpadUp", "DpadDown", "LStickLeft", "LStickRight", "LStickUp", "LStickDown", + "FocusPrev", "FocusNext", "TweakSlow", "TweakFast", "KeyLeft", "KeyRight", "KeyUp", "KeyDown" + }; + IM_ASSERT(IM_ARRAYSIZE(names) == ImGuiNavInput_COUNT); + IM_ASSERT(n >= 0 && n < ImGuiNavInput_COUNT); + return names[n]; +} + +float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode) +{ + ImGuiContext& g = *GImGui; + if (mode == ImGuiInputReadMode_Down) + return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user) + + const float t = g.IO.NavInputsDownDuration[n]; + if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input. + return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f); + if (t < 0.0f) + return 0.0f; + if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input. + return (t == 0.0f) ? 1.0f : 0.0f; + if (mode == ImGuiInputReadMode_Repeat) + return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.80f); + if (mode == ImGuiInputReadMode_RepeatSlow) + return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 1.25f, g.IO.KeyRepeatRate * 2.00f); + if (mode == ImGuiInputReadMode_RepeatFast) + return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.30f); + return 0.0f; +} + +ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor) +{ + ImVec2 delta(0.0f, 0.0f); + if (dir_sources & ImGuiNavDirSourceFlags_RawKeyboard) + delta += ImVec2((float)IsKeyDown(ImGuiKey_RightArrow) - (float)IsKeyDown(ImGuiKey_LeftArrow), (float)IsKeyDown(ImGuiKey_DownArrow) - (float)IsKeyDown(ImGuiKey_UpArrow)); + if (dir_sources & ImGuiNavDirSourceFlags_Keyboard) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode) - GetNavInputAmount(ImGuiNavInput_KeyLeft_, mode), GetNavInputAmount(ImGuiNavInput_KeyDown_, mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_, mode)); + if (dir_sources & ImGuiNavDirSourceFlags_PadDPad) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode) - GetNavInputAmount(ImGuiNavInput_DpadLeft, mode), GetNavInputAmount(ImGuiNavInput_DpadDown, mode) - GetNavInputAmount(ImGuiNavInput_DpadUp, mode)); + if (dir_sources & ImGuiNavDirSourceFlags_PadLStick) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode)); + if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow)) + delta *= slow_factor; + if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast)) + delta *= fast_factor; + return delta; +} + +static void ImGui::NavUpdate() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + io.WantSetMousePos = false; + //if (g.NavScoringDebugCount > 0) IMGUI_DEBUG_LOG("NavScoringDebugCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.NavScoringDebugCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); + + // Update Gamepad->Nav inputs mapping + // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard) + const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; + if (nav_gamepad_active && g.IO.BackendUsingLegacyNavInputArray == false) + { + for (int n = 0; n < ImGuiNavInput_COUNT; n++) + IM_ASSERT(io.NavInputs[n] == 0.0f && "Backend needs to either only use io.AddKeyEvent()/io.AddKeyAnalogEvent(), either only fill legacy io.NavInputs[]. Not both!"); + #define NAV_MAP_KEY(_KEY, _NAV_INPUT, _ACTIVATE_NAV) do { io.NavInputs[_NAV_INPUT] = io.KeysData[_KEY - ImGuiKey_KeysData_OFFSET].AnalogValue; if (_ACTIVATE_NAV && io.NavInputs[_NAV_INPUT] > 0.0f) { g.NavInputSource = ImGuiInputSource_Gamepad; } } while (0) + NAV_MAP_KEY(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate, true); + NAV_MAP_KEY(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel, true); + NAV_MAP_KEY(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu, true); + NAV_MAP_KEY(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input, true); + NAV_MAP_KEY(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft, true); + NAV_MAP_KEY(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight, true); + NAV_MAP_KEY(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp, true); + NAV_MAP_KEY(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown, true); + NAV_MAP_KEY(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, false); + NAV_MAP_KEY(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, false); + NAV_MAP_KEY(ImGuiKey_GamepadL1, ImGuiNavInput_TweakSlow, false); + NAV_MAP_KEY(ImGuiKey_GamepadR1, ImGuiNavInput_TweakFast, false); + NAV_MAP_KEY(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft, false); + NAV_MAP_KEY(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight, false); + NAV_MAP_KEY(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp, false); + NAV_MAP_KEY(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown, false); + #undef NAV_MAP_KEY + } + + // Update Keyboard->Nav inputs mapping + const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + if (nav_keyboard_active) + { + #define NAV_MAP_KEY(_KEY, _NAV_INPUT) do { if (IsKeyDown(_KEY)) { io.NavInputs[_NAV_INPUT] = 1.0f; g.NavInputSource = ImGuiInputSource_Keyboard; } } while (0) + NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate ); + NAV_MAP_KEY(ImGuiKey_Enter, ImGuiNavInput_Input ); + NAV_MAP_KEY(ImGuiKey_Escape, ImGuiNavInput_Cancel ); + NAV_MAP_KEY(ImGuiKey_LeftArrow, ImGuiNavInput_KeyLeft_ ); + NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_); + NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ ); + NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ ); + if (io.KeyCtrl) + io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; + if (io.KeyShift) + io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; + #undef NAV_MAP_KEY + } + memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration)); + for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) + io.NavInputsDownDuration[i] = (io.NavInputs[i] > 0.0f) ? (io.NavInputsDownDuration[i] < 0.0f ? 0.0f : io.NavInputsDownDuration[i] + io.DeltaTime) : -1.0f; + + // Process navigation init request (select first/default focus) + if (g.NavInitResultId != 0) + NavInitRequestApplyResult(); + g.NavInitRequest = false; + g.NavInitRequestFromMove = false; + g.NavInitResultId = 0; + g.NavJustMovedToId = 0; + + // Process navigation move request + if (g.NavMoveSubmitted) + NavMoveRequestApplyResult(); + g.NavTabbingCounter = 0; + g.NavMoveSubmitted = g.NavMoveScoringItems = false; + + // Schedule mouse position update (will be done at the bottom of this function, after 1) processing all move requests and 2) updating scrolling) + bool set_mouse_pos = false; + if (g.NavMousePosDirty && g.NavIdIsAlive) + if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow) + set_mouse_pos = true; + g.NavMousePosDirty = false; + IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu); + + // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0 + if (g.NavWindow) + NavSaveLastChildNavWindowIntoParent(g.NavWindow); + if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main) + g.NavWindow->NavLastChildNavWindow = NULL; + + // Update CTRL+TAB and Windowing features (hold Square to move/resize/etc.) + NavUpdateWindowing(); + + // Set output flags for user application + io.NavActive = (nav_keyboard_active || nav_gamepad_active) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); + io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL); + + // Process NavCancel input (to close a popup, get back to parent, clear focus) + NavUpdateCancelRequest(); + + // Process manual activation request + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavActivateInputId = 0; + g.NavActivateFlags = ImGuiActivateFlags_None; + if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) + { + bool activate_down = IsNavInputDown(ImGuiNavInput_Activate); + bool input_down = IsNavInputDown(ImGuiNavInput_Input); + bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed); + bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed); + if (g.ActiveId == 0 && activate_pressed) + { + g.NavActivateId = g.NavId; + g.NavActivateFlags = ImGuiActivateFlags_PreferTweak; + } + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && input_pressed) + { + g.NavActivateInputId = g.NavId; + g.NavActivateFlags = ImGuiActivateFlags_PreferInput; + } + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down) + g.NavActivateDownId = g.NavId; + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed) + g.NavActivatePressedId = g.NavId; + } + if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) + g.NavDisableHighlight = true; + if (g.NavActivateId != 0) + IM_ASSERT(g.NavActivateDownId == g.NavActivateId); + + // Process programmatic activation request + // FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others) + if (g.NavNextActivateId != 0) + { + if (g.NavNextActivateFlags & ImGuiActivateFlags_PreferInput) + g.NavActivateInputId = g.NavNextActivateId; + else + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavNextActivateId; + g.NavActivateFlags = g.NavNextActivateFlags; + } + g.NavNextActivateId = 0; + + // Process move requests + NavUpdateCreateMoveRequest(); + if (g.NavMoveDir == ImGuiDir_None) + NavUpdateCreateTabbingRequest(); + NavUpdateAnyRequestFlag(); + g.NavIdIsAlive = false; + + // Scrolling + if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) + { + // *Fallback* manual-scroll with Nav directional keys when window has no navigable item + ImGuiWindow* window = g.NavWindow; + const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. + const ImGuiDir move_dir = g.NavMoveDir; + if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && move_dir != ImGuiDir_None) + { + if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) + SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); + if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) + SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed)); + } + + // *Normal* Manual scroll with NavScrollXXX keys + // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds. + ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f / 10.0f, 10.0f); + if (scroll_dir.x != 0.0f && window->ScrollbarX) + SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed)); + if (scroll_dir.y != 0.0f) + SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); + } + + // Always prioritize mouse highlight if navigation is disabled + if (!nav_keyboard_active && !nav_gamepad_active) + { + g.NavDisableHighlight = true; + g.NavDisableMouseHover = set_mouse_pos = false; + } + + // Update mouse position if requested + // (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied) + if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) + { + io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); + io.WantSetMousePos = true; + //IMGUI_DEBUG_LOG("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); + } + + // [DEBUG] + g.NavScoringDebugCount = 0; +#if IMGUI_DEBUG_NAV_RECTS + if (g.NavWindow) + { + ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow); + if (1) { for (int layer = 0; layer < 2; layer++) { ImRect r = WindowRectRelToAbs(g.NavWindow, g.NavWindow->NavRectRel[layer]); draw_list->AddRect(r.Min, r.Max, IM_COL32(255,200,0,255)); } } // [DEBUG] + if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } + } +#endif +} + +void ImGui::NavInitRequestApplyResult() +{ + // In very rare cases g.NavWindow may be null (e.g. clearing focus after requesting an init request, which does happen when releasing Alt while clicking on void) + ImGuiContext& g = *GImGui; + if (!g.NavWindow) + return; + + // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) + // FIXME-NAV: On _NavFlattened windows, g.NavWindow will only be updated during subsequent frame. Not a problem currently. + IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name); + SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel); + g.NavIdIsAlive = true; // Mark as alive from previous frame as we got a result + if (g.NavInitRequestFromMove) + NavRestoreHighlightAfterMove(); +} + +void ImGui::NavUpdateCreateMoveRequest() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + ImGuiWindow* window = g.NavWindow; + + if (g.NavMoveForwardToNextFrame && window != NULL) + { + // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) + // (preserve most state, which were already set by the NavMoveRequestForward() function) + IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); + IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded); + IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); + } + else + { + // Initiate directional inputs request + g.NavMoveDir = ImGuiDir_None; + g.NavMoveFlags = ImGuiNavMoveFlags_None; + g.NavMoveScrollFlags = ImGuiScrollFlags_None; + if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs)) + { + const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat; + if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; } + } + g.NavMoveClipDir = g.NavMoveDir; + g.NavScoringNoClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); + } + + // Update PageUp/PageDown/Home/End scroll + // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? + const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + float scoring_rect_offset_y = 0.0f; + if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active) + scoring_rect_offset_y = NavUpdatePageUpPageDown(); + if (scoring_rect_offset_y != 0.0f) + { + g.NavScoringNoClipRect = window->InnerRect; + g.NavScoringNoClipRect.TranslateY(scoring_rect_offset_y); + } + + // [DEBUG] Always send a request +#if IMGUI_DEBUG_NAV_SCORING + if (io.KeyCtrl && IsKeyPressed(ImGuiKey_C)) + g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3); + if (io.KeyCtrl && g.NavMoveDir == ImGuiDir_None) + { + g.NavMoveDir = g.NavMoveDirForDebug; + g.NavMoveFlags |= ImGuiNavMoveFlags_DebugNoResult; + } +#endif + + // Submit + g.NavMoveForwardToNextFrame = false; + if (g.NavMoveDir != ImGuiDir_None) + NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags, g.NavMoveScrollFlags); + + // Moving with no reference triggers a init request (will be used as a fallback if the direction fails to find a match) + if (g.NavMoveSubmitted && g.NavId == 0) + { + IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); + g.NavInitRequest = g.NavInitRequestFromMove = true; + g.NavInitResultId = 0; + g.NavDisableHighlight = false; + } + + // When using gamepad, we project the reference nav bounding box into window visible area. + // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative + // (can't focus a visible object like we can with the mouse). + if (g.NavMoveSubmitted && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL)// && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded)) + { + bool clamp_x = (g.NavMoveFlags & (ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapX)) == 0; + bool clamp_y = (g.NavMoveFlags & (ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapY)) == 0; + ImRect inner_rect_rel = WindowRectAbsToRel(window, ImRect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1))); + if ((clamp_x || clamp_y) && !inner_rect_rel.Contains(window->NavRectRel[g.NavLayer])) + { + IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n"); + float pad_x = ImMin(inner_rect_rel.GetWidth(), window->CalcFontSize() * 0.5f); + float pad_y = ImMin(inner_rect_rel.GetHeight(), window->CalcFontSize() * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item + inner_rect_rel.Min.x = clamp_x ? (inner_rect_rel.Min.x + pad_x) : -FLT_MAX; + inner_rect_rel.Max.x = clamp_x ? (inner_rect_rel.Max.x - pad_x) : +FLT_MAX; + inner_rect_rel.Min.y = clamp_y ? (inner_rect_rel.Min.y + pad_y) : -FLT_MAX; + inner_rect_rel.Max.y = clamp_y ? (inner_rect_rel.Max.y - pad_y) : +FLT_MAX; + window->NavRectRel[g.NavLayer].ClipWithFull(inner_rect_rel); + g.NavId = g.NavFocusScopeId = 0; + } + } + + // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) + ImRect scoring_rect; + if (window != NULL) + { + ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); + scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); + scoring_rect.TranslateY(scoring_rect_offset_y); + scoring_rect.Min.x = ImMin(scoring_rect.Min.x + 1.0f, scoring_rect.Max.x); + scoring_rect.Max.x = scoring_rect.Min.x; + IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). + //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG] + //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] + } + g.NavScoringRect = scoring_rect; + g.NavScoringNoClipRect.Add(scoring_rect); +} + +void ImGui::NavUpdateCreateTabbingRequest() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + IM_ASSERT(g.NavMoveDir == ImGuiDir_None); + if (window == NULL || g.NavWindowingTarget != NULL || (window->Flags & ImGuiWindowFlags_NoNavInputs)) + return; + + const bool tab_pressed = IsKeyPressed(ImGuiKey_Tab, true) && !IsActiveIdUsingKey(ImGuiKey_Tab) && !g.IO.KeyCtrl && !g.IO.KeyAlt; + if (!tab_pressed) + return; + + // Initiate tabbing request + // (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!) + // Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests. + // See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping. + //// FIXME: We use (g.ActiveId == 0) but (g.NavDisableHighlight == false) might be righter once we can tab through anything + g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; + ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; + ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; + NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. + g.NavTabbingResultFirst.Clear(); + g.NavTabbingCounter = -1; +} + +// Apply result from previous frame navigation directional move request. Always called from NavUpdate() +void ImGui::NavMoveRequestApplyResult() +{ + ImGuiContext& g = *GImGui; +#if IMGUI_DEBUG_NAV_SCORING + if (g.NavMoveFlags & ImGuiNavMoveFlags_DebugNoResult) // [DEBUG] Scoring all items in NavWindow at all times + return; +#endif + + // Select which result to use + ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; + + // Tabbing forward wrap + if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) + if ((g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) && g.NavTabbingResultFirst.ID) + result = &g.NavTabbingResultFirst; + + // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) + if (result == NULL) + { + if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) + g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight; + if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0) + NavRestoreHighlightAfterMove(); + return; + } + + // PageUp/PageDown behavior first jumps to the bottom/top mostly visible item, _otherwise_ use the result from the previous/next page. + if (g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) + if (g.NavMoveResultLocalVisible.ID != 0 && g.NavMoveResultLocalVisible.ID != g.NavId) + result = &g.NavMoveResultLocalVisible; + + // Maybe entering a flattened child from the outside? In this case solve the tie using the regular scoring rules. + if (result != &g.NavMoveResultOther && g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow) + if ((g.NavMoveResultOther.DistBox < result->DistBox) || (g.NavMoveResultOther.DistBox == result->DistBox && g.NavMoveResultOther.DistCenter < result->DistCenter)) + result = &g.NavMoveResultOther; + IM_ASSERT(g.NavWindow && result->Window); + + // Scroll to keep newly navigated item fully into view. + if (g.NavLayer == ImGuiNavLayer_Main) + { + if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdgeY) + { + // FIXME: Should remove this + float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f; + SetScrollY(result->Window, scroll_target); + } + else + { + ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel); + ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags); + } + } + + g.NavWindow = result->Window; + if (g.ActiveId != result->ID) + ClearActiveID(); + if (g.NavId != result->ID) + { + // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) + g.NavJustMovedToId = result->ID; + g.NavJustMovedToFocusScopeId = result->FocusScopeId; + g.NavJustMovedToKeyMods = g.NavMoveKeyMods; + } + + // Focus + IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name); + SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel); + + // Tabbing: Activates Inputable or Focus non-Inputable + if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable)) + { + g.NavNextActivateId = result->ID; + g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState; + g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight; + } + + // Activate + if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate) + { + g.NavNextActivateId = result->ID; + g.NavNextActivateFlags = ImGuiActivateFlags_None; + } + + // Enable nav highlight + if ((g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0) + NavRestoreHighlightAfterMove(); +} + +// Process NavCancel input (to close a popup, get back to parent, clear focus) +// FIXME: In order to support e.g. Escape to clear a selection we'll need: +// - either to store the equivalent of ActiveIdUsingKeyInputMask for a FocusScope and test for it. +// - either to move most/all of those tests to the epilogue/end functions of the scope they are dealing with (e.g. exit child window in EndChild()) or in EndFrame(), to allow an earlier intercept +static void ImGui::NavUpdateCancelRequest() +{ + ImGuiContext& g = *GImGui; + if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) + return; + + IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n"); + if (g.ActiveId != 0) + { + if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel)) + ClearActiveID(); + } + else if (g.NavLayer != ImGuiNavLayer_Main) + { + // Leave the "menu" layer + NavRestoreLayer(ImGuiNavLayer_Main); + NavRestoreHighlightAfterMove(); + } + else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) + { + // Exit child window + ImGuiWindow* child_window = g.NavWindow; + ImGuiWindow* parent_window = g.NavWindow->ParentWindow; + IM_ASSERT(child_window->ChildId != 0); + ImRect child_rect = child_window->Rect(); + FocusWindow(parent_window); + SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_rect)); + NavRestoreHighlightAfterMove(); + } + else if (g.OpenPopupStack.Size > 0) + { + // Close open popup/menu + if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) + ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); + } + else + { + // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were + if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) + g.NavWindow->NavLastIds[0] = 0; + g.NavId = g.NavFocusScopeId = 0; + } +} + +// Handle PageUp/PageDown/Home/End keys +// Called from NavUpdateCreateMoveRequest() which will use our output to create a move request +// FIXME-NAV: This doesn't work properly with NavFlattened siblings as we use NavWindow rectangle for reference +// FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid? +static float ImGui::NavUpdatePageUpPageDown() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + if ((window->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL) + return 0.0f; + + const bool page_up_held = IsKeyDown(ImGuiKey_PageUp) && !IsActiveIdUsingKey(ImGuiKey_PageUp); + const bool page_down_held = IsKeyDown(ImGuiKey_PageDown) && !IsActiveIdUsingKey(ImGuiKey_PageDown); + const bool home_pressed = IsKeyPressed(ImGuiKey_Home) && !IsActiveIdUsingKey(ImGuiKey_Home); + const bool end_pressed = IsKeyPressed(ImGuiKey_End) && !IsActiveIdUsingKey(ImGuiKey_End); + if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out + return 0.0f; + + if (g.NavLayer != ImGuiNavLayer_Main) + NavRestoreLayer(ImGuiNavLayer_Main); + + if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) + { + // Fallback manual-scroll when window has no navigable item + if (IsKeyPressed(ImGuiKey_PageUp, true)) + SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); + else if (IsKeyPressed(ImGuiKey_PageDown, true)) + SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); + else if (home_pressed) + SetScrollY(window, 0.0f); + else if (end_pressed) + SetScrollY(window, window->ScrollMax.y); + } + else + { + ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; + const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight()); + float nav_scoring_rect_offset_y = 0.0f; + if (IsKeyPressed(ImGuiKey_PageUp, true)) + { + nav_scoring_rect_offset_y = -page_offset_y; + g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) + g.NavMoveClipDir = ImGuiDir_Up; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; + } + else if (IsKeyPressed(ImGuiKey_PageDown, true)) + { + nav_scoring_rect_offset_y = +page_offset_y; + g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) + g.NavMoveClipDir = ImGuiDir_Down; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; + } + else if (home_pressed) + { + // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y + // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdgeY flag, we don't scroll immediately to avoid scrolling happening before nav result. + // Preserve current horizontal position if we have any. + nav_rect_rel.Min.y = nav_rect_rel.Max.y = 0.0f; + if (nav_rect_rel.IsInverted()) + nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; + g.NavMoveDir = ImGuiDir_Down; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdgeY; + // FIXME-NAV: MoveClipDir left to _None, intentional? + } + else if (end_pressed) + { + nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ContentSize.y; + if (nav_rect_rel.IsInverted()) + nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; + g.NavMoveDir = ImGuiDir_Up; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdgeY; + // FIXME-NAV: MoveClipDir left to _None, intentional? + } + return nav_scoring_rect_offset_y; + } + return 0.0f; +} + +static void ImGui::NavEndFrame() +{ + ImGuiContext& g = *GImGui; + + // Show CTRL+TAB list window + if (g.NavWindowingTarget != NULL) + NavUpdateWindowingOverlay(); + + // Perform wrap-around in menus + // FIXME-NAV: Wrap may need to apply a weight bias on the other axis. e.g. 4x4 grid with 2 last items missing on last item won't handle LoopY/WrapY correctly. + // FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame. + const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY; + if (g.NavWindow && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0) + NavUpdateCreateWrappingRequest(); +} + +static void ImGui::NavUpdateCreateWrappingRequest() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + + bool do_forward = false; + ImRect bb_rel = window->NavRectRel[g.NavLayer]; + ImGuiDir clip_dir = g.NavMoveDir; + const ImGuiNavMoveFlags move_flags = g.NavMoveFlags; + if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) + { + bb_rel.Min.x = bb_rel.Max.x = window->ContentSize.x + window->WindowPadding.x; + if (move_flags & ImGuiNavMoveFlags_WrapX) + { + bb_rel.TranslateY(-bb_rel.GetHeight()); // Previous row + clip_dir = ImGuiDir_Up; + } + do_forward = true; + } + if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) + { + bb_rel.Min.x = bb_rel.Max.x = -window->WindowPadding.x; + if (move_flags & ImGuiNavMoveFlags_WrapX) + { + bb_rel.TranslateY(+bb_rel.GetHeight()); // Next row + clip_dir = ImGuiDir_Down; + } + do_forward = true; + } + if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) + { + bb_rel.Min.y = bb_rel.Max.y = window->ContentSize.y + window->WindowPadding.y; + if (move_flags & ImGuiNavMoveFlags_WrapY) + { + bb_rel.TranslateX(-bb_rel.GetWidth()); // Previous column + clip_dir = ImGuiDir_Left; + } + do_forward = true; + } + if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) + { + bb_rel.Min.y = bb_rel.Max.y = -window->WindowPadding.y; + if (move_flags & ImGuiNavMoveFlags_WrapY) + { + bb_rel.TranslateX(+bb_rel.GetWidth()); // Next column + clip_dir = ImGuiDir_Right; + } + do_forward = true; + } + if (!do_forward) + return; + window->NavRectRel[g.NavLayer] = bb_rel; + NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags); +} + +static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_UNUSED(g); + int order = window->FocusOrder; + IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking) + IM_ASSERT(g.WindowsFocusOrder[order] == window); + return order; +} + +static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // FIXME-OPT O(N) +{ + ImGuiContext& g = *GImGui; + for (int i = i_start; i >= 0 && i < g.WindowsFocusOrder.Size && i != i_stop; i += dir) + if (ImGui::IsWindowNavFocusable(g.WindowsFocusOrder[i])) + return g.WindowsFocusOrder[i]; + return NULL; +} + +static void NavUpdateWindowingHighlightWindow(int focus_change_dir) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindowingTarget); + if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal) + return; + + const int i_current = ImGui::FindWindowFocusIndex(g.NavWindowingTarget); + ImGuiWindow* window_target = FindWindowNavFocusable(i_current + focus_change_dir, -INT_MAX, focus_change_dir); + if (!window_target) + window_target = FindWindowNavFocusable((focus_change_dir < 0) ? (g.WindowsFocusOrder.Size - 1) : 0, i_current, focus_change_dir); + if (window_target) // Don't reset windowing target if there's a single window in the list + g.NavWindowingTarget = g.NavWindowingTargetAnim = window_target; + g.NavWindowingToggleLayer = false; +} + +// Windowing management mode +// Keyboard: CTRL+Tab (change focus/move/resize), Alt (toggle menu layer) +// Gamepad: Hold Menu/Square (change focus/move/resize), Tap Menu/Square (toggle menu layer) +static void ImGui::NavUpdateWindowing() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + ImGuiWindow* apply_focus_window = NULL; + bool apply_toggle_layer = false; + + ImGuiWindow* modal_window = GetTopMostPopupModal(); + bool allow_windowing = (modal_window == NULL); + if (!allow_windowing) + g.NavWindowingTarget = NULL; + + // Fade out + if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL) + { + g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - io.DeltaTime * 10.0f, 0.0f); + if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f) + g.NavWindowingTargetAnim = NULL; + } + + // Start CTRL+Tab or Square+L/R window selection + const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); + const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressed(ImGuiKey_Tab); + if (start_windowing_with_gamepad || start_windowing_with_keyboard) + if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) + { + g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; + g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; + g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer + g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; + } + + // Gamepad update + g.NavWindowingTimer += io.DeltaTime; + if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad) + { + // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise + g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); + + // Select window to focus + const int focus_change_dir = (int)IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiInputReadMode_RepeatSlow) - (int)IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiInputReadMode_RepeatSlow); + if (focus_change_dir != 0) + { + NavUpdateWindowingHighlightWindow(focus_change_dir); + g.NavWindowingHighlightAlpha = 1.0f; + } + + // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered top-most) + if (!IsNavInputDown(ImGuiNavInput_Menu)) + { + g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. + if (g.NavWindowingToggleLayer && g.NavWindow) + apply_toggle_layer = true; + else if (!g.NavWindowingToggleLayer) + apply_focus_window = g.NavWindowingTarget; + g.NavWindowingTarget = NULL; + } + } + + // Keyboard: Focus + if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Keyboard) + { + // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise + g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f + if (IsKeyPressed(ImGuiKey_Tab, true)) + NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1); + if (!io.KeyCtrl) + apply_focus_window = g.NavWindowingTarget; + } + + // Keyboard: Press and Release ALT to toggle menu layer + // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer. + // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway. + const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0) + { + g.NavWindowingToggleLayer = true; + g.NavInputSource = ImGuiInputSource_Keyboard; + } + if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard) + { + // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370) + // We cancel toggling nav layer when other modifiers are pressed. (See #4439) + if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper) + g.NavWindowingToggleLayer = false; + + // Apply layer toggle on release + // Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false) + // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss. + if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer) + if (g.ActiveId == 0 || g.ActiveIdAllowOverlap) + if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev)) + apply_toggle_layer = true; + if (!io.KeyAlt) + g.NavWindowingToggleLayer = false; + } + + // Move window + if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove)) + { + ImVec2 move_delta; + if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift) + move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_RawKeyboard, ImGuiInputReadMode_Down); + if (g.NavInputSource == ImGuiInputSource_Gamepad) + move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down); + if (move_delta.x != 0.0f || move_delta.y != 0.0f) + { + const float NAV_MOVE_SPEED = 800.0f; + const float move_speed = ImFloor(NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well + ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindowDockTree; + SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always); + MarkIniSettingsDirty(moving_window); + g.NavDisableMouseHover = true; + } + } + + // Apply final focus + if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow)) + { + ImGuiViewport* previous_viewport = g.NavWindow ? g.NavWindow->Viewport : NULL; + ClearActiveID(); + NavRestoreHighlightAfterMove(); + apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); + ClosePopupsOverWindow(apply_focus_window, false); + FocusWindow(apply_focus_window); + if (apply_focus_window->NavLastIds[0] == 0) + NavInitWindow(apply_focus_window, false); + + // If the window has ONLY a menu layer (no main layer), select it directly + // Use NavLayersActiveMaskNext since windows didn't have a chance to be Begin()-ed on this frame, + // so CTRL+Tab where the keys are only held for 1 frame will be able to use correct layers mask since + // the target window as already been previewed once. + // FIXME-NAV: This should be done in NavInit.. or in FocusWindow... However in both of those cases, + // we won't have a guarantee that windows has been visible before and therefore NavLayersActiveMask* + // won't be valid. + if (apply_focus_window->DC.NavLayersActiveMaskNext == (1 << ImGuiNavLayer_Menu)) + g.NavLayer = ImGuiNavLayer_Menu; + + // Request OS level focus + if (apply_focus_window->Viewport != previous_viewport && g.PlatformIO.Platform_SetWindowFocus) + g.PlatformIO.Platform_SetWindowFocus(apply_focus_window->Viewport); + } + if (apply_focus_window) + g.NavWindowingTarget = NULL; + + // Apply menu/layer toggle + if (apply_toggle_layer && g.NavWindow) + { + ClearActiveID(); + + // Move to parent menu if necessary + ImGuiWindow* new_nav_window = g.NavWindow; + while (new_nav_window->ParentWindow + && (new_nav_window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0 + && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 + && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) + new_nav_window = new_nav_window->ParentWindow; + if (new_nav_window != g.NavWindow) + { + ImGuiWindow* old_nav_window = g.NavWindow; + FocusWindow(new_nav_window); + new_nav_window->NavLastChildNavWindow = old_nav_window; + } + + // Toggle layer + const ImGuiNavLayer new_nav_layer = (g.NavWindow->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main; + if (new_nav_layer != g.NavLayer) + { + // Reinitialize navigation when entering menu bar with the Alt key (FIXME: could be a properly of the layer?) + const bool preserve_layer_1_nav_id = (new_nav_window->DockNodeAsHost != NULL); + if (new_nav_layer == ImGuiNavLayer_Menu && !preserve_layer_1_nav_id) + g.NavWindow->NavLastIds[new_nav_layer] = 0; + NavRestoreLayer(new_nav_layer); + NavRestoreHighlightAfterMove(); + } + } +} + +// Window has already passed the IsWindowNavFocusable() +static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window) +{ + if (window->Flags & ImGuiWindowFlags_Popup) + return "(Popup)"; + if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0) + return "(Main menu bar)"; + if (window->DockNodeAsHost) + return "(Dock node)"; + return "(Untitled)"; +} + +// Overlay displayed when using CTRL+TAB. Called by EndFrame(). +void ImGui::NavUpdateWindowingOverlay() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindowingTarget != NULL); + + if (g.NavWindowingTimer < NAV_WINDOWING_LIST_APPEAR_DELAY) + return; + + if (g.NavWindowingListWindow == NULL) + g.NavWindowingListWindow = FindWindowByName("###NavWindowingList"); + const ImGuiViewport* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ GetMainViewport(); + SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX)); + SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f); + Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings); + for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--) + { + ImGuiWindow* window = g.WindowsFocusOrder[n]; + IM_ASSERT(window != NULL); // Fix static analyzers + if (!IsWindowNavFocusable(window)) + continue; + const char* label = window->Name; + if (label == FindRenderedTextEnd(label)) + label = GetFallbackWindowNameForWindowingList(window); + Selectable(label, g.NavWindowingTarget == window); + } + End(); + PopStyleVar(); +} + + +//----------------------------------------------------------------------------- +// [SECTION] DRAG AND DROP +//----------------------------------------------------------------------------- + +void ImGui::ClearDragDrop() +{ + ImGuiContext& g = *GImGui; + g.DragDropActive = false; + g.DragDropPayload.Clear(); + g.DragDropAcceptFlags = ImGuiDragDropFlags_None; + g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; + g.DragDropAcceptFrameCount = -1; + + g.DragDropPayloadBufHeap.clear(); + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); +} + +// When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() +// If the item has an identifier: +// - This assume/require the item to be activated (typically via ButtonBehavior). +// - Therefore if you want to use this with a mouse button other than left mouse button, it is up to the item itself to activate with another button. +// - We then pull and use the mouse button that was used to activate the item and use it to carry on the drag. +// If the item has no identifier: +// - Currently always assume left mouse button. +bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // FIXME-DRAGDROP: While in the common-most "drag from non-zero active id" case we can tell the mouse button, + // in both SourceExtern and id==0 cases we may requires something else (explicit flags or some heuristic). + ImGuiMouseButton mouse_button = ImGuiMouseButton_Left; + + bool source_drag_active = false; + ImGuiID source_id = 0; + ImGuiID source_parent_id = 0; + if (!(flags & ImGuiDragDropFlags_SourceExtern)) + { + source_id = g.LastItemData.ID; + if (source_id != 0) + { + // Common path: items with ID + if (g.ActiveId != source_id) + return false; + if (g.ActiveIdMouseButton != -1) + mouse_button = g.ActiveIdMouseButton; + if (g.IO.MouseDown[mouse_button] == false || window->SkipItems) + return false; + g.ActiveIdAllowOverlap = false; + } + else + { + // Uncommon path: items without ID + if (g.IO.MouseDown[mouse_button] == false || window->SkipItems) + return false; + if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window)) + return false; + + // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: + // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag. + if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) + { + IM_ASSERT(0); + return false; + } + + // Magic fallback to handle items with no assigned ID, e.g. Text(), Image() + // We build a throwaway ID based on current ID stack + relative AABB of items in window. + // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING/RESIZINGG OF THE WIDGET, so if your widget moves your dragging operation will be canceled. + // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. + // Rely on keeping other window->LastItemXXX fields intact. + source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect); + bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id); + if (is_hovered && g.IO.MouseClicked[mouse_button]) + { + SetActiveID(source_id, window); + FocusWindow(window); + } + if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. + g.ActiveIdAllowOverlap = is_hovered; + } + if (g.ActiveId != source_id) + return false; + source_parent_id = window->IDStack.back(); + source_drag_active = IsMouseDragging(mouse_button); + + // Disable navigation and key inputs while dragging + cancel existing request if any + SetActiveIdUsingNavAndKeys(); + } + else + { + window = NULL; + source_id = ImHashStr("#SourceExtern"); + source_drag_active = true; + } + + if (source_drag_active) + { + if (!g.DragDropActive) + { + IM_ASSERT(source_id != 0); + ClearDragDrop(); + ImGuiPayload& payload = g.DragDropPayload; + payload.SourceId = source_id; + payload.SourceParentId = source_parent_id; + g.DragDropActive = true; + g.DragDropSourceFlags = flags; + g.DragDropMouseButton = mouse_button; + if (payload.SourceId == g.ActiveId) + g.ActiveIdNoClearOnFocusLoss = true; + } + g.DragDropSourceFrameCount = g.FrameCount; + g.DragDropWithinSource = true; + + if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit) + // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents. + BeginTooltip(); + if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) + { + ImGuiWindow* tooltip_window = g.CurrentWindow; + tooltip_window->Hidden = tooltip_window->SkipItems = true; + tooltip_window->HiddenFramesCanSkipItems = 1; + } + } + + if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) + g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect; + + return true; + } + return false; +} + +void ImGui::EndDragDropSource() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DragDropActive); + IM_ASSERT(g.DragDropWithinSource && "Not after a BeginDragDropSource()?"); + + if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + EndTooltip(); + + // Discard the drag if have not called SetDragDropPayload() + if (g.DragDropPayload.DataFrameCount == -1) + ClearDragDrop(); + g.DragDropWithinSource = false; +} + +// Use 'cond' to choose to submit payload on drag start or every frame +bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + ImGuiPayload& payload = g.DragDropPayload; + if (cond == 0) + cond = ImGuiCond_Always; + + IM_ASSERT(type != NULL); + IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long"); + IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); + IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); + IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() + + if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) + { + // Copy payload + ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType)); + g.DragDropPayloadBufHeap.resize(0); + if (data_size > sizeof(g.DragDropPayloadBufLocal)) + { + // Store in heap + g.DragDropPayloadBufHeap.resize((int)data_size); + payload.Data = g.DragDropPayloadBufHeap.Data; + memcpy(payload.Data, data, data_size); + } + else if (data_size > 0) + { + // Store locally + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); + payload.Data = g.DragDropPayloadBufLocal; + memcpy(payload.Data, data, data_size); + } + else + { + payload.Data = NULL; + } + payload.DataSize = (int)data_size; + } + payload.DataFrameCount = g.FrameCount; + + // Return whether the payload has been accepted + return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); +} + +bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) +{ + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; + + ImGuiWindow* window = g.CurrentWindow; + ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow; + if (hovered_window == NULL || window->RootWindowDockTree != hovered_window->RootWindowDockTree) + return false; + IM_ASSERT(id != 0); + if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId)) + return false; + if (window->SkipItems) + return false; + + IM_ASSERT(g.DragDropWithinTarget == false); + g.DragDropTargetRect = bb; + g.DragDropTargetId = id; + g.DragDropWithinTarget = true; + return true; +} + +// We don't use BeginDragDropTargetCustom() and duplicate its code because: +// 1) we use LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them. +// 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can. +// Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case) +bool ImGui::BeginDragDropTarget() +{ + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; + + ImGuiWindow* window = g.CurrentWindow; + if (!(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect)) + return false; + ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow; + if (hovered_window == NULL || window->RootWindowDockTree != hovered_window->RootWindowDockTree || window->SkipItems) + return false; + + const ImRect& display_rect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? g.LastItemData.DisplayRect : g.LastItemData.Rect; + ImGuiID id = g.LastItemData.ID; + if (id == 0) + id = window->GetIDFromRectangle(display_rect); + if (g.DragDropPayload.SourceId == id) + return false; + + IM_ASSERT(g.DragDropWithinTarget == false); + g.DragDropTargetRect = display_rect; + g.DragDropTargetId = id; + g.DragDropWithinTarget = true; + return true; +} + +bool ImGui::IsDragDropPayloadBeingAccepted() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive && g.DragDropAcceptIdPrev != 0; +} + +const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiPayload& payload = g.DragDropPayload; + IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? + IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? + if (type != NULL && !payload.IsDataType(type)) + return NULL; + + // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints. + // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! + const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId); + ImRect r = g.DragDropTargetRect; + float r_surface = r.GetWidth() * r.GetHeight(); + if (r_surface <= g.DragDropAcceptIdCurrRectSurface) + { + g.DragDropAcceptFlags = flags; + g.DragDropAcceptIdCurr = g.DragDropTargetId; + g.DragDropAcceptIdCurrRectSurface = r_surface; + } + + // Render default drop visuals + // FIXME-DRAGDROP: Settle on a proper default visuals for drop target. + payload.Preview = was_accepted_previously; + flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame) + if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) + window->DrawList->AddRect(r.Min - ImVec2(3.5f,3.5f), r.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); + + g.DragDropAcceptFrameCount = g.FrameCount; + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() + if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) + return NULL; + + return &payload; +} + +const ImGuiPayload* ImGui::GetDragDropPayload() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive ? &g.DragDropPayload : NULL; +} + +// We don't really use/need this now, but added it for the sake of consistency and because we might need it later. +void ImGui::EndDragDropTarget() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DragDropActive); + IM_ASSERT(g.DragDropWithinTarget); + g.DragDropWithinTarget = false; +} + +//----------------------------------------------------------------------------- +// [SECTION] LOGGING/CAPTURING +//----------------------------------------------------------------------------- +// All text output from the interface can be captured into tty/file/clipboard. +// By default, tree nodes are automatically opened during logging. +//----------------------------------------------------------------------------- + +// Pass text data straight to log (without being displayed) +static inline void LogTextV(ImGuiContext& g, const char* fmt, va_list args) +{ + if (g.LogFile) + { + g.LogBuffer.Buf.resize(0); + g.LogBuffer.appendfv(fmt, args); + ImFileWrite(g.LogBuffer.c_str(), sizeof(char), (ImU64)g.LogBuffer.size(), g.LogFile); + } + else + { + g.LogBuffer.appendfv(fmt, args); + } +} + +void ImGui::LogText(const char* fmt, ...) +{ + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; + + va_list args; + va_start(args, fmt); + LogTextV(g, fmt, args); + va_end(args); +} + +void ImGui::LogTextV(const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; + + LogTextV(g, fmt, 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 +// FIXME: This code is a little complicated perhaps, considering simplifying the whole system. +void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const char* prefix = g.LogNextPrefix; + const char* suffix = g.LogNextSuffix; + g.LogNextPrefix = g.LogNextSuffix = NULL; + + if (!text_end) + text_end = FindRenderedTextEnd(text, text_end); + + const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + g.Style.FramePadding.y + 1); + if (ref_pos) + g.LogLinePosY = ref_pos->y; + if (log_new_line) + { + LogText(IM_NEWLINE); + g.LogLineFirstItem = true; + } + + if (prefix) + LogRenderedText(ref_pos, prefix, prefix + strlen(prefix)); // Calculate end ourself to ensure "##" are included here. + + // Re-adjust padding if we have popped out of our starting depth + if (g.LogDepthRef > window->DC.TreeDepth) + g.LogDepthRef = window->DC.TreeDepth; + const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef); + + const char* text_remaining = text; + for (;;) + { + // Split the string. Each new line (after a '\n') is followed by indentation corresponding to the current depth of our log entry. + // We don't add a trailing \n yet to allow a subsequent item on the same line to be captured. + const char* line_start = text_remaining; + const char* line_end = ImStreolRange(line_start, text_end); + const bool is_last_line = (line_end == text_end); + if (line_start != line_end || !is_last_line) + { + const int line_length = (int)(line_end - line_start); + const int indentation = g.LogLineFirstItem ? tree_depth * 4 : 1; + LogText("%*s%.*s", indentation, "", line_length, line_start); + g.LogLineFirstItem = false; + if (*line_end == '\n') + { + LogText(IM_NEWLINE); + g.LogLineFirstItem = true; + } + } + if (is_last_line) + break; + text_remaining = line_end + 1; + } + + if (suffix) + LogRenderedText(ref_pos, suffix, suffix + strlen(suffix)); +} + +// Start logging/capturing text output +void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(g.LogEnabled == false); + IM_ASSERT(g.LogFile == NULL); + IM_ASSERT(g.LogBuffer.empty()); + g.LogEnabled = true; + g.LogType = type; + g.LogNextPrefix = g.LogNextSuffix = NULL; + g.LogDepthRef = window->DC.TreeDepth; + g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); + g.LogLinePosY = FLT_MAX; + g.LogLineFirstItem = true; +} + +// Important: doesn't copy underlying data, use carefully (prefix/suffix must be in scope at the time of the next LogRenderedText) +void ImGui::LogSetNextTextDecoration(const char* prefix, const char* suffix) +{ + ImGuiContext& g = *GImGui; + g.LogNextPrefix = prefix; + g.LogNextSuffix = suffix; +} + +void ImGui::LogToTTY(int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + IM_UNUSED(auto_open_depth); +#ifndef IMGUI_DISABLE_TTY_FUNCTIONS + LogBegin(ImGuiLogType_TTY, auto_open_depth); + g.LogFile = stdout; +#endif +} + +// Start logging/capturing text output to given file +void ImGui::LogToFile(int auto_open_depth, const char* filename) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + + // FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still + // be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE. + // By opening the file in binary mode "ab" we have consistent output everywhere. + if (!filename) + filename = g.IO.LogFilename; + if (!filename || !filename[0]) + return; + ImFileHandle f = ImFileOpen(filename, "ab"); + if (!f) + { + IM_ASSERT(0); + return; + } + + LogBegin(ImGuiLogType_File, auto_open_depth); + g.LogFile = f; +} + +// Start logging/capturing text output to clipboard +void ImGui::LogToClipboard(int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + LogBegin(ImGuiLogType_Clipboard, auto_open_depth); +} + +void ImGui::LogToBuffer(int auto_open_depth) +{ + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + LogBegin(ImGuiLogType_Buffer, auto_open_depth); +} + +void ImGui::LogFinish() +{ + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; + + LogText(IM_NEWLINE); + switch (g.LogType) + { + case ImGuiLogType_TTY: +#ifndef IMGUI_DISABLE_TTY_FUNCTIONS + fflush(g.LogFile); +#endif + break; + case ImGuiLogType_File: + ImFileClose(g.LogFile); + break; + case ImGuiLogType_Buffer: + break; + case ImGuiLogType_Clipboard: + if (!g.LogBuffer.empty()) + SetClipboardText(g.LogBuffer.begin()); + break; + case ImGuiLogType_None: + IM_ASSERT(0); + break; + } + + g.LogEnabled = false; + g.LogType = ImGuiLogType_None; + g.LogFile = NULL; + g.LogBuffer.clear(); +} + +// Helper to display logging buttons +// FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!) +void ImGui::LogButtons() +{ + ImGuiContext& g = *GImGui; + + PushID("LogButtons"); +#ifndef IMGUI_DISABLE_TTY_FUNCTIONS + const bool log_to_tty = Button("Log To TTY"); SameLine(); +#else + const bool log_to_tty = false; +#endif + const bool log_to_file = Button("Log To File"); SameLine(); + const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); + PushAllowKeyboardFocus(false); + SetNextItemWidth(80.0f); + SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL); + PopAllowKeyboardFocus(); + PopID(); + + // Start logging at the end of the function so that the buttons don't appear in the log + if (log_to_tty) + LogToTTY(); + if (log_to_file) + LogToFile(); + if (log_to_clipboard) + LogToClipboard(); +} + + +//----------------------------------------------------------------------------- +// [SECTION] SETTINGS +//----------------------------------------------------------------------------- +// - UpdateSettings() [Internal] +// - MarkIniSettingsDirty() [Internal] +// - CreateNewWindowSettings() [Internal] +// - FindWindowSettings() [Internal] +// - FindOrCreateWindowSettings() [Internal] +// - FindSettingsHandler() [Internal] +// - ClearIniSettings() [Internal] +// - LoadIniSettingsFromDisk() +// - LoadIniSettingsFromMemory() +// - SaveIniSettingsToDisk() +// - SaveIniSettingsToMemory() +// - WindowSettingsHandler_***() [Internal] +//----------------------------------------------------------------------------- + +// Called by NewFrame() +void ImGui::UpdateSettings() +{ + // Load settings on first frame (if not explicitly loaded manually before) + ImGuiContext& g = *GImGui; + if (!g.SettingsLoaded) + { + IM_ASSERT(g.SettingsWindows.empty()); + if (g.IO.IniFilename) + LoadIniSettingsFromDisk(g.IO.IniFilename); + g.SettingsLoaded = true; + } + + // Save settings (with a delay after the last modification, so we don't spam disk too much) + if (g.SettingsDirtyTimer > 0.0f) + { + g.SettingsDirtyTimer -= g.IO.DeltaTime; + if (g.SettingsDirtyTimer <= 0.0f) + { + if (g.IO.IniFilename != NULL) + SaveIniSettingsToDisk(g.IO.IniFilename); + else + g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves. + g.SettingsDirtyTimer = 0.0f; + } + } +} + +void ImGui::MarkIniSettingsDirty() +{ + ImGuiContext& g = *GImGui; + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; +} + +void ImGui::MarkIniSettingsDirty(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; +} + +ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name) +{ + ImGuiContext& g = *GImGui; + +#if !IMGUI_DEBUG_INI_SETTINGS + // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + // Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier. + if (const char* p = strstr(name, "###")) + name = p; +#endif + const size_t name_len = strlen(name); + + // Allocate chunk + const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1; + ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size); + IM_PLACEMENT_NEW(settings) ImGuiWindowSettings(); + settings->ID = ImHashStr(name, name_len); + memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator + + return settings; +} + +ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->ID == id) + return settings; + return NULL; +} + +ImGuiWindowSettings* ImGui::FindOrCreateWindowSettings(const char* name) +{ + if (ImGuiWindowSettings* settings = FindWindowSettings(ImHashStr(name))) + return settings; + return CreateNewWindowSettings(name); +} + +ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) +{ + ImGuiContext& g = *GImGui; + const ImGuiID type_hash = ImHashStr(type_name); + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].TypeHash == type_hash) + return &g.SettingsHandlers[handler_n]; + return NULL; +} + +void ImGui::ClearIniSettings() +{ + ImGuiContext& g = *GImGui; + g.SettingsIniData.clear(); + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].ClearAllFn) + g.SettingsHandlers[handler_n].ClearAllFn(&g, &g.SettingsHandlers[handler_n]); +} + +void ImGui::LoadIniSettingsFromDisk(const char* ini_filename) +{ + size_t file_data_size = 0; + char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size); + if (!file_data) + return; + LoadIniSettingsFromMemory(file_data, (size_t)file_data_size); + IM_FREE(file_data); +} + +// Zero-tolerance, no error reporting, cheap .ini parsing +void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); + //IM_ASSERT(!g.WithinFrameScope && "Cannot be called between NewFrame() and EndFrame()"); + //IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0); + + // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter). + // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy.. + if (ini_size == 0) + ini_size = strlen(ini_data); + g.SettingsIniData.Buf.resize((int)ini_size + 1); + char* const buf = g.SettingsIniData.Buf.Data; + char* const buf_end = buf + ini_size; + memcpy(buf, ini_data, ini_size); + buf_end[0] = 0; + + // Call pre-read handlers + // Some types will clear their data (e.g. dock information) some types will allow merge/override (window) + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].ReadInitFn) + g.SettingsHandlers[handler_n].ReadInitFn(&g, &g.SettingsHandlers[handler_n]); + + void* entry_data = NULL; + ImGuiSettingsHandler* entry_handler = NULL; + + char* line_end = NULL; + for (char* line = buf; line < buf_end; line = line_end + 1) + { + // Skip new lines markers, then find end of the line + while (*line == '\n' || *line == '\r') + line++; + line_end = line; + while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') + line_end++; + line_end[0] = 0; + if (line[0] == ';') + continue; + if (line[0] == '[' && line_end > line && line_end[-1] == ']') + { + // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code. + line_end[-1] = 0; + const char* name_end = line_end - 1; + const char* type_start = line + 1; + char* type_end = (char*)(void*)ImStrchrRange(type_start, name_end, ']'); + const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; + if (!type_end || !name_start) + continue; + *type_end = 0; // Overwrite first ']' + name_start++; // Skip second '[' + entry_handler = FindSettingsHandler(type_start); + entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL; + } + else if (entry_handler != NULL && entry_data != NULL) + { + // Let type handler parse the line + entry_handler->ReadLineFn(&g, entry_handler, entry_data, line); + } + } + g.SettingsLoaded = true; + + // [DEBUG] Restore untouched copy so it can be browsed in Metrics (not strictly necessary) + memcpy(buf, ini_data, ini_size); + + // Call post-read handlers + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].ApplyAllFn) + g.SettingsHandlers[handler_n].ApplyAllFn(&g, &g.SettingsHandlers[handler_n]); +} + +void ImGui::SaveIniSettingsToDisk(const char* ini_filename) +{ + ImGuiContext& g = *GImGui; + g.SettingsDirtyTimer = 0.0f; + if (!ini_filename) + return; + + size_t ini_data_size = 0; + const char* ini_data = SaveIniSettingsToMemory(&ini_data_size); + ImFileHandle f = ImFileOpen(ini_filename, "wt"); + if (!f) + return; + ImFileWrite(ini_data, sizeof(char), ini_data_size, f); + ImFileClose(f); +} + +// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer +const char* ImGui::SaveIniSettingsToMemory(size_t* out_size) +{ + ImGuiContext& g = *GImGui; + g.SettingsDirtyTimer = 0.0f; + g.SettingsIniData.Buf.resize(0); + g.SettingsIniData.Buf.push_back(0); + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + { + ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n]; + handler->WriteAllFn(&g, handler, &g.SettingsIniData); + } + if (out_size) + *out_size = (size_t)g.SettingsIniData.size(); + return g.SettingsIniData.c_str(); +} + +static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + ImGuiContext& g = *ctx; + for (int i = 0; i != g.Windows.Size; i++) + g.Windows[i]->SettingsOffset = -1; + g.SettingsWindows.clear(); +} + +static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) +{ + ImGuiWindowSettings* settings = ImGui::FindOrCreateWindowSettings(name); + ImGuiID id = settings->ID; + *settings = ImGuiWindowSettings(); // Clear existing if recycling previous entry + settings->ID = id; + settings->WantApply = true; + return (void*)settings; +} + +static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line) +{ + ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry; + int x, y; + int i; + ImU32 u1; + if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) { settings->Pos = ImVec2ih((short)x, (short)y); } + else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) { settings->Size = ImVec2ih((short)x, (short)y); } + else if (sscanf(line, "ViewportId=0x%08X", &u1) == 1) { settings->ViewportId = u1; } + else if (sscanf(line, "ViewportPos=%i,%i", &x, &y) == 2){ settings->ViewportPos = ImVec2ih((short)x, (short)y); } + else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); } + else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; } + else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; } + else if (sscanf(line, "ClassId=0x%X", &u1) == 1) { settings->ClassId = u1; } +} + +// Apply to existing windows (if any) +static void WindowSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + ImGuiContext& g = *ctx; + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->WantApply) + { + if (ImGuiWindow* window = ImGui::FindWindowByID(settings->ID)) + ApplyWindowSettings(window, settings); + settings->WantApply = false; + } +} + +static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) +{ + // Gather data from windows that were active during this session + // (if a window wasn't opened in this session we preserve its settings) + ImGuiContext& g = *ctx; + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_NoSavedSettings) + continue; + + ImGuiWindowSettings* settings = (window->SettingsOffset != -1) ? g.SettingsWindows.ptr_from_offset(window->SettingsOffset) : ImGui::FindWindowSettings(window->ID); + if (!settings) + { + settings = ImGui::CreateNewWindowSettings(window->Name); + window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings); + } + IM_ASSERT(settings->ID == window->ID); + settings->Pos = ImVec2ih(window->Pos - window->ViewportPos); + settings->Size = ImVec2ih(window->SizeFull); + settings->ViewportId = window->ViewportId; + settings->ViewportPos = ImVec2ih(window->ViewportPos); + IM_ASSERT(window->DockNode == NULL || window->DockNode->ID == window->DockId); + settings->DockId = window->DockId; + settings->ClassId = window->WindowClass.ClassId; + settings->DockOrder = window->DockOrder; + settings->Collapsed = window->Collapsed; + } + + // Write to text buffer + buf->reserve(buf->size() + g.SettingsWindows.size() * 6); // ballpark reserve + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + { + const char* settings_name = settings->GetName(); + buf->appendf("[%s][%s]\n", handler->TypeName, settings_name); + if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID) + { + buf->appendf("ViewportPos=%d,%d\n", settings->ViewportPos.x, settings->ViewportPos.y); + buf->appendf("ViewportId=0x%08X\n", settings->ViewportId); + } + if (settings->Pos.x != 0 || settings->Pos.y != 0 || settings->ViewportId == ImGui::IMGUI_VIEWPORT_DEFAULT_ID) + buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y); + if (settings->Size.x != 0 || settings->Size.y != 0) + buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y); + buf->appendf("Collapsed=%d\n", settings->Collapsed); + if (settings->DockId != 0) + { + //buf->appendf("TabId=0x%08X\n", ImHashStr("#TAB", 4, settings->ID)); // window->TabId: this is not read back but writing it makes "debugging" the .ini data easier. + if (settings->DockOrder == -1) + buf->appendf("DockId=0x%08X\n", settings->DockId); + else + buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder); + if (settings->ClassId != 0) + buf->appendf("ClassId=0x%08X\n", settings->ClassId); + } + buf->append("\n"); + } +} + + +//----------------------------------------------------------------------------- +// [SECTION] VIEWPORTS, PLATFORM WINDOWS +//----------------------------------------------------------------------------- +// - GetMainViewport() +// - FindViewportByID() +// - FindViewportByPlatformHandle() +// - SetCurrentViewport() [Internal] +// - SetWindowViewport() [Internal] +// - GetWindowAlwaysWantOwnViewport() [Internal] +// - UpdateTryMergeWindowIntoHostViewport() [Internal] +// - UpdateTryMergeWindowIntoHostViewports() [Internal] +// - TranslateWindowsInViewport() [Internal] +// - ScaleWindowsInViewport() [Internal] +// - FindHoveredViewportFromPlatformWindowStack() [Internal] +// - UpdateViewportsNewFrame() [Internal] +// - UpdateViewportsEndFrame() [Internal] +// - AddUpdateViewport() [Internal] +// - WindowSelectViewport() [Internal] +// - WindowSyncOwnedViewport() [Internal] +// - UpdatePlatformWindows() +// - RenderPlatformWindowsDefault() +// - FindPlatformMonitorForPos() [Internal] +// - FindPlatformMonitorForRect() [Internal] +// - UpdateViewportPlatformMonitor() [Internal] +// - DestroyPlatformWindow() [Internal] +// - DestroyPlatformWindows() +//----------------------------------------------------------------------------- + +ImGuiViewport* ImGui::GetMainViewport() +{ + ImGuiContext& g = *GImGui; + return g.Viewports[0]; +} + +// FIXME: This leaks access to viewports not listed in PlatformIO.Viewports[]. Problematic? (#4236) +ImGuiViewport* ImGui::FindViewportByID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + for (int n = 0; n < g.Viewports.Size; n++) + if (g.Viewports[n]->ID == id) + return g.Viewports[n]; + return NULL; +} + +ImGuiViewport* ImGui::FindViewportByPlatformHandle(void* platform_handle) +{ + ImGuiContext& g = *GImGui; + for (int i = 0; i != g.Viewports.Size; i++) + if (g.Viewports[i]->PlatformHandle == platform_handle) + return g.Viewports[i]; + return NULL; +} + +void ImGui::SetCurrentViewport(ImGuiWindow* current_window, ImGuiViewportP* viewport) +{ + ImGuiContext& g = *GImGui; + (void)current_window; + + if (viewport) + viewport->LastFrameActive = g.FrameCount; + if (g.CurrentViewport == viewport) + return; + g.CurrentDpiScale = viewport ? viewport->DpiScale : 1.0f; + g.CurrentViewport = viewport; + //IMGUI_DEBUG_LOG_VIEWPORT("SetCurrentViewport changed '%s' 0x%08X\n", current_window ? current_window->Name : NULL, viewport ? viewport->ID : 0); + + // Notify platform layer of viewport changes + // FIXME-DPI: This is only currently used for experimenting with handling of multiple DPI + if (g.CurrentViewport && g.PlatformIO.Platform_OnChangedViewport) + g.PlatformIO.Platform_OnChangedViewport(g.CurrentViewport); +} + +static void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport) +{ + // Abandon viewport + if (window->ViewportOwned && window->Viewport->Window == window) + window->Viewport->Size = ImVec2(0.0f, 0.0f); + + window->Viewport = viewport; + window->ViewportId = viewport->ID; + window->ViewportOwned = (viewport->Window == window); +} + +static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) +{ + // Tooltips and menus are not automatically forced into their own viewport when the NoMerge flag is set, however the multiplication of viewports makes them more likely to protrude and create their own. + ImGuiContext& g = *GImGui; + if (g.IO.ConfigViewportsNoAutoMerge || (window->WindowClass.ViewportFlagsOverrideSet & ImGuiViewportFlags_NoAutoMerge)) + if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) + if (!window->DockIsActive) + if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip)) == 0) + if ((window->Flags & ImGuiWindowFlags_Popup) == 0 || (window->Flags & ImGuiWindowFlags_Modal) != 0) + return true; + return false; +} + +static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) +{ + ImGuiContext& g = *GImGui; + if (window->Viewport == viewport) + return false; + if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) == 0) + return false; + if ((viewport->Flags & ImGuiViewportFlags_Minimized) != 0) + return false; + if (!viewport->GetMainRect().Contains(window->Rect())) + return false; + if (GetWindowAlwaysWantOwnViewport(window)) + return false; + + // FIXME: Can't use g.WindowsFocusOrder[] for root windows only as we care about Z order. If we maintained a DisplayOrder along with FocusOrder we could.. + for (int n = 0; n < g.Windows.Size; n++) + { + ImGuiWindow* window_behind = g.Windows[n]; + if (window_behind == window) + break; + if (window_behind->WasActive && window_behind->ViewportOwned && !(window_behind->Flags & ImGuiWindowFlags_ChildWindow)) + if (window_behind->Viewport->GetMainRect().Overlaps(window->Rect())) + return false; + } + + // Move to the existing viewport, Move child/hosted windows as well (FIXME-OPT: iterate child) + ImGuiViewportP* old_viewport = window->Viewport; + if (window->ViewportOwned) + for (int n = 0; n < g.Windows.Size; n++) + if (g.Windows[n]->Viewport == old_viewport) + SetWindowViewport(g.Windows[n], viewport); + SetWindowViewport(window, viewport); + BringWindowToDisplayFront(window); + + return true; +} + +// FIXME: handle 0 to N host viewports +static bool ImGui::UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + return UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]); +} + +// Translate Dear ImGui windows when a Host Viewport has been moved +// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!) +void ImGui::TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(viewport->Window == NULL && (viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows)); + + // 1) We test if ImGuiConfigFlags_ViewportsEnable was just toggled, which allows us to conveniently + // translate imgui windows from OS-window-local to absolute coordinates or vice-versa. + // 2) If it's not going to fit into the new size, keep it at same absolute position. + // One problem with this is that most Win32 applications doesn't update their render while dragging, + // and so the window will appear to teleport when releasing the mouse. + const bool translate_all_windows = (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) != (g.ConfigFlagsLastFrame & ImGuiConfigFlags_ViewportsEnable); + ImRect test_still_fit_rect(old_pos, old_pos + viewport->Size); + ImVec2 delta_pos = new_pos - old_pos; + for (int window_n = 0; window_n < g.Windows.Size; window_n++) // FIXME-OPT + if (translate_all_windows || (g.Windows[window_n]->Viewport == viewport && test_still_fit_rect.Contains(g.Windows[window_n]->Rect()))) + TranslateWindow(g.Windows[window_n], delta_pos); +} + +// Scale all windows (position, size). Use when e.g. changing DPI. (This is a lossy operation!) +void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale) +{ + ImGuiContext& g = *GImGui; + if (viewport->Window) + { + ScaleWindow(viewport->Window, scale); + } + else + { + for (int i = 0; i != g.Windows.Size; i++) + if (g.Windows[i]->Viewport == viewport) + ScaleWindow(g.Windows[i], scale); + } +} + +// If the backend doesn't set MouseLastHoveredViewport or doesn't honor ImGuiViewportFlags_NoInputs, we do a search ourselves. +// A) It won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window. +// B) It requires Platform_GetWindowFocus to be implemented by backend. +ImGuiViewportP* ImGui::FindHoveredViewportFromPlatformWindowStack(const ImVec2& mouse_platform_pos) +{ + ImGuiContext& g = *GImGui; + ImGuiViewportP* best_candidate = NULL; + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + if (!(viewport->Flags & (ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_Minimized)) && viewport->GetMainRect().Contains(mouse_platform_pos)) + if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount) + best_candidate = viewport; + } + return best_candidate; +} + +// Update viewports and monitor infos +// Note that this is running even if 'ImGuiConfigFlags_ViewportsEnable' is not set, in order to clear unused viewports (if any) and update monitor info. +static void ImGui::UpdateViewportsNewFrame() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.PlatformIO.Viewports.Size <= g.Viewports.Size); + + // Update Minimized status (we need it first in order to decide if we'll apply Pos/Size of the main viewport) + const bool viewports_enabled = (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) != 0; + if (viewports_enabled) + { + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + const bool platform_funcs_available = viewport->PlatformWindowCreated; + if (g.PlatformIO.Platform_GetWindowMinimized && platform_funcs_available) + { + bool minimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); + if (minimized) + viewport->Flags |= ImGuiViewportFlags_Minimized; + else + viewport->Flags &= ~ImGuiViewportFlags_Minimized; + } + } + } + + // Create/update main viewport with current platform position. + // FIXME-VIEWPORT: Size is driven by backend/user code for backward-compatibility but we should aim to make this more consistent. + ImGuiViewportP* main_viewport = g.Viewports[0]; + IM_ASSERT(main_viewport->ID == IMGUI_VIEWPORT_DEFAULT_ID); + IM_ASSERT(main_viewport->Window == NULL); + ImVec2 main_viewport_pos = viewports_enabled ? g.PlatformIO.Platform_GetWindowPos(main_viewport) : ImVec2(0.0f, 0.0f); + ImVec2 main_viewport_size = g.IO.DisplaySize; + if (viewports_enabled && (main_viewport->Flags & ImGuiViewportFlags_Minimized)) + { + main_viewport_pos = main_viewport->Pos; // Preserve last pos/size when minimized (FIXME: We don't do the same for Size outside of the viewport path) + main_viewport_size = main_viewport->Size; + } + AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_pos, main_viewport_size, ImGuiViewportFlags_OwnedByApp | ImGuiViewportFlags_CanHostOtherWindows); + + g.CurrentDpiScale = 0.0f; + g.CurrentViewport = NULL; + g.MouseViewport = NULL; + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + viewport->Idx = n; + + // Erase unused viewports + if (n > 0 && viewport->LastFrameActive < g.FrameCount - 2) + { + DestroyViewport(viewport); + n--; + continue; + } + + const bool platform_funcs_available = viewport->PlatformWindowCreated; + if (viewports_enabled) + { + // Update Position and Size (from Platform Window to ImGui) if requested. + // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. + if (!(viewport->Flags & ImGuiViewportFlags_Minimized) && platform_funcs_available) + { + // Viewport->WorkPos and WorkSize will be updated below + if (viewport->PlatformRequestMove) + viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); + if (viewport->PlatformRequestResize) + viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); + } + } + + // Update/copy monitor info + UpdateViewportPlatformMonitor(viewport); + + // Lock down space taken by menu bars and status bars, reset the offset for functions like BeginMainMenuBar() to alter them again. + viewport->WorkOffsetMin = viewport->BuildWorkOffsetMin; + viewport->WorkOffsetMax = viewport->BuildWorkOffsetMax; + viewport->BuildWorkOffsetMin = viewport->BuildWorkOffsetMax = ImVec2(0.0f, 0.0f); + viewport->UpdateWorkRect(); + + // Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back. + viewport->Alpha = 1.0f; + + // Translate Dear ImGui windows when a Host Viewport has been moved + // (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!) + const ImVec2 viewport_delta_pos = viewport->Pos - viewport->LastPos; + if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && (viewport_delta_pos.x != 0.0f || viewport_delta_pos.y != 0.0f)) + TranslateWindowsInViewport(viewport, viewport->LastPos, viewport->Pos); + + // Update DPI scale + float new_dpi_scale; + if (g.PlatformIO.Platform_GetWindowDpiScale && platform_funcs_available) + new_dpi_scale = g.PlatformIO.Platform_GetWindowDpiScale(viewport); + else if (viewport->PlatformMonitor != -1) + new_dpi_scale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; + else + new_dpi_scale = (viewport->DpiScale != 0.0f) ? viewport->DpiScale : 1.0f; + if (viewport->DpiScale != 0.0f && new_dpi_scale != viewport->DpiScale) + { + float scale_factor = new_dpi_scale / viewport->DpiScale; + if (g.IO.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) + ScaleWindowsInViewport(viewport, scale_factor); + //if (viewport == GetMainViewport()) + // g.PlatformInterface.SetWindowSize(viewport, viewport->Size * scale_factor); + + // Scale our window moving pivot so that the window will rescale roughly around the mouse position. + // FIXME-VIEWPORT: This currently creates a resizing feedback loop when a window is straddling a DPI transition border. + // (Minor: since our sizes do not perfectly linearly scale, deferring the click offset scale until we know the actual window scale ratio may get us slightly more precise mouse positioning.) + //if (g.MovingWindow != NULL && g.MovingWindow->Viewport == viewport) + // g.ActiveIdClickOffset = ImFloor(g.ActiveIdClickOffset * scale_factor); + } + viewport->DpiScale = new_dpi_scale; + } + + // Update fallback monitor + if (g.PlatformIO.Monitors.Size == 0) + { + ImGuiPlatformMonitor* monitor = &g.FallbackMonitor; + monitor->MainPos = main_viewport->Pos; + monitor->MainSize = main_viewport->Size; + monitor->WorkPos = main_viewport->WorkPos; + monitor->WorkSize = main_viewport->WorkSize; + monitor->DpiScale = main_viewport->DpiScale; + } + + if (!viewports_enabled) + { + g.MouseViewport = main_viewport; + return; + } + + // Mouse handling: decide on the actual mouse viewport for this frame between the active/focused viewport and the hovered viewport. + // Note that 'viewport_hovered' should skip over any viewport that has the ImGuiViewportFlags_NoInputs flags set. + ImGuiViewportP* viewport_hovered = NULL; + if (g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) + { + viewport_hovered = g.IO.MouseHoveredViewport ? (ImGuiViewportP*)FindViewportByID(g.IO.MouseHoveredViewport) : NULL; + if (viewport_hovered && (viewport_hovered->Flags & ImGuiViewportFlags_NoInputs)) + viewport_hovered = FindHoveredViewportFromPlatformWindowStack(g.IO.MousePos); // Backend failed to handle _NoInputs viewport: revert to our fallback. + } + else + { + // If the backend doesn't know how to honor ImGuiViewportFlags_NoInputs, we do a search ourselves. Note that this search: + // A) won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window. + // B) won't take account of how the backend apply parent<>child relationship to secondary viewports, which affects their Z order. + // C) uses LastFrameAsRefViewport as a flawed replacement for the last time a window was focused (we could/should fix that by introducing Focus functions in PlatformIO) + viewport_hovered = FindHoveredViewportFromPlatformWindowStack(g.IO.MousePos); + } + if (viewport_hovered != NULL) + g.MouseLastHoveredViewport = viewport_hovered; + else if (g.MouseLastHoveredViewport == NULL) + g.MouseLastHoveredViewport = g.Viewports[0]; + + // Update mouse reference viewport + // (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode) + // (MovingViewport->Viewport will be NULL in the rare situation where the window disappared while moving, set UpdateMouseMovingWindowNewFrame() for details) + if (g.MovingWindow && g.MovingWindow->Viewport) + g.MouseViewport = g.MovingWindow->Viewport; + else + g.MouseViewport = g.MouseLastHoveredViewport; + + // When dragging something, always refer to the last hovered viewport. + // - when releasing a moving window we will revert to aiming behind (at viewport_hovered) + // - when we are between viewports, our dragged preview will tend to show in the last viewport _even_ if we don't have tooltips in their viewports (when lacking monitor info) + // - consider the case of holding on a menu item to browse child menus: even thou a mouse button is held, there's no active id because menu items only react on mouse release. + // FIXME-VIEWPORT: This is essentially broken, when ImGuiBackendFlags_HasMouseHoveredViewport is set we want to trust when viewport_hovered==NULL and use that. + const bool is_mouse_dragging_with_an_expected_destination = g.DragDropActive; + if (is_mouse_dragging_with_an_expected_destination && viewport_hovered == NULL) + viewport_hovered = g.MouseLastHoveredViewport; + if (is_mouse_dragging_with_an_expected_destination || g.ActiveId == 0 || !IsAnyMouseDown()) + if (viewport_hovered != NULL && viewport_hovered != g.MouseViewport && !(viewport_hovered->Flags & ImGuiViewportFlags_NoInputs)) + g.MouseViewport = viewport_hovered; + + IM_ASSERT(g.MouseViewport != NULL); +} + +// Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some) +static void ImGui::UpdateViewportsEndFrame() +{ + ImGuiContext& g = *GImGui; + g.PlatformIO.Viewports.resize(0); + for (int i = 0; i < g.Viewports.Size; i++) + { + ImGuiViewportP* viewport = g.Viewports[i]; + viewport->LastPos = viewport->Pos; + if (viewport->LastFrameActive < g.FrameCount || viewport->Size.x <= 0.0f || viewport->Size.y <= 0.0f) + if (i > 0) // Always include main viewport in the list + continue; + if (viewport->Window && !IsWindowActiveAndVisible(viewport->Window)) + continue; + if (i > 0) + IM_ASSERT(viewport->Window != NULL); + g.PlatformIO.Viewports.push_back(viewport); + } + g.Viewports[0]->ClearRequestFlags(); // Clear main viewport flags because UpdatePlatformWindows() won't do it and may not even be called +} + +// FIXME: We should ideally refactor the system to call this every frame (we currently don't) +ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(id != 0); + + flags |= ImGuiViewportFlags_IsPlatformWindow; + if (window != NULL) + { + if (g.MovingWindow && g.MovingWindow->RootWindowDockTree == window) + flags |= ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_NoFocusOnAppearing; + if ((window->Flags & ImGuiWindowFlags_NoMouseInputs) && (window->Flags & ImGuiWindowFlags_NoNavInputs)) + flags |= ImGuiViewportFlags_NoInputs; + if (window->Flags & ImGuiWindowFlags_NoFocusOnAppearing) + flags |= ImGuiViewportFlags_NoFocusOnAppearing; + } + + ImGuiViewportP* viewport = (ImGuiViewportP*)FindViewportByID(id); + if (viewport) + { + if (!viewport->PlatformRequestMove) + viewport->Pos = pos; + if (!viewport->PlatformRequestResize) + viewport->Size = size; + viewport->Flags = flags | (viewport->Flags & ImGuiViewportFlags_Minimized); // Preserve existing flags + } + else + { + // New viewport + viewport = IM_NEW(ImGuiViewportP)(); + viewport->ID = id; + viewport->Idx = g.Viewports.Size; + viewport->Pos = viewport->LastPos = pos; + viewport->Size = size; + viewport->Flags = flags; + UpdateViewportPlatformMonitor(viewport); + g.Viewports.push_back(viewport); + IMGUI_DEBUG_LOG_VIEWPORT("Add Viewport %08X (%s)\n", id, window->Name); + + // We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport. + // We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame + g.DrawListSharedData.ClipRectFullscreen.x = ImMin(g.DrawListSharedData.ClipRectFullscreen.x, viewport->Pos.x); + g.DrawListSharedData.ClipRectFullscreen.y = ImMin(g.DrawListSharedData.ClipRectFullscreen.y, viewport->Pos.y); + g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x); + g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y); + + // Store initial DpiScale before the OS platform window creation, based on expected monitor data. + // This is so we can select an appropriate font size on the first frame of our window lifetime + if (viewport->PlatformMonitor != -1) + viewport->DpiScale = g.PlatformIO.Monitors[viewport->PlatformMonitor].DpiScale; + } + + viewport->Window = window; + viewport->LastFrameActive = g.FrameCount; + viewport->UpdateWorkRect(); + IM_ASSERT(window == NULL || viewport->ID == window->ID); + + if (window != NULL) + window->ViewportOwned = true; + + return viewport; +} + +static void ImGui::DestroyViewport(ImGuiViewportP* viewport) +{ + // Clear references to this viewport in windows (window->ViewportId becomes the master data) + ImGuiContext& g = *GImGui; + for (int window_n = 0; window_n < g.Windows.Size; window_n++) + { + ImGuiWindow* window = g.Windows[window_n]; + if (window->Viewport != viewport) + continue; + window->Viewport = NULL; + window->ViewportOwned = false; + } + if (viewport == g.MouseLastHoveredViewport) + g.MouseLastHoveredViewport = NULL; + + // Destroy + IMGUI_DEBUG_LOG_VIEWPORT("Delete Viewport %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a"); + DestroyPlatformWindow(viewport); // In most circumstances the platform window will already be destroyed here. + IM_ASSERT(g.PlatformIO.Viewports.contains(viewport) == false); + IM_ASSERT(g.Viewports[viewport->Idx] == viewport); + g.Viewports.erase(g.Viewports.Data + viewport->Idx); + IM_DELETE(viewport); +} + +// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten. +static void ImGui::WindowSelectViewport(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindowFlags flags = window->Flags; + window->ViewportAllowPlatformMonitorExtend = -1; + + // Restore main viewport if multi-viewport is not supported by the backend + ImGuiViewportP* main_viewport = (ImGuiViewportP*)(void*)GetMainViewport(); + if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)) + { + SetWindowViewport(window, main_viewport); + return; + } + window->ViewportOwned = false; + + // Appearing popups reset their viewport so they can inherit again + if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && window->Appearing) + { + window->Viewport = NULL; + window->ViewportId = 0; + } + + if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasViewport) == 0) + { + // By default inherit from parent window + if (window->Viewport == NULL && window->ParentWindow && (!window->ParentWindow->IsFallbackWindow || window->ParentWindow->WasActive)) + window->Viewport = window->ParentWindow->Viewport; + + // Attempt to restore saved viewport id (= window that hasn't been activated yet), try to restore the viewport based on saved 'window->ViewportPos' restored from .ini file + if (window->Viewport == NULL && window->ViewportId != 0) + { + window->Viewport = (ImGuiViewportP*)FindViewportByID(window->ViewportId); + if (window->Viewport == NULL && window->ViewportPos.x != FLT_MAX && window->ViewportPos.y != FLT_MAX) + window->Viewport = AddUpdateViewport(window, window->ID, window->ViewportPos, window->Size, ImGuiViewportFlags_None); + } + } + + bool lock_viewport = false; + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasViewport) + { + // Code explicitly request a viewport + window->Viewport = (ImGuiViewportP*)FindViewportByID(g.NextWindowData.ViewportId); + window->ViewportId = g.NextWindowData.ViewportId; // Store ID even if Viewport isn't resolved yet. + lock_viewport = true; + } + else if ((flags & ImGuiWindowFlags_ChildWindow) || (flags & ImGuiWindowFlags_ChildMenu)) + { + // Always inherit viewport from parent window + if (window->DockNode && window->DockNode->HostWindow) + IM_ASSERT(window->DockNode->HostWindow->Viewport == window->ParentWindow->Viewport); + window->Viewport = window->ParentWindow->Viewport; + } + else if (window->DockNode && window->DockNode->HostWindow) + { + // This covers the "always inherit viewport from parent window" case for when a window reattach to a node that was just created mid-frame + window->Viewport = window->DockNode->HostWindow->Viewport; + } + else if (flags & ImGuiWindowFlags_Tooltip) + { + window->Viewport = g.MouseViewport; + } + else if (GetWindowAlwaysWantOwnViewport(window)) + { + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); + } + else if (g.MovingWindow && g.MovingWindow->RootWindowDockTree == window && IsMousePosValid()) + { + if (window->Viewport != NULL && window->Viewport->Window == window) + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); + } + else + { + // Merge into host viewport? + // We cannot test window->ViewportOwned as it set lower in the function. + // Testing (g.ActiveId == 0 || g.ActiveIdAllowOverlap) to avoid merging during a short-term widget interaction. Main intent was to avoid during resize (see #4212) + bool try_to_merge_into_host_viewport = (window->Viewport && window == window->Viewport->Window && (g.ActiveId == 0 || g.ActiveIdAllowOverlap)); + if (try_to_merge_into_host_viewport) + UpdateTryMergeWindowIntoHostViewports(window); + } + + // Fallback: merge in default viewport if z-order matches, otherwise create a new viewport + if (window->Viewport == NULL) + if (!UpdateTryMergeWindowIntoHostViewport(window, main_viewport)) + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); + + // Mark window as allowed to protrude outside of its viewport and into the current monitor + if (!lock_viewport) + { + if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + { + // We need to take account of the possibility that mouse may become invalid. + // Popups/Tooltip always set ViewportAllowPlatformMonitorExtend so GetWindowAllowedExtentRect() will return full monitor bounds. + ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.BeginPopupStack.back().OpenMousePos; + bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow); + bool mouse_valid = IsMousePosValid(&mouse_ref); + if ((window->Appearing || (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_ChildMenu))) && (!use_mouse_ref || mouse_valid)) + window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos()); + else + window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; + } + else if (window->Viewport && window != window->Viewport->Window && window->Viewport->Window && !(flags & ImGuiWindowFlags_ChildWindow) && window->DockNode == NULL) + { + // When called from Begin() we don't have access to a proper version of the Hidden flag yet, so we replicate this code. + const bool will_be_visible = (window->DockIsActive && !window->DockTabIsVisible) ? false : true; + if ((window->Flags & ImGuiWindowFlags_DockNodeHost) && window->Viewport->LastFrameActive < g.FrameCount && will_be_visible) + { + // Steal/transfer ownership + IMGUI_DEBUG_LOG_VIEWPORT("Window '%s' steal Viewport %08X from Window '%s'\n", window->Name, window->Viewport->ID, window->Viewport->Window->Name); + window->Viewport->Window = window; + window->Viewport->ID = window->ID; + window->Viewport->LastNameHash = 0; + } + else if (!UpdateTryMergeWindowIntoHostViewports(window)) // Merge? + { + // New viewport + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing); + } + } + else if (window->ViewportAllowPlatformMonitorExtend < 0 && (flags & ImGuiWindowFlags_ChildWindow) == 0) + { + // Regular (non-child, non-popup) windows by default are also allowed to protrude + // Child windows are kept contained within their parent. + window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; + } + } + + // Update flags + window->ViewportOwned = (window == window->Viewport->Window); + window->ViewportId = window->Viewport->ID; + + // If the OS window has a title bar, hide our imgui title bar + //if (window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration)) + // window->Flags |= ImGuiWindowFlags_NoTitleBar; +} + +void ImGui::WindowSyncOwnedViewport(ImGuiWindow* window, ImGuiWindow* parent_window_in_stack) +{ + ImGuiContext& g = *GImGui; + + bool viewport_rect_changed = false; + + // Synchronize window --> viewport in most situations + // Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM + if (window->Viewport->PlatformRequestMove) + { + window->Pos = window->Viewport->Pos; + MarkIniSettingsDirty(window); + } + else if (memcmp(&window->Viewport->Pos, &window->Pos, sizeof(window->Pos)) != 0) + { + viewport_rect_changed = true; + window->Viewport->Pos = window->Pos; + } + + if (window->Viewport->PlatformRequestResize) + { + window->Size = window->SizeFull = window->Viewport->Size; + MarkIniSettingsDirty(window); + } + else if (memcmp(&window->Viewport->Size, &window->Size, sizeof(window->Size)) != 0) + { + viewport_rect_changed = true; + window->Viewport->Size = window->Size; + } + window->Viewport->UpdateWorkRect(); + + // The viewport may have changed monitor since the global update in UpdateViewportsNewFrame() + // Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect. + if (viewport_rect_changed) + UpdateViewportPlatformMonitor(window->Viewport); + + // Update common viewport flags + const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear; + ImGuiViewportFlags viewport_flags = window->Viewport->Flags & ~viewport_flags_to_clear; + ImGuiWindowFlags window_flags = window->Flags; + const bool is_modal = (window_flags & ImGuiWindowFlags_Modal) != 0; + const bool is_short_lived_floating_window = (window_flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0; + if (window_flags & ImGuiWindowFlags_Tooltip) + viewport_flags |= ImGuiViewportFlags_TopMost; + if ((g.IO.ConfigViewportsNoTaskBarIcon || is_short_lived_floating_window) && !is_modal) + viewport_flags |= ImGuiViewportFlags_NoTaskBarIcon; + if (g.IO.ConfigViewportsNoDecoration || is_short_lived_floating_window) + viewport_flags |= ImGuiViewportFlags_NoDecoration; + + // Not correct to set modal as topmost because: + // - Because other popups can be stacked above a modal (e.g. combo box in a modal) + // - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost" + //if (flags & ImGuiWindowFlags_Modal) + // viewport_flags |= ImGuiViewportFlags_TopMost; + + // For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them + // won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration). + // Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app, + // but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere. + if (is_short_lived_floating_window && !is_modal) + viewport_flags |= ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick; + + // We can overwrite viewport flags using ImGuiWindowClass (advanced users) + if (window->WindowClass.ViewportFlagsOverrideSet) + viewport_flags |= window->WindowClass.ViewportFlagsOverrideSet; + if (window->WindowClass.ViewportFlagsOverrideClear) + viewport_flags &= ~window->WindowClass.ViewportFlagsOverrideClear; + + // We can also tell the backend that clearing the platform window won't be necessary, + // as our window background is filling the viewport and we have disabled BgAlpha. + // FIXME: Work on support for per-viewport transparency (#2766) + if (!(window_flags & ImGuiWindowFlags_NoBackground)) + viewport_flags |= ImGuiViewportFlags_NoRendererClear; + + window->Viewport->Flags = viewport_flags; + + // Update parent viewport ID + // (the !IsFallbackWindow test mimic the one done in WindowSelectViewport()) + if (window->WindowClass.ParentViewportId != (ImGuiID)-1) + window->Viewport->ParentViewportId = window->WindowClass.ParentViewportId; + else if ((window_flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && parent_window_in_stack && (!parent_window_in_stack->IsFallbackWindow || parent_window_in_stack->WasActive)) + window->Viewport->ParentViewportId = parent_window_in_stack->Viewport->ID; + else + window->Viewport->ParentViewportId = g.IO.ConfigViewportsNoDefaultParent ? 0 : IMGUI_VIEWPORT_DEFAULT_ID; +} + +// Called by user at the end of the main loop, after EndFrame() +// This will handle the creation/update of all OS windows via function defined in the ImGuiPlatformIO api. +void ImGui::UpdatePlatformWindows() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.FrameCountEnded == g.FrameCount && "Forgot to call Render() or EndFrame() before UpdatePlatformWindows()?"); + IM_ASSERT(g.FrameCountPlatformEnded < g.FrameCount); + g.FrameCountPlatformEnded = g.FrameCount; + if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)) + return; + + // Create/resize/destroy platform windows to match each active viewport. + // Skip the main viewport (index 0), which is always fully handled by the application! + for (int i = 1; i < g.Viewports.Size; i++) + { + ImGuiViewportP* viewport = g.Viewports[i]; + + // Destroy platform window if the viewport hasn't been submitted or if it is hosting a hidden window + // (the implicit/fallback Debug##Default window will be registering its viewport then be disabled, causing a dummy DestroyPlatformWindow to be made each frame) + bool destroy_platform_window = false; + destroy_platform_window |= (viewport->LastFrameActive < g.FrameCount - 1); + destroy_platform_window |= (viewport->Window && !IsWindowActiveAndVisible(viewport->Window)); + if (destroy_platform_window) + { + DestroyPlatformWindow(viewport); + continue; + } + + // New windows that appears directly in a new viewport won't always have a size on their first frame + if (viewport->LastFrameActive < g.FrameCount || viewport->Size.x <= 0 || viewport->Size.y <= 0) + continue; + + // Create window + bool is_new_platform_window = (viewport->PlatformWindowCreated == false); + if (is_new_platform_window) + { + IMGUI_DEBUG_LOG_VIEWPORT("Create Platform Window %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a"); + g.PlatformIO.Platform_CreateWindow(viewport); + if (g.PlatformIO.Renderer_CreateWindow != NULL) + g.PlatformIO.Renderer_CreateWindow(viewport); + viewport->LastNameHash = 0; + viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Size below, before Platform_ShowWindow (FIXME: Is that necessary?) + viewport->LastRendererSize = viewport->Size; // We don't need to call Renderer_SetWindowSize() as it is expected Renderer_CreateWindow() already did it. + viewport->PlatformWindowCreated = true; + } + + // Apply Position and Size (from ImGui to Platform/Renderer backends) + if ((viewport->LastPlatformPos.x != viewport->Pos.x || viewport->LastPlatformPos.y != viewport->Pos.y) && !viewport->PlatformRequestMove) + g.PlatformIO.Platform_SetWindowPos(viewport, viewport->Pos); + if ((viewport->LastPlatformSize.x != viewport->Size.x || viewport->LastPlatformSize.y != viewport->Size.y) && !viewport->PlatformRequestResize) + g.PlatformIO.Platform_SetWindowSize(viewport, viewport->Size); + if ((viewport->LastRendererSize.x != viewport->Size.x || viewport->LastRendererSize.y != viewport->Size.y) && g.PlatformIO.Renderer_SetWindowSize) + g.PlatformIO.Renderer_SetWindowSize(viewport, viewport->Size); + viewport->LastPlatformPos = viewport->Pos; + viewport->LastPlatformSize = viewport->LastRendererSize = viewport->Size; + + // Update title bar (if it changed) + if (ImGuiWindow* window_for_title = GetWindowForTitleDisplay(viewport->Window)) + { + const char* title_begin = window_for_title->Name; + char* title_end = (char*)(intptr_t)FindRenderedTextEnd(title_begin); + const ImGuiID title_hash = ImHashStr(title_begin, title_end - title_begin); + if (viewport->LastNameHash != title_hash) + { + char title_end_backup_c = *title_end; + *title_end = 0; // Cut existing buffer short instead of doing an alloc/free, no small gain. + g.PlatformIO.Platform_SetWindowTitle(viewport, title_begin); + *title_end = title_end_backup_c; + viewport->LastNameHash = title_hash; + } + } + + // Update alpha (if it changed) + if (viewport->LastAlpha != viewport->Alpha && g.PlatformIO.Platform_SetWindowAlpha) + g.PlatformIO.Platform_SetWindowAlpha(viewport, viewport->Alpha); + viewport->LastAlpha = viewport->Alpha; + + // Optional, general purpose call to allow the backend to perform general book-keeping even if things haven't changed. + if (g.PlatformIO.Platform_UpdateWindow) + g.PlatformIO.Platform_UpdateWindow(viewport); + + if (is_new_platform_window) + { + // On startup ensure new platform window don't steal focus (give it a few frames, as nested contents may lead to viewport being created a few frames late) + if (g.FrameCount < 3) + viewport->Flags |= ImGuiViewportFlags_NoFocusOnAppearing; + + // Show window + g.PlatformIO.Platform_ShowWindow(viewport); + + // Even without focus, we assume the window becomes front-most. + // This is useful for our platform z-order heuristic when io.MouseHoveredViewport is not available. + if (viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount) + viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount; + } + + // Clear request flags + viewport->ClearRequestFlags(); + } + + // Update our implicit z-order knowledge of platform windows, which is used when the backend cannot provide io.MouseHoveredViewport. + // When setting Platform_GetWindowFocus, it is expected that the platform backend can handle calls without crashing if it doesn't have data stored. + // FIXME-VIEWPORT: We should use this information to also set dear imgui-side focus, allowing us to handle os-level alt+tab. + if (g.PlatformIO.Platform_GetWindowFocus != NULL) + { + ImGuiViewportP* focused_viewport = NULL; + for (int n = 0; n < g.Viewports.Size && focused_viewport == NULL; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + if (viewport->PlatformWindowCreated) + if (g.PlatformIO.Platform_GetWindowFocus(viewport)) + focused_viewport = viewport; + } + + // Store a tag so we can infer z-order easily from all our windows + // We compare PlatformLastFocusedViewportId so newly created viewports with _NoFocusOnAppearing flag + // will keep the front most stamp instead of losing it back to their parent viewport. + if (focused_viewport && g.PlatformLastFocusedViewportId != focused_viewport->ID) + { + if (focused_viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount) + focused_viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount; + g.PlatformLastFocusedViewportId = focused_viewport->ID; + } + } +} + +// This is a default/basic function for performing the rendering/swap of multiple Platform Windows. +// Custom renderers may prefer to not call this function at all, and instead iterate the publicly exposed platform data and handle rendering/sync themselves. +// The Render/Swap functions stored in ImGuiPlatformIO are merely here to allow for this helper to exist, but you can do it yourself: +// +// ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); +// for (int i = 1; i < platform_io.Viewports.Size; i++) +// if ((platform_io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0) +// MyRenderFunction(platform_io.Viewports[i], my_args); +// for (int i = 1; i < platform_io.Viewports.Size; i++) +// if ((platform_io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0) +// MySwapBufferFunction(platform_io.Viewports[i], my_args); +// +void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* renderer_render_arg) +{ + // Skip the main viewport (index 0), which is always fully handled by the application! + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + for (int i = 1; i < platform_io.Viewports.Size; i++) + { + ImGuiViewport* viewport = platform_io.Viewports[i]; + if (viewport->Flags & ImGuiViewportFlags_Minimized) + continue; + if (platform_io.Platform_RenderWindow) platform_io.Platform_RenderWindow(viewport, platform_render_arg); + if (platform_io.Renderer_RenderWindow) platform_io.Renderer_RenderWindow(viewport, renderer_render_arg); + } + for (int i = 1; i < platform_io.Viewports.Size; i++) + { + ImGuiViewport* viewport = platform_io.Viewports[i]; + if (viewport->Flags & ImGuiViewportFlags_Minimized) + continue; + if (platform_io.Platform_SwapBuffers) platform_io.Platform_SwapBuffers(viewport, platform_render_arg); + if (platform_io.Renderer_SwapBuffers) platform_io.Renderer_SwapBuffers(viewport, renderer_render_arg); + } +} + +static int ImGui::FindPlatformMonitorForPos(const ImVec2& pos) +{ + ImGuiContext& g = *GImGui; + for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++) + { + const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[monitor_n]; + if (ImRect(monitor.MainPos, monitor.MainPos + monitor.MainSize).Contains(pos)) + return monitor_n; + } + return -1; +} + +// Search for the monitor with the largest intersection area with the given rectangle +// We generally try to avoid searching loops but the monitor count should be very small here +// FIXME-OPT: We could test the last monitor used for that viewport first, and early +static int ImGui::FindPlatformMonitorForRect(const ImRect& rect) +{ + ImGuiContext& g = *GImGui; + + const int monitor_count = g.PlatformIO.Monitors.Size; + if (monitor_count <= 1) + return monitor_count - 1; + + // Use a minimum threshold of 1.0f so a zero-sized rect won't false positive, and will still find the correct monitor given its position. + // This is necessary for tooltips which always resize down to zero at first. + const float surface_threshold = ImMax(rect.GetWidth() * rect.GetHeight() * 0.5f, 1.0f); + int best_monitor_n = -1; + float best_monitor_surface = 0.001f; + + for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size && best_monitor_surface < surface_threshold; monitor_n++) + { + const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[monitor_n]; + const ImRect monitor_rect = ImRect(monitor.MainPos, monitor.MainPos + monitor.MainSize); + if (monitor_rect.Contains(rect)) + return monitor_n; + ImRect overlapping_rect = rect; + overlapping_rect.ClipWithFull(monitor_rect); + float overlapping_surface = overlapping_rect.GetWidth() * overlapping_rect.GetHeight(); + if (overlapping_surface < best_monitor_surface) + continue; + best_monitor_surface = overlapping_surface; + best_monitor_n = monitor_n; + } + return best_monitor_n; +} + +// Update monitor from viewport rectangle (we'll use this info to clamp windows and save windows lost in a removed monitor) +static void ImGui::UpdateViewportPlatformMonitor(ImGuiViewportP* viewport) +{ + viewport->PlatformMonitor = (short)FindPlatformMonitorForRect(viewport->GetMainRect()); +} + +// Return value is always != NULL, but don't hold on it across frames. +const ImGuiPlatformMonitor* ImGui::GetViewportPlatformMonitor(ImGuiViewport* viewport_p) +{ + ImGuiContext& g = *GImGui; + ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)viewport_p; + int monitor_idx = viewport->PlatformMonitor; + if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size) + return &g.PlatformIO.Monitors[monitor_idx]; + return &g.FallbackMonitor; +} + +void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) +{ + ImGuiContext& g = *GImGui; + if (viewport->PlatformWindowCreated) + { + if (g.PlatformIO.Renderer_DestroyWindow) + g.PlatformIO.Renderer_DestroyWindow(viewport); + if (g.PlatformIO.Platform_DestroyWindow) + g.PlatformIO.Platform_DestroyWindow(viewport); + IM_ASSERT(viewport->RendererUserData == NULL && viewport->PlatformUserData == NULL); + + // Don't clear PlatformWindowCreated for the main viewport, as we initially set that up to true in Initialize() + // The righter way may be to leave it to the backend to set this flag all-together, and made the flag public. + if (viewport->ID != IMGUI_VIEWPORT_DEFAULT_ID) + viewport->PlatformWindowCreated = false; + } + else + { + IM_ASSERT(viewport->RendererUserData == NULL && viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL); + } + viewport->RendererUserData = viewport->PlatformUserData = viewport->PlatformHandle = NULL; + viewport->ClearRequestFlags(); +} + +void ImGui::DestroyPlatformWindows() +{ + // We call the destroy window on every viewport (including the main viewport, index 0) to give a chance to the backend + // to clear any data they may have stored in e.g. PlatformUserData, RendererUserData. + // It is convenient for the platform backend code to store something in the main viewport, in order for e.g. the mouse handling + // code to operator a consistent manner. + // It is expected that the backend can handle calls to Renderer_DestroyWindow/Platform_DestroyWindow without + // crashing if it doesn't have data stored. + ImGuiContext& g = *GImGui; + for (int i = 0; i < g.Viewports.Size; i++) + DestroyPlatformWindow(g.Viewports[i]); +} + + +//----------------------------------------------------------------------------- +// [SECTION] DOCKING +//----------------------------------------------------------------------------- +// Docking: Internal Types +// Docking: Forward Declarations +// Docking: ImGuiDockContext +// Docking: ImGuiDockContext Docking/Undocking functions +// Docking: ImGuiDockNode +// Docking: ImGuiDockNode Tree manipulation functions +// Docking: Public Functions (SetWindowDock, DockSpace, DockSpaceOverViewport) +// Docking: Builder Functions +// Docking: Begin/End Support Functions (called from Begin/End) +// Docking: Settings +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Typical Docking call flow: (root level is generally public API): +//----------------------------------------------------------------------------- +// - NewFrame() new dear imgui frame +// | DockContextNewFrameUpdateUndocking() - process queued undocking requests +// | - DockContextProcessUndockWindow() - process one window undocking request +// | - DockContextProcessUndockNode() - process one whole node undocking request +// | DockContextNewFrameUpdateUndocking() - process queue docking requests, create floating dock nodes +// | - update g.HoveredDockNode - [debug] update node hovered by mouse +// | - DockContextProcessDock() - process one docking request +// | - DockNodeUpdate() +// | - DockNodeUpdateForRootNode() +// | - DockNodeUpdateFlagsAndCollapse() +// | - DockNodeFindInfo() +// | - destroy unused node or tab bar +// | - create dock node host window +// | - Begin() etc. +// | - DockNodeStartMouseMovingWindow() +// | - DockNodeTreeUpdatePosSize() +// | - DockNodeTreeUpdateSplitter() +// | - draw node background +// | - DockNodeUpdateTabBar() - create/update tab bar for a docking node +// | - DockNodeAddTabBar() +// | - DockNodeUpdateWindowMenu() +// | - DockNodeCalcTabBarLayout() +// | - BeginTabBarEx() +// | - TabItemEx() calls +// | - EndTabBar() +// | - BeginDockableDragDropTarget() +// | - DockNodeUpdate() - recurse into child nodes... +//----------------------------------------------------------------------------- +// - DockSpace() user submit a dockspace into a window +// | Begin(Child) - create a child window +// | DockNodeUpdate() - call main dock node update function +// | End(Child) +// | ItemSize() +//----------------------------------------------------------------------------- +// - Begin() +// | BeginDocked() +// | BeginDockableDragDropSource() +// | BeginDockableDragDropTarget() +// | - DockNodePreviewDockRender() +//----------------------------------------------------------------------------- +// - EndFrame() +// | DockContextEndFrame() +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Docking: Internal Types +//----------------------------------------------------------------------------- +// - ImGuiDockRequestType +// - ImGuiDockRequest +// - ImGuiDockPreviewData +// - ImGuiDockNodeSettings +// - ImGuiDockContext +//----------------------------------------------------------------------------- + +enum ImGuiDockRequestType +{ + ImGuiDockRequestType_None = 0, + ImGuiDockRequestType_Dock, + ImGuiDockRequestType_Undock, + ImGuiDockRequestType_Split // Split is the same as Dock but without a DockPayload +}; + +struct ImGuiDockRequest +{ + ImGuiDockRequestType Type; + ImGuiWindow* DockTargetWindow; // Destination/Target Window to dock into (may be a loose window or a DockNode, might be NULL in which case DockTargetNode cannot be NULL) + ImGuiDockNode* DockTargetNode; // Destination/Target Node to dock into + ImGuiWindow* DockPayload; // Source/Payload window to dock (may be a loose window or a DockNode), [Optional] + ImGuiDir DockSplitDir; + float DockSplitRatio; + bool DockSplitOuter; + ImGuiWindow* UndockTargetWindow; + ImGuiDockNode* UndockTargetNode; + + ImGuiDockRequest() + { + Type = ImGuiDockRequestType_None; + DockTargetWindow = DockPayload = UndockTargetWindow = NULL; + DockTargetNode = UndockTargetNode = NULL; + DockSplitDir = ImGuiDir_None; + DockSplitRatio = 0.5f; + DockSplitOuter = false; + } +}; + +struct ImGuiDockPreviewData +{ + ImGuiDockNode FutureNode; + bool IsDropAllowed; + bool IsCenterAvailable; + bool IsSidesAvailable; // Hold your breath, grammar freaks.. + bool IsSplitDirExplicit; // Set when hovered the drop rect (vs. implicit SplitDir==None when hovered the window) + ImGuiDockNode* SplitNode; + ImGuiDir SplitDir; + float SplitRatio; + ImRect DropRectsDraw[ImGuiDir_COUNT + 1]; // May be slightly different from hit-testing drop rects used in DockNodeCalcDropRects() + + ImGuiDockPreviewData() : FutureNode(0) { IsDropAllowed = IsCenterAvailable = IsSidesAvailable = IsSplitDirExplicit = false; SplitNode = NULL; SplitDir = ImGuiDir_None; SplitRatio = 0.f; for (int n = 0; n < IM_ARRAYSIZE(DropRectsDraw); n++) DropRectsDraw[n] = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); } +}; + +// Persistent Settings data, stored contiguously in SettingsNodes (sizeof() ~32 bytes) +struct ImGuiDockNodeSettings +{ + ImGuiID ID; + ImGuiID ParentNodeId; + ImGuiID ParentWindowId; + ImGuiID SelectedTabId; + signed char SplitAxis; + char Depth; + ImGuiDockNodeFlags Flags; // NB: We save individual flags one by one in ascii format (ImGuiDockNodeFlags_SavedFlagsMask_) + ImVec2ih Pos; + ImVec2ih Size; + ImVec2ih SizeRef; + ImGuiDockNodeSettings() { memset(this, 0, sizeof(*this)); SplitAxis = ImGuiAxis_None; } +}; + +//----------------------------------------------------------------------------- +// Docking: Forward Declarations +//----------------------------------------------------------------------------- + +namespace ImGui +{ + // ImGuiDockContext + static ImGuiDockNode* DockContextAddNode(ImGuiContext* ctx, ImGuiID id); + static void DockContextRemoveNode(ImGuiContext* ctx, ImGuiDockNode* node, bool merge_sibling_into_parent_node); + static void DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node); + static void DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req); + static void DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* window, bool clear_persistent_docking_ref = true); + static void DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node); + static void DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx); + static ImGuiDockNode* DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id); + static ImGuiDockNode* DockContextBindNodeToWindow(ImGuiContext* ctx, ImGuiWindow* window); + static void DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count); + static void DockContextBuildAddWindowsToNodes(ImGuiContext* ctx, ImGuiID root_id); // Use root_id==0 to add all + + // ImGuiDockNode + static void DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, bool add_to_tab_bar); + static void DockNodeMoveWindows(ImGuiDockNode* dst_node, ImGuiDockNode* src_node); + static void DockNodeMoveChildNodes(ImGuiDockNode* dst_node, ImGuiDockNode* src_node); + static ImGuiWindow* DockNodeFindWindowByID(ImGuiDockNode* node, ImGuiID id); + static void DockNodeApplyPosSizeToWindows(ImGuiDockNode* node); + static void DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window, ImGuiID save_dock_id); + static void DockNodeHideHostWindow(ImGuiDockNode* node); + static void DockNodeUpdate(ImGuiDockNode* node); + static void DockNodeUpdateForRootNode(ImGuiDockNode* node); + static void DockNodeUpdateFlagsAndCollapse(ImGuiDockNode* node); + static void DockNodeUpdateHasCentralNodeChild(ImGuiDockNode* node); + static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window); + static void DockNodeAddTabBar(ImGuiDockNode* node); + static void DockNodeRemoveTabBar(ImGuiDockNode* node); + static ImGuiID DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar); + static void DockNodeUpdateVisibleFlag(ImGuiDockNode* node); + static void DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window); + static bool DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window); + static void DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking); + static void DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data); + static void DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_window_menu_button_pos, ImVec2* out_close_button_pos); + static void DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired); + static bool DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking, ImVec2* test_mouse_pos); + static const char* DockNodeGetHostWindowTitle(ImGuiDockNode* node, char* buf, int buf_size) { ImFormatString(buf, buf_size, "##DockNode_%02X", node->ID); return buf; } + static int DockNodeGetTabOrder(ImGuiWindow* window); + + // ImGuiDockNode tree manipulations + static void DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiAxis split_axis, int split_first_child, float split_ratio, ImGuiDockNode* new_node); + static void DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiDockNode* merge_lead_child); + static void DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, ImGuiDockNode* only_write_to_single_node = NULL); + static void DockNodeTreeUpdateSplitter(ImGuiDockNode* node); + static ImGuiDockNode* DockNodeTreeFindVisibleNodeByPos(ImGuiDockNode* node, ImVec2 pos); + static ImGuiDockNode* DockNodeTreeFindFallbackLeafNode(ImGuiDockNode* node); + + // Settings + static void DockSettingsRenameNodeReferences(ImGuiID old_node_id, ImGuiID new_node_id); + static void DockSettingsRemoveNodeReferences(ImGuiID* node_ids, int node_ids_count); + static ImGuiDockNodeSettings* DockSettingsFindNodeSettings(ImGuiContext* ctx, ImGuiID node_id); + static void DockSettingsHandler_ClearAll(ImGuiContext*, ImGuiSettingsHandler*); + static void DockSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*); + static void* DockSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name); + static void DockSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line); + static void DockSettingsHandler_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf); +} + +//----------------------------------------------------------------------------- +// Docking: ImGuiDockContext +//----------------------------------------------------------------------------- +// The lifetime model is different from the one of regular windows: we always create a ImGuiDockNode for each ImGuiDockNodeSettings, +// or we always hold the entire docking node tree. Nodes are frequently hidden, e.g. if the window(s) or child nodes they host are not active. +// At boot time only, we run a simple GC to remove nodes that have no references. +// Because dock node settings (which are small, contiguous structures) are always mirrored by their corresponding dock nodes (more complete structures), +// we can also very easily recreate the nodes from scratch given the settings data (this is what DockContextRebuild() does). +// This is convenient as docking reconfiguration can be implemented by mostly poking at the simpler settings data. +//----------------------------------------------------------------------------- +// - DockContextInitialize() +// - DockContextShutdown() +// - DockContextClearNodes() +// - DockContextRebuildNodes() +// - DockContextNewFrameUpdateUndocking() +// - DockContextNewFrameUpdateDocking() +// - DockContextEndFrame() +// - DockContextFindNodeByID() +// - DockContextBindNodeToWindow() +// - DockContextGenNodeID() +// - DockContextAddNode() +// - DockContextRemoveNode() +// - ImGuiDockContextPruneNodeData +// - DockContextPruneUnusedSettingsNodes() +// - DockContextBuildNodesFromSettings() +// - DockContextBuildAddWindowsToNodes() +//----------------------------------------------------------------------------- + +void ImGui::DockContextInitialize(ImGuiContext* ctx) +{ + ImGuiContext& g = *ctx; + + // Add .ini handle for persistent docking data + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Docking"; + ini_handler.TypeHash = ImHashStr("Docking"); + ini_handler.ClearAllFn = DockSettingsHandler_ClearAll; + ini_handler.ReadInitFn = DockSettingsHandler_ClearAll; // Also clear on read + ini_handler.ReadOpenFn = DockSettingsHandler_ReadOpen; + ini_handler.ReadLineFn = DockSettingsHandler_ReadLine; + ini_handler.ApplyAllFn = DockSettingsHandler_ApplyAll; + ini_handler.WriteAllFn = DockSettingsHandler_WriteAll; + g.SettingsHandlers.push_back(ini_handler); +} + +void ImGui::DockContextShutdown(ImGuiContext* ctx) +{ + ImGuiDockContext* dc = &ctx->DockContext; + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + IM_DELETE(node); +} + +void ImGui::DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs) +{ + IM_UNUSED(ctx); + IM_ASSERT(ctx == GImGui); + DockBuilderRemoveNodeDockedWindows(root_id, clear_settings_refs); + DockBuilderRemoveNodeChildNodes(root_id); +} + +// [DEBUG] This function also acts as a defacto test to make sure we can rebuild from scratch without a glitch +// (Different from DockSettingsHandler_ClearAll() + DockSettingsHandler_ApplyAll() because this reuses current settings!) +void ImGui::DockContextRebuildNodes(ImGuiContext* ctx) +{ + IMGUI_DEBUG_LOG_DOCKING("DockContextRebuild()\n"); + ImGuiDockContext* dc = &ctx->DockContext; + SaveIniSettingsToMemory(); + ImGuiID root_id = 0; // Rebuild all + DockContextClearNodes(ctx, root_id, false); + DockContextBuildNodesFromSettings(ctx, dc->NodesSettings.Data, dc->NodesSettings.Size); + DockContextBuildAddWindowsToNodes(ctx, root_id); +} + +// Docking context update function, called by NewFrame() +void ImGui::DockContextNewFrameUpdateUndocking(ImGuiContext* ctx) +{ + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &ctx->DockContext; + if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) + { + if (dc->Nodes.Data.Size > 0 || dc->Requests.Size > 0) + DockContextClearNodes(ctx, 0, true); + return; + } + + // Setting NoSplit at runtime merges all nodes + if (g.IO.ConfigDockingNoSplit) + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (node->IsRootNode() && node->IsSplitNode()) + { + DockBuilderRemoveNodeChildNodes(node->ID); + //dc->WantFullRebuild = true; + } + + // Process full rebuild +#if 0 + if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C))) + dc->WantFullRebuild = true; +#endif + if (dc->WantFullRebuild) + { + DockContextRebuildNodes(ctx); + dc->WantFullRebuild = false; + } + + // Process Undocking requests (we need to process them _before_ the UpdateMouseMovingWindowNewFrame call in NewFrame) + for (int n = 0; n < dc->Requests.Size; n++) + { + ImGuiDockRequest* req = &dc->Requests[n]; + if (req->Type == ImGuiDockRequestType_Undock && req->UndockTargetWindow) + DockContextProcessUndockWindow(ctx, req->UndockTargetWindow); + else if (req->Type == ImGuiDockRequestType_Undock && req->UndockTargetNode) + DockContextProcessUndockNode(ctx, req->UndockTargetNode); + } +} + +// Docking context update function, called by NewFrame() +void ImGui::DockContextNewFrameUpdateDocking(ImGuiContext* ctx) +{ + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &ctx->DockContext; + if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) + return; + + // [DEBUG] Store hovered dock node. + // We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut. + // Note this is mostly a debug thing and isn't actually used for docking target, because docking involve more detailed filtering. + g.HoveredDockNode = NULL; + if (ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow) + { + if (hovered_window->DockNodeAsHost) + g.HoveredDockNode = DockNodeTreeFindVisibleNodeByPos(hovered_window->DockNodeAsHost, g.IO.MousePos); + else if (hovered_window->RootWindow->DockNode) + g.HoveredDockNode = hovered_window->RootWindow->DockNode; + } + + // Process Docking requests + for (int n = 0; n < dc->Requests.Size; n++) + if (dc->Requests[n].Type == ImGuiDockRequestType_Dock) + DockContextProcessDock(ctx, &dc->Requests[n]); + dc->Requests.resize(0); + + // Create windows for each automatic docking nodes + // We can have NULL pointers when we delete nodes, but because ID are recycled this should amortize nicely (and our node count will never be very high) + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (node->IsFloatingNode()) + DockNodeUpdate(node); +} + +void ImGui::DockContextEndFrame(ImGuiContext* ctx) +{ + // Draw backgrounds of node missing their window + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &g.DockContext; + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (node->LastFrameActive == g.FrameCount && node->IsVisible && node->HostWindow && node->IsLeafNode() && !node->IsBgDrawnThisFrame) + { + ImRect bg_rect(node->Pos + ImVec2(0.0f, GetFrameHeight()), node->Pos + node->Size); + ImDrawFlags bg_rounding_flags = CalcRoundingFlagsForRectInRect(bg_rect, node->HostWindow->Rect(), DOCKING_SPLITTER_SIZE); + node->HostWindow->DrawList->ChannelsSetCurrent(0); + node->HostWindow->DrawList->AddRectFilled(bg_rect.Min, bg_rect.Max, node->LastBgColor, node->HostWindow->WindowRounding, bg_rounding_flags); + } +} + +static ImGuiDockNode* ImGui::DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id) +{ + return (ImGuiDockNode*)ctx->DockContext.Nodes.GetVoidPtr(id); +} + +ImGuiID ImGui::DockContextGenNodeID(ImGuiContext* ctx) +{ + // Generate an ID for new node (the exact ID value doesn't matter as long as it is not already used) + // FIXME-OPT FIXME-DOCK: This is suboptimal, even if the node count is small enough not to be a worry.0 + // We should poke in ctx->Nodes to find a suitable ID faster. Even more so trivial that ctx->Nodes lookup is already sorted. + ImGuiID id = 0x0001; + while (DockContextFindNodeByID(ctx, id) != NULL) + id++; + return id; +} + +static ImGuiDockNode* ImGui::DockContextAddNode(ImGuiContext* ctx, ImGuiID id) +{ + // Generate an ID for the new node (the exact ID value doesn't matter as long as it is not already used) and add the first window. + if (id == 0) + id = DockContextGenNodeID(ctx); + else + IM_ASSERT(DockContextFindNodeByID(ctx, id) == NULL); + + // We don't set node->LastFrameAlive on construction. Nodes are always created at all time to reflect .ini settings! + IMGUI_DEBUG_LOG_DOCKING("DockContextAddNode 0x%08X\n", id); + ImGuiDockNode* node = IM_NEW(ImGuiDockNode)(id); + ctx->DockContext.Nodes.SetVoidPtr(node->ID, node); + return node; +} + +static void ImGui::DockContextRemoveNode(ImGuiContext* ctx, ImGuiDockNode* node, bool merge_sibling_into_parent_node) +{ + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &ctx->DockContext; + + IMGUI_DEBUG_LOG_DOCKING("DockContextRemoveNode 0x%08X\n", node->ID); + IM_ASSERT(DockContextFindNodeByID(ctx, node->ID) == node); + IM_ASSERT(node->ChildNodes[0] == NULL && node->ChildNodes[1] == NULL); + IM_ASSERT(node->Windows.Size == 0); + + if (node->HostWindow) + node->HostWindow->DockNodeAsHost = NULL; + + ImGuiDockNode* parent_node = node->ParentNode; + const bool merge = (merge_sibling_into_parent_node && parent_node != NULL); + if (merge) + { + IM_ASSERT(parent_node->ChildNodes[0] == node || parent_node->ChildNodes[1] == node); + ImGuiDockNode* sibling_node = (parent_node->ChildNodes[0] == node ? parent_node->ChildNodes[1] : parent_node->ChildNodes[0]); + DockNodeTreeMerge(&g, parent_node, sibling_node); + } + else + { + for (int n = 0; parent_node && n < IM_ARRAYSIZE(parent_node->ChildNodes); n++) + if (parent_node->ChildNodes[n] == node) + node->ParentNode->ChildNodes[n] = NULL; + dc->Nodes.SetVoidPtr(node->ID, NULL); + IM_DELETE(node); + } +} + +static int IMGUI_CDECL DockNodeComparerDepthMostFirst(const void* lhs, const void* rhs) +{ + const ImGuiDockNode* a = *(const ImGuiDockNode* const*)lhs; + const ImGuiDockNode* b = *(const ImGuiDockNode* const*)rhs; + return ImGui::DockNodeGetDepth(b) - ImGui::DockNodeGetDepth(a); +} + +// Pre C++0x doesn't allow us to use a function-local type (without linkage) as template parameter, so we moved this here. +struct ImGuiDockContextPruneNodeData +{ + int CountWindows, CountChildWindows, CountChildNodes; + ImGuiID RootId; + ImGuiDockContextPruneNodeData() { CountWindows = CountChildWindows = CountChildNodes = 0; RootId = 0; } +}; + +// Garbage collect unused nodes (run once at init time) +static void ImGui::DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx) +{ + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &ctx->DockContext; + IM_ASSERT(g.Windows.Size == 0); + + ImPool pool; + pool.Reserve(dc->NodesSettings.Size); + + // Count child nodes and compute RootID + for (int settings_n = 0; settings_n < dc->NodesSettings.Size; settings_n++) + { + ImGuiDockNodeSettings* settings = &dc->NodesSettings[settings_n]; + ImGuiDockContextPruneNodeData* parent_data = settings->ParentNodeId ? pool.GetByKey(settings->ParentNodeId) : 0; + pool.GetOrAddByKey(settings->ID)->RootId = parent_data ? parent_data->RootId : settings->ID; + if (settings->ParentNodeId) + pool.GetOrAddByKey(settings->ParentNodeId)->CountChildNodes++; + } + + // Count reference to dock ids from dockspaces + // We track the 'auto-DockNode <- manual-Window <- manual-DockSpace' in order to avoid 'auto-DockNode' being ditched by DockContextPruneUnusedSettingsNodes() + for (int settings_n = 0; settings_n < dc->NodesSettings.Size; settings_n++) + { + ImGuiDockNodeSettings* settings = &dc->NodesSettings[settings_n]; + if (settings->ParentWindowId != 0) + if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->ParentWindowId)) + if (window_settings->DockId) + if (ImGuiDockContextPruneNodeData* data = pool.GetByKey(window_settings->DockId)) + data->CountChildNodes++; + } + + // Count reference to dock ids from window settings + // We guard against the possibility of an invalid .ini file (RootID may point to a missing node) + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (ImGuiID dock_id = settings->DockId) + if (ImGuiDockContextPruneNodeData* data = pool.GetByKey(dock_id)) + { + data->CountWindows++; + if (ImGuiDockContextPruneNodeData* data_root = (data->RootId == dock_id) ? data : pool.GetByKey(data->RootId)) + data_root->CountChildWindows++; + } + + // Prune + for (int settings_n = 0; settings_n < dc->NodesSettings.Size; settings_n++) + { + ImGuiDockNodeSettings* settings = &dc->NodesSettings[settings_n]; + ImGuiDockContextPruneNodeData* data = pool.GetByKey(settings->ID); + if (data->CountWindows > 1) + continue; + ImGuiDockContextPruneNodeData* data_root = (data->RootId == settings->ID) ? data : pool.GetByKey(data->RootId); + + bool remove = false; + remove |= (data->CountWindows == 1 && settings->ParentNodeId == 0 && data->CountChildNodes == 0 && !(settings->Flags & ImGuiDockNodeFlags_CentralNode)); // Floating root node with only 1 window + remove |= (data->CountWindows == 0 && settings->ParentNodeId == 0 && data->CountChildNodes == 0); // Leaf nodes with 0 window + remove |= (data_root->CountChildWindows == 0); + if (remove) + { + IMGUI_DEBUG_LOG_DOCKING("DockContextPruneUnusedSettingsNodes: Prune 0x%08X\n", settings->ID); + DockSettingsRemoveNodeReferences(&settings->ID, 1); + settings->ID = 0; + } + } +} + +static void ImGui::DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count) +{ + // Build nodes + for (int node_n = 0; node_n < node_settings_count; node_n++) + { + ImGuiDockNodeSettings* settings = &node_settings_array[node_n]; + if (settings->ID == 0) + continue; + ImGuiDockNode* node = DockContextAddNode(ctx, settings->ID); + node->ParentNode = settings->ParentNodeId ? DockContextFindNodeByID(ctx, settings->ParentNodeId) : NULL; + node->Pos = ImVec2(settings->Pos.x, settings->Pos.y); + node->Size = ImVec2(settings->Size.x, settings->Size.y); + node->SizeRef = ImVec2(settings->SizeRef.x, settings->SizeRef.y); + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_DockNode; + if (node->ParentNode && node->ParentNode->ChildNodes[0] == NULL) + node->ParentNode->ChildNodes[0] = node; + else if (node->ParentNode && node->ParentNode->ChildNodes[1] == NULL) + node->ParentNode->ChildNodes[1] = node; + node->SelectedTabId = settings->SelectedTabId; + node->SplitAxis = (ImGuiAxis)settings->SplitAxis; + node->SetLocalFlags(settings->Flags & ImGuiDockNodeFlags_SavedFlagsMask_); + + // Bind host window immediately if it already exist (in case of a rebuild) + // This is useful as the RootWindowForTitleBarHighlight links necessary to highlight the currently focused node requires node->HostWindow to be set. + char host_window_title[20]; + ImGuiDockNode* root_node = DockNodeGetRootNode(node); + node->HostWindow = FindWindowByName(DockNodeGetHostWindowTitle(root_node, host_window_title, IM_ARRAYSIZE(host_window_title))); + } +} + +void ImGui::DockContextBuildAddWindowsToNodes(ImGuiContext* ctx, ImGuiID root_id) +{ + // Rebind all windows to nodes (they can also lazily rebind but we'll have a visible glitch during the first frame) + ImGuiContext& g = *ctx; + for (int n = 0; n < g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + if (window->DockId == 0 || window->LastFrameActive < g.FrameCount - 1) + continue; + if (window->DockNode != NULL) + continue; + + ImGuiDockNode* node = DockContextFindNodeByID(ctx, window->DockId); + IM_ASSERT(node != NULL); // This should have been called after DockContextBuildNodesFromSettings() + if (root_id == 0 || DockNodeGetRootNode(node)->ID == root_id) + DockNodeAddWindow(node, window, true); + } +} + +//----------------------------------------------------------------------------- +// Docking: ImGuiDockContext Docking/Undocking functions +//----------------------------------------------------------------------------- +// - DockContextQueueDock() +// - DockContextQueueUndockWindow() +// - DockContextQueueUndockNode() +// - DockContextQueueNotifyRemovedNode() +// - DockContextProcessDock() +// - DockContextProcessUndockWindow() +// - DockContextProcessUndockNode() +// - DockContextCalcDropPosForDocking() +//----------------------------------------------------------------------------- + +void ImGui::DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer) +{ + IM_ASSERT(target != payload); + ImGuiDockRequest req; + req.Type = ImGuiDockRequestType_Dock; + req.DockTargetWindow = target; + req.DockTargetNode = target_node; + req.DockPayload = payload; + req.DockSplitDir = split_dir; + req.DockSplitRatio = split_ratio; + req.DockSplitOuter = split_outer; + ctx->DockContext.Requests.push_back(req); +} + +void ImGui::DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window) +{ + ImGuiDockRequest req; + req.Type = ImGuiDockRequestType_Undock; + req.UndockTargetWindow = window; + ctx->DockContext.Requests.push_back(req); +} + +void ImGui::DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) +{ + ImGuiDockRequest req; + req.Type = ImGuiDockRequestType_Undock; + req.UndockTargetNode = node; + ctx->DockContext.Requests.push_back(req); +} + +void ImGui::DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node) +{ + ImGuiDockContext* dc = &ctx->DockContext; + for (int n = 0; n < dc->Requests.Size; n++) + if (dc->Requests[n].DockTargetNode == node) + dc->Requests[n].Type = ImGuiDockRequestType_None; +} + +void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req) +{ + IM_ASSERT((req->Type == ImGuiDockRequestType_Dock && req->DockPayload != NULL) || (req->Type == ImGuiDockRequestType_Split && req->DockPayload == NULL)); + IM_ASSERT(req->DockTargetWindow != NULL || req->DockTargetNode != NULL); + + ImGuiContext& g = *ctx; + IM_UNUSED(g); + + ImGuiWindow* payload_window = req->DockPayload; // Optional + ImGuiWindow* target_window = req->DockTargetWindow; + ImGuiDockNode* node = req->DockTargetNode; + if (payload_window) + IMGUI_DEBUG_LOG_DOCKING("DockContextProcessDock node 0x%08X target '%s' dock window '%s', split_dir %d\n", node ? node->ID : 0, target_window ? target_window->Name : "NULL", payload_window ? payload_window->Name : "NULL", req->DockSplitDir); + else + IMGUI_DEBUG_LOG_DOCKING("DockContextProcessDock node 0x%08X, split_dir %d\n", node ? node->ID : 0, req->DockSplitDir); + + // Decide which Tab will be selected at the end of the operation + ImGuiID next_selected_id = 0; + ImGuiDockNode* payload_node = NULL; + if (payload_window) + { + payload_node = payload_window->DockNodeAsHost; + payload_window->DockNodeAsHost = NULL; // Important to clear this as the node will have its life as a child which might be merged/deleted later. + if (payload_node && payload_node->IsLeafNode()) + next_selected_id = payload_node->TabBar->NextSelectedTabId ? payload_node->TabBar->NextSelectedTabId : payload_node->TabBar->SelectedTabId; + if (payload_node == NULL) + next_selected_id = payload_window->TabId; + } + + // FIXME-DOCK: When we are trying to dock an existing single-window node into a loose window, transfer Node ID as well + // When processing an interactive split, usually LastFrameAlive will be < g.FrameCount. But DockBuilder operations can make it ==. + if (node) + IM_ASSERT(node->LastFrameAlive <= g.FrameCount); + if (node && target_window && node == target_window->DockNodeAsHost) + IM_ASSERT(node->Windows.Size > 0 || node->IsSplitNode() || node->IsCentralNode()); + + // Create new node and add existing window to it + if (node == NULL) + { + node = DockContextAddNode(ctx, 0); + node->Pos = target_window->Pos; + node->Size = target_window->Size; + if (target_window->DockNodeAsHost == NULL) + { + DockNodeAddWindow(node, target_window, true); + node->TabBar->Tabs[0].Flags &= ~ImGuiTabItemFlags_Unsorted; + target_window->DockIsActive = true; + } + } + + ImGuiDir split_dir = req->DockSplitDir; + if (split_dir != ImGuiDir_None) + { + // Split into two, one side will be our payload node unless we are dropping a loose window + const ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; + const int split_inheritor_child_idx = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 1 : 0; // Current contents will be moved to the opposite side + const float split_ratio = req->DockSplitRatio; + DockNodeTreeSplit(ctx, node, split_axis, split_inheritor_child_idx, split_ratio, payload_node); // payload_node may be NULL here! + ImGuiDockNode* new_node = node->ChildNodes[split_inheritor_child_idx ^ 1]; + new_node->HostWindow = node->HostWindow; + node = new_node; + } + node->SetLocalFlags(node->LocalFlags & ~ImGuiDockNodeFlags_HiddenTabBar); + + if (node != payload_node) + { + // Create tab bar before we call DockNodeMoveWindows (which would attempt to move the old tab-bar, which would lead us to payload tabs wrongly appearing before target tabs!) + if (node->Windows.Size > 0 && node->TabBar == NULL) + { + DockNodeAddTabBar(node); + for (int n = 0; n < node->Windows.Size; n++) + TabBarAddTab(node->TabBar, ImGuiTabItemFlags_None, node->Windows[n]); + } + + if (payload_node != NULL) + { + // Transfer full payload node (with 1+ child windows or child nodes) + if (payload_node->IsSplitNode()) + { + if (node->Windows.Size > 0) + { + // We can dock a split payload into a node that already has windows _only_ if our payload is a node tree with a single visible node. + // In this situation, we move the windows of the target node into the currently visible node of the payload. + // This allows us to preserve some of the underlying dock tree settings nicely. + IM_ASSERT(payload_node->OnlyNodeWithWindows != NULL); // The docking should have been blocked by DockNodePreviewDockSetup() early on and never submitted. + ImGuiDockNode* visible_node = payload_node->OnlyNodeWithWindows; + if (visible_node->TabBar) + IM_ASSERT(visible_node->TabBar->Tabs.Size > 0); + DockNodeMoveWindows(node, visible_node); + DockNodeMoveWindows(visible_node, node); + DockSettingsRenameNodeReferences(node->ID, visible_node->ID); + } + if (node->IsCentralNode()) + { + // Central node property needs to be moved to a leaf node, pick the last focused one. + // FIXME-DOCK: If we had to transfer other flags here, what would the policy be? + ImGuiDockNode* last_focused_node = DockContextFindNodeByID(ctx, payload_node->LastFocusedNodeId); + IM_ASSERT(last_focused_node != NULL); + ImGuiDockNode* last_focused_root_node = DockNodeGetRootNode(last_focused_node); + IM_ASSERT(last_focused_root_node == DockNodeGetRootNode(payload_node)); + last_focused_node->SetLocalFlags(last_focused_node->LocalFlags | ImGuiDockNodeFlags_CentralNode); + node->SetLocalFlags(node->LocalFlags & ~ImGuiDockNodeFlags_CentralNode); + last_focused_root_node->CentralNode = last_focused_node; + } + + IM_ASSERT(node->Windows.Size == 0); + DockNodeMoveChildNodes(node, payload_node); + } + else + { + const ImGuiID payload_dock_id = payload_node->ID; + DockNodeMoveWindows(node, payload_node); + DockSettingsRenameNodeReferences(payload_dock_id, node->ID); + } + DockContextRemoveNode(ctx, payload_node, true); + } + else if (payload_window) + { + // Transfer single window + const ImGuiID payload_dock_id = payload_window->DockId; + node->VisibleWindow = payload_window; + DockNodeAddWindow(node, payload_window, true); + if (payload_dock_id != 0) + DockSettingsRenameNodeReferences(payload_dock_id, node->ID); + } + } + else + { + // When docking a floating single window node we want to reevaluate auto-hiding of the tab bar + node->WantHiddenTabBarUpdate = true; + } + + // Update selection immediately + if (ImGuiTabBar* tab_bar = node->TabBar) + tab_bar->NextSelectedTabId = next_selected_id; + MarkIniSettingsDirty(); +} + +// Problem: +// Undocking a large (~full screen) window would leave it so large that the bottom right sizing corner would more +// than likely be off the screen and the window would be hard to resize to fit on screen. This can be particularly problematic +// with 'ConfigWindowsMoveFromTitleBarOnly=true' and/or with 'ConfigWindowsResizeFromEdges=false' as well (the later can be +// due to missing ImGuiBackendFlags_HasMouseCursors backend flag). +// Solution: +// When undocking a window we currently force its maximum size to 90% of the host viewport or monitor. +// Reevaluate this when we implement preserving docked/undocked size ("docking_wip/undocked_size" branch). +static ImVec2 FixLargeWindowsWhenUndocking(const ImVec2& size, ImGuiViewport* ref_viewport) +{ + if (ref_viewport == NULL) + return size; + + ImGuiContext& g = *GImGui; + ImVec2 max_size = ImFloor(ref_viewport->WorkSize * 0.90f); + if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) + { + const ImGuiPlatformMonitor* monitor = ImGui::GetViewportPlatformMonitor(ref_viewport); + max_size = ImFloor(monitor->WorkSize * 0.90f); + } + return ImMin(size, max_size); +} + +void ImGui::DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* window, bool clear_persistent_docking_ref) +{ + IMGUI_DEBUG_LOG_DOCKING("DockContextProcessUndockWindow window '%s', clear_persistent_docking_ref = %d\n", window->Name, clear_persistent_docking_ref); + IM_UNUSED(ctx); + if (window->DockNode) + DockNodeRemoveWindow(window->DockNode, window, clear_persistent_docking_ref ? 0 : window->DockId); + else + window->DockId = 0; + window->Collapsed = false; + window->DockIsActive = false; + window->DockNodeIsVisible = window->DockTabIsVisible = false; + window->Size = window->SizeFull = FixLargeWindowsWhenUndocking(window->SizeFull, window->Viewport); + + MarkIniSettingsDirty(); +} + +void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) +{ + IMGUI_DEBUG_LOG_DOCKING("DockContextProcessUndockNode node %08X\n", node->ID); + IM_ASSERT(node->IsLeafNode()); + IM_ASSERT(node->Windows.Size >= 1); + + if (node->IsRootNode() || node->IsCentralNode()) + { + // In the case of a root node or central node, the node will have to stay in place. Create a new node to receive the payload. + ImGuiDockNode* new_node = DockContextAddNode(ctx, 0); + new_node->Pos = node->Pos; + new_node->Size = node->Size; + new_node->SizeRef = node->SizeRef; + DockNodeMoveWindows(new_node, node); + DockSettingsRenameNodeReferences(node->ID, new_node->ID); + for (int n = 0; n < new_node->Windows.Size; n++) + { + ImGuiWindow* window = new_node->Windows[n]; + window->Flags &= ~ImGuiWindowFlags_ChildWindow; + if (window->ParentWindow) + window->ParentWindow->DC.ChildWindows.find_erase(window); + UpdateWindowParentAndRootLinks(window, window->Flags, NULL); + } + node = new_node; + } + else + { + // Otherwise extract our node and merge our sibling back into the parent node. + IM_ASSERT(node->ParentNode->ChildNodes[0] == node || node->ParentNode->ChildNodes[1] == node); + int index_in_parent = (node->ParentNode->ChildNodes[0] == node) ? 0 : 1; + node->ParentNode->ChildNodes[index_in_parent] = NULL; + DockNodeTreeMerge(ctx, node->ParentNode, node->ParentNode->ChildNodes[index_in_parent ^ 1]); + node->ParentNode->AuthorityForViewport = ImGuiDataAuthority_Window; // The node that stays in place keeps the viewport, so our newly dragged out node will create a new viewport + node->ParentNode = NULL; + } + node->AuthorityForPos = node->AuthorityForSize = ImGuiDataAuthority_DockNode; + node->Size = FixLargeWindowsWhenUndocking(node->Size, node->Windows[0]->Viewport); + node->WantMouseMove = true; + MarkIniSettingsDirty(); +} + +// This is mostly used for automation. +bool ImGui::DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos) +{ + // In DockNodePreviewDockSetup() for a root central node instead of showing both "inner" and "outer" drop rects + // (which would be functionally identical) we only show the outer one. Reflect this here. + if (target_node && target_node->ParentNode == NULL && target_node->IsCentralNode() && split_dir != ImGuiDir_None) + split_outer = true; + ImGuiDockPreviewData split_data; + DockNodePreviewDockSetup(target, target_node, payload, &split_data, false, split_outer); + if (split_data.DropRectsDraw[split_dir+1].IsInverted()) + return false; + *out_pos = split_data.DropRectsDraw[split_dir+1].GetCenter(); + return true; +} + +//----------------------------------------------------------------------------- +// Docking: ImGuiDockNode +//----------------------------------------------------------------------------- +// - DockNodeGetTabOrder() +// - DockNodeAddWindow() +// - DockNodeRemoveWindow() +// - DockNodeMoveChildNodes() +// - DockNodeMoveWindows() +// - DockNodeApplyPosSizeToWindows() +// - DockNodeHideHostWindow() +// - ImGuiDockNodeFindInfoResults +// - DockNodeFindInfo() +// - DockNodeFindWindowByID() +// - DockNodeUpdateFlagsAndCollapse() +// - DockNodeUpdateHasCentralNodeFlag() +// - DockNodeUpdateVisibleFlag() +// - DockNodeStartMouseMovingWindow() +// - DockNodeUpdate() +// - DockNodeUpdateWindowMenu() +// - DockNodeBeginAmendTabBar() +// - DockNodeEndAmendTabBar() +// - DockNodeUpdateTabBar() +// - DockNodeAddTabBar() +// - DockNodeRemoveTabBar() +// - DockNodeIsDropAllowedOne() +// - DockNodeIsDropAllowed() +// - DockNodeCalcTabBarLayout() +// - DockNodeCalcSplitRects() +// - DockNodeCalcDropRectsAndTestMousePos() +// - DockNodePreviewDockSetup() +// - DockNodePreviewDockRender() +//----------------------------------------------------------------------------- + +ImGuiDockNode::ImGuiDockNode(ImGuiID id) +{ + ID = id; + SharedFlags = LocalFlags = LocalFlagsInWindows = MergedFlags = ImGuiDockNodeFlags_None; + ParentNode = ChildNodes[0] = ChildNodes[1] = NULL; + TabBar = NULL; + SplitAxis = ImGuiAxis_None; + + State = ImGuiDockNodeState_Unknown; + LastBgColor = IM_COL32_WHITE; + HostWindow = VisibleWindow = NULL; + CentralNode = OnlyNodeWithWindows = NULL; + CountNodeWithWindows = 0; + LastFrameAlive = LastFrameActive = LastFrameFocused = -1; + LastFocusedNodeId = 0; + SelectedTabId = 0; + WantCloseTabId = 0; + AuthorityForPos = AuthorityForSize = ImGuiDataAuthority_DockNode; + AuthorityForViewport = ImGuiDataAuthority_Auto; + IsVisible = true; + IsFocused = HasCloseButton = HasWindowMenuButton = HasCentralNodeChild = false; + IsBgDrawnThisFrame = false; + WantCloseAll = WantLockSizeOnce = WantMouseMove = WantHiddenTabBarUpdate = WantHiddenTabBarToggle = false; +} + +ImGuiDockNode::~ImGuiDockNode() +{ + IM_DELETE(TabBar); + TabBar = NULL; + ChildNodes[0] = ChildNodes[1] = NULL; +} + +int ImGui::DockNodeGetTabOrder(ImGuiWindow* window) +{ + ImGuiTabBar* tab_bar = window->DockNode->TabBar; + if (tab_bar == NULL) + return -1; + ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, window->TabId); + return tab ? tab_bar->GetTabOrder(tab) : -1; +} + +static void DockNodeHideWindowDuringHostWindowCreation(ImGuiWindow* window) +{ + window->Hidden = true; + window->HiddenFramesCanSkipItems = window->Active ? 1 : 2; +} + +static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, bool add_to_tab_bar) +{ + ImGuiContext& g = *GImGui; (void)g; + if (window->DockNode) + { + // Can overwrite an existing window->DockNode (e.g. pointing to a disabled DockSpace node) + IM_ASSERT(window->DockNode->ID != node->ID); + DockNodeRemoveWindow(window->DockNode, window, 0); + } + IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL); + IMGUI_DEBUG_LOG_DOCKING("DockNodeAddWindow node 0x%08X window '%s'\n", node->ID, window->Name); + + // If more than 2 windows appeared on the same frame leading to the creation of a new hosting window, + // we'll hide windows until the host window is ready. Hide the 1st window after its been output (so it is not visible for one frame). + // We will call DockNodeHideWindowDuringHostWindowCreation() on ourselves in Begin() + if (node->HostWindow == NULL && node->Windows.Size == 1 && node->Windows[0]->WasActive == false) + DockNodeHideWindowDuringHostWindowCreation(node->Windows[0]); + + node->Windows.push_back(window); + node->WantHiddenTabBarUpdate = true; + window->DockNode = node; + window->DockId = node->ID; + window->DockIsActive = (node->Windows.Size > 1); + window->DockTabWantClose = false; + + // When reactivating a node with one or two loose window, the window pos/size/viewport are authoritative over the node storage. + // In particular it is important we init the viewport from the first window so we don't create two viewports and drop one. + if (node->HostWindow == NULL && node->IsFloatingNode()) + { + if (node->AuthorityForPos == ImGuiDataAuthority_Auto) + node->AuthorityForPos = ImGuiDataAuthority_Window; + if (node->AuthorityForSize == ImGuiDataAuthority_Auto) + node->AuthorityForSize = ImGuiDataAuthority_Window; + if (node->AuthorityForViewport == ImGuiDataAuthority_Auto) + node->AuthorityForViewport = ImGuiDataAuthority_Window; + } + + // Add to tab bar if requested + if (add_to_tab_bar) + { + if (node->TabBar == NULL) + { + DockNodeAddTabBar(node); + node->TabBar->SelectedTabId = node->TabBar->NextSelectedTabId = node->SelectedTabId; + + // Add existing windows + for (int n = 0; n < node->Windows.Size - 1; n++) + TabBarAddTab(node->TabBar, ImGuiTabItemFlags_None, node->Windows[n]); + } + TabBarAddTab(node->TabBar, ImGuiTabItemFlags_Unsorted, window); + } + + DockNodeUpdateVisibleFlag(node); + + // Update this without waiting for the next time we Begin() in the window, so our host window will have the proper title bar color on its first frame. + if (node->HostWindow) + UpdateWindowParentAndRootLinks(window, window->Flags | ImGuiWindowFlags_ChildWindow, node->HostWindow); +} + +static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window, ImGuiID save_dock_id) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(window->DockNode == node); + //IM_ASSERT(window->RootWindowDockTree == node->HostWindow); + //IM_ASSERT(window->LastFrameActive < g.FrameCount); // We may call this from Begin() + IM_ASSERT(save_dock_id == 0 || save_dock_id == node->ID); + IMGUI_DEBUG_LOG_DOCKING("DockNodeRemoveWindow node 0x%08X window '%s'\n", node->ID, window->Name); + + window->DockNode = NULL; + window->DockIsActive = window->DockTabWantClose = false; + window->DockId = save_dock_id; + window->Flags &= ~ImGuiWindowFlags_ChildWindow; + if (window->ParentWindow) + window->ParentWindow->DC.ChildWindows.find_erase(window); + UpdateWindowParentAndRootLinks(window, window->Flags, NULL); // Update immediately + + // Remove window + bool erased = false; + for (int n = 0; n < node->Windows.Size; n++) + if (node->Windows[n] == window) + { + node->Windows.erase(node->Windows.Data + n); + erased = true; + break; + } + if (!erased) + IM_ASSERT(erased); + if (node->VisibleWindow == window) + node->VisibleWindow = NULL; + + // Remove tab and possibly tab bar + node->WantHiddenTabBarUpdate = true; + if (node->TabBar) + { + TabBarRemoveTab(node->TabBar, window->TabId); + const int tab_count_threshold_for_tab_bar = node->IsCentralNode() ? 1 : 2; + if (node->Windows.Size < tab_count_threshold_for_tab_bar) + DockNodeRemoveTabBar(node); + } + + if (node->Windows.Size == 0 && !node->IsCentralNode() && !node->IsDockSpace() && window->DockId != node->ID) + { + // Automatic dock node delete themselves if they are not holding at least one tab + DockContextRemoveNode(&g, node, true); + return; + } + + if (node->Windows.Size == 1 && !node->IsCentralNode() && node->HostWindow) + { + ImGuiWindow* remaining_window = node->Windows[0]; + if (node->HostWindow->ViewportOwned && node->IsRootNode()) + { + // Transfer viewport back to the remaining loose window + IMGUI_DEBUG_LOG_VIEWPORT("Node %08X transfer Viewport %08X=>%08X for Window '%s'\n", node->ID, node->HostWindow->Viewport->ID, remaining_window->ID, remaining_window->Name); + IM_ASSERT(node->HostWindow->Viewport->Window == node->HostWindow); + node->HostWindow->Viewport->Window = remaining_window; + node->HostWindow->Viewport->ID = remaining_window->ID; + } + remaining_window->Collapsed = node->HostWindow->Collapsed; + } + + // Update visibility immediately is required so the DockNodeUpdateRemoveInactiveChilds() processing can reflect changes up the tree + DockNodeUpdateVisibleFlag(node); +} + +static void ImGui::DockNodeMoveChildNodes(ImGuiDockNode* dst_node, ImGuiDockNode* src_node) +{ + IM_ASSERT(dst_node->Windows.Size == 0); + dst_node->ChildNodes[0] = src_node->ChildNodes[0]; + dst_node->ChildNodes[1] = src_node->ChildNodes[1]; + if (dst_node->ChildNodes[0]) + dst_node->ChildNodes[0]->ParentNode = dst_node; + if (dst_node->ChildNodes[1]) + dst_node->ChildNodes[1]->ParentNode = dst_node; + dst_node->SplitAxis = src_node->SplitAxis; + dst_node->SizeRef = src_node->SizeRef; + src_node->ChildNodes[0] = src_node->ChildNodes[1] = NULL; +} + +static void ImGui::DockNodeMoveWindows(ImGuiDockNode* dst_node, ImGuiDockNode* src_node) +{ + // Insert tabs in the same orders as currently ordered (node->Windows isn't ordered) + IM_ASSERT(src_node && dst_node && dst_node != src_node); + ImGuiTabBar* src_tab_bar = src_node->TabBar; + if (src_tab_bar != NULL) + IM_ASSERT(src_node->Windows.Size <= src_node->TabBar->Tabs.Size); + + // If the dst_node is empty we can just move the entire tab bar (to preserve selection, scrolling, etc.) + bool move_tab_bar = (src_tab_bar != NULL) && (dst_node->TabBar == NULL); + if (move_tab_bar) + { + dst_node->TabBar = src_node->TabBar; + src_node->TabBar = NULL; + } + + for (int n = 0; n < src_node->Windows.Size; n++) + { + // DockNode's TabBar may have non-window Tabs manually appended by user + if (ImGuiWindow* window = src_tab_bar ? src_tab_bar->Tabs[n].Window : src_node->Windows[n]) + { + window->DockNode = NULL; + window->DockIsActive = false; + DockNodeAddWindow(dst_node, window, move_tab_bar ? false : true); + } + } + src_node->Windows.clear(); + + if (!move_tab_bar && src_node->TabBar) + { + if (dst_node->TabBar) + dst_node->TabBar->SelectedTabId = src_node->TabBar->SelectedTabId; + DockNodeRemoveTabBar(src_node); + } +} + +static void ImGui::DockNodeApplyPosSizeToWindows(ImGuiDockNode* node) +{ + for (int n = 0; n < node->Windows.Size; n++) + { + SetWindowPos(node->Windows[n], node->Pos, ImGuiCond_Always); // We don't assign directly to Pos because it can break the calculation of SizeContents on next frame + SetWindowSize(node->Windows[n], node->Size, ImGuiCond_Always); + } +} + +static void ImGui::DockNodeHideHostWindow(ImGuiDockNode* node) +{ + if (node->HostWindow) + { + if (node->HostWindow->DockNodeAsHost == node) + node->HostWindow->DockNodeAsHost = NULL; + node->HostWindow = NULL; + } + + if (node->Windows.Size == 1) + { + node->VisibleWindow = node->Windows[0]; + node->Windows[0]->DockIsActive = false; + } + + if (node->TabBar) + DockNodeRemoveTabBar(node); +} + +// Search function called once by root node in DockNodeUpdate() +struct ImGuiDockNodeTreeInfo +{ + ImGuiDockNode* CentralNode; + ImGuiDockNode* FirstNodeWithWindows; + int CountNodesWithWindows; + //ImGuiWindowClass WindowClassForMerges; + + ImGuiDockNodeTreeInfo() { memset(this, 0, sizeof(*this)); } +}; + +static void DockNodeFindInfo(ImGuiDockNode* node, ImGuiDockNodeTreeInfo* info) +{ + if (node->Windows.Size > 0) + { + if (info->FirstNodeWithWindows == NULL) + info->FirstNodeWithWindows = node; + info->CountNodesWithWindows++; + } + if (node->IsCentralNode()) + { + IM_ASSERT(info->CentralNode == NULL); // Should be only one + IM_ASSERT(node->IsLeafNode() && "If you get this assert: please submit .ini file + repro of actions leading to this."); + info->CentralNode = node; + } + if (info->CountNodesWithWindows > 1 && info->CentralNode != NULL) + return; + if (node->ChildNodes[0]) + DockNodeFindInfo(node->ChildNodes[0], info); + if (node->ChildNodes[1]) + DockNodeFindInfo(node->ChildNodes[1], info); +} + +static ImGuiWindow* ImGui::DockNodeFindWindowByID(ImGuiDockNode* node, ImGuiID id) +{ + IM_ASSERT(id != 0); + for (int n = 0; n < node->Windows.Size; n++) + if (node->Windows[n]->ID == id) + return node->Windows[n]; + return NULL; +} + +// - Remove inactive windows/nodes. +// - Update visibility flag. +static void ImGui::DockNodeUpdateFlagsAndCollapse(ImGuiDockNode* node) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(node->ParentNode == NULL || node->ParentNode->ChildNodes[0] == node || node->ParentNode->ChildNodes[1] == node); + + // Inherit most flags + if (node->ParentNode) + node->SharedFlags = node->ParentNode->SharedFlags & ImGuiDockNodeFlags_SharedFlagsInheritMask_; + + // Recurse into children + // There is the possibility that one of our child becoming empty will delete itself and moving its sibling contents into 'node'. + // If 'node->ChildNode[0]' delete itself, then 'node->ChildNode[1]->Windows' will be moved into 'node' + // If 'node->ChildNode[1]' delete itself, then 'node->ChildNode[0]->Windows' will be moved into 'node' and the "remove inactive windows" loop will have run twice on those windows (harmless) + node->HasCentralNodeChild = false; + if (node->ChildNodes[0]) + DockNodeUpdateFlagsAndCollapse(node->ChildNodes[0]); + if (node->ChildNodes[1]) + DockNodeUpdateFlagsAndCollapse(node->ChildNodes[1]); + + // Remove inactive windows, collapse nodes + // Merge node flags overrides stored in windows + node->LocalFlagsInWindows = ImGuiDockNodeFlags_None; + for (int window_n = 0; window_n < node->Windows.Size; window_n++) + { + ImGuiWindow* window = node->Windows[window_n]; + IM_ASSERT(window->DockNode == node); + + bool node_was_active = (node->LastFrameActive + 1 == g.FrameCount); + bool remove = false; + remove |= node_was_active && (window->LastFrameActive + 1 < g.FrameCount); + remove |= node_was_active && (node->WantCloseAll || node->WantCloseTabId == window->TabId) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument); // Submit all _expected_ closure from last frame + remove |= (window->DockTabWantClose); + if (remove) + { + window->DockTabWantClose = false; + if (node->Windows.Size == 1 && !node->IsCentralNode()) + { + DockNodeHideHostWindow(node); + node->State = ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow; + DockNodeRemoveWindow(node, window, node->ID); // Will delete the node so it'll be invalid on return + return; + } + DockNodeRemoveWindow(node, window, node->ID); + window_n--; + continue; + } + + // FIXME-DOCKING: Missing policies for conflict resolution, hence the "Experimental" tag on this. + //node->LocalFlagsInWindow &= ~window->WindowClass.DockNodeFlagsOverrideClear; + node->LocalFlagsInWindows |= window->WindowClass.DockNodeFlagsOverrideSet; + } + node->UpdateMergedFlags(); + + // Auto-hide tab bar option + ImGuiDockNodeFlags node_flags = node->MergedFlags; + if (node->WantHiddenTabBarUpdate && node->Windows.Size == 1 && (node_flags & ImGuiDockNodeFlags_AutoHideTabBar) && !node->IsHiddenTabBar()) + node->WantHiddenTabBarToggle = true; + node->WantHiddenTabBarUpdate = false; + + // Cancel toggling if we know our tab bar is enforced to be hidden at all times + if (node->WantHiddenTabBarToggle && node->VisibleWindow && (node->VisibleWindow->WindowClass.DockNodeFlagsOverrideSet & ImGuiDockNodeFlags_HiddenTabBar)) + node->WantHiddenTabBarToggle = false; + + // Apply toggles at a single point of the frame (here!) + if (node->Windows.Size > 1) + node->SetLocalFlags(node->LocalFlags & ~ImGuiDockNodeFlags_HiddenTabBar); + else if (node->WantHiddenTabBarToggle) + node->SetLocalFlags(node->LocalFlags ^ ImGuiDockNodeFlags_HiddenTabBar); + node->WantHiddenTabBarToggle = false; + + DockNodeUpdateVisibleFlag(node); +} + +// This is rarely called as DockNodeUpdateForRootNode() generally does it most frames. +static void ImGui::DockNodeUpdateHasCentralNodeChild(ImGuiDockNode* node) +{ + node->HasCentralNodeChild = false; + if (node->ChildNodes[0]) + DockNodeUpdateHasCentralNodeChild(node->ChildNodes[0]); + if (node->ChildNodes[1]) + DockNodeUpdateHasCentralNodeChild(node->ChildNodes[1]); + if (node->IsRootNode()) + { + ImGuiDockNode* mark_node = node->CentralNode; + while (mark_node) + { + mark_node->HasCentralNodeChild = true; + mark_node = mark_node->ParentNode; + } + } +} + +static void ImGui::DockNodeUpdateVisibleFlag(ImGuiDockNode* node) +{ + // Update visibility flag + bool is_visible = (node->ParentNode == NULL) ? node->IsDockSpace() : node->IsCentralNode(); + is_visible |= (node->Windows.Size > 0); + is_visible |= (node->ChildNodes[0] && node->ChildNodes[0]->IsVisible); + is_visible |= (node->ChildNodes[1] && node->ChildNodes[1]->IsVisible); + node->IsVisible = is_visible; +} + +static void ImGui::DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(node->WantMouseMove == true); + StartMouseMovingWindow(window); + g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - node->Pos; + g.MovingWindow = window; // If we are docked into a non moveable root window, StartMouseMovingWindow() won't set g.MovingWindow. Override that decision. + node->WantMouseMove = false; +} + +// Update CentralNode, OnlyNodeWithWindows, LastFocusedNodeID. Copy window class. +static void ImGui::DockNodeUpdateForRootNode(ImGuiDockNode* node) +{ + DockNodeUpdateFlagsAndCollapse(node); + + // - Setup central node pointers + // - Find if there's only a single visible window in the hierarchy (in which case we need to display a regular title bar -> FIXME-DOCK: that last part is not done yet!) + // Cannot merge this with DockNodeUpdateFlagsAndCollapse() because FirstNodeWithWindows is found after window removal and child collapsing + ImGuiDockNodeTreeInfo info; + DockNodeFindInfo(node, &info); + node->CentralNode = info.CentralNode; + node->OnlyNodeWithWindows = (info.CountNodesWithWindows == 1) ? info.FirstNodeWithWindows : NULL; + node->CountNodeWithWindows = info.CountNodesWithWindows; + if (node->LastFocusedNodeId == 0 && info.FirstNodeWithWindows != NULL) + node->LastFocusedNodeId = info.FirstNodeWithWindows->ID; + + // Copy the window class from of our first window so it can be used for proper dock filtering. + // When node has mixed windows, prioritize the class with the most constraint (DockingAllowUnclassed = false) as the reference to copy. + // FIXME-DOCK: We don't recurse properly, this code could be reworked to work from DockNodeUpdateScanRec. + if (ImGuiDockNode* first_node_with_windows = info.FirstNodeWithWindows) + { + node->WindowClass = first_node_with_windows->Windows[0]->WindowClass; + for (int n = 1; n < first_node_with_windows->Windows.Size; n++) + if (first_node_with_windows->Windows[n]->WindowClass.DockingAllowUnclassed == false) + { + node->WindowClass = first_node_with_windows->Windows[n]->WindowClass; + break; + } + } + + ImGuiDockNode* mark_node = node->CentralNode; + while (mark_node) + { + mark_node->HasCentralNodeChild = true; + mark_node = mark_node->ParentNode; + } +} + +static void DockNodeSetupHostWindow(ImGuiDockNode* node, ImGuiWindow* host_window) +{ + // Remove ourselves from any previous different host window + // This can happen if a user mistakenly does (see #4295 for details): + // - N+0: DockBuilderAddNode(id, 0) // missing ImGuiDockNodeFlags_DockSpace + // - N+1: NewFrame() // will create floating host window for that node + // - N+1: DockSpace(id) // requalify node as dockspace, moving host window + if (node->HostWindow && node->HostWindow != host_window && node->HostWindow->DockNodeAsHost == node) + node->HostWindow->DockNodeAsHost = NULL; + + host_window->DockNodeAsHost = node; + node->HostWindow = host_window; +} + +static void ImGui::DockNodeUpdate(ImGuiDockNode* node) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(node->LastFrameActive != g.FrameCount); + node->LastFrameAlive = g.FrameCount; + node->IsBgDrawnThisFrame = false; + + node->CentralNode = node->OnlyNodeWithWindows = NULL; + if (node->IsRootNode()) + DockNodeUpdateForRootNode(node); + + // Remove tab bar if not needed + if (node->TabBar && node->IsNoTabBar()) + DockNodeRemoveTabBar(node); + + // Early out for hidden root dock nodes (when all DockId references are in inactive windows, or there is only 1 floating window holding on the DockId) + bool want_to_hide_host_window = false; + if (node->IsFloatingNode()) + { + if (node->Windows.Size <= 1 && node->IsLeafNode()) + if (!g.IO.ConfigDockingAlwaysTabBar && (node->Windows.Size == 0 || !node->Windows[0]->WindowClass.DockingAlwaysTabBar)) + want_to_hide_host_window = true; + if (node->CountNodeWithWindows == 0) + want_to_hide_host_window = true; + } + if (want_to_hide_host_window) + { + if (node->Windows.Size == 1) + { + // Floating window pos/size is authoritative + ImGuiWindow* single_window = node->Windows[0]; + node->Pos = single_window->Pos; + node->Size = single_window->SizeFull; + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Window; + + // Transfer focus immediately so when we revert to a regular window it is immediately selected + if (node->HostWindow && g.NavWindow == node->HostWindow) + FocusWindow(single_window); + if (node->HostWindow) + { + single_window->Viewport = node->HostWindow->Viewport; + single_window->ViewportId = node->HostWindow->ViewportId; + if (node->HostWindow->ViewportOwned) + { + single_window->Viewport->Window = single_window; + single_window->ViewportOwned = true; + } + } + } + + DockNodeHideHostWindow(node); + node->State = ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow; + node->WantCloseAll = false; + node->WantCloseTabId = 0; + node->HasCloseButton = node->HasWindowMenuButton = false; + node->LastFrameActive = g.FrameCount; + + if (node->WantMouseMove && node->Windows.Size == 1) + DockNodeStartMouseMovingWindow(node, node->Windows[0]); + return; + } + + // In some circumstance we will defer creating the host window (so everything will be kept hidden), + // while the expected visible window is resizing itself. + // This is important for first-time (no ini settings restored) single window when io.ConfigDockingAlwaysTabBar is enabled, + // otherwise the node ends up using the minimum window size. Effectively those windows will take an extra frame to show up: + // N+0: Begin(): window created (with no known size), node is created + // N+1: DockNodeUpdate(): node skip creating host window / Begin(): window size applied, not visible + // N+2: DockNodeUpdate(): node can create host window / Begin(): window becomes visible + // We could remove this frame if we could reliably calculate the expected window size during node update, before the Begin() code. + // It would require a generalization of CalcWindowExpectedSize(), probably extracting code away from Begin(). + // In reality it isn't very important as user quickly ends up with size data in .ini file. + if (node->IsVisible && node->HostWindow == NULL && node->IsFloatingNode() && node->IsLeafNode()) + { + IM_ASSERT(node->Windows.Size > 0); + ImGuiWindow* ref_window = NULL; + if (node->SelectedTabId != 0) // Note that we prune single-window-node settings on .ini loading, so this is generally 0 for them! + ref_window = DockNodeFindWindowByID(node, node->SelectedTabId); + if (ref_window == NULL) + ref_window = node->Windows[0]; + if (ref_window->AutoFitFramesX > 0 || ref_window->AutoFitFramesY > 0) + { + node->State = ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing; + return; + } + } + + const ImGuiDockNodeFlags node_flags = node->MergedFlags; + + // Decide if the node will have a close button and a window menu button + node->HasWindowMenuButton = (node->Windows.Size > 0) && (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0; + node->HasCloseButton = false; + for (int window_n = 0; window_n < node->Windows.Size; window_n++) + { + // FIXME-DOCK: Setting DockIsActive here means that for single active window in a leaf node, DockIsActive will be cleared until the next Begin() call. + ImGuiWindow* window = node->Windows[window_n]; + node->HasCloseButton |= window->HasCloseButton; + window->DockIsActive = (node->Windows.Size > 1); + } + if (node_flags & ImGuiDockNodeFlags_NoCloseButton) + node->HasCloseButton = false; + + // Bind or create host window + ImGuiWindow* host_window = NULL; + bool beginned_into_host_window = false; + if (node->IsDockSpace()) + { + // [Explicit root dockspace node] + IM_ASSERT(node->HostWindow); + host_window = node->HostWindow; + } + else + { + // [Automatic root or child nodes] + if (node->IsRootNode() && node->IsVisible) + { + ImGuiWindow* ref_window = (node->Windows.Size > 0) ? node->Windows[0] : NULL; + + // Sync Pos + if (node->AuthorityForPos == ImGuiDataAuthority_Window && ref_window) + SetNextWindowPos(ref_window->Pos); + else if (node->AuthorityForPos == ImGuiDataAuthority_DockNode) + SetNextWindowPos(node->Pos); + + // Sync Size + if (node->AuthorityForSize == ImGuiDataAuthority_Window && ref_window) + SetNextWindowSize(ref_window->SizeFull); + else if (node->AuthorityForSize == ImGuiDataAuthority_DockNode) + SetNextWindowSize(node->Size); + + // Sync Collapsed + if (node->AuthorityForSize == ImGuiDataAuthority_Window && ref_window) + SetNextWindowCollapsed(ref_window->Collapsed); + + // Sync Viewport + if (node->AuthorityForViewport == ImGuiDataAuthority_Window && ref_window) + SetNextWindowViewport(ref_window->ViewportId); + + SetNextWindowClass(&node->WindowClass); + + // Begin into the host window + char window_label[20]; + DockNodeGetHostWindowTitle(node, window_label, IM_ARRAYSIZE(window_label)); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_DockNodeHost; + window_flags |= ImGuiWindowFlags_NoFocusOnAppearing; + window_flags |= ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoCollapse; + window_flags |= ImGuiWindowFlags_NoTitleBar; + + SetNextWindowBgAlpha(0.0f); // Don't set ImGuiWindowFlags_NoBackground because it disables borders + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + Begin(window_label, NULL, window_flags); + PopStyleVar(); + beginned_into_host_window = true; + + host_window = g.CurrentWindow; + DockNodeSetupHostWindow(node, host_window); + host_window->DC.CursorPos = host_window->Pos; + node->Pos = host_window->Pos; + node->Size = host_window->Size; + + // We set ImGuiWindowFlags_NoFocusOnAppearing because we don't want the host window to take full focus (e.g. steal NavWindow) + // But we still it bring it to the front of display. There's no way to choose this precise behavior via window flags. + // One simple case to ponder if: window A has a toggle to create windows B/C/D. Dock B/C/D together, clear the toggle and enable it again. + // When reappearing B/C/D will request focus and be moved to the top of the display pile, but they are not linked to the dock host window + // during the frame they appear. The dock host window would keep its old display order, and the sorting in EndFrame would move B/C/D back + // after the dock host window, losing their top-most status. + if (node->HostWindow->Appearing) + BringWindowToDisplayFront(node->HostWindow); + + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Auto; + } + else if (node->ParentNode) + { + node->HostWindow = host_window = node->ParentNode->HostWindow; + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Auto; + } + if (node->WantMouseMove && node->HostWindow) + DockNodeStartMouseMovingWindow(node, node->HostWindow); + } + + // Update focused node (the one whose title bar is highlight) within a node tree + if (node->IsSplitNode()) + IM_ASSERT(node->TabBar == NULL); + if (node->IsRootNode()) + if (g.NavWindow && g.NavWindow->RootWindow->DockNode && g.NavWindow->RootWindow->ParentWindow == host_window) + node->LastFocusedNodeId = g.NavWindow->RootWindow->DockNode->ID; + + // Register a hit-test hole in the window unless we are currently dragging a window that is compatible with our dockspace + ImGuiDockNode* central_node = node->CentralNode; + const bool central_node_hole = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0 && central_node != NULL && central_node->IsEmpty(); + bool central_node_hole_register_hit_test_hole = central_node_hole; + if (central_node_hole) + if (const ImGuiPayload* payload = ImGui::GetDragDropPayload()) + if (payload->IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW) && DockNodeIsDropAllowed(host_window, *(ImGuiWindow**)payload->Data)) + central_node_hole_register_hit_test_hole = false; + if (central_node_hole_register_hit_test_hole) + { + // We add a little padding to match the "resize from edges" behavior and allow grabbing the splitter easily. + // (But we only add it if there's something else on the other side of the hole, otherwise for e.g. fullscreen + // covering passthru node we'd have a gap on the edge not covered by the hole) + IM_ASSERT(node->IsDockSpace()); // We cannot pass this flag without the DockSpace() api. Testing this because we also setup the hole in host_window->ParentNode + ImGuiDockNode* root_node = DockNodeGetRootNode(central_node); + ImRect root_rect(root_node->Pos, root_node->Pos + root_node->Size); + ImRect hole_rect(central_node->Pos, central_node->Pos + central_node->Size); + if (hole_rect.Min.x > root_rect.Min.x) { hole_rect.Min.x += WINDOWS_HOVER_PADDING; } + if (hole_rect.Max.x < root_rect.Max.x) { hole_rect.Max.x -= WINDOWS_HOVER_PADDING; } + if (hole_rect.Min.y > root_rect.Min.y) { hole_rect.Min.y += WINDOWS_HOVER_PADDING; } + if (hole_rect.Max.y < root_rect.Max.y) { hole_rect.Max.y -= WINDOWS_HOVER_PADDING; } + //GetForegroundDrawList()->AddRect(hole_rect.Min, hole_rect.Max, IM_COL32(255, 0, 0, 255)); + if (central_node_hole && !hole_rect.IsInverted()) + { + SetWindowHitTestHole(host_window, hole_rect.Min, hole_rect.Max - hole_rect.Min); + if (host_window->ParentWindow) + SetWindowHitTestHole(host_window->ParentWindow, hole_rect.Min, hole_rect.Max - hole_rect.Min); + } + } + + // Update position/size, process and draw resizing splitters + if (node->IsRootNode() && host_window) + { + host_window->DrawList->ChannelsSetCurrent(1); + DockNodeTreeUpdatePosSize(node, host_window->Pos, host_window->Size); + DockNodeTreeUpdateSplitter(node); + } + + // Draw empty node background (currently can only be the Central Node) + if (host_window && node->IsEmpty() && node->IsVisible) + { + host_window->DrawList->ChannelsSetCurrent(0); + node->LastBgColor = (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) ? 0 : GetColorU32(ImGuiCol_DockingEmptyBg); + if (node->LastBgColor != 0) + host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, node->LastBgColor); + node->IsBgDrawnThisFrame = true; + } + + // Draw whole dockspace background if ImGuiDockNodeFlags_PassthruCentralNode if set. + // We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size + // _after_ processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order! + const bool render_dockspace_bg = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0; + if (render_dockspace_bg && node->IsVisible) + { + host_window->DrawList->ChannelsSetCurrent(0); + if (central_node_hole) + RenderRectFilledWithHole(host_window->DrawList, node->Rect(), central_node->Rect(), GetColorU32(ImGuiCol_WindowBg), 0.0f); + else + host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, GetColorU32(ImGuiCol_WindowBg), 0.0f); + } + + // Draw and populate Tab Bar + if (host_window) + host_window->DrawList->ChannelsSetCurrent(1); + if (host_window && node->Windows.Size > 0) + { + DockNodeUpdateTabBar(node, host_window); + } + else + { + node->WantCloseAll = false; + node->WantCloseTabId = 0; + node->IsFocused = false; + } + if (node->TabBar && node->TabBar->SelectedTabId) + node->SelectedTabId = node->TabBar->SelectedTabId; + else if (node->Windows.Size > 0) + node->SelectedTabId = node->Windows[0]->ID; + + // Draw payload drop target + if (host_window && node->IsVisible) + if (node->IsRootNode() && (g.MovingWindow == NULL || g.MovingWindow->RootWindowDockTree != host_window)) + BeginDockableDragDropTarget(host_window); + + // We update this after DockNodeUpdateTabBar() + node->LastFrameActive = g.FrameCount; + + // Recurse into children + // FIXME-DOCK FIXME-OPT: Should not need to recurse into children + if (host_window) + { + if (node->ChildNodes[0]) + DockNodeUpdate(node->ChildNodes[0]); + if (node->ChildNodes[1]) + DockNodeUpdate(node->ChildNodes[1]); + + // Render outer borders last (after the tab bar) + if (node->IsRootNode()) + { + host_window->DrawList->ChannelsSetCurrent(1); + RenderWindowOuterBorders(host_window); + } + + // Further rendering (= hosted windows background) will be drawn on layer 0 + host_window->DrawList->ChannelsSetCurrent(0); + } + + // End host window + if (beginned_into_host_window) //-V1020 + End(); +} + +// Compare TabItem nodes given the last known DockOrder (will persist in .ini file as hint), used to sort tabs when multiple tabs are added on the same frame. +static int IMGUI_CDECL TabItemComparerByDockOrder(const void* lhs, const void* rhs) +{ + ImGuiWindow* a = ((const ImGuiTabItem*)lhs)->Window; + ImGuiWindow* b = ((const ImGuiTabItem*)rhs)->Window; + if (int d = ((a->DockOrder == -1) ? INT_MAX : a->DockOrder) - ((b->DockOrder == -1) ? INT_MAX : b->DockOrder)) + return d; + return (a->BeginOrderWithinContext - b->BeginOrderWithinContext); +} + +static ImGuiID ImGui::DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar) +{ + // Try to position the menu so it is more likely to stays within the same viewport + ImGuiContext& g = *GImGui; + ImGuiID ret_tab_id = 0; + if (g.Style.WindowMenuButtonPosition == ImGuiDir_Left) + SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + else + SetNextWindowPos(ImVec2(node->Pos.x + node->Size.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(1.0f, 0.0f)); + if (BeginPopup("#WindowMenu")) + { + node->IsFocused = true; + if (tab_bar->Tabs.Size == 1) + { + if (MenuItem("Hide tab bar", NULL, node->IsHiddenTabBar())) + node->WantHiddenTabBarToggle = true; + } + else + { + for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + if (tab->Flags & ImGuiTabItemFlags_Button) + continue; + if (Selectable(tab_bar->GetTabName(tab), tab->ID == tab_bar->SelectedTabId)) + ret_tab_id = tab->ID; + SameLine(); + Text(" "); + } + } + EndPopup(); + } + return ret_tab_id; +} + +// User helper to append/amend into a dock node tab bar. Most commonly used to add e.g. a "+" button. +bool ImGui::DockNodeBeginAmendTabBar(ImGuiDockNode* node) +{ + if (node->TabBar == NULL || node->HostWindow == NULL) + return false; + if (node->MergedFlags & ImGuiDockNodeFlags_KeepAliveOnly) + return false; + Begin(node->HostWindow->Name); + PushOverrideID(node->ID); + bool ret = BeginTabBarEx(node->TabBar, node->TabBar->BarRect, node->TabBar->Flags, node); + IM_UNUSED(ret); + IM_ASSERT(ret); + return true; +} + +void ImGui::DockNodeEndAmendTabBar() +{ + EndTabBar(); + PopID(); + End(); +} + +// Submit the tab bar corresponding to a dock node and various housekeeping details. +static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + + const bool node_was_active = (node->LastFrameActive + 1 == g.FrameCount); + const bool closed_all = node->WantCloseAll && node_was_active; + const ImGuiID closed_one = node->WantCloseTabId && node_was_active; + node->WantCloseAll = false; + node->WantCloseTabId = 0; + + // Decide if we should use a focused title bar color + bool is_focused = false; + ImGuiDockNode* root_node = DockNodeGetRootNode(node); + if (g.NavWindowingTarget) + is_focused = (g.NavWindowingTarget->DockNode == node); + else if (g.NavWindow && g.NavWindow->RootWindowForTitleBarHighlight == host_window->RootWindowDockTree && root_node->LastFocusedNodeId == node->ID) + is_focused = true; + + // Hidden tab bar will show a triangle on the upper-left (in Begin) + if (node->IsHiddenTabBar() || node->IsNoTabBar()) + { + node->VisibleWindow = (node->Windows.Size > 0) ? node->Windows[0] : NULL; + node->IsFocused = is_focused; + if (is_focused) + node->LastFrameFocused = g.FrameCount; + if (node->VisibleWindow) + { + // Notify root of visible window (used to display title in OS task bar) + if (is_focused || root_node->VisibleWindow == NULL) + root_node->VisibleWindow = node->VisibleWindow; + if (node->TabBar) + node->TabBar->VisibleTabId = node->VisibleWindow->TabId; + } + return; + } + + // Move ourselves to the Menu layer (so we can be accessed by tapping Alt) + undo SkipItems flag in order to draw over the title bar even if the window is collapsed + bool backup_skip_item = host_window->SkipItems; + if (!node->IsDockSpace()) + { + host_window->SkipItems = false; + host_window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; + } + + // Use PushOverrideID() instead of PushID() to use the node id _without_ the host window ID. + // This is to facilitate computing those ID from the outside, and will affect more or less only the ID of the collapse button, popup and tabs, + // as docked windows themselves will override the stack with their own root ID. + PushOverrideID(node->ID); + ImGuiTabBar* tab_bar = node->TabBar; + bool tab_bar_is_recreated = (tab_bar == NULL); // Tab bar are automatically destroyed when a node gets hidden + if (tab_bar == NULL) + { + DockNodeAddTabBar(node); + tab_bar = node->TabBar; + } + + ImGuiID focus_tab_id = 0; + node->IsFocused = is_focused; + + const ImGuiDockNodeFlags node_flags = node->MergedFlags; + const bool has_window_menu_button = (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0 && (style.WindowMenuButtonPosition != ImGuiDir_None); + + // In a dock node, the Collapse Button turns into the Window Menu button. + // FIXME-DOCK FIXME-OPT: Could we recycle popups id across multiple dock nodes? + if (has_window_menu_button && IsPopupOpen("#WindowMenu")) + { + if (ImGuiID tab_id = DockNodeUpdateWindowMenu(node, tab_bar)) + focus_tab_id = tab_bar->NextSelectedTabId = tab_id; + is_focused |= node->IsFocused; + } + + // Layout + ImRect title_bar_rect, tab_bar_rect; + ImVec2 window_menu_button_pos; + ImVec2 close_button_pos; + DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &window_menu_button_pos, &close_button_pos); + + // Submit new tabs, they will be added as Unsorted and sorted below based on relative DockOrder value. + const int tabs_count_old = tab_bar->Tabs.Size; + for (int window_n = 0; window_n < node->Windows.Size; window_n++) + { + ImGuiWindow* window = node->Windows[window_n]; + if (TabBarFindTabByID(tab_bar, window->TabId) == NULL) + TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window); + } + + // Title bar + if (is_focused) + node->LastFrameFocused = g.FrameCount; + ImU32 title_bar_col = GetColorU32(host_window->Collapsed ? ImGuiCol_TitleBgCollapsed : is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); + ImDrawFlags rounding_flags = CalcRoundingFlagsForRectInRect(title_bar_rect, host_window->Rect(), DOCKING_SPLITTER_SIZE); + host_window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, host_window->WindowRounding, rounding_flags); + + // Docking/Collapse button + if (has_window_menu_button) + { + if (CollapseButton(host_window->GetID("#COLLAPSE"), window_menu_button_pos, node)) // == DockNodeGetWindowMenuButtonId(node) + OpenPopup("#WindowMenu"); + if (IsItemActive()) + focus_tab_id = tab_bar->SelectedTabId; + } + + // If multiple tabs are appearing on the same frame, sort them based on their persistent DockOrder value + int tabs_unsorted_start = tab_bar->Tabs.Size; + for (int tab_n = tab_bar->Tabs.Size - 1; tab_n >= 0 && (tab_bar->Tabs[tab_n].Flags & ImGuiTabItemFlags_Unsorted); tab_n--) + { + // FIXME-DOCK: Consider only clearing the flag after the tab has been alive for a few consecutive frames, allowing late comers to not break sorting? + tab_bar->Tabs[tab_n].Flags &= ~ImGuiTabItemFlags_Unsorted; + tabs_unsorted_start = tab_n; + } + if (tab_bar->Tabs.Size > tabs_unsorted_start) + { + IMGUI_DEBUG_LOG_DOCKING("In node 0x%08X: %d new appearing tabs:%s\n", node->ID, tab_bar->Tabs.Size - tabs_unsorted_start, (tab_bar->Tabs.Size > tabs_unsorted_start + 1) ? " (will sort)" : ""); + for (int tab_n = tabs_unsorted_start; tab_n < tab_bar->Tabs.Size; tab_n++) + IMGUI_DEBUG_LOG_DOCKING(" - Tab '%s' Order %d\n", tab_bar->Tabs[tab_n].Window->Name, tab_bar->Tabs[tab_n].Window->DockOrder); + if (tab_bar->Tabs.Size > tabs_unsorted_start + 1) + ImQsort(tab_bar->Tabs.Data + tabs_unsorted_start, tab_bar->Tabs.Size - tabs_unsorted_start, sizeof(ImGuiTabItem), TabItemComparerByDockOrder); + } + + // Apply NavWindow focus back to the tab bar + if (g.NavWindow && g.NavWindow->RootWindow->DockNode == node) + tab_bar->SelectedTabId = g.NavWindow->RootWindow->ID; + + // Selected newly added tabs, or persistent tab ID if the tab bar was just recreated + if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabId) != NULL) + tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = node->SelectedTabId; + else if (tab_bar->Tabs.Size > tabs_count_old) + tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = tab_bar->Tabs.back().Window->TabId; + + // Begin tab bar + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_AutoSelectNewTabs; // | ImGuiTabBarFlags_NoTabListScrollingButtons); + tab_bar_flags |= ImGuiTabBarFlags_SaveSettings | ImGuiTabBarFlags_DockNode; + if (!host_window->Collapsed && is_focused) + tab_bar_flags |= ImGuiTabBarFlags_IsFocused; + BeginTabBarEx(tab_bar, tab_bar_rect, tab_bar_flags, node); + //host_window->DrawList->AddRect(tab_bar_rect.Min, tab_bar_rect.Max, IM_COL32(255,0,255,255)); + + // Backup style colors + ImVec4 backup_style_cols[ImGuiWindowDockStyleCol_COUNT]; + for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++) + backup_style_cols[color_n] = g.Style.Colors[GWindowDockStyleColors[color_n]]; + + // Submit actual tabs + node->VisibleWindow = NULL; + for (int window_n = 0; window_n < node->Windows.Size; window_n++) + { + ImGuiWindow* window = node->Windows[window_n]; + if ((closed_all || closed_one == window->TabId) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument)) + continue; + if (window->LastFrameActive + 1 >= g.FrameCount || !node_was_active) + { + ImGuiTabItemFlags tab_item_flags = 0; + tab_item_flags |= window->WindowClass.TabItemFlagsOverrideSet; + if (window->Flags & ImGuiWindowFlags_UnsavedDocument) + tab_item_flags |= ImGuiTabItemFlags_UnsavedDocument; + if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton) + tab_item_flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton; + + // Apply stored style overrides for the window + for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++) + g.Style.Colors[GWindowDockStyleColors[color_n]] = ColorConvertU32ToFloat4(window->DockStyle.Colors[color_n]); + + // Note that TabItemEx() calls TabBarCalcTabID() so our tab item ID will ignore the current ID stack (rightly so) + bool tab_open = true; + TabItemEx(tab_bar, window->Name, window->HasCloseButton ? &tab_open : NULL, tab_item_flags, window); + if (!tab_open) + node->WantCloseTabId = window->TabId; + if (tab_bar->VisibleTabId == window->TabId) + node->VisibleWindow = window; + + // Store last item data so it can be queried with IsItemXXX functions after the user Begin() call + window->DockTabItemStatusFlags = g.LastItemData.StatusFlags; + window->DockTabItemRect = g.LastItemData.Rect; + + // Update navigation ID on menu layer + if (g.NavWindow && g.NavWindow->RootWindow == window && (window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0) + host_window->NavLastIds[1] = window->TabId; + } + } + + // Restore style colors + for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++) + g.Style.Colors[GWindowDockStyleColors[color_n]] = backup_style_cols[color_n]; + + // Notify root of visible window (used to display title in OS task bar) + if (node->VisibleWindow) + if (is_focused || root_node->VisibleWindow == NULL) + root_node->VisibleWindow = node->VisibleWindow; + + // Close button (after VisibleWindow was updated) + // Note that VisibleWindow may have been overrided by CTRL+Tabbing, so VisibleWindow->TabId may be != from tab_bar->SelectedTabId + const bool close_button_is_enabled = node->HasCloseButton && node->VisibleWindow && node->VisibleWindow->HasCloseButton; + const bool close_button_is_visible = node->HasCloseButton; + //const bool close_button_is_visible = close_button_is_enabled; // Most people would expect this behavior of not even showing the button (leaving a hole since we can't claim that space as other windows in the tba bar have one) + if (close_button_is_visible) + { + if (!close_button_is_enabled) + { + PushItemFlag(ImGuiItemFlags_Disabled, true); + PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_Text] * ImVec4(1.0f,1.0f,1.0f,0.4f)); + } + if (CloseButton(host_window->GetID("#CLOSE"), close_button_pos)) + { + node->WantCloseAll = true; + for (int n = 0; n < tab_bar->Tabs.Size; n++) + TabBarCloseTab(tab_bar, &tab_bar->Tabs[n]); + } + //if (IsItemActive()) + // focus_tab_id = tab_bar->SelectedTabId; + if (!close_button_is_enabled) + { + PopStyleColor(); + PopItemFlag(); + } + } + + // When clicking on the title bar outside of tabs, we still focus the selected tab for that node + // FIXME: TabItem use AllowItemOverlap so we manually perform a more specific test for now (hovered || held) + ImGuiID title_bar_id = host_window->GetID("#TITLEBAR"); + if (g.HoveredId == 0 || g.HoveredId == title_bar_id || g.ActiveId == title_bar_id) + { + bool held; + ButtonBehavior(title_bar_rect, title_bar_id, NULL, &held, ImGuiButtonFlags_AllowItemOverlap); + if (g.HoveredId == title_bar_id) + { + // ImGuiButtonFlags_AllowItemOverlap + SetItemAllowOverlap() required for appending into dock node tab bar, + // otherwise dragging window will steal HoveredId and amended tabs cannot get them. + g.LastItemData.ID = title_bar_id; + SetItemAllowOverlap(); + } + if (held) + { + if (IsMouseClicked(0)) + focus_tab_id = tab_bar->SelectedTabId; + + // Forward moving request to selected window + if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_bar->SelectedTabId)) + StartMouseMovingWindowOrNode(tab->Window ? tab->Window : node->HostWindow, node, false); + } + } + + // Forward focus from host node to selected window + //if (is_focused && g.NavWindow == host_window && !g.NavWindowingTarget) + // focus_tab_id = tab_bar->SelectedTabId; + + // When clicked on a tab we requested focus to the docked child + // This overrides the value set by "forward focus from host node to selected window". + if (tab_bar->NextSelectedTabId) + focus_tab_id = tab_bar->NextSelectedTabId; + + // Apply navigation focus + if (focus_tab_id != 0) + if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, focus_tab_id)) + if (tab->Window) + { + FocusWindow(tab->Window); + NavInitWindow(tab->Window, false); + } + + EndTabBar(); + PopID(); + + // Restore SkipItems flag + if (!node->IsDockSpace()) + { + host_window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + host_window->SkipItems = backup_skip_item; + } +} + +static void ImGui::DockNodeAddTabBar(ImGuiDockNode* node) +{ + IM_ASSERT(node->TabBar == NULL); + node->TabBar = IM_NEW(ImGuiTabBar); +} + +static void ImGui::DockNodeRemoveTabBar(ImGuiDockNode* node) +{ + if (node->TabBar == NULL) + return; + IM_DELETE(node->TabBar); + node->TabBar = NULL; +} + +static bool DockNodeIsDropAllowedOne(ImGuiWindow* payload, ImGuiWindow* host_window) +{ + if (host_window->DockNodeAsHost && host_window->DockNodeAsHost->IsDockSpace() && payload->BeginOrderWithinContext < host_window->BeginOrderWithinContext) + return false; + + ImGuiWindowClass* host_class = host_window->DockNodeAsHost ? &host_window->DockNodeAsHost->WindowClass : &host_window->WindowClass; + ImGuiWindowClass* payload_class = &payload->WindowClass; + if (host_class->ClassId != payload_class->ClassId) + { + if (host_class->ClassId != 0 && host_class->DockingAllowUnclassed && payload_class->ClassId == 0) + return true; + if (payload_class->ClassId != 0 && payload_class->DockingAllowUnclassed && host_class->ClassId == 0) + return true; + return false; + } + + // Prevent docking any window created above a popup + // Technically we should support it (e.g. in the case of a long-lived modal window that had fancy docking features), + // by e.g. adding a 'if (!ImGui::IsWindowWithinBeginStackOf(host_window, popup_window))' test. + // But it would requires more work on our end because the dock host windows is technically created in NewFrame() + // and our ->ParentXXX and ->RootXXX pointers inside windows are currently mislading or lacking. + ImGuiContext& g = *GImGui; + for (int i = g.OpenPopupStack.Size - 1; i >= 0; i--) + if (ImGuiWindow* popup_window = g.OpenPopupStack[i].Window) + if (ImGui::IsWindowWithinBeginStackOf(payload, popup_window)) // Payload is created from within a popup begin stack. + return false; + + return true; +} + +static bool ImGui::DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* root_payload) +{ + if (root_payload->DockNodeAsHost && root_payload->DockNodeAsHost->IsSplitNode()) // FIXME-DOCK: Missing filtering + return true; + + const int payload_count = root_payload->DockNodeAsHost ? root_payload->DockNodeAsHost->Windows.Size : 1; + for (int payload_n = 0; payload_n < payload_count; payload_n++) + { + ImGuiWindow* payload = root_payload->DockNodeAsHost ? root_payload->DockNodeAsHost->Windows[payload_n] : root_payload; + if (DockNodeIsDropAllowedOne(payload, host_window)) + return true; + } + return false; +} + +// window menu button == collapse button when not in a dock node. +// FIXME: This is similar to RenderWindowTitleBarContents(), may want to share code. +static void ImGui::DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_window_menu_button_pos, ImVec2* out_close_button_pos) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + + ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + g.FontSize + g.Style.FramePadding.y * 2.0f); + if (out_title_rect) { *out_title_rect = r; } + + r.Min.x += style.WindowBorderSize; + r.Max.x -= style.WindowBorderSize; + + float button_sz = g.FontSize; + + ImVec2 window_menu_button_pos = r.Min; + r.Min.x += style.FramePadding.x; + r.Max.x -= style.FramePadding.x; + if (node->HasCloseButton) + { + r.Max.x -= button_sz; + if (out_close_button_pos) *out_close_button_pos = ImVec2(r.Max.x - style.FramePadding.x, r.Min.y); + } + if (node->HasWindowMenuButton && style.WindowMenuButtonPosition == ImGuiDir_Left) + { + r.Min.x += button_sz + style.ItemInnerSpacing.x; + } + else if (node->HasWindowMenuButton && style.WindowMenuButtonPosition == ImGuiDir_Right) + { + r.Max.x -= button_sz + style.FramePadding.x; + window_menu_button_pos = ImVec2(r.Max.x, r.Min.y); + } + if (out_tab_bar_rect) { *out_tab_bar_rect = r; } + if (out_window_menu_button_pos) { *out_window_menu_button_pos = window_menu_button_pos; } +} + +void ImGui::DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired) +{ + ImGuiContext& g = *GImGui; + const float dock_spacing = g.Style.ItemInnerSpacing.x; + const ImGuiAxis axis = (dir == ImGuiDir_Left || dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; + pos_new[axis ^ 1] = pos_old[axis ^ 1]; + size_new[axis ^ 1] = size_old[axis ^ 1]; + + // Distribute size on given axis (with a desired size or equally) + const float w_avail = size_old[axis] - dock_spacing; + if (size_new_desired[axis] > 0.0f && size_new_desired[axis] <= w_avail * 0.5f) + { + size_new[axis] = size_new_desired[axis]; + size_old[axis] = IM_FLOOR(w_avail - size_new[axis]); + } + else + { + size_new[axis] = IM_FLOOR(w_avail * 0.5f); + size_old[axis] = IM_FLOOR(w_avail - size_new[axis]); + } + + // Position each node + if (dir == ImGuiDir_Right || dir == ImGuiDir_Down) + { + pos_new[axis] = pos_old[axis] + size_old[axis] + dock_spacing; + } + else if (dir == ImGuiDir_Left || dir == ImGuiDir_Up) + { + pos_new[axis] = pos_old[axis]; + pos_old[axis] = pos_new[axis] + size_new[axis] + dock_spacing; + } +} + +// Retrieve the drop rectangles for a given direction or for the center + perform hit testing. +bool ImGui::DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_r, bool outer_docking, ImVec2* test_mouse_pos) +{ + ImGuiContext& g = *GImGui; + + const float parent_smaller_axis = ImMin(parent.GetWidth(), parent.GetHeight()); + const float hs_for_central_nodes = ImMin(g.FontSize * 1.5f, ImMax(g.FontSize * 0.5f, parent_smaller_axis / 8.0f)); + float hs_w; // Half-size, longer axis + float hs_h; // Half-size, smaller axis + ImVec2 off; // Distance from edge or center + if (outer_docking) + { + //hs_w = ImFloor(ImClamp(parent_smaller_axis - hs_for_central_nodes * 4.0f, g.FontSize * 0.5f, g.FontSize * 8.0f)); + //hs_h = ImFloor(hs_w * 0.15f); + //off = ImVec2(ImFloor(parent.GetWidth() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h), ImFloor(parent.GetHeight() * 0.5f - GetFrameHeightWithSpacing() * 1.4f - hs_h)); + hs_w = ImFloor(hs_for_central_nodes * 1.50f); + hs_h = ImFloor(hs_for_central_nodes * 0.80f); + off = ImVec2(ImFloor(parent.GetWidth() * 0.5f - hs_h), ImFloor(parent.GetHeight() * 0.5f - hs_h)); + } + else + { + hs_w = ImFloor(hs_for_central_nodes); + hs_h = ImFloor(hs_for_central_nodes * 0.90f); + off = ImVec2(ImFloor(hs_w * 2.40f), ImFloor(hs_w * 2.40f)); + } + + ImVec2 c = ImFloor(parent.GetCenter()); + if (dir == ImGuiDir_None) { out_r = ImRect(c.x - hs_w, c.y - hs_w, c.x + hs_w, c.y + hs_w); } + else if (dir == ImGuiDir_Up) { out_r = ImRect(c.x - hs_w, c.y - off.y - hs_h, c.x + hs_w, c.y - off.y + hs_h); } + else if (dir == ImGuiDir_Down) { out_r = ImRect(c.x - hs_w, c.y + off.y - hs_h, c.x + hs_w, c.y + off.y + hs_h); } + else if (dir == ImGuiDir_Left) { out_r = ImRect(c.x - off.x - hs_h, c.y - hs_w, c.x - off.x + hs_h, c.y + hs_w); } + else if (dir == ImGuiDir_Right) { out_r = ImRect(c.x + off.x - hs_h, c.y - hs_w, c.x + off.x + hs_h, c.y + hs_w); } + + if (test_mouse_pos == NULL) + return false; + + ImRect hit_r = out_r; + if (!outer_docking) + { + // Custom hit testing for the 5-way selection, designed to reduce flickering when moving diagonally between sides + hit_r.Expand(ImFloor(hs_w * 0.30f)); + ImVec2 mouse_delta = (*test_mouse_pos - c); + float mouse_delta_len2 = ImLengthSqr(mouse_delta); + float r_threshold_center = hs_w * 1.4f; + float r_threshold_sides = hs_w * (1.4f + 1.2f); + if (mouse_delta_len2 < r_threshold_center * r_threshold_center) + return (dir == ImGuiDir_None); + if (mouse_delta_len2 < r_threshold_sides * r_threshold_sides) + return (dir == ImGetDirQuadrantFromDelta(mouse_delta.x, mouse_delta.y)); + } + return hit_r.Contains(*test_mouse_pos); +} + +// host_node may be NULL if the window doesn't have a DockNode already. +// FIXME-DOCK: This is misnamed since it's also doing the filtering. +static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, ImGuiDockPreviewData* data, bool is_explicit_target, bool is_outer_docking) +{ + ImGuiContext& g = *GImGui; + + // There is an edge case when docking into a dockspace which only has inactive nodes. + // In this case DockNodeTreeFindNodeByPos() will have selected a leaf node which is inactive. + // Because the inactive leaf node doesn't have proper pos/size yet, we'll use the root node as reference. + ImGuiDockNode* root_payload_as_host = root_payload->DockNodeAsHost; + ImGuiDockNode* ref_node_for_rect = (host_node && !host_node->IsVisible) ? DockNodeGetRootNode(host_node) : host_node; + if (ref_node_for_rect) + IM_ASSERT(ref_node_for_rect->IsVisible); + + // Filter, figure out where we are allowed to dock + ImGuiDockNodeFlags src_node_flags = root_payload_as_host ? root_payload_as_host->MergedFlags : root_payload->WindowClass.DockNodeFlagsOverrideSet; + ImGuiDockNodeFlags dst_node_flags = host_node ? host_node->MergedFlags : host_window->WindowClass.DockNodeFlagsOverrideSet; + data->IsCenterAvailable = true; + if (is_outer_docking) + data->IsCenterAvailable = false; + else if (dst_node_flags & ImGuiDockNodeFlags_NoDocking) + data->IsCenterAvailable = false; + else if (host_node && (dst_node_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) && host_node->IsCentralNode()) + data->IsCenterAvailable = false; + else if ((!host_node || !host_node->IsEmpty()) && root_payload_as_host && root_payload_as_host->IsSplitNode() && (root_payload_as_host->OnlyNodeWithWindows == NULL)) // Is _visibly_ split? + data->IsCenterAvailable = false; + else if (dst_node_flags & ImGuiDockNodeFlags_NoDockingOverMe) + data->IsCenterAvailable = false; + else if ((src_node_flags & ImGuiDockNodeFlags_NoDockingOverOther) && (!host_node || !host_node->IsEmpty())) + data->IsCenterAvailable = false; + else if ((src_node_flags & ImGuiDockNodeFlags_NoDockingOverEmpty) && host_node && host_node->IsEmpty()) + data->IsCenterAvailable = false; + + data->IsSidesAvailable = true; + if ((dst_node_flags & ImGuiDockNodeFlags_NoSplit) || g.IO.ConfigDockingNoSplit) + data->IsSidesAvailable = false; + else if (!is_outer_docking && host_node && host_node->ParentNode == NULL && host_node->IsCentralNode()) + data->IsSidesAvailable = false; + else if ((dst_node_flags & ImGuiDockNodeFlags_NoDockingSplitMe) || (src_node_flags & ImGuiDockNodeFlags_NoDockingSplitOther)) + data->IsSidesAvailable = false; + + // Build a tentative future node (reuse same structure because it is practical. Shape will be readjusted when previewing a split) + data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (root_payload->HasCloseButton); + data->FutureNode.HasWindowMenuButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0); + data->FutureNode.Pos = ref_node_for_rect ? ref_node_for_rect->Pos : host_window->Pos; + data->FutureNode.Size = ref_node_for_rect ? ref_node_for_rect->Size : host_window->Size; + + // Calculate drop shapes geometry for allowed splitting directions + IM_ASSERT(ImGuiDir_None == -1); + data->SplitNode = host_node; + data->SplitDir = ImGuiDir_None; + data->IsSplitDirExplicit = false; + if (!host_window->Collapsed) + for (int dir = ImGuiDir_None; dir < ImGuiDir_COUNT; dir++) + { + if (dir == ImGuiDir_None && !data->IsCenterAvailable) + continue; + if (dir != ImGuiDir_None && !data->IsSidesAvailable) + continue; + if (DockNodeCalcDropRectsAndTestMousePos(data->FutureNode.Rect(), (ImGuiDir)dir, data->DropRectsDraw[dir+1], is_outer_docking, &g.IO.MousePos)) + { + data->SplitDir = (ImGuiDir)dir; + data->IsSplitDirExplicit = true; + } + } + + // When docking without holding Shift, we only allow and preview docking when hovering over a drop rect or over the title bar + data->IsDropAllowed = (data->SplitDir != ImGuiDir_None) || (data->IsCenterAvailable); + if (!is_explicit_target && !data->IsSplitDirExplicit && !g.IO.ConfigDockingWithShift) + data->IsDropAllowed = false; + + // Calculate split area + data->SplitRatio = 0.0f; + if (data->SplitDir != ImGuiDir_None) + { + ImGuiDir split_dir = data->SplitDir; + ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; + ImVec2 pos_new, pos_old = data->FutureNode.Pos; + ImVec2 size_new, size_old = data->FutureNode.Size; + DockNodeCalcSplitRects(pos_old, size_old, pos_new, size_new, split_dir, root_payload->Size); + + // Calculate split ratio so we can pass it down the docking request + float split_ratio = ImSaturate(size_new[split_axis] / data->FutureNode.Size[split_axis]); + data->FutureNode.Pos = pos_new; + data->FutureNode.Size = size_new; + data->SplitRatio = (split_dir == ImGuiDir_Right || split_dir == ImGuiDir_Down) ? (1.0f - split_ratio) : (split_ratio); + } +} + +static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, const ImGuiDockPreviewData* data) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindow == host_window); // Because we rely on font size to calculate tab sizes + + // With this option, we only display the preview on the target viewport, and the payload viewport is made transparent. + // To compensate for the single layer obstructed by the payload, we'll increase the alpha of the preview nodes. + const bool is_transparent_payload = g.IO.ConfigDockingTransparentPayload; + + // In case the two windows involved are on different viewports, we will draw the overlay on each of them. + int overlay_draw_lists_count = 0; + ImDrawList* overlay_draw_lists[2]; + overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(host_window->Viewport); + if (host_window->Viewport != root_payload->Viewport && !is_transparent_payload) + overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(root_payload->Viewport); + + // Draw main preview rectangle + const ImU32 overlay_col_main = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.60f : 0.40f); + const ImU32 overlay_col_drop = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 0.90f : 0.70f); + const ImU32 overlay_col_drop_hovered = GetColorU32(ImGuiCol_DockingPreview, is_transparent_payload ? 1.20f : 1.00f); + const ImU32 overlay_col_lines = GetColorU32(ImGuiCol_NavWindowingHighlight, is_transparent_payload ? 0.80f : 0.60f); + + // Display area preview + const bool can_preview_tabs = (root_payload->DockNodeAsHost == NULL || root_payload->DockNodeAsHost->Windows.Size > 0); + if (data->IsDropAllowed) + { + ImRect overlay_rect = data->FutureNode.Rect(); + if (data->SplitDir == ImGuiDir_None && can_preview_tabs) + overlay_rect.Min.y += GetFrameHeight(); + if (data->SplitDir != ImGuiDir_None || data->IsCenterAvailable) + for (int overlay_n = 0; overlay_n < overlay_draw_lists_count; overlay_n++) + overlay_draw_lists[overlay_n]->AddRectFilled(overlay_rect.Min, overlay_rect.Max, overlay_col_main, host_window->WindowRounding, CalcRoundingFlagsForRectInRect(overlay_rect, host_window->Rect(), DOCKING_SPLITTER_SIZE)); + } + + // Display tab shape/label preview unless we are splitting node (it generally makes the situation harder to read) + if (data->IsDropAllowed && can_preview_tabs && data->SplitDir == ImGuiDir_None && data->IsCenterAvailable) + { + // Compute target tab bar geometry so we can locate our preview tabs + ImRect tab_bar_rect; + DockNodeCalcTabBarLayout(&data->FutureNode, NULL, &tab_bar_rect, NULL, NULL); + ImVec2 tab_pos = tab_bar_rect.Min; + if (host_node && host_node->TabBar) + { + if (!host_node->IsHiddenTabBar() && !host_node->IsNoTabBar()) + tab_pos.x += host_node->TabBar->WidthAllTabs + g.Style.ItemInnerSpacing.x; // We don't use OffsetNewTab because when using non-persistent-order tab bar it is incremented with each Tab submission. + else + tab_pos.x += g.Style.ItemInnerSpacing.x + TabItemCalcSize(host_node->Windows[0]->Name, host_node->Windows[0]->HasCloseButton).x; + } + else if (!(host_window->Flags & ImGuiWindowFlags_DockNodeHost)) + { + tab_pos.x += g.Style.ItemInnerSpacing.x + TabItemCalcSize(host_window->Name, host_window->HasCloseButton).x; // Account for slight offset which will be added when changing from title bar to tab bar + } + + // Draw tab shape/label preview (payload may be a loose window or a host window carrying multiple tabbed windows) + if (root_payload->DockNodeAsHost) + IM_ASSERT(root_payload->DockNodeAsHost->Windows.Size <= root_payload->DockNodeAsHost->TabBar->Tabs.Size); + ImGuiTabBar* tab_bar_with_payload = root_payload->DockNodeAsHost ? root_payload->DockNodeAsHost->TabBar : NULL; + const int payload_count = tab_bar_with_payload ? tab_bar_with_payload->Tabs.Size : 1; + for (int payload_n = 0; payload_n < payload_count; payload_n++) + { + // DockNode's TabBar may have non-window Tabs manually appended by user + ImGuiWindow* payload_window = tab_bar_with_payload ? tab_bar_with_payload->Tabs[payload_n].Window : root_payload; + if (tab_bar_with_payload && payload_window == NULL) + continue; + if (!DockNodeIsDropAllowedOne(payload_window, host_window)) + continue; + + // Calculate the tab bounding box for each payload window + ImVec2 tab_size = TabItemCalcSize(payload_window->Name, payload_window->HasCloseButton); + ImRect tab_bb(tab_pos.x, tab_pos.y, tab_pos.x + tab_size.x, tab_pos.y + tab_size.y); + tab_pos.x += tab_size.x + g.Style.ItemInnerSpacing.x; + const ImU32 overlay_col_text = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_Text]); + const ImU32 overlay_col_tabs = GetColorU32(payload_window->DockStyle.Colors[ImGuiWindowDockStyleCol_TabActive]); + PushStyleColor(ImGuiCol_Text, overlay_col_text); + for (int overlay_n = 0; overlay_n < overlay_draw_lists_count; overlay_n++) + { + ImGuiTabItemFlags tab_flags = ImGuiTabItemFlags_Preview | ((payload_window->Flags & ImGuiWindowFlags_UnsavedDocument) ? ImGuiTabItemFlags_UnsavedDocument : 0); + if (!tab_bar_rect.Contains(tab_bb)) + overlay_draw_lists[overlay_n]->PushClipRect(tab_bar_rect.Min, tab_bar_rect.Max); + TabItemBackground(overlay_draw_lists[overlay_n], tab_bb, tab_flags, overlay_col_tabs); + TabItemLabelAndCloseButton(overlay_draw_lists[overlay_n], tab_bb, tab_flags, g.Style.FramePadding, payload_window->Name, 0, 0, false, NULL, NULL); + if (!tab_bar_rect.Contains(tab_bb)) + overlay_draw_lists[overlay_n]->PopClipRect(); + } + PopStyleColor(); + } + } + + // Display drop boxes + const float overlay_rounding = ImMax(3.0f, g.Style.FrameRounding); + for (int dir = ImGuiDir_None; dir < ImGuiDir_COUNT; dir++) + { + if (!data->DropRectsDraw[dir + 1].IsInverted()) + { + ImRect draw_r = data->DropRectsDraw[dir + 1]; + ImRect draw_r_in = draw_r; + draw_r_in.Expand(-2.0f); + ImU32 overlay_col = (data->SplitDir == (ImGuiDir)dir && data->IsSplitDirExplicit) ? overlay_col_drop_hovered : overlay_col_drop; + for (int overlay_n = 0; overlay_n < overlay_draw_lists_count; overlay_n++) + { + ImVec2 center = ImFloor(draw_r_in.GetCenter()); + overlay_draw_lists[overlay_n]->AddRectFilled(draw_r.Min, draw_r.Max, overlay_col, overlay_rounding); + overlay_draw_lists[overlay_n]->AddRect(draw_r_in.Min, draw_r_in.Max, overlay_col_lines, overlay_rounding); + if (dir == ImGuiDir_Left || dir == ImGuiDir_Right) + overlay_draw_lists[overlay_n]->AddLine(ImVec2(center.x, draw_r_in.Min.y), ImVec2(center.x, draw_r_in.Max.y), overlay_col_lines); + if (dir == ImGuiDir_Up || dir == ImGuiDir_Down) + overlay_draw_lists[overlay_n]->AddLine(ImVec2(draw_r_in.Min.x, center.y), ImVec2(draw_r_in.Max.x, center.y), overlay_col_lines); + } + } + + // Stop after ImGuiDir_None + if ((host_node && (host_node->MergedFlags & ImGuiDockNodeFlags_NoSplit)) || g.IO.ConfigDockingNoSplit) + return; + } +} + +//----------------------------------------------------------------------------- +// Docking: ImGuiDockNode Tree manipulation functions +//----------------------------------------------------------------------------- +// - DockNodeTreeSplit() +// - DockNodeTreeMerge() +// - DockNodeTreeUpdatePosSize() +// - DockNodeTreeUpdateSplitterFindTouchingNode() +// - DockNodeTreeUpdateSplitter() +// - DockNodeTreeFindFallbackLeafNode() +// - DockNodeTreeFindNodeByPos() +//----------------------------------------------------------------------------- + +void ImGui::DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiAxis split_axis, int split_inheritor_child_idx, float split_ratio, ImGuiDockNode* new_node) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(split_axis != ImGuiAxis_None); + + ImGuiDockNode* child_0 = (new_node && split_inheritor_child_idx != 0) ? new_node : DockContextAddNode(ctx, 0); + child_0->ParentNode = parent_node; + + ImGuiDockNode* child_1 = (new_node && split_inheritor_child_idx != 1) ? new_node : DockContextAddNode(ctx, 0); + child_1->ParentNode = parent_node; + + ImGuiDockNode* child_inheritor = (split_inheritor_child_idx == 0) ? child_0 : child_1; + DockNodeMoveChildNodes(child_inheritor, parent_node); + parent_node->ChildNodes[0] = child_0; + parent_node->ChildNodes[1] = child_1; + parent_node->ChildNodes[split_inheritor_child_idx]->VisibleWindow = parent_node->VisibleWindow; + parent_node->SplitAxis = split_axis; + parent_node->VisibleWindow = NULL; + parent_node->AuthorityForPos = parent_node->AuthorityForSize = ImGuiDataAuthority_DockNode; + + float size_avail = (parent_node->Size[split_axis] - DOCKING_SPLITTER_SIZE); + size_avail = ImMax(size_avail, g.Style.WindowMinSize[split_axis] * 2.0f); + IM_ASSERT(size_avail > 0.0f); // If you created a node manually with DockBuilderAddNode(), you need to also call DockBuilderSetNodeSize() before splitting. + child_0->SizeRef = child_1->SizeRef = parent_node->Size; + child_0->SizeRef[split_axis] = ImFloor(size_avail * split_ratio); + child_1->SizeRef[split_axis] = ImFloor(size_avail - child_0->SizeRef[split_axis]); + + DockNodeMoveWindows(parent_node->ChildNodes[split_inheritor_child_idx], parent_node); + DockSettingsRenameNodeReferences(parent_node->ID, parent_node->ChildNodes[split_inheritor_child_idx]->ID); + DockNodeUpdateHasCentralNodeChild(DockNodeGetRootNode(parent_node)); + DockNodeTreeUpdatePosSize(parent_node, parent_node->Pos, parent_node->Size); + + // Flags transfer (e.g. this is where we transfer the ImGuiDockNodeFlags_CentralNode property) + child_0->SharedFlags = parent_node->SharedFlags & ImGuiDockNodeFlags_SharedFlagsInheritMask_; + child_1->SharedFlags = parent_node->SharedFlags & ImGuiDockNodeFlags_SharedFlagsInheritMask_; + child_inheritor->LocalFlags = parent_node->LocalFlags & ImGuiDockNodeFlags_LocalFlagsTransferMask_; + parent_node->LocalFlags &= ~ImGuiDockNodeFlags_LocalFlagsTransferMask_; + child_0->UpdateMergedFlags(); + child_1->UpdateMergedFlags(); + parent_node->UpdateMergedFlags(); + if (child_inheritor->IsCentralNode()) + DockNodeGetRootNode(parent_node)->CentralNode = child_inheritor; +} + +void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiDockNode* merge_lead_child) +{ + // When called from DockContextProcessUndockNode() it is possible that one of the child is NULL. + ImGuiDockNode* child_0 = parent_node->ChildNodes[0]; + ImGuiDockNode* child_1 = parent_node->ChildNodes[1]; + IM_ASSERT(child_0 || child_1); + IM_ASSERT(merge_lead_child == child_0 || merge_lead_child == child_1); + if ((child_0 && child_0->Windows.Size > 0) || (child_1 && child_1->Windows.Size > 0)) + { + IM_ASSERT(parent_node->TabBar == NULL); + IM_ASSERT(parent_node->Windows.Size == 0); + } + IMGUI_DEBUG_LOG_DOCKING("DockNodeTreeMerge 0x%08X & 0x%08X back into parent 0x%08X\n", child_0 ? child_0->ID : 0, child_1 ? child_1->ID : 0, parent_node->ID); + + ImVec2 backup_last_explicit_size = parent_node->SizeRef; + DockNodeMoveChildNodes(parent_node, merge_lead_child); + if (child_0) + { + DockNodeMoveWindows(parent_node, child_0); // Generally only 1 of the 2 child node will have windows + DockSettingsRenameNodeReferences(child_0->ID, parent_node->ID); + } + if (child_1) + { + DockNodeMoveWindows(parent_node, child_1); + DockSettingsRenameNodeReferences(child_1->ID, parent_node->ID); + } + DockNodeApplyPosSizeToWindows(parent_node); + parent_node->AuthorityForPos = parent_node->AuthorityForSize = parent_node->AuthorityForViewport = ImGuiDataAuthority_Auto; + parent_node->VisibleWindow = merge_lead_child->VisibleWindow; + parent_node->SizeRef = backup_last_explicit_size; + + // Flags transfer + parent_node->LocalFlags &= ~ImGuiDockNodeFlags_LocalFlagsTransferMask_; // Preserve Dockspace flag + parent_node->LocalFlags |= (child_0 ? child_0->LocalFlags : 0) & ImGuiDockNodeFlags_LocalFlagsTransferMask_; + parent_node->LocalFlags |= (child_1 ? child_1->LocalFlags : 0) & ImGuiDockNodeFlags_LocalFlagsTransferMask_; + parent_node->LocalFlagsInWindows = (child_0 ? child_0->LocalFlagsInWindows : 0) | (child_1 ? child_1->LocalFlagsInWindows : 0); // FIXME: Would be more consistent to update from actual windows + parent_node->UpdateMergedFlags(); + + if (child_0) + { + ctx->DockContext.Nodes.SetVoidPtr(child_0->ID, NULL); + IM_DELETE(child_0); + } + if (child_1) + { + ctx->DockContext.Nodes.SetVoidPtr(child_1->ID, NULL); + IM_DELETE(child_1); + } +} + +// Update Pos/Size for a node hierarchy (don't affect child Windows yet) +// (Depth-first, Pre-Order) +void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, ImGuiDockNode* only_write_to_single_node) +{ + // During the regular dock node update we write to all nodes. + // 'only_write_to_single_node' is only set when turning a node visible mid-frame and we need its size right-away. + const bool write_to_node = only_write_to_single_node == NULL || only_write_to_single_node == node; + if (write_to_node) + { + node->Pos = pos; + node->Size = size; + } + + if (node->IsLeafNode()) + return; + + ImGuiDockNode* child_0 = node->ChildNodes[0]; + ImGuiDockNode* child_1 = node->ChildNodes[1]; + ImVec2 child_0_pos = pos, child_1_pos = pos; + ImVec2 child_0_size = size, child_1_size = size; + + const bool child_0_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_0)); + const bool child_1_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_1)); + const bool child_0_is_or_will_be_visible = child_0->IsVisible || child_0_is_toward_single_node; + const bool child_1_is_or_will_be_visible = child_1->IsVisible || child_1_is_toward_single_node; + + if (child_0_is_or_will_be_visible && child_1_is_or_will_be_visible) + { + ImGuiContext& g = *GImGui; + const float spacing = DOCKING_SPLITTER_SIZE; + const ImGuiAxis axis = (ImGuiAxis)node->SplitAxis; + const float size_avail = ImMax(size[axis] - spacing, 0.0f); + + // Size allocation policy + // 1) The first 0..WindowMinSize[axis]*2 are allocated evenly to both windows. + const float size_min_each = ImFloor(ImMin(size_avail, g.Style.WindowMinSize[axis] * 2.0f) * 0.5f); + + // FIXME: Blocks 2) and 3) are essentially doing nearly the same thing. + // Difference are: write-back to SizeRef; application of a minimum size; rounding before ImFloor() + // Clarify and rework differences between Size & SizeRef and purpose of WantLockSizeOnce + + // 2) Process locked absolute size (during a splitter resize we preserve the child of nodes not touching the splitter edge) + if (child_0->WantLockSizeOnce && !child_1->WantLockSizeOnce) + { + child_0_size[axis] = child_0->SizeRef[axis] = ImMin(size_avail - 1.0f, child_0->Size[axis]); + child_1_size[axis] = child_1->SizeRef[axis] = (size_avail - child_0_size[axis]); + IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); + } + else if (child_1->WantLockSizeOnce && !child_0->WantLockSizeOnce) + { + child_1_size[axis] = child_1->SizeRef[axis] = ImMin(size_avail - 1.0f, child_1->Size[axis]); + child_0_size[axis] = child_0->SizeRef[axis] = (size_avail - child_1_size[axis]); + IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); + } + else if (child_0->WantLockSizeOnce && child_1->WantLockSizeOnce) + { + // FIXME-DOCK: We cannot honor the requested size, so apply ratio. + // Currently this path will only be taken if code programmatically sets WantLockSizeOnce + float split_ratio = child_0_size[axis] / (child_0_size[axis] + child_1_size[axis]); + child_0_size[axis] = child_0->SizeRef[axis] = ImFloor(size_avail * split_ratio); + child_1_size[axis] = child_1->SizeRef[axis] = (size_avail - child_0_size[axis]); + IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); + } + + // 3) If one window is the central node (~ use remaining space, should be made explicit!), use explicit size from the other, and remainder for the central node + else if (child_0->SizeRef[axis] != 0.0f && child_1->HasCentralNodeChild) + { + child_0_size[axis] = ImMin(size_avail - size_min_each, child_0->SizeRef[axis]); + child_1_size[axis] = (size_avail - child_0_size[axis]); + } + else if (child_1->SizeRef[axis] != 0.0f && child_0->HasCentralNodeChild) + { + child_1_size[axis] = ImMin(size_avail - size_min_each, child_1->SizeRef[axis]); + child_0_size[axis] = (size_avail - child_1_size[axis]); + } + else + { + // 4) Otherwise distribute according to the relative ratio of each SizeRef value + float split_ratio = child_0->SizeRef[axis] / (child_0->SizeRef[axis] + child_1->SizeRef[axis]); + child_0_size[axis] = ImMax(size_min_each, ImFloor(size_avail * split_ratio + 0.5f)); + child_1_size[axis] = (size_avail - child_0_size[axis]); + } + + child_1_pos[axis] += spacing + child_0_size[axis]; + } + + if (only_write_to_single_node == NULL) + child_0->WantLockSizeOnce = child_1->WantLockSizeOnce = false; + + const bool child_0_recurse = only_write_to_single_node ? child_0_is_toward_single_node : child_0->IsVisible; + const bool child_1_recurse = only_write_to_single_node ? child_1_is_toward_single_node : child_1->IsVisible; + if (child_0_recurse) + DockNodeTreeUpdatePosSize(child_0, child_0_pos, child_0_size); + if (child_1_recurse) + DockNodeTreeUpdatePosSize(child_1, child_1_pos, child_1_size); +} + +static void DockNodeTreeUpdateSplitterFindTouchingNode(ImGuiDockNode* node, ImGuiAxis axis, int side, ImVector* touching_nodes) +{ + if (node->IsLeafNode()) + { + touching_nodes->push_back(node); + return; + } + if (node->ChildNodes[0]->IsVisible) + if (node->SplitAxis != axis || side == 0 || !node->ChildNodes[1]->IsVisible) + DockNodeTreeUpdateSplitterFindTouchingNode(node->ChildNodes[0], axis, side, touching_nodes); + if (node->ChildNodes[1]->IsVisible) + if (node->SplitAxis != axis || side == 1 || !node->ChildNodes[0]->IsVisible) + DockNodeTreeUpdateSplitterFindTouchingNode(node->ChildNodes[1], axis, side, touching_nodes); +} + +// (Depth-First, Pre-Order) +void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node) +{ + if (node->IsLeafNode()) + return; + + ImGuiContext& g = *GImGui; + + ImGuiDockNode* child_0 = node->ChildNodes[0]; + ImGuiDockNode* child_1 = node->ChildNodes[1]; + if (child_0->IsVisible && child_1->IsVisible) + { + // Bounding box of the splitter cover the space between both nodes (w = Spacing, h = Size[xy^1] for when splitting horizontally) + const ImGuiAxis axis = (ImGuiAxis)node->SplitAxis; + IM_ASSERT(axis != ImGuiAxis_None); + ImRect bb; + bb.Min = child_0->Pos; + bb.Max = child_1->Pos; + bb.Min[axis] += child_0->Size[axis]; + bb.Max[axis ^ 1] += child_1->Size[axis ^ 1]; + //if (g.IO.KeyCtrl) GetForegroundDrawList(g.CurrentWindow->Viewport)->AddRect(bb.Min, bb.Max, IM_COL32(255,0,255,255)); + + const ImGuiDockNodeFlags merged_flags = child_0->MergedFlags | child_1->MergedFlags; // Merged flags for BOTH childs + const ImGuiDockNodeFlags no_resize_axis_flag = (axis == ImGuiAxis_X) ? ImGuiDockNodeFlags_NoResizeX : ImGuiDockNodeFlags_NoResizeY; + if ((merged_flags & ImGuiDockNodeFlags_NoResize) || (merged_flags & no_resize_axis_flag)) + { + ImGuiWindow* window = g.CurrentWindow; + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator), g.Style.FrameRounding); + } + else + { + //bb.Min[axis] += 1; // Display a little inward so highlight doesn't connect with nearby tabs on the neighbor node. + //bb.Max[axis] -= 1; + PushID(node->ID); + + // Find resizing limits by gathering list of nodes that are touching the splitter line. + ImVector touching_nodes[2]; + float min_size = g.Style.WindowMinSize[axis]; + float resize_limits[2]; + resize_limits[0] = node->ChildNodes[0]->Pos[axis] + min_size; + resize_limits[1] = node->ChildNodes[1]->Pos[axis] + node->ChildNodes[1]->Size[axis] - min_size; + + ImGuiID splitter_id = GetID("##Splitter"); + if (g.ActiveId == splitter_id) // Only process when splitter is active + { + DockNodeTreeUpdateSplitterFindTouchingNode(child_0, axis, 1, &touching_nodes[0]); + DockNodeTreeUpdateSplitterFindTouchingNode(child_1, axis, 0, &touching_nodes[1]); + for (int touching_node_n = 0; touching_node_n < touching_nodes[0].Size; touching_node_n++) + resize_limits[0] = ImMax(resize_limits[0], touching_nodes[0][touching_node_n]->Rect().Min[axis] + min_size); + for (int touching_node_n = 0; touching_node_n < touching_nodes[1].Size; touching_node_n++) + resize_limits[1] = ImMin(resize_limits[1], touching_nodes[1][touching_node_n]->Rect().Max[axis] - min_size); + + // [DEBUG] Render touching nodes & limits + /* + ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); + for (int n = 0; n < 2; n++) + { + for (int touching_node_n = 0; touching_node_n < touching_nodes[n].Size; touching_node_n++) + draw_list->AddRect(touching_nodes[n][touching_node_n]->Pos, touching_nodes[n][touching_node_n]->Pos + touching_nodes[n][touching_node_n]->Size, IM_COL32(0, 255, 0, 255)); + if (axis == ImGuiAxis_X) + draw_list->AddLine(ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y), ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y + node->ChildNodes[n]->Size.y), IM_COL32(255, 0, 255, 255), 3.0f); + else + draw_list->AddLine(ImVec2(node->ChildNodes[n]->Pos.x, resize_limits[n]), ImVec2(node->ChildNodes[n]->Pos.x + node->ChildNodes[n]->Size.x, resize_limits[n]), IM_COL32(255, 0, 255, 255), 3.0f); + } + */ + } + + // Use a short delay before highlighting the splitter (and changing the mouse cursor) in order for regular mouse movement to not highlight many splitters + float cur_size_0 = child_0->Size[axis]; + float cur_size_1 = child_1->Size[axis]; + float min_size_0 = resize_limits[0] - child_0->Pos[axis]; + float min_size_1 = child_1->Pos[axis] + child_1->Size[axis] - resize_limits[1]; + ImU32 bg_col = GetColorU32(ImGuiCol_WindowBg); + if (SplitterBehavior(bb, GetID("##Splitter"), axis, &cur_size_0, &cur_size_1, min_size_0, min_size_1, WINDOWS_HOVER_PADDING, WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER, bg_col)) + { + if (touching_nodes[0].Size > 0 && touching_nodes[1].Size > 0) + { + child_0->Size[axis] = child_0->SizeRef[axis] = cur_size_0; + child_1->Pos[axis] -= cur_size_1 - child_1->Size[axis]; + child_1->Size[axis] = child_1->SizeRef[axis] = cur_size_1; + + // Lock the size of every node that is a sibling of the node we are touching + // This might be less desirable if we can merge sibling of a same axis into the same parental level. + for (int side_n = 0; side_n < 2; side_n++) + for (int touching_node_n = 0; touching_node_n < touching_nodes[side_n].Size; touching_node_n++) + { + ImGuiDockNode* touching_node = touching_nodes[side_n][touching_node_n]; + //ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); + //draw_list->AddRect(touching_node->Pos, touching_node->Pos + touching_node->Size, IM_COL32(255, 128, 0, 255)); + while (touching_node->ParentNode != node) + { + if (touching_node->ParentNode->SplitAxis == axis) + { + // Mark other node so its size will be preserved during the upcoming call to DockNodeTreeUpdatePosSize(). + ImGuiDockNode* node_to_preserve = touching_node->ParentNode->ChildNodes[side_n]; + node_to_preserve->WantLockSizeOnce = true; + //draw_list->AddRect(touching_node->Pos, touching_node->Rect().Max, IM_COL32(255, 0, 0, 255)); + //draw_list->AddRectFilled(node_to_preserve->Pos, node_to_preserve->Rect().Max, IM_COL32(0, 255, 0, 100)); + } + touching_node = touching_node->ParentNode; + } + } + + DockNodeTreeUpdatePosSize(child_0, child_0->Pos, child_0->Size); + DockNodeTreeUpdatePosSize(child_1, child_1->Pos, child_1->Size); + MarkIniSettingsDirty(); + } + } + PopID(); + } + } + + if (child_0->IsVisible) + DockNodeTreeUpdateSplitter(child_0); + if (child_1->IsVisible) + DockNodeTreeUpdateSplitter(child_1); +} + +ImGuiDockNode* ImGui::DockNodeTreeFindFallbackLeafNode(ImGuiDockNode* node) +{ + if (node->IsLeafNode()) + return node; + if (ImGuiDockNode* leaf_node = DockNodeTreeFindFallbackLeafNode(node->ChildNodes[0])) + return leaf_node; + if (ImGuiDockNode* leaf_node = DockNodeTreeFindFallbackLeafNode(node->ChildNodes[1])) + return leaf_node; + return NULL; +} + +ImGuiDockNode* ImGui::DockNodeTreeFindVisibleNodeByPos(ImGuiDockNode* node, ImVec2 pos) +{ + if (!node->IsVisible) + return NULL; + + const float dock_spacing = 0.0f;// g.Style.ItemInnerSpacing.x; // FIXME: Relation to DOCKING_SPLITTER_SIZE? + ImRect r(node->Pos, node->Pos + node->Size); + r.Expand(dock_spacing * 0.5f); + bool inside = r.Contains(pos); + if (!inside) + return NULL; + + if (node->IsLeafNode()) + return node; + if (ImGuiDockNode* hovered_node = DockNodeTreeFindVisibleNodeByPos(node->ChildNodes[0], pos)) + return hovered_node; + if (ImGuiDockNode* hovered_node = DockNodeTreeFindVisibleNodeByPos(node->ChildNodes[1], pos)) + return hovered_node; + + return NULL; +} + +//----------------------------------------------------------------------------- +// Docking: Public Functions (SetWindowDock, DockSpace, DockSpaceOverViewport) +//----------------------------------------------------------------------------- +// - SetWindowDock() [Internal] +// - DockSpace() +// - DockSpaceOverViewport() +//----------------------------------------------------------------------------- + +// [Internal] Called via SetNextWindowDockID() +void ImGui::SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond) +{ + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowDockAllowFlags & cond) == 0) + return; + window->SetWindowDockAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + + if (window->DockId == dock_id) + return; + + // If the user attempt to set a dock id that is a split node, we'll dig within to find a suitable docking spot + ImGuiContext* ctx = GImGui; + if (ImGuiDockNode* new_node = DockContextFindNodeByID(ctx, dock_id)) + if (new_node->IsSplitNode()) + { + // Policy: Find central node or latest focused node. We first move back to our root node. + new_node = DockNodeGetRootNode(new_node); + if (new_node->CentralNode) + { + IM_ASSERT(new_node->CentralNode->IsCentralNode()); + dock_id = new_node->CentralNode->ID; + } + else + { + dock_id = new_node->LastFocusedNodeId; + } + } + + if (window->DockId == dock_id) + return; + + if (window->DockNode) + DockNodeRemoveWindow(window->DockNode, window, 0); + window->DockId = dock_id; +} + +// Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a CentralNode by default. +// The Central Node is always displayed even when empty and shrink/extend according to the requested size of its neighbors. +// DockSpace() needs to be submitted _before_ any window they can host. If you use a dockspace, submit it early in your app. +ImGuiID ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class) +{ + ImGuiContext* ctx = GImGui; + ImGuiContext& g = *ctx; + ImGuiWindow* window = GetCurrentWindow(); + if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) + return 0; + + // Early out if parent window is hidden/collapsed + // This is faster but also DockNodeUpdateTabBar() relies on TabBarLayout() running (which won't if SkipItems=true) to set NextSelectedTabId = 0). See #2960. + // If for whichever reason this is causing problem we would need to ensure that DockNodeUpdateTabBar() ends up clearing NextSelectedTabId even if SkipItems=true. + if (window->SkipItems) + flags |= ImGuiDockNodeFlags_KeepAliveOnly; + + IM_ASSERT((flags & ImGuiDockNodeFlags_DockSpace) == 0); + IM_ASSERT(id != 0); + ImGuiDockNode* node = DockContextFindNodeByID(ctx, id); + if (!node) + { + IMGUI_DEBUG_LOG_DOCKING("DockSpace: dockspace node 0x%08X created\n", id); + node = DockContextAddNode(ctx, id); + node->SetLocalFlags(ImGuiDockNodeFlags_CentralNode); + } + if (window_class && window_class->ClassId != node->WindowClass.ClassId) + IMGUI_DEBUG_LOG_DOCKING("DockSpace: dockspace node 0x%08X: setup WindowClass 0x%08X -> 0x%08X\n", id, node->WindowClass.ClassId, window_class->ClassId); + node->SharedFlags = flags; + node->WindowClass = window_class ? *window_class : ImGuiWindowClass(); + + // When a DockSpace transitioned form implicit to explicit this may be called a second time + // It is possible that the node has already been claimed by a docked window which appeared before the DockSpace() node, so we overwrite IsDockSpace again. + if (node->LastFrameActive == g.FrameCount && !(flags & ImGuiDockNodeFlags_KeepAliveOnly)) + { + IM_ASSERT(node->IsDockSpace() == false && "Cannot call DockSpace() twice a frame with the same ID"); + node->SetLocalFlags(node->LocalFlags | ImGuiDockNodeFlags_DockSpace); + return id; + } + node->SetLocalFlags(node->LocalFlags | ImGuiDockNodeFlags_DockSpace); + + // Keep alive mode, this is allow windows docked into this node so stay docked even if they are not visible + if (flags & ImGuiDockNodeFlags_KeepAliveOnly) + { + node->LastFrameAlive = g.FrameCount; + return id; + } + + const ImVec2 content_avail = GetContentRegionAvail(); + ImVec2 size = ImFloor(size_arg); + if (size.x <= 0.0f) + size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) + if (size.y <= 0.0f) + size.y = ImMax(content_avail.y + size.y, 4.0f); + IM_ASSERT(size.x > 0.0f && size.y > 0.0f); + + node->Pos = window->DC.CursorPos; + node->Size = node->SizeRef = size; + SetNextWindowPos(node->Pos); + SetNextWindowSize(node->Size); + g.NextWindowData.PosUndock = false; + + // FIXME-DOCK: Why do we need a child window to host a dockspace, could we host it in the existing window? + // FIXME-DOCK: What is the reason for not simply calling BeginChild()? (OK to have a reason but should be commented) + ImGuiWindowFlags window_flags = ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_DockNodeHost; + window_flags |= ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar; + window_flags |= ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; + window_flags |= ImGuiWindowFlags_NoBackground; + + char title[256]; + ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", window->Name, id); + + PushStyleVar(ImGuiStyleVar_ChildBorderSize, 0.0f); + Begin(title, NULL, window_flags); + PopStyleVar(); + + ImGuiWindow* host_window = g.CurrentWindow; + DockNodeSetupHostWindow(node, host_window); + host_window->ChildId = window->GetID(title); + node->OnlyNodeWithWindows = NULL; + + IM_ASSERT(node->IsRootNode()); + + // We need to handle the rare case were a central node is missing. + // This can happen if the node was first created manually with DockBuilderAddNode() but _without_ the ImGuiDockNodeFlags_Dockspace. + // Doing it correctly would set the _CentralNode flags, which would then propagate according to subsequent split. + // It would also be ambiguous to attempt to assign a central node while there are split nodes, so we wait until there's a single node remaining. + // The specific sub-property of _CentralNode we are interested in recovering here is the "Don't delete when empty" property, + // as it doesn't make sense for an empty dockspace to not have this property. + if (node->IsLeafNode() && !node->IsCentralNode()) + node->SetLocalFlags(node->LocalFlags | ImGuiDockNodeFlags_CentralNode); + + // Update the node + DockNodeUpdate(node); + + End(); + ItemSize(size); + return id; +} + +// Tips: Use with ImGuiDockNodeFlags_PassthruCentralNode! +// The limitation with this call is that your window won't have a menu bar. +// Even though we could pass window flags, it would also require the user to be able to call BeginMenuBar() somehow meaning we can't Begin/End in a single function. +// But you can also use BeginMainMenuBar(). If you really want a menu bar inside the same window as the one hosting the dockspace, you will need to copy this code somewhere and tweak it. +ImGuiID ImGui::DockSpaceOverViewport(const ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class) +{ + if (viewport == NULL) + viewport = GetMainViewport(); + + SetNextWindowPos(viewport->WorkPos); + SetNextWindowSize(viewport->WorkSize); + SetNextWindowViewport(viewport->ID); + + ImGuiWindowFlags host_window_flags = 0; + host_window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking; + host_window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) + host_window_flags |= ImGuiWindowFlags_NoBackground; + + char label[32]; + ImFormatString(label, IM_ARRAYSIZE(label), "DockSpaceViewport_%08X", viewport->ID); + + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + Begin(label, NULL, host_window_flags); + PopStyleVar(3); + + ImGuiID dockspace_id = GetID("DockSpace"); + DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags, window_class); + End(); + + return dockspace_id; +} + +//----------------------------------------------------------------------------- +// Docking: Builder Functions +//----------------------------------------------------------------------------- +// Very early end-user API to manipulate dock nodes. +// Only available in imgui_internal.h. Expect this API to change/break! +// It is expected that those functions are all called _before_ the dockspace node submission. +//----------------------------------------------------------------------------- +// - DockBuilderDockWindow() +// - DockBuilderGetNode() +// - DockBuilderSetNodePos() +// - DockBuilderSetNodeSize() +// - DockBuilderAddNode() +// - DockBuilderRemoveNode() +// - DockBuilderRemoveNodeChildNodes() +// - DockBuilderRemoveNodeDockedWindows() +// - DockBuilderSplitNode() +// - DockBuilderCopyNodeRec() +// - DockBuilderCopyNode() +// - DockBuilderCopyWindowSettings() +// - DockBuilderCopyDockSpace() +// - DockBuilderFinish() +//----------------------------------------------------------------------------- + +void ImGui::DockBuilderDockWindow(const char* window_name, ImGuiID node_id) +{ + // We don't preserve relative order of multiple docked windows (by clearing DockOrder back to -1) + ImGuiID window_id = ImHashStr(window_name); + if (ImGuiWindow* window = FindWindowByID(window_id)) + { + // Apply to created window + SetWindowDock(window, node_id, ImGuiCond_Always); + window->DockOrder = -1; + } + else + { + // Apply to settings + ImGuiWindowSettings* settings = FindWindowSettings(window_id); + if (settings == NULL) + settings = CreateNewWindowSettings(window_name); + settings->DockId = node_id; + settings->DockOrder = -1; + } +} + +ImGuiDockNode* ImGui::DockBuilderGetNode(ImGuiID node_id) +{ + ImGuiContext* ctx = GImGui; + return DockContextFindNodeByID(ctx, node_id); +} + +void ImGui::DockBuilderSetNodePos(ImGuiID node_id, ImVec2 pos) +{ + ImGuiContext* ctx = GImGui; + ImGuiDockNode* node = DockContextFindNodeByID(ctx, node_id); + if (node == NULL) + return; + node->Pos = pos; + node->AuthorityForPos = ImGuiDataAuthority_DockNode; +} + +void ImGui::DockBuilderSetNodeSize(ImGuiID node_id, ImVec2 size) +{ + ImGuiContext* ctx = GImGui; + ImGuiDockNode* node = DockContextFindNodeByID(ctx, node_id); + if (node == NULL) + return; + IM_ASSERT(size.x > 0.0f && size.y > 0.0f); + node->Size = node->SizeRef = size; + node->AuthorityForSize = ImGuiDataAuthority_DockNode; +} + +// Make sure to use the ImGuiDockNodeFlags_DockSpace flag to create a dockspace node! Otherwise this will create a floating node! +// - Floating node: you can then call DockBuilderSetNodePos()/DockBuilderSetNodeSize() to position and size the floating node. +// - Dockspace node: calling DockBuilderSetNodePos() is unnecessary. +// - If you intend to split a node immediately after creation using DockBuilderSplitNode(), make sure to call DockBuilderSetNodeSize() beforehand! +// For various reason, the splitting code currently needs a base size otherwise space may not be allocated as precisely as you would expect. +// - Use (id == 0) to let the system allocate a node identifier. +// - Existing node with a same id will be removed. +ImGuiID ImGui::DockBuilderAddNode(ImGuiID id, ImGuiDockNodeFlags flags) +{ + ImGuiContext* ctx = GImGui; + + if (id != 0) + DockBuilderRemoveNode(id); + + ImGuiDockNode* node = NULL; + if (flags & ImGuiDockNodeFlags_DockSpace) + { + DockSpace(id, ImVec2(0, 0), (flags & ~ImGuiDockNodeFlags_DockSpace) | ImGuiDockNodeFlags_KeepAliveOnly); + node = DockContextFindNodeByID(ctx, id); + } + else + { + node = DockContextAddNode(ctx, id); + node->SetLocalFlags(flags); + } + node->LastFrameAlive = ctx->FrameCount; // Set this otherwise BeginDocked will undock during the same frame. + return node->ID; +} + +void ImGui::DockBuilderRemoveNode(ImGuiID node_id) +{ + ImGuiContext* ctx = GImGui; + ImGuiDockNode* node = DockContextFindNodeByID(ctx, node_id); + if (node == NULL) + return; + DockBuilderRemoveNodeDockedWindows(node_id, true); + DockBuilderRemoveNodeChildNodes(node_id); + // Node may have moved or deleted if e.g. any merge happened + node = DockContextFindNodeByID(ctx, node_id); + if (node == NULL) + return; + if (node->IsCentralNode() && node->ParentNode) + node->ParentNode->SetLocalFlags(node->ParentNode->LocalFlags | ImGuiDockNodeFlags_CentralNode); + DockContextRemoveNode(ctx, node, true); +} + +// root_id = 0 to remove all, root_id != 0 to remove child of given node. +void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiID root_id) +{ + ImGuiContext* ctx = GImGui; + ImGuiDockContext* dc = &ctx->DockContext; + + ImGuiDockNode* root_node = root_id ? DockContextFindNodeByID(ctx, root_id) : NULL; + if (root_id && root_node == NULL) + return; + bool has_central_node = false; + + ImGuiDataAuthority backup_root_node_authority_for_pos = root_node ? root_node->AuthorityForPos : ImGuiDataAuthority_Auto; + ImGuiDataAuthority backup_root_node_authority_for_size = root_node ? root_node->AuthorityForSize : ImGuiDataAuthority_Auto; + + // Process active windows + ImVector nodes_to_remove; + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + { + bool want_removal = (root_id == 0) || (node->ID != root_id && DockNodeGetRootNode(node)->ID == root_id); + if (want_removal) + { + if (node->IsCentralNode()) + has_central_node = true; + if (root_id != 0) + DockContextQueueNotifyRemovedNode(ctx, node); + if (root_node) + { + DockNodeMoveWindows(root_node, node); + DockSettingsRenameNodeReferences(node->ID, root_node->ID); + } + nodes_to_remove.push_back(node); + } + } + + // DockNodeMoveWindows->DockNodeAddWindow will normally set those when reaching two windows (which is only adequate during interactive merge) + // Make sure we don't lose our current pos/size. (FIXME-DOCK: Consider tidying up that code in DockNodeAddWindow instead) + if (root_node) + { + root_node->AuthorityForPos = backup_root_node_authority_for_pos; + root_node->AuthorityForSize = backup_root_node_authority_for_size; + } + + // Apply to settings + for (ImGuiWindowSettings* settings = ctx->SettingsWindows.begin(); settings != NULL; settings = ctx->SettingsWindows.next_chunk(settings)) + if (ImGuiID window_settings_dock_id = settings->DockId) + for (int n = 0; n < nodes_to_remove.Size; n++) + if (nodes_to_remove[n]->ID == window_settings_dock_id) + { + settings->DockId = root_id; + break; + } + + // Not really efficient, but easier to destroy a whole hierarchy considering DockContextRemoveNode is attempting to merge nodes + if (nodes_to_remove.Size > 1) + ImQsort(nodes_to_remove.Data, nodes_to_remove.Size, sizeof(ImGuiDockNode*), DockNodeComparerDepthMostFirst); + for (int n = 0; n < nodes_to_remove.Size; n++) + DockContextRemoveNode(ctx, nodes_to_remove[n], false); + + if (root_id == 0) + { + dc->Nodes.Clear(); + dc->Requests.clear(); + } + else if (has_central_node) + { + root_node->CentralNode = root_node; + root_node->SetLocalFlags(root_node->LocalFlags | ImGuiDockNodeFlags_CentralNode); + } +} + +void ImGui::DockBuilderRemoveNodeDockedWindows(ImGuiID root_id, bool clear_settings_refs) +{ + // Clear references in settings + ImGuiContext* ctx = GImGui; + ImGuiContext& g = *ctx; + if (clear_settings_refs) + { + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + { + bool want_removal = (root_id == 0) || (settings->DockId == root_id); + if (!want_removal && settings->DockId != 0) + if (ImGuiDockNode* node = DockContextFindNodeByID(ctx, settings->DockId)) + if (DockNodeGetRootNode(node)->ID == root_id) + want_removal = true; + if (want_removal) + settings->DockId = 0; + } + } + + // Clear references in windows + for (int n = 0; n < g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + bool want_removal = (root_id == 0) || (window->DockNode && DockNodeGetRootNode(window->DockNode)->ID == root_id) || (window->DockNodeAsHost && window->DockNodeAsHost->ID == root_id); + if (want_removal) + { + const ImGuiID backup_dock_id = window->DockId; + IM_UNUSED(backup_dock_id); + DockContextProcessUndockWindow(ctx, window, clear_settings_refs); + if (!clear_settings_refs) + IM_ASSERT(window->DockId == backup_dock_id); + } + } +} + +// If 'out_id_at_dir' or 'out_id_at_opposite_dir' are non NULL, the function will write out the ID of the two new nodes created. +// Return value is ID of the node at the specified direction, so same as (*out_id_at_dir) if that pointer is set. +// FIXME-DOCK: We are not exposing nor using split_outer. +ImGuiID ImGui::DockBuilderSplitNode(ImGuiID id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir) +{ + ImGuiContext* ctx = GImGui; + IM_ASSERT(split_dir != ImGuiDir_None); + IMGUI_DEBUG_LOG_DOCKING("DockBuilderSplitNode node 0x%08X, split_dir %d\n", id, split_dir); + + ImGuiDockNode* node = DockContextFindNodeByID(ctx, id); + if (node == NULL) + { + IM_ASSERT(node != NULL); + return 0; + } + + IM_ASSERT(!node->IsSplitNode()); // Assert if already Split + + ImGuiDockRequest req; + req.Type = ImGuiDockRequestType_Split; + req.DockTargetWindow = NULL; + req.DockTargetNode = node; + req.DockPayload = NULL; + req.DockSplitDir = split_dir; + req.DockSplitRatio = ImSaturate((split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? size_ratio_for_node_at_dir : 1.0f - size_ratio_for_node_at_dir); + req.DockSplitOuter = false; + DockContextProcessDock(ctx, &req); + + ImGuiID id_at_dir = node->ChildNodes[(split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 0 : 1]->ID; + ImGuiID id_at_opposite_dir = node->ChildNodes[(split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 1 : 0]->ID; + if (out_id_at_dir) + *out_id_at_dir = id_at_dir; + if (out_id_at_opposite_dir) + *out_id_at_opposite_dir = id_at_opposite_dir; + return id_at_dir; +} + +static ImGuiDockNode* DockBuilderCopyNodeRec(ImGuiDockNode* src_node, ImGuiID dst_node_id_if_known, ImVector* out_node_remap_pairs) +{ + ImGuiContext* ctx = GImGui; + ImGuiDockNode* dst_node = ImGui::DockContextAddNode(ctx, dst_node_id_if_known); + dst_node->SharedFlags = src_node->SharedFlags; + dst_node->LocalFlags = src_node->LocalFlags; + dst_node->LocalFlagsInWindows = ImGuiDockNodeFlags_None; + dst_node->Pos = src_node->Pos; + dst_node->Size = src_node->Size; + dst_node->SizeRef = src_node->SizeRef; + dst_node->SplitAxis = src_node->SplitAxis; + dst_node->UpdateMergedFlags(); + + out_node_remap_pairs->push_back(src_node->ID); + out_node_remap_pairs->push_back(dst_node->ID); + + for (int child_n = 0; child_n < IM_ARRAYSIZE(src_node->ChildNodes); child_n++) + if (src_node->ChildNodes[child_n]) + { + dst_node->ChildNodes[child_n] = DockBuilderCopyNodeRec(src_node->ChildNodes[child_n], 0, out_node_remap_pairs); + dst_node->ChildNodes[child_n]->ParentNode = dst_node; + } + + IMGUI_DEBUG_LOG_DOCKING("Fork node %08X -> %08X (%d childs)\n", src_node->ID, dst_node->ID, dst_node->IsSplitNode() ? 2 : 0); + return dst_node; +} + +void ImGui::DockBuilderCopyNode(ImGuiID src_node_id, ImGuiID dst_node_id, ImVector* out_node_remap_pairs) +{ + ImGuiContext* ctx = GImGui; + IM_ASSERT(src_node_id != 0); + IM_ASSERT(dst_node_id != 0); + IM_ASSERT(out_node_remap_pairs != NULL); + + DockBuilderRemoveNode(dst_node_id); + + ImGuiDockNode* src_node = DockContextFindNodeByID(ctx, src_node_id); + IM_ASSERT(src_node != NULL); + + out_node_remap_pairs->clear(); + DockBuilderCopyNodeRec(src_node, dst_node_id, out_node_remap_pairs); + + IM_ASSERT((out_node_remap_pairs->Size % 2) == 0); +} + +void ImGui::DockBuilderCopyWindowSettings(const char* src_name, const char* dst_name) +{ + ImGuiWindow* src_window = FindWindowByName(src_name); + if (src_window == NULL) + return; + if (ImGuiWindow* dst_window = FindWindowByName(dst_name)) + { + dst_window->Pos = src_window->Pos; + dst_window->Size = src_window->Size; + dst_window->SizeFull = src_window->SizeFull; + dst_window->Collapsed = src_window->Collapsed; + } + else if (ImGuiWindowSettings* dst_settings = FindOrCreateWindowSettings(dst_name)) + { + ImVec2ih window_pos_2ih = ImVec2ih(src_window->Pos); + if (src_window->ViewportId != 0 && src_window->ViewportId != IMGUI_VIEWPORT_DEFAULT_ID) + { + dst_settings->ViewportPos = window_pos_2ih; + dst_settings->ViewportId = src_window->ViewportId; + dst_settings->Pos = ImVec2ih(0, 0); + } + else + { + dst_settings->Pos = window_pos_2ih; + } + dst_settings->Size = ImVec2ih(src_window->SizeFull); + dst_settings->Collapsed = src_window->Collapsed; + } +} + +// FIXME: Will probably want to change this signature, in particular how the window remapping pairs are passed. +void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_dockspace_id, ImVector* in_window_remap_pairs) +{ + IM_ASSERT(src_dockspace_id != 0); + IM_ASSERT(dst_dockspace_id != 0); + IM_ASSERT(in_window_remap_pairs != NULL); + IM_ASSERT((in_window_remap_pairs->Size % 2) == 0); + + // Duplicate entire dock + // FIXME: When overwriting dst_dockspace_id, windows that aren't part of our dockspace window class but that are docked in a same node will be split apart, + // whereas we could attempt to at least keep them together in a new, same floating node. + ImVector node_remap_pairs; + DockBuilderCopyNode(src_dockspace_id, dst_dockspace_id, &node_remap_pairs); + + // Attempt to transition all the upcoming windows associated to dst_dockspace_id into the newly created hierarchy of dock nodes + // (The windows associated to src_dockspace_id are staying in place) + ImVector src_windows; + for (int remap_window_n = 0; remap_window_n < in_window_remap_pairs->Size; remap_window_n += 2) + { + const char* src_window_name = (*in_window_remap_pairs)[remap_window_n]; + const char* dst_window_name = (*in_window_remap_pairs)[remap_window_n + 1]; + ImGuiID src_window_id = ImHashStr(src_window_name); + src_windows.push_back(src_window_id); + + // Search in the remapping tables + ImGuiID src_dock_id = 0; + if (ImGuiWindow* src_window = FindWindowByID(src_window_id)) + src_dock_id = src_window->DockId; + else if (ImGuiWindowSettings* src_window_settings = FindWindowSettings(src_window_id)) + src_dock_id = src_window_settings->DockId; + ImGuiID dst_dock_id = 0; + for (int dock_remap_n = 0; dock_remap_n < node_remap_pairs.Size; dock_remap_n += 2) + if (node_remap_pairs[dock_remap_n] == src_dock_id) + { + dst_dock_id = node_remap_pairs[dock_remap_n + 1]; + //node_remap_pairs[dock_remap_n] = node_remap_pairs[dock_remap_n + 1] = 0; // Clear + break; + } + + if (dst_dock_id != 0) + { + // Docked windows gets redocked into the new node hierarchy. + IMGUI_DEBUG_LOG_DOCKING("Remap live window '%s' 0x%08X -> '%s' 0x%08X\n", src_window_name, src_dock_id, dst_window_name, dst_dock_id); + DockBuilderDockWindow(dst_window_name, dst_dock_id); + } + else + { + // Floating windows gets their settings transferred (regardless of whether the new window already exist or not) + // When this is leading to a Copy and not a Move, we would get two overlapping floating windows. Could we possibly dock them together? + IMGUI_DEBUG_LOG_DOCKING("Remap window settings '%s' -> '%s'\n", src_window_name, dst_window_name); + DockBuilderCopyWindowSettings(src_window_name, dst_window_name); + } + } + + // Anything else in the source nodes of 'node_remap_pairs' are windows that were docked in src_dockspace_id but are not owned by it (unaffiliated windows, e.g. "ImGui Demo") + // Find those windows and move to them to the cloned dock node. This may be optional? + for (int dock_remap_n = 0; dock_remap_n < node_remap_pairs.Size; dock_remap_n += 2) + if (ImGuiID src_dock_id = node_remap_pairs[dock_remap_n]) + { + ImGuiID dst_dock_id = node_remap_pairs[dock_remap_n + 1]; + ImGuiDockNode* node = DockBuilderGetNode(src_dock_id); + for (int window_n = 0; window_n < node->Windows.Size; window_n++) + { + ImGuiWindow* window = node->Windows[window_n]; + if (src_windows.contains(window->ID)) + continue; + + // Docked windows gets redocked into the new node hierarchy. + IMGUI_DEBUG_LOG_DOCKING("Remap window '%s' %08X -> %08X\n", window->Name, src_dock_id, dst_dock_id); + DockBuilderDockWindow(window->Name, dst_dock_id); + } + } +} + +// FIXME-DOCK: This is awkward because in series of split user is likely to loose access to its root node. +void ImGui::DockBuilderFinish(ImGuiID root_id) +{ + ImGuiContext* ctx = GImGui; + //DockContextRebuild(ctx); + DockContextBuildAddWindowsToNodes(ctx, root_id); +} + +//----------------------------------------------------------------------------- +// Docking: Begin/End Support Functions (called from Begin/End) +//----------------------------------------------------------------------------- +// - GetWindowAlwaysWantOwnTabBar() +// - DockContextBindNodeToWindow() +// - BeginDocked() +// - BeginDockableDragDropSource() +// - BeginDockableDragDropTarget() +//----------------------------------------------------------------------------- + +bool ImGui::GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.IO.ConfigDockingAlwaysTabBar || window->WindowClass.DockingAlwaysTabBar) + if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking)) == 0) + if (!window->IsFallbackWindow) // We don't support AlwaysTabBar on the fallback/implicit window to avoid unused dock-node overhead/noise + return true; + return false; +} + +static ImGuiDockNode* ImGui::DockContextBindNodeToWindow(ImGuiContext* ctx, ImGuiWindow* window) +{ + ImGuiContext& g = *ctx; + ImGuiDockNode* node = DockContextFindNodeByID(ctx, window->DockId); + IM_ASSERT(window->DockNode == NULL); + + // We should not be docking into a split node (SetWindowDock should avoid this) + if (node && node->IsSplitNode()) + { + DockContextProcessUndockWindow(ctx, window); + return NULL; + } + + // Create node + if (node == NULL) + { + node = DockContextAddNode(ctx, window->DockId); + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Window; + node->LastFrameAlive = g.FrameCount; + } + + // If the node just turned visible and is part of a hierarchy, it doesn't have a Size assigned by DockNodeTreeUpdatePosSize() yet, + // so we're forcing a Pos/Size update from the first ancestor that is already visible (often it will be the root node). + // If we don't do this, the window will be assigned a zero-size on its first frame, which won't ideally warm up the layout. + // This is a little wonky because we don't normally update the Pos/Size of visible node mid-frame. + if (!node->IsVisible) + { + ImGuiDockNode* ancestor_node = node; + while (!ancestor_node->IsVisible && ancestor_node->ParentNode) + ancestor_node = ancestor_node->ParentNode; + IM_ASSERT(ancestor_node->Size.x > 0.0f && ancestor_node->Size.y > 0.0f); + DockNodeUpdateHasCentralNodeChild(DockNodeGetRootNode(ancestor_node)); + DockNodeTreeUpdatePosSize(ancestor_node, ancestor_node->Pos, ancestor_node->Size, node); + } + + // Add window to node + bool node_was_visible = node->IsVisible; + DockNodeAddWindow(node, window, true); + node->IsVisible = node_was_visible; // Don't mark visible right away (so DockContextEndFrame() doesn't render it, maybe other side effects? will see) + IM_ASSERT(node == window->DockNode); + return node; +} + +void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) +{ + ImGuiContext* ctx = GImGui; + ImGuiContext& g = *ctx; + + // Clear fields ahead so most early-out paths don't have to do it + window->DockIsActive = window->DockNodeIsVisible = window->DockTabIsVisible = false; + + const bool auto_dock_node = GetWindowAlwaysWantOwnTabBar(window); + if (auto_dock_node) + { + if (window->DockId == 0) + { + IM_ASSERT(window->DockNode == NULL); + window->DockId = DockContextGenNodeID(ctx); + } + } + else + { + // Calling SetNextWindowPos() undock windows by default (by setting PosUndock) + bool want_undock = false; + want_undock |= (window->Flags & ImGuiWindowFlags_NoDocking) != 0; + want_undock |= (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) && (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) && g.NextWindowData.PosUndock; + if (want_undock) + { + DockContextProcessUndockWindow(ctx, window); + return; + } + } + + // Bind to our dock node + ImGuiDockNode* node = window->DockNode; + if (node != NULL) + IM_ASSERT(window->DockId == node->ID); + if (window->DockId != 0 && node == NULL) + { + node = DockContextBindNodeToWindow(ctx, window); + if (node == NULL) + return; + } + +#if 0 + // Undock if the ImGuiDockNodeFlags_NoDockingInCentralNode got set + if (node->IsCentralNode && (node->Flags & ImGuiDockNodeFlags_NoDockingInCentralNode)) + { + DockContextProcessUndockWindow(ctx, window); + return; + } +#endif + + // Undock if our dockspace node disappeared + // Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace node can be maintained alive while being inactive with ImGuiDockNodeFlags_KeepAliveOnly. + if (node->LastFrameAlive < g.FrameCount) + { + // If the window has been orphaned, transition the docknode to an implicit node processed in DockContextNewFrameUpdateDocking() + ImGuiDockNode* root_node = DockNodeGetRootNode(node); + if (root_node->LastFrameAlive < g.FrameCount) + DockContextProcessUndockWindow(ctx, window); + else + window->DockIsActive = true; + return; + } + + // Store style overrides + for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++) + window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]); + + // Fast path return. It is common for windows to hold on a persistent DockId but be the only visible window, + // and never create neither a host window neither a tab bar. + // FIXME-DOCK: replace ->HostWindow NULL compare with something more explicit (~was initially intended as a first frame test) + if (node->HostWindow == NULL) + { + if (node->State == ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing) + window->DockIsActive = true; + if (node->Windows.Size > 1) + DockNodeHideWindowDuringHostWindowCreation(window); + return; + } + + // We can have zero-sized nodes (e.g. children of a small-size dockspace) + IM_ASSERT(node->HostWindow); + IM_ASSERT(node->IsLeafNode()); + IM_ASSERT(node->Size.x >= 0.0f && node->Size.y >= 0.0f); + node->State = ImGuiDockNodeState_HostWindowVisible; + + // Undock if we are submitted earlier than the host window + if (!(node->MergedFlags & ImGuiDockNodeFlags_KeepAliveOnly) && window->BeginOrderWithinContext < node->HostWindow->BeginOrderWithinContext) + { + DockContextProcessUndockWindow(ctx, window); + return; + } + + // Position/Size window + SetNextWindowPos(node->Pos); + SetNextWindowSize(node->Size); + g.NextWindowData.PosUndock = false; // Cancel implicit undocking of SetNextWindowPos() + window->DockIsActive = true; + window->DockNodeIsVisible = true; + window->DockTabIsVisible = false; + if (node->MergedFlags & ImGuiDockNodeFlags_KeepAliveOnly) + return; + + // When the window is selected we mark it as visible. + if (node->VisibleWindow == window) + window->DockTabIsVisible = true; + + // Update window flag + IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) == 0); + window->Flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoResize; + if (node->IsHiddenTabBar() || node->IsNoTabBar()) + window->Flags |= ImGuiWindowFlags_NoTitleBar; + else + window->Flags &= ~ImGuiWindowFlags_NoTitleBar; // Clear the NoTitleBar flag in case the user set it: confusingly enough we need a title bar height so we are correctly offset, but it won't be displayed! + + // Save new dock order only if the window has been visible once already + // This allows multiple windows to be created in the same frame and have their respective dock orders preserved. + if (node->TabBar && window->WasActive) + window->DockOrder = (short)DockNodeGetTabOrder(window); + + if ((node->WantCloseAll || node->WantCloseTabId == window->TabId) && p_open != NULL) + *p_open = false; + + // Update ChildId to allow returning from Child to Parent with Escape + ImGuiWindow* parent_window = window->DockNode->HostWindow; + window->ChildId = parent_window->GetID(window->Name); +} + +void ImGui::BeginDockableDragDropSource(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.ActiveId == window->MoveId); + IM_ASSERT(g.MovingWindow == window); + IM_ASSERT(g.CurrentWindow == window); + + g.LastItemData.ID = window->MoveId; + window = window->RootWindowDockTree; + IM_ASSERT((window->Flags & ImGuiWindowFlags_NoDocking) == 0); + bool is_drag_docking = (g.IO.ConfigDockingWithShift) || ImRect(0, 0, window->SizeFull.x, GetFrameHeight()).Contains(g.ActiveIdClickOffset); // FIXME-DOCKING: Need to make this stateful and explicit + if (is_drag_docking && BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip | ImGuiDragDropFlags_SourceNoHoldToOpenOthers | ImGuiDragDropFlags_SourceAutoExpirePayload)) + { + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, &window, sizeof(window)); + EndDragDropSource(); + + // Store style overrides + for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++) + window->DockStyle.Colors[color_n] = ColorConvertFloat4ToU32(g.Style.Colors[GWindowDockStyleColors[color_n]]); + } +} + +void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window) +{ + ImGuiContext* ctx = GImGui; + ImGuiContext& g = *ctx; + + //IM_ASSERT(window->RootWindowDockTree == window); // May also be a DockSpace + IM_ASSERT((window->Flags & ImGuiWindowFlags_NoDocking) == 0); + if (!g.DragDropActive) + return; + //GetForegroundDrawList(window)->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); + if (!BeginDragDropTargetCustom(window->Rect(), window->ID)) + return; + + // Peek into the payload before calling AcceptDragDropPayload() so we can handle overlapping dock nodes with filtering + // (this is a little unusual pattern, normally most code would call AcceptDragDropPayload directly) + const ImGuiPayload* payload = &g.DragDropPayload; + if (!payload->IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW) || !DockNodeIsDropAllowed(window, *(ImGuiWindow**)payload->Data)) + { + EndDragDropTarget(); + return; + } + + ImGuiWindow* payload_window = *(ImGuiWindow**)payload->Data; + if (AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect)) + { + // Select target node + // (Important: we cannot use g.HoveredDockNode here! Because each of our target node have filters based on payload, each candidate drop target will do its own evaluation) + bool dock_into_floating_window = false; + ImGuiDockNode* node = NULL; + if (window->DockNodeAsHost) + { + // Cannot assume that node will != NULL even though we passed the rectangle test: it depends on padding/spacing handled by DockNodeTreeFindVisibleNodeByPos(). + node = DockNodeTreeFindVisibleNodeByPos(window->DockNodeAsHost, g.IO.MousePos); + + // There is an edge case when docking into a dockspace which only has _inactive_ nodes (because none of the windows are active) + // In this case we need to fallback into any leaf mode, possibly the central node. + // FIXME-20181220: We should not have to test for IsLeafNode() here but we have another bug to fix first. + if (node && node->IsDockSpace() && node->IsRootNode()) + node = (node->CentralNode && node->IsLeafNode()) ? node->CentralNode : DockNodeTreeFindFallbackLeafNode(node); + } + else + { + if (window->DockNode) + node = window->DockNode; + else + dock_into_floating_window = true; // Dock into a regular window + } + + const ImRect explicit_target_rect = (node && node->TabBar && !node->IsHiddenTabBar() && !node->IsNoTabBar()) ? node->TabBar->BarRect : ImRect(window->Pos, window->Pos + ImVec2(window->Size.x, GetFrameHeight())); + const bool is_explicit_target = g.IO.ConfigDockingWithShift || IsMouseHoveringRect(explicit_target_rect.Min, explicit_target_rect.Max); + + // Preview docking request and find out split direction/ratio + //const bool do_preview = true; // Ignore testing for payload->IsPreview() which removes one frame of delay, but breaks overlapping drop targets within the same window. + const bool do_preview = payload->IsPreview() || payload->IsDelivery(); + if (do_preview && (node != NULL || dock_into_floating_window)) + { + ImGuiDockPreviewData split_inner; + ImGuiDockPreviewData split_outer; + ImGuiDockPreviewData* split_data = &split_inner; + if (node && (node->ParentNode || node->IsCentralNode())) + if (ImGuiDockNode* root_node = DockNodeGetRootNode(node)) + { + DockNodePreviewDockSetup(window, root_node, payload_window, &split_outer, is_explicit_target, true); + if (split_outer.IsSplitDirExplicit) + split_data = &split_outer; + } + DockNodePreviewDockSetup(window, node, payload_window, &split_inner, is_explicit_target, false); + if (split_data == &split_outer) + split_inner.IsDropAllowed = false; + + // Draw inner then outer, so that previewed tab (in inner data) will be behind the outer drop boxes + DockNodePreviewDockRender(window, node, payload_window, &split_inner); + DockNodePreviewDockRender(window, node, payload_window, &split_outer); + + // Queue docking request + if (split_data->IsDropAllowed && payload->IsDelivery()) + DockContextQueueDock(ctx, window, split_data->SplitNode, payload_window, split_data->SplitDir, split_data->SplitRatio, split_data == &split_outer); + } + } + EndDragDropTarget(); +} + +//----------------------------------------------------------------------------- +// Docking: Settings +//----------------------------------------------------------------------------- +// - DockSettingsRenameNodeReferences() +// - DockSettingsRemoveNodeReferences() +// - DockSettingsFindNodeSettings() +// - DockSettingsHandler_ApplyAll() +// - DockSettingsHandler_ReadOpen() +// - DockSettingsHandler_ReadLine() +// - DockSettingsHandler_DockNodeToSettings() +// - DockSettingsHandler_WriteAll() +//----------------------------------------------------------------------------- + +static void ImGui::DockSettingsRenameNodeReferences(ImGuiID old_node_id, ImGuiID new_node_id) +{ + ImGuiContext& g = *GImGui; + IMGUI_DEBUG_LOG_DOCKING("DockSettingsRenameNodeReferences: from 0x%08X -> to 0x%08X\n", old_node_id, new_node_id); + for (int window_n = 0; window_n < g.Windows.Size; window_n++) + { + ImGuiWindow* window = g.Windows[window_n]; + if (window->DockId == old_node_id && window->DockNode == NULL) + window->DockId = new_node_id; + } + //// FIXME-OPT: We could remove this loop by storing the index in the map + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->DockId == old_node_id) + settings->DockId = new_node_id; +} + +// Remove references stored in ImGuiWindowSettings to the given ImGuiDockNodeSettings +static void ImGui::DockSettingsRemoveNodeReferences(ImGuiID* node_ids, int node_ids_count) +{ + ImGuiContext& g = *GImGui; + int found = 0; + //// FIXME-OPT: We could remove this loop by storing the index in the map + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + for (int node_n = 0; node_n < node_ids_count; node_n++) + if (settings->DockId == node_ids[node_n]) + { + settings->DockId = 0; + settings->DockOrder = -1; + if (++found < node_ids_count) + break; + return; + } +} + +static ImGuiDockNodeSettings* ImGui::DockSettingsFindNodeSettings(ImGuiContext* ctx, ImGuiID id) +{ + // FIXME-OPT + ImGuiDockContext* dc = &ctx->DockContext; + for (int n = 0; n < dc->NodesSettings.Size; n++) + if (dc->NodesSettings[n].ID == id) + return &dc->NodesSettings[n]; + return NULL; +} + +// Clear settings data +static void ImGui::DockSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + ImGuiDockContext* dc = &ctx->DockContext; + dc->NodesSettings.clear(); + DockContextClearNodes(ctx, 0, true); +} + +// Recreate nodes based on settings data +static void ImGui::DockSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + // Prune settings at boot time only + ImGuiDockContext* dc = &ctx->DockContext; + if (ctx->Windows.Size == 0) + DockContextPruneUnusedSettingsNodes(ctx); + DockContextBuildNodesFromSettings(ctx, dc->NodesSettings.Data, dc->NodesSettings.Size); + DockContextBuildAddWindowsToNodes(ctx, 0); +} + +static void* ImGui::DockSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) +{ + if (strcmp(name, "Data") != 0) + return NULL; + return (void*)1; +} + +static void ImGui::DockSettingsHandler_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler*, void*, const char* line) +{ + char c = 0; + int x = 0, y = 0; + int r = 0; + + // Parsing, e.g. + // " DockNode ID=0x00000001 Pos=383,193 Size=201,322 Split=Y,0.506 " + // " DockNode ID=0x00000002 Parent=0x00000001 " + // Important: this code expect currently fields in a fixed order. + ImGuiDockNodeSettings node; + line = ImStrSkipBlank(line); + if (strncmp(line, "DockNode", 8) == 0) { line = ImStrSkipBlank(line + strlen("DockNode")); } + else if (strncmp(line, "DockSpace", 9) == 0) { line = ImStrSkipBlank(line + strlen("DockSpace")); node.Flags |= ImGuiDockNodeFlags_DockSpace; } + else return; + if (sscanf(line, "ID=0x%08X%n", &node.ID, &r) == 1) { line += r; } else return; + if (sscanf(line, " Parent=0x%08X%n", &node.ParentNodeId, &r) == 1) { line += r; if (node.ParentNodeId == 0) return; } + if (sscanf(line, " Window=0x%08X%n", &node.ParentWindowId, &r) ==1) { line += r; if (node.ParentWindowId == 0) return; } + if (node.ParentNodeId == 0) + { + if (sscanf(line, " Pos=%i,%i%n", &x, &y, &r) == 2) { line += r; node.Pos = ImVec2ih((short)x, (short)y); } else return; + if (sscanf(line, " Size=%i,%i%n", &x, &y, &r) == 2) { line += r; node.Size = ImVec2ih((short)x, (short)y); } else return; + } + else + { + if (sscanf(line, " SizeRef=%i,%i%n", &x, &y, &r) == 2) { line += r; node.SizeRef = ImVec2ih((short)x, (short)y); } + } + if (sscanf(line, " Split=%c%n", &c, &r) == 1) { line += r; if (c == 'X') node.SplitAxis = ImGuiAxis_X; else if (c == 'Y') node.SplitAxis = ImGuiAxis_Y; } + if (sscanf(line, " NoResize=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_NoResize; } + if (sscanf(line, " CentralNode=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_CentralNode; } + if (sscanf(line, " NoTabBar=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_NoTabBar; } + if (sscanf(line, " HiddenTabBar=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_HiddenTabBar; } + if (sscanf(line, " NoWindowMenuButton=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_NoWindowMenuButton; } + if (sscanf(line, " NoCloseButton=%d%n", &x, &r) == 1) { line += r; if (x != 0) node.Flags |= ImGuiDockNodeFlags_NoCloseButton; } + if (sscanf(line, " Selected=0x%08X%n", &node.SelectedTabId,&r) == 1) { line += r; } + if (node.ParentNodeId != 0) + if (ImGuiDockNodeSettings* parent_settings = DockSettingsFindNodeSettings(ctx, node.ParentNodeId)) + node.Depth = parent_settings->Depth + 1; + ctx->DockContext.NodesSettings.push_back(node); +} + +static void DockSettingsHandler_DockNodeToSettings(ImGuiDockContext* dc, ImGuiDockNode* node, int depth) +{ + ImGuiDockNodeSettings node_settings; + IM_ASSERT(depth < (1 << (sizeof(node_settings.Depth) << 3))); + node_settings.ID = node->ID; + node_settings.ParentNodeId = node->ParentNode ? node->ParentNode->ID : 0; + node_settings.ParentWindowId = (node->IsDockSpace() && node->HostWindow && node->HostWindow->ParentWindow) ? node->HostWindow->ParentWindow->ID : 0; + node_settings.SelectedTabId = node->SelectedTabId; + node_settings.SplitAxis = (signed char)(node->IsSplitNode() ? node->SplitAxis : ImGuiAxis_None); + node_settings.Depth = (char)depth; + node_settings.Flags = (node->LocalFlags & ImGuiDockNodeFlags_SavedFlagsMask_); + node_settings.Pos = ImVec2ih(node->Pos); + node_settings.Size = ImVec2ih(node->Size); + node_settings.SizeRef = ImVec2ih(node->SizeRef); + dc->NodesSettings.push_back(node_settings); + if (node->ChildNodes[0]) + DockSettingsHandler_DockNodeToSettings(dc, node->ChildNodes[0], depth + 1); + if (node->ChildNodes[1]) + DockSettingsHandler_DockNodeToSettings(dc, node->ChildNodes[1], depth + 1); +} + +static void ImGui::DockSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) +{ + ImGuiContext& g = *ctx; + ImGuiDockContext* dc = &ctx->DockContext; + if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) + return; + + // Gather settings data + // (unlike our windows settings, because nodes are always built we can do a full rewrite of the SettingsNode buffer) + dc->NodesSettings.resize(0); + dc->NodesSettings.reserve(dc->Nodes.Data.Size); + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (node->IsRootNode()) + DockSettingsHandler_DockNodeToSettings(dc, node, 0); + + int max_depth = 0; + for (int node_n = 0; node_n < dc->NodesSettings.Size; node_n++) + max_depth = ImMax((int)dc->NodesSettings[node_n].Depth, max_depth); + + // Write to text buffer + buf->appendf("[%s][Data]\n", handler->TypeName); + for (int node_n = 0; node_n < dc->NodesSettings.Size; node_n++) + { + const int line_start_pos = buf->size(); (void)line_start_pos; + const ImGuiDockNodeSettings* node_settings = &dc->NodesSettings[node_n]; + buf->appendf("%*s%s%*s", node_settings->Depth * 2, "", (node_settings->Flags & ImGuiDockNodeFlags_DockSpace) ? "DockSpace" : "DockNode ", (max_depth - node_settings->Depth) * 2, ""); // Text align nodes to facilitate looking at .ini file + buf->appendf(" ID=0x%08X", node_settings->ID); + if (node_settings->ParentNodeId) + { + buf->appendf(" Parent=0x%08X SizeRef=%d,%d", node_settings->ParentNodeId, node_settings->SizeRef.x, node_settings->SizeRef.y); + } + else + { + if (node_settings->ParentWindowId) + buf->appendf(" Window=0x%08X", node_settings->ParentWindowId); + buf->appendf(" Pos=%d,%d Size=%d,%d", node_settings->Pos.x, node_settings->Pos.y, node_settings->Size.x, node_settings->Size.y); + } + if (node_settings->SplitAxis != ImGuiAxis_None) + buf->appendf(" Split=%c", (node_settings->SplitAxis == ImGuiAxis_X) ? 'X' : 'Y'); + if (node_settings->Flags & ImGuiDockNodeFlags_NoResize) + buf->appendf(" NoResize=1"); + if (node_settings->Flags & ImGuiDockNodeFlags_CentralNode) + buf->appendf(" CentralNode=1"); + if (node_settings->Flags & ImGuiDockNodeFlags_NoTabBar) + buf->appendf(" NoTabBar=1"); + if (node_settings->Flags & ImGuiDockNodeFlags_HiddenTabBar) + buf->appendf(" HiddenTabBar=1"); + if (node_settings->Flags & ImGuiDockNodeFlags_NoWindowMenuButton) + buf->appendf(" NoWindowMenuButton=1"); + if (node_settings->Flags & ImGuiDockNodeFlags_NoCloseButton) + buf->appendf(" NoCloseButton=1"); + if (node_settings->SelectedTabId) + buf->appendf(" Selected=0x%08X", node_settings->SelectedTabId); + +#if IMGUI_DEBUG_INI_SETTINGS + // [DEBUG] Include comments in the .ini file to ease debugging + if (ImGuiDockNode* node = DockContextFindNodeByID(ctx, node_settings->ID)) + { + buf->appendf("%*s", ImMax(2, (line_start_pos + 92) - buf->size()), ""); // Align everything + if (node->IsDockSpace() && node->HostWindow && node->HostWindow->ParentWindow) + buf->appendf(" ; in '%s'", node->HostWindow->ParentWindow->Name); + // Iterate settings so we can give info about windows that didn't exist during the session. + int contains_window = 0; + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->DockId == node_settings->ID) + { + if (contains_window++ == 0) + buf->appendf(" ; contains "); + buf->appendf("'%s' ", settings->GetName()); + } + } +#endif + buf->appendf("\n"); + } + buf->appendf("\n"); +} + + +//----------------------------------------------------------------------------- +// [SECTION] PLATFORM DEPENDENT HELPERS +//----------------------------------------------------------------------------- + +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) + +#ifdef _MSC_VER +#pragma comment(lib, "user32") +#pragma comment(lib, "kernel32") +#endif + +// Win32 clipboard implementation +// We use g.ClipboardHandlerData for temporary storage to ensure it is freed on Shutdown() +static const char* GetClipboardTextFn_DefaultImpl(void*) +{ + ImGuiContext& g = *GImGui; + g.ClipboardHandlerData.clear(); + if (!::OpenClipboard(NULL)) + return NULL; + HANDLE wbuf_handle = ::GetClipboardData(CF_UNICODETEXT); + if (wbuf_handle == NULL) + { + ::CloseClipboard(); + return NULL; + } + if (const WCHAR* wbuf_global = (const WCHAR*)::GlobalLock(wbuf_handle)) + { + int buf_len = ::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, NULL, 0, NULL, NULL); + g.ClipboardHandlerData.resize(buf_len); + ::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, g.ClipboardHandlerData.Data, buf_len, NULL, NULL); + } + ::GlobalUnlock(wbuf_handle); + ::CloseClipboard(); + return g.ClipboardHandlerData.Data; +} + +static void SetClipboardTextFn_DefaultImpl(void*, const char* text) +{ + if (!::OpenClipboard(NULL)) + return; + const int wbuf_length = ::MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0); + HGLOBAL wbuf_handle = ::GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(WCHAR)); + if (wbuf_handle == NULL) + { + ::CloseClipboard(); + return; + } + WCHAR* wbuf_global = (WCHAR*)::GlobalLock(wbuf_handle); + ::MultiByteToWideChar(CP_UTF8, 0, text, -1, wbuf_global, wbuf_length); + ::GlobalUnlock(wbuf_handle); + ::EmptyClipboard(); + if (::SetClipboardData(CF_UNICODETEXT, wbuf_handle) == NULL) + ::GlobalFree(wbuf_handle); + ::CloseClipboard(); +} + +#elif defined(__APPLE__) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS) + +#include // Use old API to avoid need for separate .mm file +static PasteboardRef main_clipboard = 0; + +// OSX clipboard implementation +// If you enable this you will need to add '-framework ApplicationServices' to your linker command-line! +static void SetClipboardTextFn_DefaultImpl(void*, const char* text) +{ + if (!main_clipboard) + PasteboardCreate(kPasteboardClipboard, &main_clipboard); + PasteboardClear(main_clipboard); + CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, strlen(text)); + if (cf_data) + { + PasteboardPutItemFlavor(main_clipboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), cf_data, 0); + CFRelease(cf_data); + } +} + +static const char* GetClipboardTextFn_DefaultImpl(void*) +{ + if (!main_clipboard) + PasteboardCreate(kPasteboardClipboard, &main_clipboard); + PasteboardSynchronize(main_clipboard); + + ItemCount item_count = 0; + PasteboardGetItemCount(main_clipboard, &item_count); + for (ItemCount i = 0; i < item_count; i++) + { + PasteboardItemID item_id = 0; + PasteboardGetItemIdentifier(main_clipboard, i + 1, &item_id); + CFArrayRef flavor_type_array = 0; + PasteboardCopyItemFlavors(main_clipboard, item_id, &flavor_type_array); + for (CFIndex j = 0, nj = CFArrayGetCount(flavor_type_array); j < nj; j++) + { + CFDataRef cf_data; + if (PasteboardCopyItemFlavorData(main_clipboard, item_id, CFSTR("public.utf8-plain-text"), &cf_data) == noErr) + { + ImGuiContext& g = *GImGui; + g.ClipboardHandlerData.clear(); + int length = (int)CFDataGetLength(cf_data); + g.ClipboardHandlerData.resize(length + 1); + CFDataGetBytes(cf_data, CFRangeMake(0, length), (UInt8*)g.ClipboardHandlerData.Data); + g.ClipboardHandlerData[length] = 0; + CFRelease(cf_data); + return g.ClipboardHandlerData.Data; + } + } + } + return NULL; +} + +#else + +// Local Dear ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers. +static const char* GetClipboardTextFn_DefaultImpl(void*) +{ + ImGuiContext& g = *GImGui; + return g.ClipboardHandlerData.empty() ? NULL : g.ClipboardHandlerData.begin(); +} + +static void SetClipboardTextFn_DefaultImpl(void*, const char* text) +{ + ImGuiContext& g = *GImGui; + g.ClipboardHandlerData.clear(); + const char* text_end = text + strlen(text); + g.ClipboardHandlerData.resize((int)(text_end - text) + 1); + memcpy(&g.ClipboardHandlerData[0], text, (size_t)(text_end - text)); + g.ClipboardHandlerData[(int)(text_end - text)] = 0; +} + +#endif + +// Win32 API IME support (for Asian languages, etc.) +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) + +#include +#ifdef _MSC_VER +#pragma comment(lib, "imm32") +#endif + +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data) +{ + // Notify OS Input Method Editor of text input position + HWND hwnd = (HWND)viewport->PlatformHandleRaw; +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (hwnd == 0) + hwnd = (HWND)ImGui::GetIO().ImeWindowHandle; +#endif + if (hwnd == 0) + return; + + ::ImmAssociateContextEx(hwnd, NULL, data->WantVisible ? IACE_DEFAULT : 0); + + if (HIMC himc = ::ImmGetContext(hwnd)) + { + COMPOSITIONFORM composition_form = {}; + composition_form.ptCurrentPos.x = (LONG)(data->InputPos.x - viewport->Pos.x); + composition_form.ptCurrentPos.y = (LONG)(data->InputPos.y - viewport->Pos.y); + composition_form.dwStyle = CFS_FORCE_POSITION; + ::ImmSetCompositionWindow(himc, &composition_form); + CANDIDATEFORM candidate_form = {}; + candidate_form.dwStyle = CFS_CANDIDATEPOS; + candidate_form.ptCurrentPos.x = (LONG)(data->InputPos.x - viewport->Pos.x); + candidate_form.ptCurrentPos.y = (LONG)(data->InputPos.y - viewport->Pos.y); + ::ImmSetCandidateWindow(himc, &candidate_form); + ::ImmReleaseContext(hwnd, himc); + } +} + +#else + +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport*, ImGuiPlatformImeData*) {} + +#endif + +//----------------------------------------------------------------------------- +// [SECTION] METRICS/DEBUGGER WINDOW +//----------------------------------------------------------------------------- +// - RenderViewportThumbnail() [Internal] +// - RenderViewportsThumbnails() [Internal] +// - MetricsHelpMarker() [Internal] +// - ShowMetricsWindow() +// - DebugNodeColumns() [Internal] +// - DebugNodeDockNode() [Internal] +// - DebugNodeDrawList() [Internal] +// - DebugNodeDrawCmdShowMeshAndBoundingBox() [Internal] +// - DebugNodeStorage() [Internal] +// - DebugNodeTabBar() [Internal] +// - DebugNodeViewport() [Internal] +// - DebugNodeWindow() [Internal] +// - DebugNodeWindowSettings() [Internal] +// - DebugNodeWindowsList() [Internal] +// - DebugNodeWindowsListByBeginStackParent() [Internal] +//----------------------------------------------------------------------------- + +#ifndef IMGUI_DISABLE_METRICS_WINDOW + +void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + ImVec2 scale = bb.GetSize() / viewport->Size; + ImVec2 off = bb.Min - viewport->Pos * scale; + float alpha_mul = (viewport->Flags & ImGuiViewportFlags_Minimized) ? 0.30f : 1.00f; + window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul * 0.40f)); + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* thumb_window = g.Windows[i]; + if (!thumb_window->WasActive || (thumb_window->Flags & ImGuiWindowFlags_ChildWindow)) + continue; + if (thumb_window->Viewport != viewport) + continue; + + ImRect thumb_r = thumb_window->Rect(); + ImRect title_r = thumb_window->TitleBarRect(); + thumb_r = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(off + thumb_r.Max * scale)); + title_r = ImRect(ImFloor(off + title_r.Min * scale), ImFloor(off + ImVec2(title_r.Max.x, title_r.Min.y) * scale) + ImVec2(0,5)); // Exaggerate title bar height + thumb_r.ClipWithFull(bb); + title_r.ClipWithFull(bb); + const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); + window->DrawList->AddRectFilled(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_WindowBg, alpha_mul)); + window->DrawList->AddRectFilled(title_r.Min, title_r.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul)); + window->DrawList->AddRect(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_Border, alpha_mul)); + window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r.Min, GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, FindRenderedTextEnd(thumb_window->Name)); + } + draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border, alpha_mul)); +} + +static void RenderViewportsThumbnails() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // We don't display full monitor bounds (we could, but it often looks awkward), instead we display just enough to cover all of our viewports. + float SCALE = 1.0f / 8.0f; + ImRect bb_full(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); + for (int n = 0; n < g.Viewports.Size; n++) + bb_full.Add(g.Viewports[n]->GetMainRect()); + ImVec2 p = window->DC.CursorPos; + ImVec2 off = p - bb_full.Min * SCALE; + for (int n = 0; n < g.Viewports.Size; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + ImRect viewport_draw_bb(off + (viewport->Pos) * SCALE, off + (viewport->Pos + viewport->Size) * SCALE); + ImGui::DebugRenderViewportThumbnail(window->DrawList, viewport, viewport_draw_bb); + } + ImGui::Dummy(bb_full.GetSize() * SCALE); +} + +static int IMGUI_CDECL ViewportComparerByFrontMostStampCount(const void* lhs, const void* rhs) +{ + const ImGuiViewportP* a = *(const ImGuiViewportP* const *)lhs; + const ImGuiViewportP* b = *(const ImGuiViewportP* const *)rhs; + return b->LastFrontMostStampCount - a->LastFrontMostStampCount; +} + +// Avoid naming collision with imgui_demo.cpp's HelpMarker() for unity builds. +static void MetricsHelpMarker(const char* desc) +{ + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +#ifndef IMGUI_DISABLE_DEMO_WINDOWS +namespace ImGui { void ShowFontAtlas(ImFontAtlas* atlas); } +#endif + +void ImGui::ShowMetricsWindow(bool* p_open) +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; + if (cfg->ShowStackTool) + ShowStackToolWindow(&cfg->ShowStackTool); + + if (!Begin("Dear ImGui Metrics/Debugger", p_open) || GetCurrentWindow()->BeginCount > 1) + { + End(); + return; + } + + // Basic info + Text("Dear ImGui %s", GetVersion()); + Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3); + Text("%d visible windows, %d active allocations", io.MetricsRenderWindows, io.MetricsActiveAllocations); + //SameLine(); if (SmallButton("GC")) { g.GcCompactAll = true; } + + Separator(); + + // Debugging enums + enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentIdeal, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type + const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentIdeal", "ContentRegionRect" }; + enum { TRT_OuterRect, TRT_InnerRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsWorkRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentFrozen, TRT_ColumnsContentUnfrozen, TRT_Count }; // Tables Rect Type + const char* trt_rects_names[TRT_Count] = { "OuterRect", "InnerRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsWorkRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" }; + if (cfg->ShowWindowsRectsType < 0) + cfg->ShowWindowsRectsType = WRT_WorkRect; + if (cfg->ShowTablesRectsType < 0) + cfg->ShowTablesRectsType = TRT_WorkRect; + + struct Funcs + { + static ImRect GetTableRect(ImGuiTable* table, int rect_type, int n) + { + if (rect_type == TRT_OuterRect) { return table->OuterRect; } + else if (rect_type == TRT_InnerRect) { return table->InnerRect; } + else if (rect_type == TRT_WorkRect) { return table->WorkRect; } + else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; } + else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; } + else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; } + else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); } + else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); } + else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; } + else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate + else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } + else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } + else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table->LastFirstRowHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); } + IM_ASSERT(0); + return ImRect(); + } + + static ImRect GetWindowRect(ImGuiWindow* window, int rect_type) + { + if (rect_type == WRT_OuterRect) { return window->Rect(); } + else if (rect_type == WRT_OuterRectClipped) { return window->OuterRectClipped; } + else if (rect_type == WRT_InnerRect) { return window->InnerRect; } + else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; } + else if (rect_type == WRT_WorkRect) { return window->WorkRect; } + else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); } + else if (rect_type == WRT_ContentIdeal) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSizeIdeal); } + else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; } + IM_ASSERT(0); + return ImRect(); + } + }; + + // Tools + if (TreeNode("Tools")) + { + // Stack Tool is your best friend! + Checkbox("Show stack tool", &cfg->ShowStackTool); + SameLine(); + MetricsHelpMarker("You can also call ImGui::ShowStackToolWindow() from your code."); + + Checkbox("Show windows begin order", &cfg->ShowWindowsBeginOrder); + Checkbox("Show windows rectangles", &cfg->ShowWindowsRects); + SameLine(); + SetNextItemWidth(GetFontSize() * 12); + cfg->ShowWindowsRects |= Combo("##show_windows_rect_type", &cfg->ShowWindowsRectsType, wrt_rects_names, WRT_Count, WRT_Count); + if (cfg->ShowWindowsRects && g.NavWindow != NULL) + { + BulletText("'%s':", g.NavWindow->Name); + Indent(); + for (int rect_n = 0; rect_n < WRT_Count; rect_n++) + { + ImRect r = Funcs::GetWindowRect(g.NavWindow, rect_n); + Text("(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), wrt_rects_names[rect_n]); + } + Unindent(); + } + + Checkbox("Show tables rectangles", &cfg->ShowTablesRects); + SameLine(); + SetNextItemWidth(GetFontSize() * 12); + cfg->ShowTablesRects |= Combo("##show_table_rects_type", &cfg->ShowTablesRectsType, trt_rects_names, TRT_Count, TRT_Count); + if (cfg->ShowTablesRects && g.NavWindow != NULL) + { + for (int table_n = 0; table_n < g.Tables.GetMapSize(); table_n++) + { + ImGuiTable* table = g.Tables.TryGetMapData(table_n); + if (table == NULL || table->LastFrameActive < g.FrameCount - 1 || (table->OuterWindow != g.NavWindow && table->InnerWindow != g.NavWindow)) + continue; + + BulletText("Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name); + if (IsItemHovered()) + GetForegroundDrawList()->AddRect(table->OuterRect.Min - ImVec2(1, 1), table->OuterRect.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + Indent(); + char buf[128]; + for (int rect_n = 0; rect_n < TRT_Count; rect_n++) + { + if (rect_n >= TRT_ColumnsRect) + { + if (rect_n != TRT_ColumnsRect && rect_n != TRT_ColumnsClipRect) + continue; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImRect r = Funcs::GetTableRect(table, rect_n, column_n); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) Col %d %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), column_n, trt_rects_names[rect_n]); + Selectable(buf); + if (IsItemHovered()) + GetForegroundDrawList()->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + } + } + else + { + ImRect r = Funcs::GetTableRect(table, rect_n, -1); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), trt_rects_names[rect_n]); + Selectable(buf); + if (IsItemHovered()) + GetForegroundDrawList()->AddRect(r.Min - ImVec2(1, 1), r.Max + ImVec2(1, 1), IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); + } + } + Unindent(); + } + } + + // The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted. + if (Button("Item Picker..")) + DebugStartItemPicker(); + SameLine(); + MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash."); + + TreePop(); + } + + // Windows + if (TreeNode("Windows", "Windows (%d)", g.Windows.Size)) + { + //SetNextItemOpen(true, ImGuiCond_Once); + DebugNodeWindowsList(&g.Windows, "By display order"); + DebugNodeWindowsList(&g.WindowsFocusOrder, "By focus order (root windows)"); + if (TreeNode("By submission order (begin stack)")) + { + // Here we display windows in their submitted order/hierarchy, however note that the Begin stack doesn't constitute a Parent<>Child relationship! + ImVector& temp_buffer = g.WindowsTempSortBuffer; + temp_buffer.resize(0); + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i]->LastFrameActive + 1 >= g.FrameCount) + temp_buffer.push_back(g.Windows[i]); + struct Func { static int IMGUI_CDECL WindowComparerByBeginOrder(const void* lhs, const void* rhs) { return ((int)(*(const ImGuiWindow* const *)lhs)->BeginOrderWithinContext - (*(const ImGuiWindow* const*)rhs)->BeginOrderWithinContext); } }; + ImQsort(temp_buffer.Data, (size_t)temp_buffer.Size, sizeof(ImGuiWindow*), Func::WindowComparerByBeginOrder); + DebugNodeWindowsListByBeginStackParent(temp_buffer.Data, temp_buffer.Size, NULL); + TreePop(); + } + + TreePop(); + } + + // DrawLists + int drawlist_count = 0; + for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++) + drawlist_count += g.Viewports[viewport_i]->DrawDataBuilder.GetDrawListCount(); + if (TreeNode("DrawLists", "DrawLists (%d)", drawlist_count)) + { + Checkbox("Show ImDrawCmd mesh when hovering", &cfg->ShowDrawCmdMesh); + Checkbox("Show ImDrawCmd bounding boxes when hovering", &cfg->ShowDrawCmdBoundingBoxes); + for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++) + { + ImGuiViewportP* viewport = g.Viewports[viewport_i]; + bool viewport_has_drawlist = false; + for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++) + for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++) + { + if (!viewport_has_drawlist) + Text("Active DrawLists in Viewport #%d, ID: 0x%08X", viewport->Idx, viewport->ID); + viewport_has_drawlist = true; + DebugNodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList"); + } + } + TreePop(); + } + + // Viewports + if (TreeNode("Viewports", "Viewports (%d)", g.Viewports.Size)) + { + Indent(GetTreeNodeToLabelSpacing()); + RenderViewportsThumbnails(); + Unindent(GetTreeNodeToLabelSpacing()); + + bool open = TreeNode("Monitors", "Monitors (%d)", g.PlatformIO.Monitors.Size); + SameLine(); + MetricsHelpMarker("Dear ImGui uses monitor data:\n- to query DPI settings on a per monitor basis\n- to position popup/tooltips so they don't straddle monitors."); + if (open) + { + for (int i = 0; i < g.PlatformIO.Monitors.Size; i++) + { + const ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[i]; + BulletText("Monitor #%d: DPI %.0f%%\n MainMin (%.0f,%.0f), MainMax (%.0f,%.0f), MainSize (%.0f,%.0f)\n WorkMin (%.0f,%.0f), WorkMax (%.0f,%.0f), WorkSize (%.0f,%.0f)", + i, mon.DpiScale * 100.0f, + mon.MainPos.x, mon.MainPos.y, mon.MainPos.x + mon.MainSize.x, mon.MainPos.y + mon.MainSize.y, mon.MainSize.x, mon.MainSize.y, + mon.WorkPos.x, mon.WorkPos.y, mon.WorkPos.x + mon.WorkSize.x, mon.WorkPos.y + mon.WorkSize.y, mon.WorkSize.x, mon.WorkSize.y); + } + TreePop(); + } + + BulletText("MouseViewport: 0x%08X (UserHovered 0x%08X, LastHovered 0x%08X)", g.MouseViewport ? g.MouseViewport->ID : 0, g.IO.MouseHoveredViewport, g.MouseLastHoveredViewport ? g.MouseLastHoveredViewport->ID : 0); + if (TreeNode("Inferred Z order (front-to-back)")) + { + static ImVector viewports; + viewports.resize(g.Viewports.Size); + memcpy(viewports.Data, g.Viewports.Data, g.Viewports.size_in_bytes()); + if (viewports.Size > 1) + ImQsort(viewports.Data, viewports.Size, sizeof(ImGuiViewport*), ViewportComparerByFrontMostStampCount); + for (int i = 0; i < viewports.Size; i++) + BulletText("Viewport #%d, ID: 0x%08X, FrontMostStampCount = %08d, Window: \"%s\"", viewports[i]->Idx, viewports[i]->ID, viewports[i]->LastFrontMostStampCount, viewports[i]->Window ? viewports[i]->Window->Name : "N/A"); + TreePop(); + } + + for (int i = 0; i < g.Viewports.Size; i++) + DebugNodeViewport(g.Viewports[i]); + TreePop(); + } + + // Details for Popups + if (TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size)) + { + for (int i = 0; i < g.OpenPopupStack.Size; i++) + { + ImGuiWindow* window = g.OpenPopupStack[i].Window; + BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); + } + TreePop(); + } + + // Details for TabBars + if (TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.GetAliveCount())) + { + for (int n = 0; n < g.TabBars.GetMapSize(); n++) + if (ImGuiTabBar* tab_bar = g.TabBars.TryGetMapData(n)) + { + PushID(tab_bar); + DebugNodeTabBar(tab_bar, "TabBar"); + PopID(); + } + TreePop(); + } + + // Details for Tables + if (TreeNode("Tables", "Tables (%d)", g.Tables.GetAliveCount())) + { + for (int n = 0; n < g.Tables.GetMapSize(); n++) + if (ImGuiTable* table = g.Tables.TryGetMapData(n)) + DebugNodeTable(table); + TreePop(); + } + + // Details for Fonts +#ifndef IMGUI_DISABLE_DEMO_WINDOWS + ImFontAtlas* atlas = g.IO.Fonts; + if (TreeNode("Fonts", "Fonts (%d)", atlas->Fonts.Size)) + { + ShowFontAtlas(atlas); + TreePop(); + } +#endif + + // Details for Docking +#ifdef IMGUI_HAS_DOCK + if (TreeNode("Docking")) + { + static bool root_nodes_only = true; + ImGuiDockContext* dc = &g.DockContext; + Checkbox("List root nodes", &root_nodes_only); + Checkbox("Ctrl shows window dock info", &cfg->ShowDockingNodes); + if (SmallButton("Clear nodes")) { DockContextClearNodes(&g, 0, true); } + SameLine(); + if (SmallButton("Rebuild all")) { dc->WantFullRebuild = true; } + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (!root_nodes_only || node->IsRootNode()) + DebugNodeDockNode(node, "Node"); + TreePop(); + } +#endif // #ifdef IMGUI_HAS_DOCK + + // Settings + if (TreeNode("Settings")) + { + if (SmallButton("Clear")) + ClearIniSettings(); + SameLine(); + if (SmallButton("Save to memory")) + SaveIniSettingsToMemory(); + SameLine(); + if (SmallButton("Save to disk")) + SaveIniSettingsToDisk(g.IO.IniFilename); + SameLine(); + if (g.IO.IniFilename) + Text("\"%s\"", g.IO.IniFilename); + else + TextUnformatted(""); + Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer); + if (TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size)) + { + for (int n = 0; n < g.SettingsHandlers.Size; n++) + BulletText("%s", g.SettingsHandlers[n].TypeName); + TreePop(); + } + if (TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size())) + { + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + DebugNodeWindowSettings(settings); + TreePop(); + } + + if (TreeNode("SettingsTables", "Settings packed data: Tables: %d bytes", g.SettingsTables.size())) + { + for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) + DebugNodeTableSettings(settings); + TreePop(); + } + +#ifdef IMGUI_HAS_DOCK + if (TreeNode("SettingsDocking", "Settings packed data: Docking")) + { + ImGuiDockContext* dc = &g.DockContext; + Text("In SettingsWindows:"); + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->DockId != 0) + BulletText("Window '%s' -> DockId %08X", settings->GetName(), settings->DockId); + Text("In SettingsNodes:"); + for (int n = 0; n < dc->NodesSettings.Size; n++) + { + ImGuiDockNodeSettings* settings = &dc->NodesSettings[n]; + const char* selected_tab_name = NULL; + if (settings->SelectedTabId) + { + if (ImGuiWindow* window = FindWindowByID(settings->SelectedTabId)) + selected_tab_name = window->Name; + else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedTabId)) + selected_tab_name = window_settings->GetName(); + } + BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedTabId, selected_tab_name ? selected_tab_name : settings->SelectedTabId ? "N/A" : ""); + } + TreePop(); + } +#endif // #ifdef IMGUI_HAS_DOCK + + if (TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size())) + { + InputTextMultiline("##Ini", (char*)(void*)g.SettingsIniData.c_str(), g.SettingsIniData.Buf.Size, ImVec2(-FLT_MIN, GetTextLineHeight() * 20), ImGuiInputTextFlags_ReadOnly); + TreePop(); + } + TreePop(); + } + + // Misc Details + if (TreeNode("Internal state")) + { + Text("WINDOWING"); + Indent(); + Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); + Text("HoveredWindow->Root: '%s'", g.HoveredWindow ? g.HoveredWindow->RootWindowDockTree->Name : "NULL"); + Text("HoveredWindowUnderMovingWindow: '%s'", g.HoveredWindowUnderMovingWindow ? g.HoveredWindowUnderMovingWindow->Name : "NULL"); + Text("HoveredDockNode: 0x%08X", g.HoveredDockNode ? g.HoveredDockNode->ID : 0); + Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL"); + Text("MouseViewport: 0x%08X (UserHovered 0x%08X, LastHovered 0x%08X)", g.MouseViewport->ID, g.IO.MouseHoveredViewport, g.MouseLastHoveredViewport ? g.MouseLastHoveredViewport->ID : 0); + Unindent(); + + Text("ITEMS"); + Indent(); + Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, GetInputSourceName(g.ActiveIdSource)); + Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); + + int active_id_using_key_input_count = 0; + for (int n = 0; n < ImGuiKey_NamedKey_COUNT; n++) + active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0; + Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count); + Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame + Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); + Unindent(); + + Text("NAV,FOCUS"); + Indent(); + Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); + Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); + Text("NavInputSource: %s", GetInputSourceName(g.NavInputSource)); + Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); + Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId); + Text("NavActivateFlags: %04X", g.NavActivateFlags); + Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); + Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId); + Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL"); + Unindent(); + + TreePop(); + } + + // Overlay: Display windows Rectangles and Begin Order + if (cfg->ShowWindowsRects || cfg->ShowWindowsBeginOrder) + { + for (int n = 0; n < g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + if (!window->WasActive) + continue; + ImDrawList* draw_list = GetForegroundDrawList(window); + if (cfg->ShowWindowsRects) + { + ImRect r = Funcs::GetWindowRect(window, cfg->ShowWindowsRectsType); + draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255)); + } + if (cfg->ShowWindowsBeginOrder && !(window->Flags & ImGuiWindowFlags_ChildWindow)) + { + char buf[32]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext); + float font_size = GetFontSize(); + draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255)); + draw_list->AddText(window->Pos, IM_COL32(255, 255, 255, 255), buf); + } + } + } + + // Overlay: Display Tables Rectangles + if (cfg->ShowTablesRects) + { + for (int table_n = 0; table_n < g.Tables.GetMapSize(); table_n++) + { + ImGuiTable* table = g.Tables.TryGetMapData(table_n); + if (table == NULL || table->LastFrameActive < g.FrameCount - 1) + continue; + ImDrawList* draw_list = GetForegroundDrawList(table->OuterWindow); + if (cfg->ShowTablesRectsType >= TRT_ColumnsRect) + { + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImRect r = Funcs::GetTableRect(table, cfg->ShowTablesRectsType, column_n); + ImU32 col = (table->HoveredColumnBody == column_n) ? IM_COL32(255, 255, 128, 255) : IM_COL32(255, 0, 128, 255); + float thickness = (table->HoveredColumnBody == column_n) ? 3.0f : 1.0f; + draw_list->AddRect(r.Min, r.Max, col, 0.0f, 0, thickness); + } + } + else + { + ImRect r = Funcs::GetTableRect(table, cfg->ShowTablesRectsType, -1); + draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255)); + } + } + } + +#ifdef IMGUI_HAS_DOCK + // Overlay: Display Docking info + if (cfg->ShowDockingNodes && g.IO.KeyCtrl && g.HoveredDockNode) + { + char buf[64] = ""; + char* p = buf; + ImGuiDockNode* node = g.HoveredDockNode; + ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); + p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : ""); + p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId); + p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y); + p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y); + int depth = DockNodeGetDepth(node); + overlay_draw_list->AddRect(node->Pos + ImVec2(3, 3) * (float)depth, node->Pos + node->Size - ImVec2(3, 3) * (float)depth, IM_COL32(200, 100, 100, 255)); + ImVec2 pos = node->Pos + ImVec2(3, 3) * (float)depth; + overlay_draw_list->AddRectFilled(pos - ImVec2(1, 1), pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255)); + overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf); + } +#endif // #ifdef IMGUI_HAS_DOCK + + End(); +} + +// [DEBUG] List fonts in a font atlas and display its texture +void ImGui::ShowFontAtlas(ImFontAtlas* atlas) +{ + for (int i = 0; i < atlas->Fonts.Size; i++) + { + ImFont* font = atlas->Fonts[i]; + PushID(font); + DebugNodeFont(font); + PopID(); + } + if (TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) + { + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f); + Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col); + TreePop(); + } +} + +// [DEBUG] Display contents of Columns +void ImGui::DebugNodeColumns(ImGuiOldColumns* columns) +{ + if (!TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) + return; + BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->OffMaxX - columns->OffMinX, columns->OffMinX, columns->OffMaxX); + for (int column_n = 0; column_n < columns->Columns.Size; column_n++) + BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, GetColumnOffsetFromNorm(columns, columns->Columns[column_n].OffsetNorm)); + TreePop(); +} + +static void DebugNodeDockNodeFlags(ImGuiDockNodeFlags* p_flags, const char* label, bool enabled) +{ + using namespace ImGui; + PushID(label); + PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + Text("%s:", label); + if (!enabled) + BeginDisabled(); + CheckboxFlags("NoSplit", p_flags, ImGuiDockNodeFlags_NoSplit); + CheckboxFlags("NoResize", p_flags, ImGuiDockNodeFlags_NoResize); + CheckboxFlags("NoResizeX", p_flags, ImGuiDockNodeFlags_NoResizeX); + CheckboxFlags("NoResizeY",p_flags, ImGuiDockNodeFlags_NoResizeY); + CheckboxFlags("NoTabBar", p_flags, ImGuiDockNodeFlags_NoTabBar); + CheckboxFlags("HiddenTabBar", p_flags, ImGuiDockNodeFlags_HiddenTabBar); + CheckboxFlags("NoWindowMenuButton", p_flags, ImGuiDockNodeFlags_NoWindowMenuButton); + CheckboxFlags("NoCloseButton", p_flags, ImGuiDockNodeFlags_NoCloseButton); + CheckboxFlags("NoDocking", p_flags, ImGuiDockNodeFlags_NoDocking); + CheckboxFlags("NoDockingSplitMe", p_flags, ImGuiDockNodeFlags_NoDockingSplitMe); + CheckboxFlags("NoDockingSplitOther", p_flags, ImGuiDockNodeFlags_NoDockingSplitOther); + CheckboxFlags("NoDockingOverMe", p_flags, ImGuiDockNodeFlags_NoDockingOverMe); + CheckboxFlags("NoDockingOverOther", p_flags, ImGuiDockNodeFlags_NoDockingOverOther); + CheckboxFlags("NoDockingOverEmpty", p_flags, ImGuiDockNodeFlags_NoDockingOverEmpty); + if (!enabled) + EndDisabled(); + PopStyleVar(); + PopID(); +} + +// [DEBUG] Display contents of ImDockNode +void ImGui::DebugNodeDockNode(ImGuiDockNode* node, const char* label) +{ + ImGuiContext& g = *GImGui; + const bool is_alive = (g.FrameCount - node->LastFrameAlive < 2); // Submitted with ImGuiDockNodeFlags_KeepAliveOnly + const bool is_active = (g.FrameCount - node->LastFrameActive < 2); // Submitted + if (!is_alive) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } + bool open; + if (node->Windows.Size > 0) + open = TreeNode((void*)(intptr_t)node->ID, "%s 0x%04X%s: %d windows (vis: '%s')", label, node->ID, node->IsVisible ? "" : " (hidden)", node->Windows.Size, node->VisibleWindow ? node->VisibleWindow->Name : "NULL"); + else + open = TreeNode((void*)(intptr_t)node->ID, "%s 0x%04X%s: %s split (vis: '%s')", label, node->ID, node->IsVisible ? "" : " (hidden)", (node->SplitAxis == ImGuiAxis_X) ? "horizontal" : (node->SplitAxis == ImGuiAxis_Y) ? "vertical" : "n/a", node->VisibleWindow ? node->VisibleWindow->Name : "NULL"); + if (!is_alive) { PopStyleColor(); } + if (is_active && IsItemHovered()) + if (ImGuiWindow* window = node->HostWindow ? node->HostWindow : node->VisibleWindow) + GetForegroundDrawList(window)->AddRect(node->Pos, node->Pos + node->Size, IM_COL32(255, 255, 0, 255)); + if (open) + { + IM_ASSERT(node->ChildNodes[0] == NULL || node->ChildNodes[0]->ParentNode == node); + IM_ASSERT(node->ChildNodes[1] == NULL || node->ChildNodes[1]->ParentNode == node); + BulletText("Pos (%.0f,%.0f), Size (%.0f, %.0f) Ref (%.0f, %.0f)", + node->Pos.x, node->Pos.y, node->Size.x, node->Size.y, node->SizeRef.x, node->SizeRef.y); + DebugNodeWindow(node->HostWindow, "HostWindow"); + DebugNodeWindow(node->VisibleWindow, "VisibleWindow"); + BulletText("SelectedTabID: 0x%08X, LastFocusedNodeID: 0x%08X", node->SelectedTabId, node->LastFocusedNodeId); + BulletText("Misc:%s%s%s%s%s%s", + node->IsDockSpace() ? " IsDockSpace" : "", + node->IsCentralNode() ? " IsCentralNode" : "", + is_alive ? " IsAlive" : "", is_active ? " IsActive" : "", + node->WantLockSizeOnce ? " WantLockSizeOnce" : "", + node->HasCentralNodeChild ? " HasCentralNodeChild" : ""); + if (TreeNode("flags", "Flags Merged: 0x%04X, Local: 0x%04X, InWindows: 0x%04X, Shared: 0x%04X", node->MergedFlags, node->LocalFlags, node->LocalFlagsInWindows, node->SharedFlags)) + { + if (BeginTable("flags", 4)) + { + TableNextColumn(); DebugNodeDockNodeFlags(&node->MergedFlags, "MergedFlags", false); + TableNextColumn(); DebugNodeDockNodeFlags(&node->LocalFlags, "LocalFlags", true); + TableNextColumn(); DebugNodeDockNodeFlags(&node->LocalFlagsInWindows, "LocalFlagsInWindows", false); + TableNextColumn(); DebugNodeDockNodeFlags(&node->SharedFlags, "SharedFlags", true); + EndTable(); + } + TreePop(); + } + if (node->ParentNode) + DebugNodeDockNode(node->ParentNode, "ParentNode"); + if (node->ChildNodes[0]) + DebugNodeDockNode(node->ChildNodes[0], "Child[0]"); + if (node->ChildNodes[1]) + DebugNodeDockNode(node->ChildNodes[1], "Child[1]"); + if (node->TabBar) + DebugNodeTabBar(node->TabBar, "TabBar"); + TreePop(); + } +} + +// [DEBUG] Display contents of ImDrawList +// Note that both 'window' and 'viewport' may be NULL here. Viewport is generally null of destroyed popups which previously owned a viewport. +void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label) +{ + ImGuiContext& g = *GImGui; + ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; + int cmd_count = draw_list->CmdBuffer.Size; + if (cmd_count > 0 && draw_list->CmdBuffer.back().ElemCount == 0 && draw_list->CmdBuffer.back().UserCallback == NULL) + cmd_count--; + bool node_open = TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, cmd_count); + if (draw_list == GetWindowDrawList()) + { + SameLine(); + TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) + if (node_open) + TreePop(); + return; + } + + ImDrawList* fg_draw_list = viewport ? GetForegroundDrawList(viewport) : NULL; // Render additional visuals into the top-most draw list + if (window && IsItemHovered() && fg_draw_list) + fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); + if (!node_open) + return; + + if (window && !window->WasActive) + TextDisabled("Warning: owning Window is inactive. This DrawList is not being rendered!"); + + for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.Data; pcmd < draw_list->CmdBuffer.Data + cmd_count; pcmd++) + { + if (pcmd->UserCallback) + { + BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); + continue; + } + + char buf[300]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d tris, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)", + pcmd->ElemCount / 3, (void*)(intptr_t)pcmd->TextureId, + pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); + bool pcmd_node_open = TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf); + if (IsItemHovered() && (cfg->ShowDrawCmdMesh || cfg->ShowDrawCmdBoundingBoxes) && fg_draw_list) + DebugNodeDrawCmdShowMeshAndBoundingBox(fg_draw_list, draw_list, pcmd, cfg->ShowDrawCmdMesh, cfg->ShowDrawCmdBoundingBoxes); + if (!pcmd_node_open) + continue; + + // Calculate approximate coverage area (touched pixel count) + // This will be in pixels squared as long there's no post-scaling happening to the renderer output. + const ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; + const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + pcmd->VtxOffset; + float total_area = 0.0f; + for (unsigned int idx_n = pcmd->IdxOffset; idx_n < pcmd->IdxOffset + pcmd->ElemCount; ) + { + ImVec2 triangle[3]; + for (int n = 0; n < 3; n++, idx_n++) + triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos; + total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]); + } + + // Display vertex information summary. Hover to get all triangles drawn in wire-frame + ImFormatString(buf, IM_ARRAYSIZE(buf), "Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px", pcmd->ElemCount, pcmd->VtxOffset, pcmd->IdxOffset, total_area); + Selectable(buf); + if (IsItemHovered() && fg_draw_list) + DebugNodeDrawCmdShowMeshAndBoundingBox(fg_draw_list, draw_list, pcmd, true, false); + + // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. + ImGuiListClipper clipper; + clipper.Begin(pcmd->ElemCount / 3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. + while (clipper.Step()) + for (int prim = clipper.DisplayStart, idx_i = pcmd->IdxOffset + clipper.DisplayStart * 3; prim < clipper.DisplayEnd; prim++) + { + char* buf_p = buf, * buf_end = buf + IM_ARRAYSIZE(buf); + ImVec2 triangle[3]; + for (int n = 0; n < 3; n++, idx_i++) + { + const ImDrawVert& v = vtx_buffer[idx_buffer ? idx_buffer[idx_i] : idx_i]; + triangle[n] = v.pos; + buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n", + (n == 0) ? "Vert:" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + } + + Selectable(buf, false); + if (fg_draw_list && IsItemHovered()) + { + ImDrawListFlags backup_flags = fg_draw_list->Flags; + fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles. + fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f); + fg_draw_list->Flags = backup_flags; + } + } + TreePop(); + } + TreePop(); +} + +// [DEBUG] Display mesh/aabb of a ImDrawCmd +void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb) +{ + IM_ASSERT(show_mesh || show_aabb); + + // Draw wire-frame version of all triangles + ImRect clip_rect = draw_cmd->ClipRect; + ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); + ImDrawListFlags backup_flags = out_draw_list->Flags; + out_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles. + for (unsigned int idx_n = draw_cmd->IdxOffset, idx_end = draw_cmd->IdxOffset + draw_cmd->ElemCount; idx_n < idx_end; ) + { + ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; // We don't hold on those pointers past iterations as ->AddPolyline() may invalidate them if out_draw_list==draw_list + ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset; + + ImVec2 triangle[3]; + for (int n = 0; n < 3; n++, idx_n++) + vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos)); + if (show_mesh) + out_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), ImDrawFlags_Closed, 1.0f); // In yellow: mesh triangles + } + // Draw bounding boxes + if (show_aabb) + { + out_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255, 0, 255, 255)); // In pink: clipping rectangle submitted to GPU + out_draw_list->AddRect(ImFloor(vtxs_rect.Min), ImFloor(vtxs_rect.Max), IM_COL32(0, 255, 255, 255)); // In cyan: bounding box of triangles + } + out_draw_list->Flags = backup_flags; +} + +// [DEBUG] Display details for a single font, called by ShowStyleEditor(). +void ImGui::DebugNodeFont(ImFont* font) +{ + bool opened = TreeNode(font, "Font: \"%s\"\n%.2f px, %d glyphs, %d file(s)", + font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount); + SameLine(); + if (SmallButton("Set as default")) + GetIO().FontDefault = font; + if (!opened) + return; + + // Display preview text + PushFont(font); + Text("The quick brown fox jumps over the lazy dog"); + PopFont(); + + // Display details + SetNextItemWidth(GetFontSize() * 8); + DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); + SameLine(); MetricsHelpMarker( + "Note than the default embedded font is NOT meant to be scaled.\n\n" + "Font are currently rendered into bitmaps at a given size at the time of building the atlas. " + "You may oversample them to get some flexibility with scaling. " + "You can also render at multiple sizes and select which one to use at runtime.\n\n" + "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)"); + Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); + char c_str[5]; + Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar); + Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar); + const int surface_sqrt = (int)ImSqrt((float)font->MetricsTotalSurface); + Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt); + for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) + if (font->ConfigData) + if (const ImFontConfig* cfg = &font->ConfigData[config_i]) + BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)", + config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y); + + // Display all glyphs of the fonts in separate pages of 256 characters + if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) + { + ImDrawList* draw_list = GetWindowDrawList(); + const ImU32 glyph_col = GetColorU32(ImGuiCol_Text); + const float cell_size = font->FontSize * 1; + const float cell_spacing = GetStyle().ItemSpacing.y; + for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256) + { + // Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k) + // This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT + // is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here) + if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095)) + { + base += 4096 - 256; + continue; + } + + int count = 0; + for (unsigned int n = 0; n < 256; n++) + if (font->FindGlyphNoFallback((ImWchar)(base + n))) + count++; + if (count <= 0) + continue; + if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph")) + continue; + + // Draw a 16x16 grid of glyphs + ImVec2 base_pos = GetCursorScreenPos(); + for (unsigned int n = 0; n < 256; n++) + { + // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions + // available here and thus cannot easily generate a zero-terminated UTF-8 encoded string. + ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing)); + ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size); + const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n)); + draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50)); + if (glyph) + font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n)); + if (glyph && IsMouseHoveringRect(cell_p1, cell_p2)) + { + BeginTooltip(); + Text("Codepoint: U+%04X", base + n); + Separator(); + Text("Visible: %d", glyph->Visible); + Text("AdvanceX: %.1f", glyph->AdvanceX); + Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); + Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); + EndTooltip(); + } + } + Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16)); + TreePop(); + } + TreePop(); + } + TreePop(); +} + +// [DEBUG] Display contents of ImGuiStorage +void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) +{ + if (!TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) + return; + for (int n = 0; n < storage->Data.Size; n++) + { + const ImGuiStorage::ImGuiStoragePair& p = storage->Data[n]; + BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer. + } + TreePop(); +} + +// [DEBUG] Display contents of ImGuiTabBar +void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label) +{ + // Standalone tab bars (not associated to docking/windows functionality) currently hold no discernible strings. + char buf[256]; + char* p = buf; + const char* buf_end = buf + IM_ARRAYSIZE(buf); + const bool is_active = (tab_bar->PrevFrameVisible >= GetFrameCount() - 2); + p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*"); + p += ImFormatString(p, buf_end - p, " { "); + for (int tab_n = 0; tab_n < ImMin(tab_bar->Tabs.Size, 3); tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + p += ImFormatString(p, buf_end - p, "%s'%s'", + tab_n > 0 ? ", " : "", (tab->Window || tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???"); + } + p += ImFormatString(p, buf_end - p, (tab_bar->Tabs.Size > 3) ? " ... }" : " } "); + if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } + bool open = TreeNode(label, "%s", buf); + if (!is_active) { PopStyleColor(); } + if (is_active && IsItemHovered()) + { + ImDrawList* draw_list = GetForegroundDrawList(); + draw_list->AddRect(tab_bar->BarRect.Min, tab_bar->BarRect.Max, IM_COL32(255, 255, 0, 255)); + draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); + draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); + } + if (open) + { + for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) + { + const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + PushID(tab); + if (SmallButton("<")) { TabBarQueueReorder(tab_bar, tab, -1); } SameLine(0, 2); + if (SmallButton(">")) { TabBarQueueReorder(tab_bar, tab, +1); } SameLine(); + Text("%02d%c Tab 0x%08X '%s' Offset: %.1f, Width: %.1f/%.1f", + tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->Window || tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???", tab->Offset, tab->Width, tab->ContentWidth); + PopID(); + } + TreePop(); + } +} + +void ImGui::DebugNodeViewport(ImGuiViewportP* viewport) +{ + SetNextItemOpen(true, ImGuiCond_Once); + if (TreeNode((void*)(intptr_t)viewport->ID, "Viewport #%d, ID: 0x%08X, Parent: 0x%08X, Window: \"%s\"", viewport->Idx, viewport->ID, viewport->ParentViewportId, viewport->Window ? viewport->Window->Name : "N/A")) + { + ImGuiWindowFlags flags = viewport->Flags; + BulletText("Main Pos: (%.0f,%.0f), Size: (%.0f,%.0f)\nWorkArea Offset Left: %.0f Top: %.0f, Right: %.0f, Bottom: %.0f\nMonitor: %d, DpiScale: %.0f%%", + viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y, + viewport->WorkOffsetMin.x, viewport->WorkOffsetMin.y, viewport->WorkOffsetMax.x, viewport->WorkOffsetMax.y, + viewport->PlatformMonitor, viewport->DpiScale * 100.0f); + if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200, 200); viewport->UpdateWorkRect(); if (viewport->Window) viewport->Window->Pos = viewport->Pos; } } + BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s%s%s%s%s%s", viewport->Flags, + //(flags & ImGuiViewportFlags_IsPlatformWindow) ? " IsPlatformWindow" : "", // Omitting because it is the standard + (flags & ImGuiViewportFlags_IsPlatformMonitor) ? " IsPlatformMonitor" : "", + (flags & ImGuiViewportFlags_OwnedByApp) ? " OwnedByApp" : "", + (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "", + (flags & ImGuiViewportFlags_NoTaskBarIcon) ? " NoTaskBarIcon" : "", + (flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", + (flags & ImGuiViewportFlags_NoFocusOnClick) ? " NoFocusOnClick" : "", + (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "", + (flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", + (flags & ImGuiViewportFlags_TopMost) ? " TopMost" : "", + (flags & ImGuiViewportFlags_Minimized) ? " Minimized" : "", + (flags & ImGuiViewportFlags_NoAutoMerge) ? " NoAutoMerge" : "", + (flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : ""); + for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++) + for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++) + DebugNodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList"); + TreePop(); + } +} + +void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label) +{ + if (window == NULL) + { + BulletText("%s: NULL", label); + return; + } + + ImGuiContext& g = *GImGui; + const bool is_active = window->WasActive; + ImGuiTreeNodeFlags tree_node_flags = (window == g.NavWindow) ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags_None; + if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } + const bool open = TreeNodeEx(label, tree_node_flags, "%s '%s'%s", label, window->Name, is_active ? "" : " *Inactive*"); + if (!is_active) { PopStyleColor(); } + if (IsItemHovered() && is_active) + GetForegroundDrawList(window)->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); + if (!open) + return; + + if (window->MemoryCompacted) + TextDisabled("Note: some memory buffers have been compacted/freed."); + + ImGuiWindowFlags flags = window->Flags; + DebugNodeDrawList(window, window->Viewport, window->DrawList, "DrawList"); + BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) Ideal (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y, window->ContentSizeIdeal.x, window->ContentSizeIdeal.y); + BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags, + (flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "", + (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "", + (flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : ""); + BulletText("WindowClassId: 0x%08X", window->WindowClass.ClassId); + BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s", window->Scroll.x, window->ScrollMax.x, window->Scroll.y, window->ScrollMax.y, window->ScrollbarX ? "X" : "", window->ScrollbarY ? "Y" : ""); + BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1); + BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems); + for (int layer = 0; layer < ImGuiNavLayer_COUNT; layer++) + { + ImRect r = window->NavRectRel[layer]; + if (r.Min.x >= r.Max.y && r.Min.y >= r.Max.y) + { + BulletText("NavLastIds[%d]: 0x%08X", layer, window->NavLastIds[layer]); + continue; + } + BulletText("NavLastIds[%d]: 0x%08X at +(%.1f,%.1f)(%.1f,%.1f)", layer, window->NavLastIds[layer], r.Min.x, r.Min.y, r.Max.x, r.Max.y); + if (IsItemHovered()) + GetForegroundDrawList(window)->AddRect(r.Min + window->Pos, r.Max + window->Pos, IM_COL32(255, 255, 0, 255)); + } + BulletText("NavLayersActiveMask: %X, NavLastChildNavWindow: %s", window->DC.NavLayersActiveMask, window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); + + BulletText("Viewport: %d%s, ViewportId: 0x%08X, ViewportPos: (%.1f,%.1f)", window->Viewport ? window->Viewport->Idx : -1, window->ViewportOwned ? " (Owned)" : "", window->ViewportId, window->ViewportPos.x, window->ViewportPos.y); + BulletText("ViewportMonitor: %d", window->Viewport ? window->Viewport->PlatformMonitor : -1); + BulletText("DockId: 0x%04X, DockOrder: %d, Act: %d, Vis: %d", window->DockId, window->DockOrder, window->DockIsActive, window->DockTabIsVisible); + if (window->DockNode || window->DockNodeAsHost) + DebugNodeDockNode(window->DockNodeAsHost ? window->DockNodeAsHost : window->DockNode, window->DockNodeAsHost ? "DockNodeAsHost" : "DockNode"); + + if (window->RootWindow != window) { DebugNodeWindow(window->RootWindow, "RootWindow"); } + if (window->RootWindowDockTree != window->RootWindow) { DebugNodeWindow(window->RootWindowDockTree, "RootWindowDockTree"); } + if (window->ParentWindow != NULL) { DebugNodeWindow(window->ParentWindow, "ParentWindow"); } + if (window->DC.ChildWindows.Size > 0) { DebugNodeWindowsList(&window->DC.ChildWindows, "ChildWindows"); } + if (window->ColumnsStorage.Size > 0 && TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size)) + { + for (int n = 0; n < window->ColumnsStorage.Size; n++) + DebugNodeColumns(&window->ColumnsStorage[n]); + TreePop(); + } + DebugNodeStorage(&window->StateStorage, "Storage"); + TreePop(); +} + +void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings* settings) +{ + Text("0x%08X \"%s\" Pos (%d,%d) Size (%d,%d) Collapsed=%d", + settings->ID, settings->GetName(), settings->Pos.x, settings->Pos.y, settings->Size.x, settings->Size.y, settings->Collapsed); +} + +void ImGui::DebugNodeWindowsList(ImVector* windows, const char* label) +{ + if (!TreeNode(label, "%s (%d)", label, windows->Size)) + return; + for (int i = windows->Size - 1; i >= 0; i--) // Iterate front to back + { + PushID((*windows)[i]); + DebugNodeWindow((*windows)[i], "Window"); + PopID(); + } + TreePop(); +} + +// FIXME-OPT: This is technically suboptimal, but it is simpler this way. +void ImGui::DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack) +{ + for (int i = 0; i < windows_size; i++) + { + ImGuiWindow* window = windows[i]; + if (window->ParentWindowInBeginStack != parent_in_begin_stack) + continue; + char buf[20]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "[%04d] Window", window->BeginOrderWithinContext); + //BulletText("[%04d] Window '%s'", window->BeginOrderWithinContext, window->Name); + DebugNodeWindow(window, buf); + Indent(); + DebugNodeWindowsListByBeginStackParent(windows + i + 1, windows_size - i - 1, window); + Unindent(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, STACK TOOL) +//----------------------------------------------------------------------------- + +// [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack. +void ImGui::UpdateDebugToolItemPicker() +{ + ImGuiContext& g = *GImGui; + g.DebugItemPickerBreakId = 0; + if (!g.DebugItemPickerActive) + return; + + const ImGuiID hovered_id = g.HoveredIdPreviousFrame; + SetMouseCursor(ImGuiMouseCursor_Hand); + if (IsKeyPressed(ImGuiKey_Escape)) + g.DebugItemPickerActive = false; + if (IsMouseClicked(0) && hovered_id) + { + g.DebugItemPickerBreakId = hovered_id; + g.DebugItemPickerActive = false; + } + SetNextWindowBgAlpha(0.60f); + BeginTooltip(); + Text("HoveredId: 0x%08X", hovered_id); + Text("Press ESC to abort picking."); + TextColored(GetStyleColorVec4(hovered_id ? ImGuiCol_Text : ImGuiCol_TextDisabled), "Click to break in debugger!"); + EndTooltip(); +} + +// [DEBUG] Stack Tool: update queries. Called by NewFrame() +void ImGui::UpdateDebugToolStackQueries() +{ + ImGuiContext& g = *GImGui; + ImGuiStackTool* tool = &g.DebugStackTool; + + // Clear hook when stack tool is not visible + g.DebugHookIdInfo = 0; + if (g.FrameCount != tool->LastActiveFrame + 1) + return; + + // Update queries. The steps are: -1: query Stack, >= 0: query each stack item + // We can only perform 1 ID Info query every frame. This is designed so the GetID() tests are cheap and constant-time + const ImGuiID query_id = g.HoveredIdPreviousFrame ? g.HoveredIdPreviousFrame : g.ActiveId; + if (tool->QueryId != query_id) + { + tool->QueryId = query_id; + tool->StackLevel = -1; + tool->Results.resize(0); + } + if (query_id == 0) + return; + + // Advance to next stack level when we got our result, or after 2 frames (in case we never get a result) + int stack_level = tool->StackLevel; + if (stack_level >= 0 && stack_level < tool->Results.Size) + if (tool->Results[stack_level].QuerySuccess || tool->Results[stack_level].QueryFrameCount > 2) + tool->StackLevel++; + + // Update hook + stack_level = tool->StackLevel; + if (stack_level == -1) + g.DebugHookIdInfo = query_id; + if (stack_level >= 0 && stack_level < tool->Results.Size) + { + g.DebugHookIdInfo = tool->Results[stack_level].ID; + tool->Results[stack_level].QueryFrameCount++; + } +} + +// [DEBUG] Stack tool: hooks called by GetID() family functions +void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiStackTool* tool = &g.DebugStackTool; + + // Step 0: stack query + // This assume that the ID was computed with the current ID stack, which tends to be the case for our widget. + if (tool->StackLevel == -1) + { + tool->StackLevel++; + tool->Results.resize(window->IDStack.Size + 1, ImGuiStackLevelInfo()); + for (int n = 0; n < window->IDStack.Size + 1; n++) + tool->Results[n].ID = (n < window->IDStack.Size) ? window->IDStack[n] : id; + return; + } + + // Step 1+: query for individual level + IM_ASSERT(tool->StackLevel >= 0); + if (tool->StackLevel != window->IDStack.Size) + return; + ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel]; + IM_ASSERT(info->ID == id && info->QueryFrameCount > 0); + + int data_len; + switch (data_type) + { + case ImGuiDataType_S32: + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id); + break; + case ImGuiDataType_String: + data_len = data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id); + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "\"%.*s\"", data_len, (const char*)data_id); + break; + case ImGuiDataType_Pointer: + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id); + break; + case ImGuiDataType_ID: + if (info->Desc[0] == 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one. + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id); + break; + default: + IM_ASSERT(0); + } + info->QuerySuccess = true; +} + +// Stack Tool: Display UI +void ImGui::ShowStackToolWindow(bool* p_open) +{ + ImGuiContext& g = *GImGui; + if (!(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize)) + SetNextWindowSize(ImVec2(0.0f, GetFontSize() * 8.0f), ImGuiCond_FirstUseEver); + if (!Begin("Dear ImGui Stack Tool", p_open) || GetCurrentWindow()->BeginCount > 1) + { + End(); + return; + } + + // Display hovered/active status + const ImGuiID hovered_id = g.HoveredIdPreviousFrame; + const ImGuiID active_id = g.ActiveId; +#ifdef IMGUI_ENABLE_TEST_ENGINE + Text("HoveredId: 0x%08X (\"%s\"), ActiveId: 0x%08X (\"%s\")", hovered_id, hovered_id ? ImGuiTestEngine_FindItemDebugLabel(&g, hovered_id) : "", active_id, active_id ? ImGuiTestEngine_FindItemDebugLabel(&g, active_id) : ""); +#else + Text("HoveredId: 0x%08X, ActiveId: 0x%08X", hovered_id, active_id); +#endif + SameLine(); + MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details."); + + // Display decorated stack + ImGuiStackTool* tool = &g.DebugStackTool; + tool->LastActiveFrame = g.FrameCount; + if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders)) + { + const float id_width = CalcTextSize("0xDDDDDDDD").x; + TableSetupColumn("Seed", ImGuiTableColumnFlags_WidthFixed, id_width); + TableSetupColumn("PushID", ImGuiTableColumnFlags_WidthStretch); + TableSetupColumn("Result", ImGuiTableColumnFlags_WidthFixed, id_width); + TableHeadersRow(); + for (int n = 0; n < tool->Results.Size; n++) + { + ImGuiStackLevelInfo* info = &tool->Results[n]; + TableNextColumn(); + Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0); + + TableNextColumn(); + ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? FindWindowByID(info->ID) : NULL; + if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked) + Text("\"%s\" [window]", window->Name); + else if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id) + TextUnformatted(info->Desc); + else if (tool->StackLevel >= tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers. + { +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (const char* label = ImGuiTestEngine_FindItemDebugLabel(&g, info->ID)) // Source: ImGuiTestEngine's ItemInfo() + Text("??? \"%s\"", label); + else +#endif + TextUnformatted("???"); + } + + TableNextColumn(); + Text("0x%08X", info->ID); + if (n == tool->Results.Size - 1) + TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_Header)); + } + EndTable(); + } + End(); +} + +#else + +void ImGui::ShowMetricsWindow(bool*) {} +void ImGui::ShowFontAtlas(ImFontAtlas*) {} +void ImGui::DebugNodeColumns(ImGuiOldColumns*) {} +void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {} +void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {} +void ImGui::DebugNodeFont(ImFont*) {} +void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {} +void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {} +void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {} +void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings*) {} +void ImGui::DebugNodeWindowsList(ImVector*, const char*) {} +void ImGui::DebugNodeViewport(ImGuiViewportP*) {} + +void ImGui::ShowStackToolWindow(bool*) {} +void ImGui::DebugHookIdInfo(ImGuiID, ImGuiDataType, const void*, const void*) {} +void ImGui::UpdateDebugToolItemPicker() {} +void ImGui::UpdateDebugToolStackQueries() {} + +#endif // #ifndef IMGUI_DISABLE_METRICS_WINDOW + +//----------------------------------------------------------------------------- + +// Include imgui_user.inl at the end of imgui.cpp to access private data/functions that aren't exposed. +// Prefer just including imgui_internal.h from your code rather than using this define. If a declaration is missing from imgui_internal.h add it or request it on the github. +#ifdef IMGUI_INCLUDE_IMGUI_USER_INL +#include "imgui_user.inl" +#endif + +//----------------------------------------------------------------------------- + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui.h b/libultraship/libultraship/Lib/ImGui/imgui.h new file mode 100644 index 000000000..fa2dadcda --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui.h @@ -0,0 +1,3300 @@ +// dear imgui, v1.87 +// (headers) + +// Help: +// - Read FAQ at http://dearimgui.org/faq +// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. +// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. +// Read imgui.cpp for details, links and comments. + +// Resources: +// - FAQ http://dearimgui.org/faq +// - Homepage & latest https://github.com/ocornut/imgui +// - Releases & changelog https://github.com/ocornut/imgui/releases +// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!) +// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Glossary https://github.com/ocornut/imgui/wiki/Glossary +// - Issues & support https://github.com/ocornut/imgui/issues + +// Getting Started? +// - For first-time users having issues compiling/linking/running or issues loading fonts: +// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. + +/* + +Index of this file: +// [SECTION] Header mess +// [SECTION] Forward declarations and basic types +// [SECTION] Dear ImGui end-user API functions +// [SECTION] Flags & Enumerations +// [SECTION] Helpers: Memory allocations macros, ImVector<> +// [SECTION] ImGuiStyle +// [SECTION] ImGuiIO +// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiWindowClass, ImGuiPayload, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs) +// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) +// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData) +// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont) +// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport) +// [SECTION] Platform Dependent Interfaces (ImGuiPlatformIO, ImGuiPlatformMonitor, ImGuiPlatformImeData) +// [SECTION] Obsolete functions and types + +*/ + +#pragma once + +// Configuration file with compile-time options (edit imconfig.h or '#define IMGUI_USER_CONFIG "myfilename.h" from your build system') +#ifdef IMGUI_USER_CONFIG +#include IMGUI_USER_CONFIG +#endif +#if !defined(IMGUI_DISABLE_INCLUDE_IMCONFIG_H) || defined(IMGUI_INCLUDE_IMCONFIG_H) +#include "imconfig.h" +#endif + +#ifndef IMGUI_DISABLE + +//----------------------------------------------------------------------------- +// [SECTION] Header mess +//----------------------------------------------------------------------------- + +// Includes +#include // FLT_MIN, FLT_MAX +#include // va_list, va_start, va_end +#include // ptrdiff_t, NULL +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp + +// Version +// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) +#define IMGUI_VERSION "1.87" +#define IMGUI_VERSION_NUM 18701 +#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) +#define IMGUI_HAS_TABLE +#define IMGUI_HAS_VIEWPORT // Viewport WIP branch +#define IMGUI_HAS_DOCK // Docking WIP branch + +// Define attributes of all API symbols declarations (e.g. for DLL under Windows) +// IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h) +// Using dear imgui via a shared library is not recommended, because we don't guarantee backward nor forward ABI compatibility (also function call overhead, as dear imgui is a call-heavy API) +#ifndef IMGUI_API +#define IMGUI_API +#endif +#ifndef IMGUI_IMPL_API +#define IMGUI_IMPL_API IMGUI_API +#endif + +// Helper Macros +#ifndef IM_ASSERT +#include +#define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h +#endif +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! +#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. +#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11 + +// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. +#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__) +#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1))) +#define IM_FMTLIST(FMT) __attribute__((format(gnu_printf, FMT, 0))) +#elif !defined(IMGUI_USE_STB_SPRINTF) && (defined(__clang__) || defined(__GNUC__)) +#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) +#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) +#else +#define IM_FMTARGS(FMT) +#define IM_FMTLIST(FMT) +#endif + +// Disable some of MSVC most aggressive Debug runtime checks in function header/footer (used in some simple/low-level functions) +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(IMGUI_DEBUG_PARANOID) +#define IM_MSVC_RUNTIME_CHECKS_OFF __pragma(runtime_checks("",off)) __pragma(check_stack(off)) __pragma(strict_gs_check(push,off)) +#define IM_MSVC_RUNTIME_CHECKS_RESTORE __pragma(runtime_checks("",restore)) __pragma(check_stack()) __pragma(strict_gs_check(pop)) +#else +#define IM_MSVC_RUNTIME_CHECKS_OFF +#define IM_MSVC_RUNTIME_CHECKS_RESTORE +#endif + +// Warnings +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6). +#endif +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Forward declarations and basic types +//----------------------------------------------------------------------------- + +// Forward declarations +struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit() +struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback) +struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix. +struct ImDrawList; // A single draw command list (generally one per window, conceptually you may see this as a dynamic "mesh" builder) +struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself) +struct ImDrawListSplitter; // Helper to split a draw list into different layers which can be drawn into out of order, then flattened back. +struct ImDrawVert; // A single vertex (pos + uv + col = 20 bytes by default. Override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) +struct ImFont; // Runtime data for a single font within a parent ImFontAtlas +struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader +struct ImFontBuilderIO; // Opaque interface to a font builder (stb_truetype or FreeType). +struct ImFontConfig; // Configuration data when adding a font or merging fonts +struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset) +struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data +struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using) +struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h) +struct ImGuiIO; // Main configuration and I/O between your application and ImGui +struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use) +struct ImGuiKeyData; // Storage for ImGuiIO and IsKeyDown(), IsKeyPressed() etc functions. +struct ImGuiListClipper; // Helper to manually clip large list of items +struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame +struct ImGuiPayload; // User data payload for drag and drop operations +struct ImGuiPlatformIO; // Multi-viewport support: interface for Platform/Renderer backends + viewports to render +struct ImGuiPlatformMonitor; // Multi-viewport support: user-provided bounds for each connected monitor/display. Used when positioning popups and tooltips to avoid them straddling monitors +struct ImGuiPlatformImeData; // Platform IME data for io.SetPlatformImeDataFn() function. +struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use) +struct ImGuiStorage; // Helper for key->value storage +struct ImGuiStyle; // Runtime data for styling/colors +struct ImGuiTableSortSpecs; // Sorting specifications for a table (often handling sort specs for a single column, occasionally more) +struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table +struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder) +struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]") +struct ImGuiViewport; // A Platform Window (always 1 unless multi-viewport are enabled. One per platform window to output to). In the future may represent Platform Monitor +struct ImGuiWindowClass; // Window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info) + +// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags without overhead, and to not pollute the top of this file) +// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! +// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. +typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling +typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions +typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type +typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction +typedef int ImGuiKey; // -> enum ImGuiKey_ // Enum: A key identifier +typedef int ImGuiNavInput; // -> enum ImGuiNavInput_ // Enum: An input identifier for navigation +typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle) +typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier +typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending) +typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling +typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor() +typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions +typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance +typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build +typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags +typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton() +typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc. +typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags +typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo() +typedef int ImGuiDockNodeFlags; // -> enum ImGuiDockNodeFlags_ // Flags: for DockSpace() +typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for BeginDragDropSource(), AcceptDragDropPayload() +typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() +typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. +typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() +typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super) +typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() +typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable() +typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. +typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar() +typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem() +typedef int ImGuiTableFlags; // -> enum ImGuiTableFlags_ // Flags: For BeginTable() +typedef int ImGuiTableColumnFlags; // -> enum ImGuiTableColumnFlags_// Flags: For TableSetupColumn() +typedef int ImGuiTableRowFlags; // -> enum ImGuiTableRowFlags_ // Flags: For TableNextRow() +typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader() +typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport +typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild() + +// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] +// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. +// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. +#ifndef ImTextureID +typedef void* ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) +#endif + +// ImDrawIdx: vertex index. [Compile-time configurable type] +// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended). +// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file. +#ifndef ImDrawIdx +typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends) +#endif + +// Scalar data types +typedef unsigned int ImGuiID;// A unique ID used by widgets (typically the result of hashing a stack of string) +typedef signed char ImS8; // 8-bit signed integer +typedef unsigned char ImU8; // 8-bit unsigned integer +typedef signed short ImS16; // 16-bit signed integer +typedef unsigned short ImU16; // 16-bit unsigned integer +typedef signed int ImS32; // 32-bit signed integer == int +typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) +typedef signed long long ImS64; // 64-bit signed integer +typedef unsigned long long ImU64; // 64-bit unsigned integer + +// Character types +// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) +typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings. +typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. +#ifdef IMGUI_USE_WCHAR32 // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16] +typedef ImWchar32 ImWchar; +#else +typedef ImWchar16 ImWchar; +#endif + +// Callback and functions types +typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); // Callback function for ImGui::InputText() +typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); // Callback function for ImGui::SetNextWindowSizeConstraints() +typedef void* (*ImGuiMemAllocFunc)(size_t sz, void* user_data); // Function signature for ImGui::SetAllocatorFunctions() +typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data); // Function signature for ImGui::SetAllocatorFunctions() + +// ImVec2: 2D vector used to store positions, sizes etc. [Compile-time configurable type] +// This is a frequently used type in the API. Consider using IM_VEC2_CLASS_EXTRA to create implicit cast from/to our preferred type. +IM_MSVC_RUNTIME_CHECKS_OFF +struct ImVec2 +{ + float x, y; + ImVec2() { x = y = 0.0f; } + ImVec2(float _x, float _y) { x = _x; y = _y; } + float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. + float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. +#ifdef IM_VEC2_CLASS_EXTRA + IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. +#endif +}; + +// ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type] +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 + IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. +#endif +}; +IM_MSVC_RUNTIME_CHECKS_RESTORE + +//----------------------------------------------------------------------------- +// [SECTION] Dear ImGui end-user API functions +// (Note that ImGui:: being a namespace, you can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!) +//----------------------------------------------------------------------------- + +namespace ImGui +{ + // Context creation and access + // - Each context create its own ImFontAtlas by default. You may instance one yourself and pass it to CreateContext() to share a font atlas between contexts. + // - DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() + // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for details. + IMGUI_API ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL); + IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context + IMGUI_API ImGuiContext* GetCurrentContext(); + IMGUI_API void SetCurrentContext(ImGuiContext* ctx); + + // Main + IMGUI_API ImGuiIO& GetIO(); // access the IO structure (mouse/keyboard/gamepad inputs, time, various configuration options/flags) + IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame! + IMGUI_API void NewFrame(); // start a new Dear ImGui frame, you can submit any command from this point until Render()/EndFrame(). + IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(). If you don't need to render data (skipping rendering) you may call EndFrame() without Render()... but you'll have wasted CPU already! If you don't need to render, better to not create any windows and not call NewFrame() at all! + IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can then get call GetDrawData(). + IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render. + + // Demo, Debug, Information + IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! + IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debugger window. display Dear ImGui internals: windows, draw commands, various internal state, etc. + IMGUI_API void ShowStackToolWindow(bool* p_open = NULL); // create Stack Tool window. hover items with mouse to query information about the source of their unique ID. + IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information. + IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) + IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles. + IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts. + IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). + IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.80 WIP" (essentially the value for IMGUI_VERSION from the compiled version of imgui.cpp) + + // Styles + IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default) + IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // best used with borders and a custom, thicker font + IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // classic imgui style + + // Windows + // - Begin() = push window to the stack and start appending to it. End() = pop window from the stack. + // - Passing 'bool* p_open != NULL' shows a window-closing widget in the upper-right corner of the window, + // which clicking will set the boolean to false when clicked. + // - You may append multiple times to the same window during the same frame by calling Begin()/End() pairs multiple times. + // Some information such as 'flags' or 'p_open' will only be considered by the first call to Begin(). + // - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting + // anything to the window. Always call a matching End() for each Begin() call, regardless of its return value! + // [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu, + // BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function + // returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.] + // - Note that the bottom of window stack always contains a window called "Debug". + IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); + IMGUI_API void End(); + + // Child Windows + // - Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window. Child windows can embed their own child. + // - For each independent axis of 'size': ==0.0f: use remaining host window size / >0.0f: fixed size / <0.0f: use remaining window size minus abs(size) / Each axis can use a different mode, e.g. ImVec2(0,400). + // - BeginChild() returns false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window. + // Always call a matching EndChild() for each BeginChild() call, regardless of its return value. + // [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu, + // BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function + // returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.] + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); + IMGUI_API void EndChild(); + + // Windows Utilities + // - 'current window' = the window we are appending into while inside a Begin()/End() block. 'next window' = next window we will Begin() into. + IMGUI_API bool IsWindowAppearing(); + IMGUI_API bool IsWindowCollapsed(); + IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags=0); // is current window focused? or its root/child, depending on flags. see flags for options. + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ! + IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the current window, to append your own drawing primitives + IMGUI_API float GetWindowDpiScale(); // get DPI scale currently associated to the current window's viewport. + IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList API) + IMGUI_API ImVec2 GetWindowSize(); // get current window size + IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x) + IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y) + IMGUI_API ImGuiViewport*GetWindowViewport(); // get viewport currently associated to the current window. + + // Window manipulation + // - Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin). + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. + IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() + IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints. + IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin() + IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() + IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin() + IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground. + IMGUI_API void SetNextWindowViewport(ImGuiID viewport_id); // set next window viewport + IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. + IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0, 0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. + IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). + IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / top-most. prefer using SetNextWindowFocus(). + IMGUI_API void SetWindowFontScale(float scale); // [OBSOLETE] set font scale. Adjust IO.FontGlobalScale if you want to scale all windows. This is an old API! For correct scaling, prefer to reload font + rebuild ImFontAtlas + call style.ScaleAllSizes(). + IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position. + IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. + IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state + IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus. + + // Content region + // - Retrieve available space from a given point. GetContentRegionAvail() is frequently useful. + // - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion) + IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() + IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates + IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min for the full window (roughly (0,0)-Scroll), in window coordinates + IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates + + // Windows Scrolling + IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()] + IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()] + IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()] + IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0 .. GetScrollMaxY()] + IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.x - WindowSize.x - DecorationsSize.x + IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.y - WindowSize.y - DecorationsSize.y + IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. + IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. + IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position. + IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position. + + // 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, ImU32 col); // modify a style color. always use this if you modify the style after NewFrame(). + IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); + IMGUI_API void PopStyleColor(int count = 1); + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame(). + IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame(). + IMGUI_API void PopStyleVar(int count = 1); + IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // == tab stop enable. Allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets + IMGUI_API void PopAllowKeyboardFocus(); + IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. + IMGUI_API void PopButtonRepeat(); + + // Parameters stacks (current window) + IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side). + IMGUI_API void PopItemWidth(); + IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -FLT_MIN always align width to the right side) + IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions. + IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position 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(); + + // Style read access + // - Use the style editor (ShowStyleEditor() function) to interactively see what the colors are) + IMGUI_API ImFont* GetFont(); // get current font + IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied + IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API + IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier, packed as a 32-bit value suitable for ImDrawList + IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList + IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied, packed as a 32-bit value suitable for ImDrawList + IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in. + + // Cursor / Layout + // - By "cursor" we mean the current output position. + // - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down. + // - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceding widget. + // - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API: + // Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos() + // Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. + IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. + IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f); // call between widgets or groups to layout them horizontally. X position given in window coordinates. + IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context. + IMGUI_API void Spacing(); // add vertical spacing. + IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size. unlike InvisibleButton(), Dummy() won't take the mouse click or be navigable into. + IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by indent_w, or style.IndentSpacing if indent_w <= 0 + IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by indent_w, or style.IndentSpacing if indent_w <= 0 + IMGUI_API void BeginGroup(); // lock horizontal starting position + IMGUI_API void EndGroup(); // unlock horizontal starting position + capture the whole group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) + IMGUI_API ImVec2 GetCursorPos(); // cursor position in window coordinates (relative to window position) + IMGUI_API float GetCursorPosX(); // (some functions are using window-relative coordinates, such as: GetCursorPos, GetCursorStartPos, GetContentRegionMax, GetWindowContentRegion* etc. + IMGUI_API float GetCursorPosY(); // other functions such as GetCursorScreenPos or everything in ImDrawList:: + IMGUI_API void SetCursorPos(const ImVec2& local_pos); // are using the main, absolute coordinate system. + IMGUI_API void SetCursorPosX(float local_x); // GetWindowPos() + GetCursorPos() == GetCursorScreenPos() etc.) + IMGUI_API void SetCursorPosY(float local_y); // + IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position in window coordinates + IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates (useful to work with ImDrawList API). generally top-left == GetMainViewport()->Pos == (0,0) in single viewport mode, and bottom-right == GetMainViewport()->Pos+Size == io.DisplaySize in single-viewport mode. + IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute coordinates + IMGUI_API void AlignTextToFramePadding(); // vertically align upcoming text baseline to FramePadding.y so that it will align properly to regularly framed items (call if you have text on a line before a framed item) + IMGUI_API float GetTextLineHeight(); // ~ FontSize + IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text) + IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 + IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) + + // ID stack/scopes + // Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui. + // - Those questions are answered and impacted by understanding of the ID stack system: + // - "Q: Why is my widget not reacting when I click on it?" + // - "Q: How can I have widgets with an empty label?" + // - "Q: How can I have multiple widgets with the same label?" + // - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely + // want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them. + // - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others. + // - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID, + // whereas "str_id" denote a string that is only used as an ID and not normally displayed. + IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string). + IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string). + IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer). + IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer). + IMGUI_API void PopID(); // pop from the ID stack. + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself + IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); + IMGUI_API ImGuiID GetID(const void* ptr_id); + + // Widgets: Text + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. + IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // formatted text + IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API void TextDisabled(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextDisabledV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void TextWrapped(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). + IMGUI_API void TextWrappedV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_FMTARGS(2); // display text+label aligned the same way as value+label widgets + IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() + IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); + + // Widgets: Main + // - Most widgets return true when the value has been changed or when pressed/selected + // - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state. + IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button + IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text + IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) + IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape + IMGUI_API void ImageRotated(ImTextureID tex_id, ImVec2 center, ImVec2 size, float angle); + 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,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API bool Checkbox(const char* label, bool* v); + IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value); + IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); + IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; } + IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer + IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL); + IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses + + // Widgets: Combo Box + // - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items. + // - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. This is analogous to how ListBox are created. + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); + IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! + IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); + IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\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 popup_max_height_in_items = -1); + + // Widgets: Drag Sliders + // - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp. + // - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', + // the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x + // - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. + // - Format string may also be set to NULL or use the default format ("%f" or "%d"). + // - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). + // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used. + // - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum. + // - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. + // - Legacy: Pre-1.78 there are DragXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. + // If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361 + 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* format = "%.3f", ImGuiSliderFlags flags = 0); // If v_min >= 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* format = "%.3f", ImGuiSliderFlags flags = 0); + 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* format = "%.3f", ImGuiSliderFlags flags = 0); + 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* format = "%.3f", ImGuiSliderFlags flags = 0); + IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", const char* format_max = NULL, ImGuiSliderFlags flags = 0); + IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0); // If v_min >= 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* format = "%d", ImGuiSliderFlags flags = 0); + 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* format = "%d", ImGuiSliderFlags flags = 0); + 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* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL, ImGuiSliderFlags flags = 0); + IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0); + IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0); + + // Widgets: Regular Sliders + // - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp. + // - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. + // - Format string may also be set to NULL or use the default format ("%f" or "%d"). + // - Legacy: Pre-1.78 there are SliderXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. + // If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361 + IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display. + IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f, const char* format = "%.0f deg", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0); + IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0); + IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); + IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0); + IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0); + + // Widgets: Input with Keyboard + // - If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp. + // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc. + IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputFloat4(const char* label, float v[4], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0, double step_fast = 0.0, const char* format = "%.6f", ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0); + IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0); + + // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little color square that can be left-clicked to open a picker, and right-clicked to open an option menu.) + // - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. + // - You can pass the address of a first float element out of a contiguous structure, e.g. &myvector.x + IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0)); // display a color square/button, hover for details, return true when pressed. + IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. + + // Widgets: Trees + // - TreeNode functions return true when the node is open, in which case you need to also call TreePop() when you are finished displaying the tree node contents. + IMGUI_API bool TreeNode(const char* label); + IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to easily decorelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). + IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // " + IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0); + IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); + IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); + IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); + IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); + IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call TreePush/TreePop yourself if desired. + IMGUI_API void TreePush(const void* ptr_id = NULL); // " + IMGUI_API void TreePop(); // ~ Unindent()+PopId() + IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode + IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). + IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header. + IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. + + // Widgets: Selectables + // - A selectable highlights when hovered, and can display another color when selected. + // - Neighbors selectable extend their highlight bounds in order to leave no gap between them. This is so a series of selected Selectable appear contiguous. + IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height + IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. + + // Widgets: List Boxes + // - This is essentially a thin wrapper to using BeginChild/EndChild with some stylistic changes. + // - The BeginListBox()/EndListBox() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() or any items. + // - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created. + // - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth + // - Choose frame height: size.y > 0.0f: custom / size.y < 0.0f or -FLT_MIN: bottom-align / size.y = 0.0f (default): arbitrary default height which can fit ~7 items + IMGUI_API bool BeginListBox(const char* label, const ImVec2& size = ImVec2(0, 0)); // open a framed scrolling region + IMGUI_API void EndListBox(); // only call EndListBox() if BeginListBox() returned true! + IMGUI_API bool ListBox(const char* label, int* current_item, const char* const 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); + + // Widgets: Data Plotting + // - Consider using ImPlot (https://github.com/epezent/implot) which is much better! + 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), int 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), int 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: Value() Helpers. + // - Those are merely shortcut to calling Text() with a format string. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to 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); + + // Widgets: Menus + // - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar. + // - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it. + // - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it. + // - Not that MenuItem() keyboardshortcuts are displayed as a convenience but _not processed_ by Dear ImGui at the moment. + IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). + IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! + IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. + IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! + IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! + IMGUI_API void EndMenu(); // only call EndMenu() if BeginMenu() returns true! + IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. + IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL + + // Tooltips + // - Tooltip are windows following the mouse. They do not take focus away. + IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items). + IMGUI_API void EndTooltip(); + IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip(). + IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); + + // Popups, Modals + // - They block normal mouse hovering detection (and therefore most mouse interactions) behind them. + // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - Their visibility state (~bool) is held internally instead of being held by the programmer as we are used to with regular Begin*() calls. + // - The 3 properties above are related: we need to retain popup visibility state in the library because popups may be closed as any time. + // - You can bypass the hovering restriction by using ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered(). + // - IMPORTANT: Popup identifiers are relative to the current ID stack, so OpenPopup and BeginPopup generally needs to be at the same level of the stack. + // This is sometimes leading to confusing mistakes. May rework this in the future. + + // Popups: begin/end functions + // - BeginPopup(): query popup state, if open start appending into the window. Call EndPopup() afterwards. ImGuiWindowFlags are forwarded to the window. + // - BeginPopupModal(): block every interactions behind the window, cannot be closed by user, add a dimming background, has a title bar. + IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. + IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it. + IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! + + // Popups: open/close functions + // - OpenPopup(): set popup state to open. ImGuiPopupFlags are available for opening options. + // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually. + // - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options). + // - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup(). + // - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened. + // - IMPORTANT: Notice that for OpenPopupOnItemClick() we exceptionally default flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter + IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!). + IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks + IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors) + IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into. + + // Popups: open+begin combined functions helpers + // - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking. + // - They are convenient to easily create context menus, hence the name. + // - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future. + // - IMPORTANT: Notice that we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight. + IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! + IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window. + IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows). + + // Popups: query functions + // - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack. + // - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack. + // - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open. + IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open. + + // Tables + // - Full-featured replacement for old Columns API. + // - See Demo->Tables for demo code. + // - See top of imgui_tables.cpp for general commentary. + // - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags. + // The typical call flow is: + // - 1. Call BeginTable(). + // - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults. + // - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows. + // - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data. + // - 5. Populate contents: + // - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column. + // - If you are using tables as a sort of grid, where every columns is holding the same type of contents, + // you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex(). + // TableNextColumn() will automatically wrap-around into the next row if needed. + // - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column! + // - Summary of possible call flow: + // -------------------------------------------------------------------------------------------------------- + // TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1") // OK + // TableNextRow() -> TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK + // TableNextColumn() -> Text("Hello 0") -> TableNextColumn() -> Text("Hello 1") // OK: TableNextColumn() automatically gets to next row! + // TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear! + // -------------------------------------------------------------------------------------------------------- + // - 5. Call EndTable() + IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f); + IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true! + IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row. + IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible. + IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible. + + // Tables: Headers & Columns declaration + // - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc. + // - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column. + // Headers are required to perform: reordering, sorting, and opening the context menu. + // The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody. + // - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in + // some advanced use cases (e.g. adding custom widgets in header row). + // - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled. + IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0); + IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. + IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu + IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used) + + // Tables: Sorting + // - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting. + // - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed + // since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may + // wastefully sort your data every frame! + // - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). + IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). + + // Tables: Miscellaneous functions + // - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index. + IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable) + IMGUI_API int TableGetColumnIndex(); // return current column index. + IMGUI_API int TableGetRowIndex(); // return current row index. + IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column. + IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column. + IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change user accessible enabled/disabled state of a column. Set to false to hide the column. User can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody) + IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details. + + // Legacy Columns API (prefer using Tables!) + // - You can also use SameLine(pos_x) to mimic simplified columns. + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); + IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column + IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column + 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 typically 0.0f + 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 int GetColumnsCount(); + + // Tab Bars, Tabs + // Note: Tabs are automatically created by the docking system. Use this to create tab bars/tabs yourself without docking being involved. + IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar + IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true! + IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected. + IMGUI_API void EndTabItem(); // only call EndTabItem() if BeginTabItem() returns true! + IMGUI_API bool TabItemButton(const char* label, ImGuiTabItemFlags flags = 0); // create a Tab behaving like a button. return true when clicked. cannot be selected in the tab bar. + IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name. + + // Docking + // [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable. + // Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking! + // - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking/undocking. + // - Drag from window menu button (upper-left button) to undock an entire node (all windows). + // - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to _enable_ docking/undocking. + // About dockspaces: + // - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details. + // - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport. + // This is often used with ImGuiDockNodeFlags_PassthruCentralNode. + // - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! + // - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked. + // e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly. + IMGUI_API ImGuiID DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL); + IMGUI_API ImGuiID DockSpaceOverViewport(const ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL); + IMGUI_API void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id + IMGUI_API void SetNextWindowClass(const ImGuiWindowClass* window_class); // set next window class (control docking compatibility + provide hints to platform backend via custom viewport flags and platform parent/child relationship) + IMGUI_API ImGuiID GetWindowDockID(); + IMGUI_API bool IsWindowDocked(); // is current window docked into another window? + + // Logging/Capture + // - All text output from the interface can be captured into tty/file/clipboard. By default, tree nodes are automatically opened during logging. + IMGUI_API void LogToTTY(int auto_open_depth = -1); // start logging to tty (stdout) + IMGUI_API void LogToFile(int auto_open_depth = -1, const char* filename = NULL); // start logging to file + IMGUI_API void LogToClipboard(int auto_open_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, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) + IMGUI_API void LogTextV(const char* fmt, va_list args) IM_FMTLIST(1); + + // Drag and Drop + // - On source items, call BeginDragDropSource(), if it returns true also call SetDragDropPayload() + EndDragDropSource(). + // - On target candidates, call BeginDragDropTarget(), if it returns true also call AcceptDragDropPayload() + EndDragDropTarget(). + // - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback "..." tooltip, see #1725) + // - An item can be both drag source and drop target. + IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call after submitting an item which may be dragged. when this return true, you can call SetDragDropPayload() + EndDragDropSource() + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. Return true when payload has been accepted. + IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! + IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive a payload. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() + IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. + IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true! + IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type. + + // Disabling [BETA API] + // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors) + // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) + // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. + IMGUI_API void BeginDisabled(bool disabled = true); + IMGUI_API void EndDisabled(); + + // Clipping + // - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only. + IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); + IMGUI_API void PopClipRect(); + + // Focus, Activation + // - Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHereY()" when applicable to signify "this is the default item" + IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window. + 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. Use -1 to access previous widget. + + // Item/Widgets Utilities and Query Functions + // - Most of the functions are referring to the previous Item that has been submitted. + // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions. + IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. + IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false) + IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation? + IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this it NOT equivalent to the behavior of e.g. Button(). Read comments in function definition. + IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling) + IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets. + IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive). + IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing. + IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). + IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode(). + IMGUI_API bool IsAnyItemHovered(); // is any item hovered? + IMGUI_API bool IsAnyItemActive(); // is any item active? + IMGUI_API bool IsAnyItemFocused(); // is any item focused? + IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space) + IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space) + IMGUI_API ImVec2 GetItemRectSize(); // get size of last item + IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. + + // Viewports + // - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. + // - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports. + // - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. + IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. This can never be NULL. + + // Miscellaneous Utilities + IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. + IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. + IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame. + IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame. + IMGUI_API ImDrawList* GetBackgroundDrawList(); // get background draw list for the viewport associated to the current window. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents. + IMGUI_API ImDrawList* GetForegroundDrawList(); // get foreground draw list for the viewport associated to the current window. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents. + IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents. + IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents. + IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances. + IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.). + IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it) + IMGUI_API ImGuiStorage* GetStateStorage(); + IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) + + // Text Utilities + IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); + + // Color Utilities + IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); + 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); + + // Inputs Utilities: Keyboard + // Without IMGUI_DISABLE_OBSOLETE_KEYIO: (legacy support) + // - For 'ImGuiKey key' you can still use your legacy native/user indices according to how your backend/engine stored them in io.KeysDown[]. + // With IMGUI_DISABLE_OBSOLETE_KEYIO: (this is the way forward) + // - Any use of 'ImGuiKey' will assert when key < 512 will be passed, previously reserved as native/user keys indices + // - GetKeyIndex() is pass-through and therefore deprecated (gone if IMGUI_DISABLE_OBSOLETE_KEYIO is defined) + IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held. + IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate + IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)? + IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate + IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. + IMGUI_API void CaptureKeyboardFromApp(bool want_capture_keyboard_value = true); // attention: misleading name! manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application to handle). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard_value"; after the next NewFrame() call. + + // Inputs Utilities: Mouse + // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. + // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. + // - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold') + IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held? + IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1. + IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down) + IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true) + IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0). + IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block. + IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available + IMGUI_API bool IsAnyMouseDown(); // [WILL OBSOLETE] is any mouse button held? This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid. + IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls + IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves) + IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) + IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) + IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); // + IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is 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 cursor_type); // set desired cursor type + IMGUI_API void CaptureMouseFromApp(bool want_capture_mouse_value = true); // attention: misleading name! manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application to handle). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse_value;" after the next NewFrame() call. + + // Clipboard Utilities + // - Also see the LogToClipboard() function to capture GUI into clipboard, or easily output text data to the clipboard. + IMGUI_API const char* GetClipboardText(); + IMGUI_API void SetClipboardText(const char* text); + + // Settings/.Ini Utilities + // - The disk functions are automatically called if io.IniFilename != NULL (default is "imgui.ini"). + // - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually. + // - Important: default value "imgui.ini" is relative to current working dir! Most apps will want to lock this to an absolute path (e.g. same path as executables). + IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename). + IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source. + IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext). + IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. + + // Debug Utilities + // - This is used by the IMGUI_CHECKVERSION() macro. + IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro. + + // Memory Allocators + // - Those functions are not reliant on the current context. + // - DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() + // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. + IMGUI_API void SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data = NULL); + IMGUI_API void GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data); + IMGUI_API void* MemAlloc(size_t size); + IMGUI_API void MemFree(void* ptr); + + // (Optional) Platform/OS interface for multi-viewport support + // Read comments around the ImGuiPlatformIO structure for more details. + // Note: You may use GetWindowViewport() to get the current viewport of the current window. + IMGUI_API ImGuiPlatformIO& GetPlatformIO(); // platform/renderer functions, for backend to setup + viewports list. + IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport. + IMGUI_API void RenderPlatformWindowsDefault(void* platform_render_arg = NULL, void* renderer_render_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport which doesn't have the ImGuiViewportFlags_Minimized flag set. May be reimplemented by user for custom rendering needs. + IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from backend Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext(). + IMGUI_API ImGuiViewport* FindViewportByID(ImGuiID id); // this is a helper for backends. + IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for backends. the type platform_handle is decided by the backend (e.g. HWND, MyWindow*, GLFWwindow* etc.) + +} // namespace ImGui + +//----------------------------------------------------------------------------- +// [SECTION] Flags & Enumerations +//----------------------------------------------------------------------------- + +// Flags for ImGui::Begin() +enum ImGuiWindowFlags_ +{ + ImGuiWindowFlags_None = 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 scrollbars (window can still scroll with mouse or programmatically) + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it. Also referred to as Window Menu Button (e.g. within a docking node). + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame + ImGuiWindowFlags_NoBackground = 1 << 7, // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f). + ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file + ImGuiWindowFlags_NoMouseInputs = 1 << 9, // Disable catching mouse, hovering test with pass through. + ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. + ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state + ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programmatically giving it focus) + ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) + ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) + ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) + ImGuiWindowFlags_NoNavInputs = 1 << 18, // No gamepad/keyboard navigation within the window + ImGuiWindowFlags_NoNavFocus = 1 << 19, // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB) + ImGuiWindowFlags_UnsavedDocument = 1 << 20, // Display a dot next to the title. When used in a tab/docking context, tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar. + ImGuiWindowFlags_NoDocking = 1 << 21, // Disable docking of this window + + ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_NoDecoration = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse, + ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + + // [Internal] + ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] On child window: allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows. + ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() + ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() + ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() + ImGuiWindowFlags_ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu() + ImGuiWindowFlags_DockNodeHost = 1 << 29 // Don't use! For internal use by Begin()/NewFrame() + + // [Obsolete] + //ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // [Obsolete] --> Set io.ConfigWindowsResizeFromEdges=true and make sure mouse cursors are supported by backend (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) +}; + +// Flags for ImGui::InputText() +enum ImGuiInputTextFlags_ +{ + ImGuiInputTextFlags_None = 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 every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. + ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. + ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally + ImGuiInputTextFlags_AlwaysOverwrite = 1 << 13, // Overwrite mode + ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). + ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) + ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) + ImGuiInputTextFlags_CallbackEdit = 1 << 19 // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) + + // Obsolete names (will be removed soon) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior +#endif +}; + +// Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*() +enum ImGuiTreeNodeFlags_ +{ + ImGuiTreeNodeFlags_None = 0, + ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected + ImGuiTreeNodeFlags_Framed = 1 << 1, // Draw frame with background (e.g. for CollapsingHeader) + ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one + ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) + ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open + ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. + ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). + ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). + ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line. In the future we may refactor the hit system to be front-to-back, allowing natural overlaps and then this can become the default. + ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (bypass the indented area). + ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 13, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 14, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog +}; + +// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions. +// - To be backward compatible with older API which took an 'int mouse_button = 1' argument, we need to treat +// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags. +// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags. +// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0. +// IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter +// and want to another another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag. +// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later). +enum ImGuiPopupFlags_ +{ + ImGuiPopupFlags_None = 0, + ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranteed to always be == 0 (same as ImGuiMouseButton_Left) + ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranteed to always be == 1 (same as ImGuiMouseButton_Right) + ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle) + ImGuiPopupFlags_MouseButtonMask_ = 0x1F, + ImGuiPopupFlags_MouseButtonDefault_ = 1, + ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack + ImGuiPopupFlags_NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space + ImGuiPopupFlags_AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup. + ImGuiPopupFlags_AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level) + ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel +}; + +// Flags for ImGui::Selectable() +enum ImGuiSelectableFlags_ +{ + ImGuiSelectableFlags_None = 0, + ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too + ImGuiSelectableFlags_Disabled = 1 << 3, // Cannot be selected, display grayed out text + ImGuiSelectableFlags_AllowItemOverlap = 1 << 4 // (WIP) Hit testing to allow subsequent widgets to overlap this one +}; + +// Flags for ImGui::BeginCombo() +enum ImGuiComboFlags_ +{ + ImGuiComboFlags_None = 0, + ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default + ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() + ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) + ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible + ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_NoArrowButton = 1 << 5, // Display on the preview box without the square arrow button + ImGuiComboFlags_NoPreview = 1 << 6, // Display only a square arrow button + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest +}; + +// Flags for ImGui::BeginTabBar() +enum ImGuiTabBarFlags_ +{ + ImGuiTabBarFlags_None = 0, + ImGuiTabBarFlags_Reorderable = 1 << 0, // Allow manually dragging tabs to re-order them + New tabs are appended at the end of list + ImGuiTabBarFlags_AutoSelectNewTabs = 1 << 1, // Automatically select new tabs when they appear + ImGuiTabBarFlags_TabListPopupButton = 1 << 2, // Disable buttons to open the tab list popup + ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 3, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false. + ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4, // Disable scrolling buttons (apply when fitting policy is ImGuiTabBarFlags_FittingPolicyScroll) + ImGuiTabBarFlags_NoTooltip = 1 << 5, // Disable tooltips when hovering a tab + ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 6, // Resize tabs when they don't fit + ImGuiTabBarFlags_FittingPolicyScroll = 1 << 7, // Add scroll buttons when tabs don't fit + ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_FittingPolicyScroll, + ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown +}; + +// Flags for ImGui::BeginTabItem() +enum ImGuiTabItemFlags_ +{ + ImGuiTabItemFlags_None = 0, + ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Display a dot next to the title + tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar. + ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem() + ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false. + ImGuiTabItemFlags_NoPushId = 1 << 3, // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem() + ImGuiTabItemFlags_NoTooltip = 1 << 4, // Disable tooltip for the given tab + ImGuiTabItemFlags_NoReorder = 1 << 5, // Disable reordering this tab or having another tab cross over this tab + ImGuiTabItemFlags_Leading = 1 << 6, // Enforce the tab position to the left of the tab bar (after the tab list popup button) + ImGuiTabItemFlags_Trailing = 1 << 7 // Enforce the tab position to the right of the tab bar (before the scrolling buttons) +}; + +// Flags for ImGui::BeginTable() +// - Important! Sizing policies have complex and subtle side effects, much more so than you would expect. +// Read comments/demos carefully + experiment with live demos to get acquainted with them. +// - The DEFAULT sizing policies are: +// - Default to ImGuiTableFlags_SizingFixedFit if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize. +// - Default to ImGuiTableFlags_SizingStretchSame if ScrollX is off. +// - When ScrollX is off: +// - Table defaults to ImGuiTableFlags_SizingStretchSame -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch with same weight. +// - Columns sizing policy allowed: Stretch (default), Fixed/Auto. +// - Fixed Columns (if any) will generally obtain their requested width (unless the table cannot fit them all). +// - Stretch Columns will share the remaining width according to their respective weight. +// - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors. +// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns. +// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing). +// - When ScrollX is on: +// - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed +// - Columns sizing policy allowed: Fixed/Auto mostly. +// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed. +// - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop. +// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable(). +// If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again. +// - Read on documentation at the top of imgui_tables.cpp for details. +enum ImGuiTableFlags_ +{ + // Features + ImGuiTableFlags_None = 0, + ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns. + ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers) + ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu. + ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate. + ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file. + ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow(). + // Decorations + ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually) + ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows. + ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom. + ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns. + ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides. + ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders. + ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders. + ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders. + ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders. + ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders. + ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style + ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style + // Sizing Policy (read above for defaults) + ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width. + ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible. + ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths. + ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overridden by TableSetupColumn(). + // Sizing Extra Options + ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. + ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible. + ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable. + ImGuiTableFlags_PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth. + // Clipping + ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). + // Padding + ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers. + ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding. + ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off). + // Scrolling + ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. + ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. + // Sorting + ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1). + ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0). + + // [Internal] Combinations and masks + ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame + + // Obsolete names (will be removed soon) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12 + //, ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01 +#endif +}; + +// Flags for ImGui::TableSetupColumn() +enum ImGuiTableColumnFlags_ +{ + // Input configuration flags + ImGuiTableColumnFlags_None = 0, + ImGuiTableColumnFlags_Disabled = 1 << 0, // Overriding/master disable flag: hide column, won't show in context menu (unlike calling TableSetColumnEnabled() which manipulates the user accessible state) + ImGuiTableColumnFlags_DefaultHide = 1 << 1, // Default as a hidden/disabled column. + ImGuiTableColumnFlags_DefaultSort = 1 << 2, // Default as a sorting column. + ImGuiTableColumnFlags_WidthStretch = 1 << 3, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp). + ImGuiTableColumnFlags_WidthFixed = 1 << 4, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable). + ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing. + ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column. + ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column. + ImGuiTableColumnFlags_NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command). + ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table). + ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction. + ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction. + ImGuiTableColumnFlags_NoHeaderLabel = 1 << 12, // TableHeadersRow() will not submit label for this column. Convenient for some small columns. Name will still appear in context menu. + ImGuiTableColumnFlags_NoHeaderWidth = 1 << 13, // Disable header text width contribution to automatic column width. + ImGuiTableColumnFlags_PreferSortAscending = 1 << 14, // Make the initial sort direction Ascending when first sorting on this column (default). + ImGuiTableColumnFlags_PreferSortDescending = 1 << 15, // Make the initial sort direction Descending when first sorting on this column. + ImGuiTableColumnFlags_IndentEnable = 1 << 16, // Use current Indent value when entering cell (default for column 0). + ImGuiTableColumnFlags_IndentDisable = 1 << 17, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored. + + // Output status flags, read-only via TableGetColumnFlags() + ImGuiTableColumnFlags_IsEnabled = 1 << 24, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags. + ImGuiTableColumnFlags_IsVisible = 1 << 25, // Status: is visible == is enabled AND not clipped by scrolling. + ImGuiTableColumnFlags_IsSorted = 1 << 26, // Status: is currently part of the sort specs + ImGuiTableColumnFlags_IsHovered = 1 << 27, // Status: is hovered by mouse + + // [Internal] Combinations and masks + ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed, + ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable, + ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered, + ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) + + // Obsolete names (will be removed soon) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //ImGuiTableColumnFlags_WidthAuto = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, // Column will not stretch and keep resizing based on submitted contents. +#endif +}; + +// Flags for ImGui::TableNextRow() +enum ImGuiTableRowFlags_ +{ + ImGuiTableRowFlags_None = 0, + ImGuiTableRowFlags_Headers = 1 << 0 // Identify header row (set default background color + width of its contents accounted differently for auto column width) +}; + +// Enum for ImGui::TableSetBgColor() +// Background colors are rendering in 3 layers: +// - Layer 0: draw with RowBg0 color if set, otherwise draw with ColumnBg0 if set. +// - Layer 1: draw with RowBg1 color if set, otherwise draw with ColumnBg1 if set. +// - Layer 2: draw with CellBg color if set. +// The purpose of the two row/columns layers is to let you decide if a background color changes should override or blend with the existing color. +// When using ImGuiTableFlags_RowBg on the table, each row has the RowBg0 color automatically set for odd/even rows. +// If you set the color of RowBg0 target, your color will override the existing RowBg0 color. +// If you set the color of RowBg1 or ColumnBg1 target, your color will blend over the RowBg0 color. +enum ImGuiTableBgTarget_ +{ + ImGuiTableBgTarget_None = 0, + ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) + ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking) + ImGuiTableBgTarget_CellBg = 3 // Set cell background color (top-most color) +}; + +// Flags for ImGui::IsWindowFocused() +enum ImGuiFocusedFlags_ +{ + ImGuiFocusedFlags_None = 0, + ImGuiFocusedFlags_ChildWindows = 1 << 0, // Return true if any children of the window is focused + ImGuiFocusedFlags_RootWindow = 1 << 1, // Test from root window (top most parent of the current hierarchy) + ImGuiFocusedFlags_AnyWindow = 1 << 2, // Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use 'io.WantCaptureMouse' instead! Please read the FAQ! + ImGuiFocusedFlags_NoPopupHierarchy = 1 << 3, // Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow) + ImGuiFocusedFlags_DockHierarchy = 1 << 4, // Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow) + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows +}; + +// Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() +// Note: if you are trying to check whether your mouse should be dispatched to Dear ImGui or to your app, you should use 'io.WantCaptureMouse' instead! Please read the FAQ! +// Note: windows with the ImGuiWindowFlags_NoInputs flag are ignored by IsWindowHovered() calls. +enum ImGuiHoveredFlags_ +{ + ImGuiHoveredFlags_None = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. + ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered + ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) + ImGuiHoveredFlags_AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered + ImGuiHoveredFlags_NoPopupHierarchy = 1 << 3, // IsWindowHovered() only: Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow) + ImGuiHoveredFlags_DockHierarchy = 1 << 4, // IsWindowHovered() only: Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow) + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 5, // Return true even if a popup window is normally blocking access to this item/window + //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 6, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window + ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows +}; + +// Flags for ImGui::DockSpace(), shared/inherited by child nodes. +// (Some flags can be applied to individual nodes directly) +// FIXME-DOCK: Also see ImGuiDockNodeFlagsPrivate_ which may involve using the WIP and internal DockBuilder api. +enum ImGuiDockNodeFlags_ +{ + ImGuiDockNodeFlags_None = 0, + ImGuiDockNodeFlags_KeepAliveOnly = 1 << 0, // Shared // Don't display the dockspace node but keep it alive. Windows docked into this dockspace node won't be undocked. + //ImGuiDockNodeFlags_NoCentralNode = 1 << 1, // Shared // Disable Central Node (the node which can stay empty) + ImGuiDockNodeFlags_NoDockingInCentralNode = 1 << 2, // Shared // Disable docking inside the Central Node, which will be always kept empty. + ImGuiDockNodeFlags_PassthruCentralNode = 1 << 3, // Shared // Enable passthru dockspace: 1) DockSpace() will render a ImGuiCol_WindowBg background covering everything excepted the Central Node when empty. Meaning the host window should probably use SetNextWindowBgAlpha(0.0f) prior to Begin() when using this. 2) When Central Node is empty: let inputs pass-through + won't display a DockingEmptyBg background. See demo for details. + ImGuiDockNodeFlags_NoSplit = 1 << 4, // Shared/Local // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disabled to reduce confusion). Note: when turned off, existing splits will be preserved. + ImGuiDockNodeFlags_NoResize = 1 << 5, // Shared/Local // Disable resizing node using the splitter/separators. Useful with programmatically setup dockspaces. + ImGuiDockNodeFlags_AutoHideTabBar = 1 << 6 // Shared/Local // Tab bar will automatically hide when there is a single window in the dock node. +}; + +// Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() +enum ImGuiDragDropFlags_ +{ + ImGuiDragDropFlags_None = 0, + // BeginDragDropSource() flags + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior. + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return false, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. + ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. + ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. + ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of dear imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. + ImGuiDragDropFlags_SourceAutoExpirePayload = 1 << 5, // Automatically expire the payload if the source cease to be submitted (otherwise payloads are persisting while being dragged) + // AcceptDragDropPayload() flags + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, // Request hiding the BeginDragDropSource tooltip from the BeginDragDropTarget site. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. +}; + +// Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui. +#define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3]: Standard type for colors, without alpha. User code may use this type. +#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4]: Standard type for colors. User code may use this type. + +// A primary data type +enum ImGuiDataType_ +{ + ImGuiDataType_S8, // signed char / char (with sensible compilers) + ImGuiDataType_U8, // unsigned char + ImGuiDataType_S16, // short + ImGuiDataType_U16, // unsigned short + ImGuiDataType_S32, // int + ImGuiDataType_U32, // unsigned int + ImGuiDataType_S64, // long long / __int64 + ImGuiDataType_U64, // unsigned long long / unsigned __int64 + ImGuiDataType_Float, // float + ImGuiDataType_Double, // double + ImGuiDataType_COUNT +}; + +// A cardinal direction +enum ImGuiDir_ +{ + ImGuiDir_None = -1, + ImGuiDir_Left = 0, + ImGuiDir_Right = 1, + ImGuiDir_Up = 2, + ImGuiDir_Down = 3, + ImGuiDir_COUNT +}; + +// A sorting direction +enum ImGuiSortDirection_ +{ + ImGuiSortDirection_None = 0, + ImGuiSortDirection_Ascending = 1, // Ascending = 0->9, A->Z etc. + ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc. +}; + +enum ImGuiKey_ +{ + // Keyboard + ImGuiKey_None = 0, + ImGuiKey_Tab = 512, // == ImGuiKey_NamedKey_BEGIN + ImGuiKey_LeftArrow, + ImGuiKey_RightArrow, + ImGuiKey_UpArrow, + ImGuiKey_DownArrow, + ImGuiKey_PageUp, + ImGuiKey_PageDown, + ImGuiKey_Home, + ImGuiKey_End, + ImGuiKey_Insert, + ImGuiKey_Delete, + ImGuiKey_Backspace, + ImGuiKey_Space, + ImGuiKey_Enter, + ImGuiKey_Escape, + ImGuiKey_LeftCtrl, ImGuiKey_LeftShift, ImGuiKey_LeftAlt, ImGuiKey_LeftSuper, + ImGuiKey_RightCtrl, ImGuiKey_RightShift, ImGuiKey_RightAlt, ImGuiKey_RightSuper, + ImGuiKey_Menu, + ImGuiKey_0, ImGuiKey_1, ImGuiKey_2, ImGuiKey_3, ImGuiKey_4, ImGuiKey_5, ImGuiKey_6, ImGuiKey_7, ImGuiKey_8, ImGuiKey_9, + ImGuiKey_A, ImGuiKey_B, ImGuiKey_C, ImGuiKey_D, ImGuiKey_E, ImGuiKey_F, ImGuiKey_G, ImGuiKey_H, ImGuiKey_I, ImGuiKey_J, + ImGuiKey_K, ImGuiKey_L, ImGuiKey_M, ImGuiKey_N, ImGuiKey_O, ImGuiKey_P, ImGuiKey_Q, ImGuiKey_R, ImGuiKey_S, ImGuiKey_T, + ImGuiKey_U, ImGuiKey_V, ImGuiKey_W, ImGuiKey_X, ImGuiKey_Y, ImGuiKey_Z, + ImGuiKey_F1, ImGuiKey_F2, ImGuiKey_F3, ImGuiKey_F4, ImGuiKey_F5, ImGuiKey_F6, + ImGuiKey_F7, ImGuiKey_F8, ImGuiKey_F9, ImGuiKey_F10, ImGuiKey_F11, ImGuiKey_F12, + ImGuiKey_Apostrophe, // ' + ImGuiKey_Comma, // , + ImGuiKey_Minus, // - + ImGuiKey_Period, // . + ImGuiKey_Slash, // / + ImGuiKey_Semicolon, // ; + ImGuiKey_Equal, // = + ImGuiKey_LeftBracket, // [ + ImGuiKey_Backslash, // \ (this text inhibit multiline comment caused by backslash) + ImGuiKey_RightBracket, // ] + ImGuiKey_GraveAccent, // ` + ImGuiKey_CapsLock, + ImGuiKey_ScrollLock, + ImGuiKey_NumLock, + ImGuiKey_PrintScreen, + ImGuiKey_Pause, + ImGuiKey_Keypad0, ImGuiKey_Keypad1, ImGuiKey_Keypad2, ImGuiKey_Keypad3, ImGuiKey_Keypad4, + ImGuiKey_Keypad5, ImGuiKey_Keypad6, ImGuiKey_Keypad7, ImGuiKey_Keypad8, ImGuiKey_Keypad9, + ImGuiKey_KeypadDecimal, + ImGuiKey_KeypadDivide, + ImGuiKey_KeypadMultiply, + ImGuiKey_KeypadSubtract, + ImGuiKey_KeypadAdd, + ImGuiKey_KeypadEnter, + ImGuiKey_KeypadEqual, + + // Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION action + ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS) // -- + ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS) // -- + ImGuiKey_GamepadFaceUp, // Y (Xbox) X (Switch) Triangle (PS) // -> ImGuiNavInput_Input + ImGuiKey_GamepadFaceDown, // A (Xbox) B (Switch) Cross (PS) // -> ImGuiNavInput_Activate + ImGuiKey_GamepadFaceLeft, // X (Xbox) Y (Switch) Square (PS) // -> ImGuiNavInput_Menu + ImGuiKey_GamepadFaceRight, // B (Xbox) A (Switch) Circle (PS) // -> ImGuiNavInput_Cancel + ImGuiKey_GamepadDpadUp, // D-pad Up // -> ImGuiNavInput_DpadUp + ImGuiKey_GamepadDpadDown, // D-pad Down // -> ImGuiNavInput_DpadDown + ImGuiKey_GamepadDpadLeft, // D-pad Left // -> ImGuiNavInput_DpadLeft + ImGuiKey_GamepadDpadRight, // D-pad Right // -> ImGuiNavInput_DpadRight + ImGuiKey_GamepadL1, // L Bumper (Xbox) L (Switch) L1 (PS) // -> ImGuiNavInput_FocusPrev + ImGuiNavInput_TweakSlow + ImGuiKey_GamepadR1, // R Bumper (Xbox) R (Switch) R1 (PS) // -> ImGuiNavInput_FocusNext + ImGuiNavInput_TweakFast + ImGuiKey_GamepadL2, // L Trigger (Xbox) ZL (Switch) L2 (PS) [Analog] + ImGuiKey_GamepadR2, // R Trigger (Xbox) ZR (Switch) R2 (PS) [Analog] + ImGuiKey_GamepadL3, // L Thumbstick (Xbox) L3 (Switch) L3 (PS) + ImGuiKey_GamepadR3, // R Thumbstick (Xbox) R3 (Switch) R3 (PS) + ImGuiKey_GamepadLStickUp, // [Analog] // -> ImGuiNavInput_LStickUp + ImGuiKey_GamepadLStickDown, // [Analog] // -> ImGuiNavInput_LStickDown + ImGuiKey_GamepadLStickLeft, // [Analog] // -> ImGuiNavInput_LStickLeft + ImGuiKey_GamepadLStickRight, // [Analog] // -> ImGuiNavInput_LStickRight + ImGuiKey_GamepadRStickUp, // [Analog] + ImGuiKey_GamepadRStickDown, // [Analog] + ImGuiKey_GamepadRStickLeft, // [Analog] + ImGuiKey_GamepadRStickRight, // [Analog] + + // Keyboard Modifiers + // - This is mirroring the data also written to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper, in a format allowing + // them to be accessed via standard key API, allowing calls such as IsKeyPressed(), IsKeyReleased(), querying duration etc. + // - Code polling every keys (e.g. an interface to detect a key press for input mapping) might want to ignore those + // and prefer using the real keys (e.g. ImGuiKey_LeftCtrl, ImGuiKey_RightCtrl instead of ImGuiKey_ModCtrl). + // - In theory the value of keyboard modifiers should be roughly equivalent to a logical or of the equivalent left/right keys. + // In practice: it's complicated; mods are often provided from different sources. Keyboard layout, IME, sticky keys and + // backends tend to interfere and break that equivalence. The safer decision is to relay that ambiguity down to the end-user... + ImGuiKey_ModCtrl, + ImGuiKey_ModShift, + ImGuiKey_ModAlt, + ImGuiKey_ModSuper, + + ImGuiKey_COUNT, // No valid ImGuiKey is ever greater than this value + + // [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + a io.KeyMap[] array. + // We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE) + ImGuiKey_NamedKey_BEGIN = 512, + ImGuiKey_NamedKey_END = ImGuiKey_COUNT, + ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN, +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys + ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN // First key stored in KeysData[0] +#else + ImGuiKey_KeysData_SIZE = ImGuiKey_COUNT, // Size of KeysData[]: hold legacy 0..512 keycodes + named keys + ImGuiKey_KeysData_OFFSET = 0 // First key stored in KeysData[0] +#endif + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter // Renamed in 1.87 +#endif +}; + +// Helper "flags" version of key-mods to store and compare multiple key-mods easily. Sometimes used for storage (e.g. io.KeyMods) but otherwise not much used in public API. +enum ImGuiKeyModFlags_ +{ + ImGuiKeyModFlags_None = 0, + ImGuiKeyModFlags_Ctrl = 1 << 0, + ImGuiKeyModFlags_Shift = 1 << 1, + ImGuiKeyModFlags_Alt = 1 << 2, + ImGuiKeyModFlags_Super = 1 << 3 // Cmd/Super/Windows key +}; + +// Gamepad/Keyboard navigation +// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.AddKeyEvent() calls. +// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Backend: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). +// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://dearimgui.org/controls_sheets. +enum ImGuiNavInput_ +{ + // Gamepad Mapping + ImGuiNavInput_Activate, // Activate / Open / Toggle / Tweak value // e.g. Cross (PS4), A (Xbox), A (Switch), Space (Keyboard) + ImGuiNavInput_Cancel, // Cancel / Close / Exit // e.g. Circle (PS4), B (Xbox), B (Switch), Escape (Keyboard) + ImGuiNavInput_Input, // Text input / On-Screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) + ImGuiNavInput_Menu, // Tap: Toggle menu / Hold: Focus, Move, Resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) + ImGuiNavInput_DpadLeft, // Move / Tweak / Resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) + ImGuiNavInput_DpadRight, // + ImGuiNavInput_DpadUp, // + ImGuiNavInput_DpadDown, // + ImGuiNavInput_LStickLeft, // Scroll / Move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down + ImGuiNavInput_LStickRight, // + ImGuiNavInput_LStickUp, // + ImGuiNavInput_LStickDown, // + ImGuiNavInput_FocusPrev, // Focus Next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) + ImGuiNavInput_FocusNext, // Focus Prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) + ImGuiNavInput_TweakSlow, // Slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) + ImGuiNavInput_TweakFast, // Faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) + + // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. + // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from keyboard keys instead of io.NavInputs[]. + ImGuiNavInput_KeyLeft_, // Move left // = Arrow keys + ImGuiNavInput_KeyRight_, // Move right + ImGuiNavInput_KeyUp_, // Move up + ImGuiNavInput_KeyDown_, // Move down + ImGuiNavInput_COUNT +}; + +// Configuration flags stored in io.ConfigFlags. Set by user/application. +enum ImGuiConfigFlags_ +{ + ImGuiConfigFlags_None = 0, + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.AddKeyEvent() calls + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui backend to fill io.NavInputs[]. Backend also needs to set ImGuiBackendFlags_HasGamepad. + ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. + ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information set by the backend. + ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. + + // [BETA] Docking + ImGuiConfigFlags_DockingEnable = 1 << 6, // Docking enable flags. + + // [BETA] Viewports + // When using viewports it is recommended that your default value for ImGuiCol_WindowBg is opaque (Alpha=1.0) so transition to a viewport won't be noticeable. + ImGuiConfigFlags_ViewportsEnable = 1 << 10, // Viewport enable flags (require both ImGuiBackendFlags_PlatformHasViewports + ImGuiBackendFlags_RendererHasViewports set by the respective backends) + ImGuiConfigFlags_DpiEnableScaleViewports= 1 << 14, // [BETA: Don't use] FIXME-DPI: Reposition and resize imgui windows when the DpiScale of a viewport changed (mostly useful for the main viewport hosting other window). Note that resizing the main window itself is up to your application. + ImGuiConfigFlags_DpiEnableScaleFonts = 1 << 15, // [BETA: Don't use] FIXME-DPI: Request bitmap-scaled fonts to match DpiScale. This is a very low-quality workaround. The correct way to handle DPI is _currently_ to replace the atlas and/or fonts in the Platform_OnChangedViewport callback, but this is all early work in progress. + + // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are not used by core Dear ImGui) + ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware. + ImGuiConfigFlags_IsTouchScreen = 1 << 21 // Application is using a touch screen instead of a mouse. +}; + +// Backend capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom backend. +enum ImGuiBackendFlags_ +{ + ImGuiBackendFlags_None = 0, + ImGuiBackendFlags_HasGamepad = 1 << 0, // Backend Platform supports gamepad and currently has one connected. + ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Backend Platform supports honoring GetMouseCursor() value to change the OS cursor shape. + ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). + ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. + + // [BETA] Viewports + ImGuiBackendFlags_PlatformHasViewports = 1 << 10, // Backend Platform supports multiple viewports. + ImGuiBackendFlags_HasMouseHoveredViewport=1 << 11, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under. + ImGuiBackendFlags_RendererHasViewports = 1 << 12 // Backend Renderer supports multiple viewports. +}; + +// Enumeration for PushStyleColor() / PopStyleColor() +enum ImGuiCol_ +{ + ImGuiCol_Text, + ImGuiCol_TextDisabled, + ImGuiCol_WindowBg, // Background of normal windows + ImGuiCol_ChildBg, // Background of child windows + ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows + ImGuiCol_Border, + ImGuiCol_BorderShadow, + ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBg, + ImGuiCol_TitleBgActive, + ImGuiCol_TitleBgCollapsed, + ImGuiCol_MenuBarBg, + ImGuiCol_ScrollbarBg, + ImGuiCol_ScrollbarGrab, + ImGuiCol_ScrollbarGrabHovered, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_CheckMark, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, // Header* colors are used for CollapsingHeader, TreeNode, Selectable, MenuItem + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_Separator, + ImGuiCol_SeparatorHovered, + ImGuiCol_SeparatorActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_Tab, + ImGuiCol_TabHovered, + ImGuiCol_TabActive, + ImGuiCol_TabUnfocused, + ImGuiCol_TabUnfocusedActive, + ImGuiCol_DockingPreview, // Preview overlay color when about to docking something + ImGuiCol_DockingEmptyBg, // Background color for empty node (e.g. CentralNode with no window docked into it) + ImGuiCol_PlotLines, + ImGuiCol_PlotLinesHovered, + ImGuiCol_PlotHistogram, + ImGuiCol_PlotHistogramHovered, + ImGuiCol_TableHeaderBg, // Table header background + ImGuiCol_TableBorderStrong, // Table outer and header borders (prefer using Alpha=1.0 here) + ImGuiCol_TableBorderLight, // Table inner borders (prefer using Alpha=1.0 here) + ImGuiCol_TableRowBg, // Table row background (even rows) + ImGuiCol_TableRowBgAlt, // Table row background (odd rows) + ImGuiCol_TextSelectedBg, + ImGuiCol_DragDropTarget, + ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item + ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB + ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active + ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active + ImGuiCol_COUNT +}; + +// Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. +// - The enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. +// During initialization or between frames, feel free to just poke into ImGuiStyle directly. +// - Tip: Use your programming IDE navigation facilities on the names in the _second column_ below to find the actual members and their description. +// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. +// - When changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. +enum ImGuiStyleVar_ +{ + // Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions) + ImGuiStyleVar_Alpha, // float Alpha + ImGuiStyleVar_DisabledAlpha, // float DisabledAlpha + ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding + ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize + ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize + ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign + ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize + ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize + ImGuiStyleVar_FramePadding, // ImVec2 FramePadding + ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize + ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing + ImGuiStyleVar_IndentSpacing, // float IndentSpacing + ImGuiStyleVar_CellPadding, // ImVec2 CellPadding + ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize + ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding + ImGuiStyleVar_GrabMinSize, // float GrabMinSize + ImGuiStyleVar_GrabRounding, // float GrabRounding + ImGuiStyleVar_TabRounding, // float TabRounding + ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign + ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign + ImGuiStyleVar_COUNT +}; + +// Flags for InvisibleButton() [extended in imgui_internal.h] +enum ImGuiButtonFlags_ +{ + ImGuiButtonFlags_None = 0, + ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default) + ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button + ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button + + // [Internal] + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, + ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft +}; + +// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() +enum ImGuiColorEditFlags_ +{ + ImGuiColorEditFlags_None = 0, + ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (will only read 3 components from the input pointer). + ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on color square. + ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. + ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable color square preview next to the inputs. (e.g. to show only the inputs) + ImGuiColorEditFlags_NoInputs = 1 << 5, // // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview color square). + ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. + ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). + ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small color square preview instead. + ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source. + ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default) + + // User Options (right-click on widget to change some of them). + ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. + ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well). + ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex. + ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // " + ImGuiColorEditFlags_DisplayHex = 1 << 22, // [Display] // " + ImGuiColorEditFlags_Uint8 = 1 << 23, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255. + ImGuiColorEditFlags_Float = 1 << 24, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_PickerHueBar = 1 << 25, // [Picker] // ColorPicker: bar for Hue, rectangle for Sat/Value. + ImGuiColorEditFlags_PickerHueWheel = 1 << 26, // [Picker] // ColorPicker: wheel for Hue, triangle for Sat/Value. + ImGuiColorEditFlags_InputRGB = 1 << 27, // [Input] // ColorEdit, ColorPicker: input and output data in RGB format. + ImGuiColorEditFlags_InputHSV = 1 << 28, // [Input] // ColorEdit, ColorPicker: input and output data in HSV format. + + // Defaults Options. You can set application defaults using SetColorEditOptions(). The intent is that you probably don't want to + // override them in most of your calls. Let the user choose via the option menu and/or call SetColorEditOptions() once during startup. + ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar, + + // [Internal] Masks + ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex, + ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float, + ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV + + // Obsolete names (will be removed) + // ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69] +}; + +// Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. +// We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. +enum ImGuiSliderFlags_ +{ + ImGuiSliderFlags_None = 0, + ImGuiSliderFlags_AlwaysClamp = 1 << 4, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. + ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits. + ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits) + ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget + ImGuiSliderFlags_InvalidMask_ = 0x7000000F // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiSliderFlags_ClampOnInput = ImGuiSliderFlags_AlwaysClamp // [renamed in 1.79] +#endif +}; + +// Identify a mouse button. +// Those values are guaranteed to be stable and we frequently use 0/1 directly. Named enums provided for convenience. +enum ImGuiMouseButton_ +{ + ImGuiMouseButton_Left = 0, + ImGuiMouseButton_Right = 1, + ImGuiMouseButton_Middle = 2, + ImGuiMouseButton_COUNT = 5 +}; + +// Enumeration for GetMouseCursor() +// User code may request backend to display given cursor by calling SetMouseCursor(), which is why we have some cursors that are marked unused here +enum ImGuiMouseCursor_ +{ + ImGuiMouseCursor_None = -1, + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. + ImGuiMouseCursor_ResizeAll, // (Unused by Dear ImGui functions) + ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border + ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column + ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window + ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window + ImGuiMouseCursor_Hand, // (Unused by Dear ImGui functions. Use for e.g. hyperlinks) + ImGuiMouseCursor_NotAllowed, // When hovering something with disallowed interaction. Usually a crossed circle. + ImGuiMouseCursor_COUNT +}; + +// Enumeration for ImGui::SetWindow***(), SetNextWindow***(), SetNextItem***() functions +// Represent a condition. +// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. +enum ImGuiCond_ +{ + ImGuiCond_None = 0, // No condition (always set the variable), same as _Always + ImGuiCond_Always = 1 << 0, // No condition (always set the variable) + ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed) + ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file) + ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) +}; + +//----------------------------------------------------------------------------- +// [SECTION] Helpers: Memory allocations macros, ImVector<> +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE() +// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. +// Defining a custom placement new() with a custom parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. +//----------------------------------------------------------------------------- + +struct ImNewWrapper {}; +inline void* operator new(size_t, ImNewWrapper, void* ptr) { return ptr; } +inline void operator delete(void*, ImNewWrapper, void*) {} // This is only required so we can use the symmetrical new() +#define IM_ALLOC(_SIZE) ImGui::MemAlloc(_SIZE) +#define IM_FREE(_PTR) ImGui::MemFree(_PTR) +#define IM_PLACEMENT_NEW(_PTR) new(ImNewWrapper(), _PTR) +#define IM_NEW(_TYPE) new(ImNewWrapper(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE +template void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } } + +//----------------------------------------------------------------------------- +// ImVector<> +// Lightweight std::vector<>-like class to avoid dragging dependencies (also, some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug). +//----------------------------------------------------------------------------- +// - You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our public structures are relying on it. +// - We use std-like naming convention here, which is a little unusual for this codebase. +// - Important: clear() frees memory, resize(0) keep the allocated buffer. We use resize(0) a lot to intentionally recycle allocated buffers across frames and amortize our costs. +// - Important: our implementation does NOT call C++ constructors/destructors, we treat everything as raw data! This is intentional but be extra mindful of that, +// Do NOT use this class as a std::vector replacement in your own code! Many of the structures used by dear imgui can be safely initialized by a zero-memset. +//----------------------------------------------------------------------------- + +IM_MSVC_RUNTIME_CHECKS_OFF +template +struct ImVector +{ + int Size; + int Capacity; + T* Data; + + // Provide standard typedefs but we don't use them ourselves. + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + // Constructors, destructor + inline ImVector() { Size = Capacity = 0; Data = NULL; } + inline ImVector(const ImVector& src) { Size = Capacity = 0; Data = NULL; operator=(src); } + inline ImVector& operator=(const ImVector& src) { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; } + inline ~ImVector() { if (Data) IM_FREE(Data); } // Important: does not destruct anything + + inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } } // Important: does not destruct anything + inline void clear_delete() { for (int n = 0; n < Size; n++) IM_DELETE(Data[n]); clear(); } // Important: never called automatically! always explicit. + inline void clear_destruct() { for (int n = 0; n < Size; n++) Data[n].~T(); clear(); } // Important: never called automatically! always explicit. + + inline bool empty() const { return Size == 0; } + inline int size() const { return Size; } + inline int size_in_bytes() const { return Size * (int)sizeof(T); } + inline int max_size() const { return 0x7FFFFFFF / (int)sizeof(T); } + inline int capacity() const { return Capacity; } + inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } + inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } + + inline T* begin() { return Data; } + inline const T* begin() const { return Data; } + inline T* end() { return Data + Size; } + inline const T* end() const { return Data + Size; } + inline T& front() { IM_ASSERT(Size > 0); return Data[0]; } + inline const T& front() const { IM_ASSERT(Size > 0); return Data[0]; } + inline T& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; } + inline const T& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; } + inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; T* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } + + inline int _grow_capacity(int sz) const { int new_capacity = Capacity ? (Capacity + Capacity / 2) : 8; return new_capacity > sz ? new_capacity : sz; } + inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } + inline void resize(int new_size, const T& v) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; } + inline void shrink(int new_size) { IM_ASSERT(new_size <= Size); Size = new_size; } // Resize a vector to a smaller size, guaranteed not to cause a reallocation + inline void reserve(int new_capacity) { if (new_capacity <= Capacity) return; T* new_data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); IM_FREE(Data); } Data = new_data; Capacity = new_capacity; } + + // NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden. + inline void push_back(const T& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); memcpy(&Data[Size], &v, sizeof(v)); Size++; } + inline void pop_back() { IM_ASSERT(Size > 0); Size--; } + inline void push_front(const T& v) { if (Size == 0) push_back(v); else insert(Data, v); } + inline T* erase(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; } + inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last > it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; } + inline T* erase_unsorted(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; } + inline T* insert(const T* it, const T& v) { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; } + inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } + inline T* find(const T& v) { T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data == v) break; else ++data; return data; } + inline const T* find(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data == v) break; else ++data; return data; } + inline bool find_erase(const T& v) { const T* it = find(v); if (it < Data + Size) { erase(it); return true; } return false; } + inline bool find_erase_unsorted(const T& v) { const T* it = find(v); if (it < Data + Size) { erase_unsorted(it); return true; } return false; } + inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; return (int)off; } +}; +IM_MSVC_RUNTIME_CHECKS_RESTORE + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiStyle +//----------------------------------------------------------------------------- +// You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame(). +// During the frame, use ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values, +// and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors. +//----------------------------------------------------------------------------- + +struct ImGuiStyle +{ + float Alpha; // Global alpha applies to everything in Dear ImGui. + float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha. + ImVec2 WindowPadding; // Padding within a window. + float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended. + float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints(). + ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. + ImGuiDir WindowMenuButtonPosition; // Side of the collapsing/docking button in the title bar (None/Left/Right). Defaults to ImGuiDir_Left. + float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + float PopupRounding; // Radius of popup window corners rounding. (Note that tooltip windows use WindowRounding) + float PopupBorderSize; // Thickness of border around popup/tooltip windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + 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). + float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + 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 CellPadding; // Padding within a table cell + 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! + float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). + float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar. + float ScrollbarRounding; // Radius of grab corners for scrollbar. + float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. + float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. + float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. + float TabBorderSize; // Thickness of border around tabs. + float TabMinWidthForCloseButton; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. + ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). + ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. + ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly! + float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later. + bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). + bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList). + bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). + float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + ImVec4 Colors[ImGuiCol_COUNT]; + + IMGUI_API ImGuiStyle(); + IMGUI_API void ScaleAllSizes(float scale_factor); +}; + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiIO +//----------------------------------------------------------------------------- +// Communicate most settings and inputs/outputs to Dear ImGui using this structure. +// Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage. +//----------------------------------------------------------------------------- + +// [Internal] Storage used by IsKeyDown(), IsKeyPressed() etc functions. +// If prior to 1.87 you used io.KeysDownDuration[] (which was marked as internal), you should use GetKeyData(key)->DownDuration and not io.KeysData[key]->DownDuration. +struct ImGuiKeyData +{ + bool Down; // True for if key is down + float DownDuration; // Duration the key has been down (<0.0f: not pressed, 0.0f: just pressed, >0.0f: time held) + float DownDurationPrev; // Last frame duration the key has been down + float AnalogValue; // 0.0f..1.0f for gamepad values +}; + +struct ImGuiIO +{ + //------------------------------------------------------------------ + // Configuration (fill once) // Default value + //------------------------------------------------------------------ + + ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. + ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend. + ImVec2 DisplaySize; // // Main display size, in pixels (generally == GetMainViewport()->Size) + float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file (important: default "imgui.ini" is relative to current working dir!). Set NULL to disable automatic .ini loading/saving or if you want to manually call LoadIniSettingsXXX() / SaveIniSettingsXXX() functions. + 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. + float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). + float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. + void* UserData; // = NULL // Store your own data for retrieval by callbacks. + + ImFontAtlas*Fonts; // // Font atlas: load, rasterize and pack one or more fonts into a single texture. + float FontGlobalScale; // = 1.0f // Global scale all fonts + bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. + ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0]. + ImVec2 DisplayFramebufferScale; // = (1, 1) // For retina display or other situations where window coordinates are different from framebuffer coordinates. This generally ends up in ImDrawData::FramebufferScale. + + // Docking options (when ImGuiConfigFlags_DockingEnable is set) + bool ConfigDockingNoSplit; // = false // Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars. + bool ConfigDockingWithShift; // = false // Enable docking with holding Shift key (reduce visual noise, allows dropping in wider space) + bool ConfigDockingAlwaysTabBar; // = false // [BETA] [FIXME: This currently creates regression with auto-sizing and general overhead] Make every single floating window display within a docking node. + bool ConfigDockingTransparentPayload;// = false // [BETA] Make window or viewport transparent when docking and only display docking boxes on the target viewport. Useful if rendering of multiple viewport cannot be synced. Best used with ConfigViewportsNoAutoMerge. + + // Viewport options (when ImGuiConfigFlags_ViewportsEnable is set) + bool ConfigViewportsNoAutoMerge; // = false; // Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it. May also set ImGuiViewportFlags_NoAutoMerge on individual viewport. + bool ConfigViewportsNoTaskBarIcon; // = false // Disable default OS task bar icon flag for secondary viewports. When a viewport doesn't want a task bar icon, ImGuiViewportFlags_NoTaskBarIcon will be set on it. + bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size). + bool ConfigViewportsNoDefaultParent; // = false // Disable default OS parenting to main viewport for secondary viewports. By default, viewports are marked with ParentViewportId = , expecting the platform backend to setup a parent/child relationship between the OS windows (some backend may ignore this). Set to true if you want the default to be 0, then all viewports will be top-level OS windows. + + // Miscellaneous options + bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. + bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. + bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. + bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). + bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. + bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) + bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. + float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. + + //------------------------------------------------------------------ + // Platform Functions + // (the imgui_impl_xxxx backend files are setting those up for you) + //------------------------------------------------------------------ + + // Optional: Platform/Renderer backend name (informational only! will be displayed in About Window) + User data for backend/wrappers to store their own stuff. + const char* BackendPlatformName; // = NULL + const char* BackendRendererName; // = NULL + void* BackendPlatformUserData; // = NULL // User data for platform backend + void* BackendRendererUserData; // = NULL // User data for renderer backend + void* BackendLanguageUserData; // = NULL // User data for non C++ programming language backend + + // 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* user_data); + void (*SetClipboardTextFn)(void* user_data, const char* text); + void* ClipboardUserData; + + // Optional: Notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME on Windows) + // (default to use native imm32 api on Windows) + void (*SetPlatformImeDataFn)(ImGuiViewport* viewport, ImGuiPlatformImeData* data); +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + void* ImeWindowHandle; // = NULL // [Obsolete] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. +#else + void* _UnusedPadding; // Unused field to keep data structure the same size. +#endif + + //------------------------------------------------------------------ + // Input - Call before calling NewFrame() + //------------------------------------------------------------------ + + // Input Functions + IMGUI_API void AddKeyEvent(ImGuiKey key, bool down); // Queue a new key down/up event. Key should be "translated" (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) + IMGUI_API void AddKeyAnalogEvent(ImGuiKey key, bool down, float v); // Queue a new key down/up event for analog values (e.g. ImGuiKey_Gamepad_ values). Dead-zones should be handled by the backend. + IMGUI_API void AddMousePosEvent(float x, float y); // Queue a mouse position update. Use -FLT_MAX,-FLT_MAX to signify no mouse (e.g. app not focused and not hovered) + IMGUI_API void AddMouseButtonEvent(int button, bool down); // Queue a mouse button change + IMGUI_API void AddMouseWheelEvent(float wh_x, float wh_y); // Queue a mouse wheel update + IMGUI_API void AddMouseViewportEvent(ImGuiID id); // Queue a mouse hovered viewport. Requires backend to set ImGuiBackendFlags_HasMouseHoveredViewport to call this (for multi-viewport support). + IMGUI_API void AddFocusEvent(bool focused); // Queue a gain/loss of focus for the application (generally based on OS/platform focus of your window) + IMGUI_API void AddInputCharacter(unsigned int c); // Queue a new character input + IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue a new character input from an UTF-16 character, it can be a surrogate + IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue a new characters input from an UTF-8 string + + IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually + IMGUI_API void ClearInputKeys(); // [Internal] Release all keys + IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode. + + //------------------------------------------------------------------ + // Output - Updated by NewFrame() or EndFrame()/Render() + // (when reading from the io.WantCaptureMouse, io.WantCaptureKeyboard flags to dispatch your inputs, it is + // generally easier and more correct to use their state BEFORE calling NewFrame(). See FAQ for details!) + //------------------------------------------------------------------ + + bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.). + bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). + bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). + bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. + bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! + bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. + bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). + float Framerate; // Rough estimate of application framerate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames. + int MetricsRenderVertices; // Vertices output during last call to Render() + int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 + int MetricsRenderWindows; // Number of visible windows + int MetricsActiveWindows; // Number of active windows + int MetricsActiveAllocations; // Number of active allocations, updated by MemAlloc/MemFree based on current context. May be off if you have multiple imgui contexts. + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. + + // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. + // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. + bool KeysDown[512]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). +#endif + + //------------------------------------------------------------------ + // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! + //------------------------------------------------------------------ + + // Main Input State + // (this block used to be written by backend, since 1.87 it is best to NOT write to those directly, call the AddXXX functions above instead) + // (reading from those variables is fair game, as they are extremely unlikely to be moving anywhere) + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) + bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all backends. + ImGuiID MouseHoveredViewport; // (Optional) Modify using io.AddMouseViewportEvent(). With multi-viewports: viewport the OS mouse is hovering. If possible _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag is much better (few backends can handle that). Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows). + bool KeyCtrl; // Keyboard modifier down: Control + bool KeyShift; // Keyboard modifier down: Shift + bool KeyAlt; // Keyboard modifier down: Alt + bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows + float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). + + // Other state maintained from data above + IO function calls + ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame() + ImGuiKeyModFlags KeyModsPrev; // Key mods flags (from previous frame) + ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this. + bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. + ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) + ImVec2 MouseClickedPos[5]; // Position at time of clicking + double MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseClicked[5]; // Mouse button went from !Down to Down (same as MouseClickedCount[x] != 0) + bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? (same as MouseClickedCount[x] == 2) + ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down + ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done. + bool MouseReleased[5]; // Mouse button went from Down to !Down + bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. + bool MouseDownOwnedUnlessPopupClose[5]; //Track if button was clicked inside a dear imgui window. + float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) + float MouseDownDurationPrev[5]; // Previous time the mouse button has been down + ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds) + float NavInputsDownDuration[ImGuiNavInput_COUNT]; + float NavInputsDownDurationPrev[ImGuiNavInput_COUNT]; + float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui. + bool AppFocusLost; + ImS8 BackendUsingLegacyKeyArrays; // -1: unknown, 0: using AddKeyEvent(), 1: using legacy io.KeysDown[] + bool BackendUsingLegacyNavInputArray; // 0: using AddKeyAnalogEvent(), 1: writing to legacy io.NavInputs[] directly + ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() + ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. + + IMGUI_API ImGuiIO(); +}; + +//----------------------------------------------------------------------------- +// [SECTION] Misc data structures +//----------------------------------------------------------------------------- + +// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used. +// The callback function should return 0 by default. +// Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details) +// - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) +// - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration +// - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB +// - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows +// - ImGuiInputTextFlags_CallbackCharFilter: Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. +// - ImGuiInputTextFlags_CallbackResize: Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. +struct ImGuiInputTextCallbackData +{ + ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + void* UserData; // What user passed to InputText() // Read-only + + // Arguments for the different callback events + // - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary. + // - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state. + ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0; + ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History] + char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer! + int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length() + int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1 + bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always] + int CursorPos; // // Read-write // [Completion,History,Always] + int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection) + int SelectionEnd; // // Read-write // [Completion,History,Always] + + // Helper functions for text manipulation. + // Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection. + IMGUI_API ImGuiInputTextCallbackData(); + IMGUI_API void DeleteChars(int pos, int bytes_count); + IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); + void SelectAll() { SelectionStart = 0; SelectionEnd = BufTextLen; } + void ClearSelection() { SelectionStart = SelectionEnd = BufTextLen; } + bool HasSelection() const { return SelectionStart != SelectionEnd; } +}; + +// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). +// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. +struct ImGuiSizeCallbackData +{ + void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. +}; + +// [ALPHA] Rarely used / very advanced uses only. Use with SetNextWindowClass() and DockSpace() functions. +// Important: the content of this class is still highly WIP and likely to change and be refactored +// before we stabilize Docking features. Please be mindful if using this. +// Provide hints: +// - To the platform backend via altered viewport flags (enable/disable OS decoration, OS task bar icons, etc.) +// - To the platform backend for OS level parent/child relationships of viewport. +// - To the docking system for various options and filtering. +struct ImGuiWindowClass +{ + ImGuiID ClassId; // User data. 0 = Default class (unclassed). Windows of different classes cannot be docked with each others. + ImGuiID ParentViewportId; // Hint for the platform backend. -1: use default. 0: request platform backend to not parent the platform. != 0: request platform backend to create a parent<>child relationship between the platform windows. Not conforming backends are free to e.g. parent every viewport to the main viewport or not. + ImGuiViewportFlags ViewportFlagsOverrideSet; // Viewport flags to set when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis. + ImGuiViewportFlags ViewportFlagsOverrideClear; // Viewport flags to clear when a window of this class owns a viewport. This allows you to enforce OS decoration or task bar icon, override the defaults on a per-window basis. + ImGuiTabItemFlags TabItemFlagsOverrideSet; // [EXPERIMENTAL] TabItem flags to set when a window of this class gets submitted into a dock node tab bar. May use with ImGuiTabItemFlags_Leading or ImGuiTabItemFlags_Trailing. + ImGuiDockNodeFlags DockNodeFlagsOverrideSet; // [EXPERIMENTAL] Dock node flags to set when a window of this class is hosted by a dock node (it doesn't have to be selected!) + bool DockingAlwaysTabBar; // Set to true to enforce single floating windows of this class always having their own docking node (equivalent of setting the global io.ConfigDockingAlwaysTabBar) + bool DockingAllowUnclassed; // Set to true to allow windows of this class to be docked/merged with an unclassed window. // FIXME-DOCK: Move to DockNodeFlags override? + + ImGuiWindowClass() { memset(this, 0, sizeof(*this)); ParentViewportId = (ImGuiID)-1; DockingAllowUnclassed = true; } +}; + +// Data payload for Drag and Drop operations: AcceptDragDropPayload(), GetDragDropPayload() +struct ImGuiPayload +{ + // Members + void* Data; // Data (copied and owned by dear imgui) + int DataSize; // Data size + + // [Internal] + ImGuiID SourceId; // Source item id + ImGuiID SourceParentId; // Source parent id (if available) + int DataFrameCount; // Data timestamp + char DataType[32 + 1]; // Data type tag (short user-supplied string, 32 characters max) + bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) + bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. + + ImGuiPayload() { Clear(); } + void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; } + bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsPreview() const { return Preview; } + bool IsDelivery() const { return Delivery; } +}; + +// Sorting specification for one column of a table (sizeof == 12 bytes) +struct ImGuiTableColumnSortSpecs +{ + ImGuiID ColumnUserID; // User id of the column (if specified by a TableSetupColumn() call) + ImS16 ColumnIndex; // Index of the column + ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here) + ImGuiSortDirection SortDirection : 8; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending (you can use this or SortSign, whichever is more convenient for your sort function) + + ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); } +}; + +// Sorting specifications for a table (often handling sort specs for a single column, occasionally more) +// Obtained by calling TableGetSortSpecs(). +// When 'SpecsDirty == true' you can sort your data. It will be true with sorting specs have changed since last call, or the first time. +// Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame! +struct ImGuiTableSortSpecs +{ + const ImGuiTableColumnSortSpecs* Specs; // Pointer to sort spec array. + int SpecsCount; // Sort spec count. Most often 1. May be > 1 when ImGuiTableFlags_SortMulti is enabled. May be == 0 when ImGuiTableFlags_SortTristate is enabled. + bool SpecsDirty; // Set to true when specs have changed since last time! Use this to sort again, then clear the flag. + + ImGuiTableSortSpecs() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) +//----------------------------------------------------------------------------- + +// Helper: Unicode defines +#define IM_UNICODE_CODEPOINT_INVALID 0xFFFD // Invalid Unicode code point (standard value). +#ifdef IMGUI_USE_WCHAR32 +#define IM_UNICODE_CODEPOINT_MAX 0x10FFFF // Maximum Unicode code point supported by this build. +#else +#define IM_UNICODE_CODEPOINT_MAX 0xFFFF // Maximum Unicode code point supported by this build. +#endif + +// Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); +struct ImGuiOnceUponAFrame +{ + ImGuiOnceUponAFrame() { RefFrame = -1; } + mutable int RefFrame; + operator bool() 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 +{ + IMGUI_API ImGuiTextFilter(const char* default_filter = ""); + IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build + IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const; + IMGUI_API void Build(); + void Clear() { InputBuf[0] = 0; Build(); } + bool IsActive() const { return !Filters.empty(); } + + // [Internal] + struct ImGuiTextRange + { + const char* b; + const char* e; + + ImGuiTextRange() { b = e = NULL; } + ImGuiTextRange(const char* _b, const char* _e) { b = _b; e = _e; } + bool empty() const { return b == e; } + IMGUI_API void split(char separator, ImVector* out) const; + }; + char InputBuf[256]; + ImVectorFilters; + int CountGrep; +}; + +// Helper: Growable text buffer for logging/accumulating text +// (this could be called 'ImGuiTextBuilder' / 'ImGuiStringBuilder') +struct ImGuiTextBuffer +{ + ImVector Buf; + IMGUI_API static char EmptyString[1]; + + ImGuiTextBuffer() { } + inline char operator[](int i) const { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; } + const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; } + const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator + int size() const { return Buf.Size ? Buf.Size - 1 : 0; } + bool empty() const { return Buf.Size <= 1; } + void clear() { Buf.clear(); } + void reserve(int capacity) { Buf.reserve(capacity); } + const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; } + IMGUI_API void append(const char* str, const char* str_end = NULL); + IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2); + IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); +}; + +// Helper: Key->Value storage +// Typically you don't have to worry about this since a storage is held within each Window. +// We use it to e.g. store collapse state for a tree (Int 0/1) +// This is optimized for efficient lookup (dichotomy into a contiguous buffer) and rare insertion (typically tied to user interactions aka max once a frame) +// You can use it as custom user storage for temporary values. Declare your own storage if, for example: +// - 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 (probably not efficient, but convenient) +// Types are NOT stored, so it is up to you to make sure your Key don't collide with different types. +struct ImGuiStorage +{ + // [Internal] + struct ImGuiStoragePair + { + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; + ImGuiStoragePair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } + ImGuiStoragePair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } + ImGuiStoragePair(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, paid once. A typical frame shouldn't need to insert any new pair. + void Clear() { Data.clear(); } + IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; + IMGUI_API void SetInt(ImGuiID key, int val); + IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const; + IMGUI_API void SetBool(ImGuiID key, bool 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 for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct) + // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; + IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); + IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false); + IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f); + 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); + + // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. + IMGUI_API void BuildSortByKey(); +}; + +// Helper: Manually clip large list of items. +// If you have lots evenly spaced items and you have a random access to the list, you can perform coarse +// clipping based on visibility to only submit items that are in view. +// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. +// (Dear ImGui already clip items based on their bounds but: it needs to first layout the item to do so, and generally +// fetching/submitting your own data incurs additional cost. Coarse clipping using ImGuiListClipper allows you to easily +// scale using lists with tens of thousands of items without a problem) +// Usage: +// ImGuiListClipper clipper; +// clipper.Begin(1000); // We have 1000 elements, evenly spaced. +// while (clipper.Step()) +// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) +// ImGui::Text("line number %d", i); +// Generally what happens is: +// - Clipper lets you process the first element (DisplayStart = 0, DisplayEnd = 1) regardless of it being visible or not. +// - User code submit that one element. +// - Clipper can measure the height of the first element +// - Clipper calculate the actual range of elements to display based on the current clipping rectangle, position the cursor before the first visible element. +// - User code submit visible elements. +// - The clipper also handles various subtleties related to keyboard/gamepad navigation, wrapping etc. +struct ImGuiListClipper +{ + int DisplayStart; // First item to display, updated by each call to Step() + int DisplayEnd; // End of items to display (exclusive) + int ItemsCount; // [Internal] Number of items + float ItemsHeight; // [Internal] Height of item after a first step and item submission can calculate it + float StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed + void* TempData; // [Internal] Internal data + + // items_count: Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step) + // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). + IMGUI_API ImGuiListClipper(); + IMGUI_API ~ImGuiListClipper(); + IMGUI_API void Begin(int items_count, float items_height = -1.0f); + IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. + IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + + // Call ForceDisplayRangeByIndices() before first call to Step() if you need a range of items to be displayed regardless of visibility. + IMGUI_API void ForceDisplayRangeByIndices(int item_min, int item_max); // item_max is exclusive e.g. use (42, 42+1) to make item 42 always visible BUT due to alignment/padding of certain items it is likely that an extra item may be included on either end of the display range. + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79] +#endif +}; + +// Helpers macros to generate 32-bit encoded colors +#ifdef IMGUI_USE_BGRA_PACKED_COLOR +#define IM_COL32_R_SHIFT 16 +#define IM_COL32_G_SHIFT 8 +#define IM_COL32_B_SHIFT 0 +#define IM_COL32_A_SHIFT 24 +#define IM_COL32_A_MASK 0xFF000000 +#else +#define IM_COL32_R_SHIFT 0 +#define IM_COL32_G_SHIFT 8 +#define IM_COL32_B_SHIFT 16 +#define IM_COL32_A_SHIFT 24 +#define IM_COL32_A_MASK 0xFF000000 +#endif +#define IM_COL32(R,G,B,A) (((ImU32)(A)<> IM_COL32_R_SHIFT) & 0xFF) * sc; Value.y = (float)((rgba >> IM_COL32_G_SHIFT) & 0xFF) * sc; Value.z = (float)((rgba >> IM_COL32_B_SHIFT) & 0xFF) * sc; Value.w = (float)((rgba >> IM_COL32_A_SHIFT) & 0xFF) * sc; } + 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; } + inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } + inline operator ImVec4() const { return Value; } + + // FIXME-OBSOLETE: May need to obsolete/cleanup those helpers. + inline void SetHSV(float h, float s, float v, float a = 1.0f){ ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); Value.w = a; } + 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); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData) +// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. +//----------------------------------------------------------------------------- + +// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking. +#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX +#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63) +#endif + +// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h] +// NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering, +// you can poke into the draw list for that! Draw callback may be useful for example to: +// A) Change your GPU render state, +// B) render a complex 3D scene inside a UI element without an intermediate texture/render target, etc. +// The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) { cmd.UserCallback(parent_list, cmd); } else { RenderTriangles() }' +// If you want to override the signature of ImDrawCallback, you can simply use e.g. '#define ImDrawCallback MyDrawCallback' (in imconfig.h) + update rendering backend accordingly. +#ifndef ImDrawCallback +typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); +#endif + +// Special Draw callback value to request renderer backend to reset the graphics/render state. +// The renderer backend needs to handle this special value, otherwise it will crash trying to call a function at this address. +// This is useful for example if you submitted callbacks which you know have altered the render state and you want it to be restored. +// It is not done by default because they are many perfectly useful way of altering render state for imgui contents (e.g. changing shader/blending settings before an Image call). +#define ImDrawCallback_ResetRenderState (ImDrawCallback)(-1) + +// Typically, 1 command = 1 GPU draw call (unless command is a callback) +// - VtxOffset: When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset' is enabled, +// this fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices. +// Backends made for <1.71. will typically ignore the VtxOffset fields. +// - The ClipRect/TextureId/VtxOffset fields must be contiguous as we memcmp() them together (this is asserted for). +struct ImDrawCmd +{ + ImVec4 ClipRect; // 4*4 // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates + ImTextureID TextureId; // 4-8 // 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. + unsigned int VtxOffset; // 4 // Start offset in vertex buffer. ImGuiBackendFlags_RendererHasVtxOffset: always 0, otherwise may be >0 to support meshes larger than 64K vertices with 16-bit indices. + unsigned int IdxOffset; // 4 // Start offset in index buffer. + unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. + ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. + void* UserCallbackData; // 4-8 // The draw callback code can access this. + + ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed + + // Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature) + inline ImTextureID GetTexID() const { return TextureId; } +}; + +// Vertex layout +#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT +struct ImDrawVert +{ + ImVec2 pos; + ImVec2 uv; + ImU32 col; +}; +#else +// You can override 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 within the macro (you can either declare the struct or use a typedef). This is because ImVec2/ImU32 are likely not declared a the time you'd want to set your type up. +// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM. +IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; +#endif + +// [Internal] For use by ImDrawList +struct ImDrawCmdHeader +{ + ImVec4 ClipRect; + ImTextureID TextureId; + unsigned int VtxOffset; +}; + +// [Internal] For use by ImDrawListSplitter +struct ImDrawChannel +{ + ImVector _CmdBuffer; + ImVector _IdxBuffer; +}; + + +// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order. +// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call. +struct ImDrawListSplitter +{ + int _Current; // Current channel number (0) + int _Count; // Number of active channels (1+) + ImVector _Channels; // Draw channels (not resized down so _Count might be < Channels.Size) + + inline ImDrawListSplitter() { memset(this, 0, sizeof(*this)); } + inline ~ImDrawListSplitter() { ClearFreeMemory(); } + inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame + IMGUI_API void ClearFreeMemory(); + IMGUI_API void Split(ImDrawList* draw_list, int count); + IMGUI_API void Merge(ImDrawList* draw_list); + IMGUI_API void SetCurrentChannel(ImDrawList* draw_list, int channel_idx); +}; + +// Flags for ImDrawList functions +// (Legacy: bit 0 must always correspond to ImDrawFlags_Closed to be backward compatible with old API using a bool. Bits 1..3 must be unused) +enum ImDrawFlags_ +{ + ImDrawFlags_None = 0, + ImDrawFlags_Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason) + ImDrawFlags_RoundCornersTopLeft = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01. + ImDrawFlags_RoundCornersTopRight = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02. + ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04. + ImDrawFlags_RoundCornersBottomRight = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08. + ImDrawFlags_RoundCornersNone = 1 << 8, // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag! + ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight, + ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, + ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft, + ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight, + ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, + ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified. + ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone +}; + +// Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. +// It is however possible to temporarily alter flags between calls to ImDrawList:: functions. +enum ImDrawListFlags_ +{ + ImDrawListFlags_None = 0, + ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles) + ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering. + ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles). + ImDrawListFlags_AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. +}; + +// 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. +// Each dear imgui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to +// access the current window draw list and draw custom primitives. +// You can interleave normal ImGui:: calls and adding primitives to the current draw list. +// In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize). +// You are totally free to apply whatever transformation matrix to want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!) +// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. +struct ImDrawList +{ + // This is what you have to render + ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. + ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those + ImVector VtxBuffer; // Vertex buffer. + ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. + + // [Internal, used while building lists] + unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0. + const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) + const char* _OwnerName; // Pointer to owner window's name for debugging + ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImVector _ClipRectStack; // [Internal] + ImVector _TextureIdStack; // [Internal] + ImVector _Path; // [Internal] current path building + ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back(). + ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) + float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content + + // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) + ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; } + + ~ImDrawList() { _ClearFreeMemory(); } + IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) + IMGUI_API void PushClipRectFullScreen(); + IMGUI_API void PopClipRect(); + IMGUI_API void PushTextureID(ImTextureID texture_id); + IMGUI_API void PopTextureID(); + inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); } + inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); } + + // Primitives + // - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners. + // - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred). + // In older versions (until Dear ImGui 1.77) the AddCircle functions defaulted to num_segments == 12. + // In future versions we will use textures to provide cheaper and higher-quality circles. + // Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides. + IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size) + IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size) + IMGUI_API void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); + IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col); + IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col); + IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 1.0f); + IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0); + IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f); + IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments); + IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); + 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 ImVec4* cpu_fine_clip_rect = NULL); + IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. + IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points) + IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points) + + // Image primitives + // - Read FAQ to understand what ImTextureID is. + // - "p_min" and "p_max" represent the upper-left and lower-right corners of the rectangle. + // - "uv_min" and "uv_max" represent the normalized texture coordinates to use for those corners. Using (0,0)->(1,1) texture coordinates will generally display the entire texture. + IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min = ImVec2(0, 0), const ImVec2& uv_max = ImVec2(1, 1), ImU32 col = IM_COL32_WHITE); + IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1 = ImVec2(0, 0), const ImVec2& uv2 = ImVec2(1, 0), const ImVec2& uv3 = ImVec2(1, 1), const ImVec2& uv4 = ImVec2(0, 1), ImU32 col = IM_COL32_WHITE); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags = 0); + + // Stateful path API, add points then finish with PathFillConvex() or PathStroke() + inline void PathClear() { _Path.Size = 0; } + inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } + inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); } + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } // Note: Anti-aliased filling requires points to be in clockwise order. + inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; } + IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0); + IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle + IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points) + IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points) + IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0); + + // Advanced + IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' 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 + IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer. + + // Advanced: Channels + // - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives) + // - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end) + // - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place! + // Prefer using your own persistent instance of ImDrawListSplitter as you can stack them. + // Using the ImDrawList::ChannelsXXXX you cannot stack a split over another. + inline void ChannelsSplit(int count) { _Splitter.Split(this, count); } + inline void ChannelsMerge() { _Splitter.Merge(this); } + inline void ChannelsSetCurrent(int n) { _Splitter.SetCurrentChannel(this, n); } + + // Advanced: Primitives allocations + // - We render triangles (three vertices) + // - All primitives needs to be reserved via PrimReserve() beforehand. + IMGUI_API void PrimReserve(int idx_count, int vtx_count); + IMGUI_API void PrimUnreserve(int idx_count, int vtx_count); + IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles) + IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col); + inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; } + inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; } + inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021) + inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021) +#endif + + // [Internal helpers] + IMGUI_API void _ResetForNewFrame(); + IMGUI_API void _ClearFreeMemory(); + IMGUI_API void _PopUnusedDrawCmd(); + IMGUI_API void _TryMergeDrawCmds(); + IMGUI_API void _OnChangedClipRect(); + IMGUI_API void _OnChangedTextureID(); + IMGUI_API void _OnChangedVtxOffset(); + IMGUI_API int _CalcCircleAutoSegmentCount(float radius) const; + IMGUI_API void _PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step); + IMGUI_API void _PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments); +}; + +// All draw data to render a Dear ImGui frame +// (NB: the style and the naming convention here is a little inconsistent, we currently preserve them for backward compatibility purpose, +// as this is one of the oldest structure exposed by the library! Basically, ImDrawList == CmdList) +struct ImDrawData +{ + bool Valid; // Only valid after Render() is called and before the next NewFrame() is called. + int CmdListsCount; // Number of ImDrawList* to render + int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size + int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size + ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here. + ImVec2 DisplayPos; // Top-left position of the viewport to render (== top-left of the orthogonal projection matrix to use) (== GetMainViewport()->Pos for the main viewport, == (0.0) in most single-viewport applications) + ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications) + ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display. + ImGuiViewport* OwnerViewport; // Viewport carrying the ImDrawData instance, might be of use to the renderer (generally not). + + // Functions + ImDrawData() { Clear(); } + void Clear() { memset(this, 0, sizeof(*this)); } // The ImDrawList are owned by ImGuiContext! + IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! + IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than Dear ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. +}; + +//----------------------------------------------------------------------------- +// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFontGlyphRangesBuilder, ImFont) +//----------------------------------------------------------------------------- + +struct ImFontConfig +{ + void* FontData; // // TTF/OTF data + int FontDataSize; // // TTF/OTF data size + bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). + int FontNo; // 0 // Index of font within TTF/OTF file + float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height). + int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal so you can reduce this to 2 to save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details. + int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis. + bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. + ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. + const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font + float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs + bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. + unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure. + float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. + ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. + + // [Internal] + char Name[40]; // Name (strictly to ease debugging) + ImFont* DstFont; + + IMGUI_API ImFontConfig(); +}; + +// Hold rendering data for one glyph. +// (Note: some language parsers may fail to convert the 31+1 bitfield members, in this case maybe drop store a single u32 or we can rework this) +struct ImFontGlyph +{ + unsigned int Colored : 1; // Flag to indicate glyph is colored and should generally ignore tinting (make it usable with no shift on little-endian as this is used in loops) + unsigned int Visible : 1; // Flag to indicate glyph has no visible pixels (e.g. space). Allow early out when rendering. + unsigned int Codepoint : 30; // 0x0000..0x10FFFF + float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) + float X0, Y0, X1, Y1; // Glyph corners + float U0, V0, U1, V1; // Texture coordinates +}; + +// Helper to build glyph ranges from text/string data. Feed your application strings/characters to it then call BuildRanges(). +// This is essentially a tightly packed of vector of 64k booleans = 8KB storage. +struct ImFontGlyphRangesBuilder +{ + ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) + + ImFontGlyphRangesBuilder() { Clear(); } + inline void Clear() { int size_in_bytes = (IM_UNICODE_CODEPOINT_MAX + 1) / 8; UsedChars.resize(size_in_bytes / (int)sizeof(ImU32)); memset(UsedChars.Data, 0, (size_t)size_in_bytes); } + inline bool GetBit(size_t n) const { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array + inline void SetBit(size_t n) { int off = (int)(n >> 5); ImU32 mask = 1u << (n & 31); UsedChars[off] |= mask; } // Set bit n in the array + inline void AddChar(ImWchar c) { SetBit(c); } // Add character + IMGUI_API void AddText(const char* text, const char* text_end = NULL); // Add string (each character of the UTF-8 string are added) + IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault()) to force add all of ASCII/Latin+Ext + IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges +}; + +// See ImFontAtlas::AddCustomRectXXX functions. +struct ImFontAtlasCustomRect +{ + unsigned short Width, Height; // Input // Desired rectangle dimension + unsigned short X, Y; // Output // Packed position in Atlas + unsigned int GlyphID; // Input // For custom font glyphs only (ID < 0x110000) + float GlyphAdvanceX; // Input // For custom font glyphs only: glyph xadvance + ImVec2 GlyphOffset; // Input // For custom font glyphs only: glyph display offset + ImFont* Font; // Input // For custom font glyphs only: target font + ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0, 0); Font = NULL; } + bool IsPacked() const { return X != 0xFFFF; } +}; + +// Flags for ImFontAtlas build +enum ImFontAtlasFlags_ +{ + ImFontAtlasFlags_None = 0, + ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two + ImFontAtlasFlags_NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas (save a little texture memory) + ImFontAtlasFlags_NoBakedLines = 1 << 2 // Don't build thick line textures into the atlas (save a little texture memory). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU). +}; + +// Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding: +// - One or more fonts. +// - Custom graphics data needed to render the shapes needed by Dear ImGui. +// - Mouse cursor shapes for software cursor rendering (unless setting 'Flags |= ImFontAtlasFlags_NoMouseCursors' in the font atlas). +// It is the user-code responsibility to setup/build the atlas, then upload the pixel data into a texture accessible by your graphics api. +// - Optionally, call any of the AddFont*** functions. If you don't call any, the default font embedded in the code will be loaded for you. +// - Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. +// - Upload the pixels data into a texture within your graphics system (see imgui_impl_xxxx.cpp examples) +// - Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture in a format natural to your graphics API. +// This value will be passed back to you during rendering to identify the texture. Read FAQ entry about ImTextureID for more details. +// Common pitfalls: +// - If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the +// atlas is build (when calling GetTexData*** or Build()). We only copy the pointer, not the data. +// - Important: By default, AddFontFromMemoryTTF() takes ownership of the data. Even though we are not writing to it, we will free the pointer on destruction. +// You can set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed, +// - Even though many functions are suffixed with "TTF", OTF data is supported just as well. +// - This is an old API and it is currently awkward for those and and various other reasons! We will address them in the future! +struct ImFontAtlas +{ + IMGUI_API ImFontAtlas(); + IMGUI_API ~ImFontAtlas(); + IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); + IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); + IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); + IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after destruction of the atlas. Set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed. + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. + IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. + IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts. + IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates). + IMGUI_API void Clear(); // Clear all input and output. + + // Build atlas, retrieve pixel data. + // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). + // The pitch is always = Width * BytesPerPixels (1 or 4) + // Building in RGBA32 format is provided for convenience and compatibility, but note that unless you manually manipulate or copy color data into + // the texture (e.g. when using the AddCustomRect*** api), then the RGB pixels emitted will always be white (~75% of memory/bandwidth waste. + IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. + 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 + bool IsBuilt() const { return Fonts.Size > 0 && TexReady; } // Bit ambiguous: used to detect when user didn't built texture but effectively we should check TexID != 0 except that would be backend dependent... + void SetTexID(ImTextureID id) { TexID = id; } + + //------------------------------------------- + // Glyph Ranges + //------------------------------------------- + + // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) + // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. + // NB: Consider using ImFontGlyphRangesBuilder to build glyph ranges from textual data. + IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin + IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters + IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 2999 Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChineseFull(); // Default + Half-Width + Japanese Hiragana/Katakana + full set of about 21000 CJK Unified Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese + IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters + IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters + IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters + + //------------------------------------------- + // [BETA] Custom Rectangles/Glyphs API + //------------------------------------------- + + // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. + // - After calling Build(), you can query the rectangle position and render your pixels. + // - If you render colored output, set 'atlas->TexPixelsUseColors = true' as this may help some backends decide of prefered texture format. + // - You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), + // so you can render e.g. custom colorful icons and use them as regular glyphs. + // - Read docs/FONTS.md for more details about using colorful icons. + // - Note: this API may be redesigned later in order to support multi-monitor varying DPI settings. + IMGUI_API int AddCustomRectRegular(int width, int height); + IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0)); + ImFontAtlasCustomRect* GetCustomRectByIndex(int index) { IM_ASSERT(index >= 0); return &CustomRects[index]; } + + // [Internal] + IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const; + IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); + + //------------------------------------------- + // Members + //------------------------------------------- + + ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) + ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. + int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0. + bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert. + + // [Internal] + // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. + bool TexReady; // Set when texture was built matching current font input + bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format. + 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; // Texture width calculated during Build(). + int TexHeight; // Texture height calculated during Build(). + ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight) + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel + ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. + ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. + ImVector ConfigData; // Configuration data + ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines + + // [Internal] Font builder + const ImFontBuilderIO* FontBuilderIO; // Opaque interface to a font builder (default to stb_truetype, can be changed to use FreeType by defining IMGUI_ENABLE_FREETYPE). + unsigned int FontBuilderFlags; // Shared flags (for all fonts) for custom font builder. THIS IS BUILD IMPLEMENTATION DEPENDENT. Per-font override is also available in ImFontConfig. + + // [Internal] Packing data + int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors + int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines + + // [Obsolete] + //typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ + //typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ +}; + +// Font runtime data and rendering +// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). +struct ImFont +{ + // Members: Hot ~20/24 bytes (for CalcTextSize) + ImVector IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this this info, and are often bottleneck in large UI). + float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX + float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading) + + // Members: Hot ~28/40 bytes (for CalcTextSize + render loop) + ImVector IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point. + ImVector Glyphs; // 12-16 // out // // All glyphs. + const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar) + + // Members: Cold ~32/40 bytes + ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into + const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData + short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont. + ImWchar FallbackChar; // 2 // out // = FFFD/'?' // Character used if a glyph isn't found. + ImWchar EllipsisChar; // 2 // out // = '...' // Character used for ellipsis rendering. + ImWchar DotChar; // 2 // out // = '.' // Character used for ellipsis rendering (if a single '...' character isn't found) + bool DirtyLookupTables; // 1 // out // + float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale() + float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] + int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) + ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints. + + // Methods + IMGUI_API ImFont(); + IMGUI_API ~ImFont(); + IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; + IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const; + float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } + bool IsLoaded() const { return ContainerAtlas != NULL; } + const char* GetDebugName() const { return ConfigData ? ConfigData->Name : ""; } + + // '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 const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; + IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const; + IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; + + // [Internal] Don't use! + IMGUI_API void BuildLookupTable(); + IMGUI_API void ClearOutputData(); + IMGUI_API void GrowIndex(int new_size); + IMGUI_API void AddGlyph(const ImFontConfig* src_cfg, ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); + IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. + IMGUI_API void SetGlyphVisible(ImWchar c, bool visible); + IMGUI_API bool IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last); +}; + +//----------------------------------------------------------------------------- +// [SECTION] Viewports +//----------------------------------------------------------------------------- + +// Flags stored in ImGuiViewport::Flags, giving indications to the platform backends. +enum ImGuiViewportFlags_ +{ + ImGuiViewportFlags_None = 0, + ImGuiViewportFlags_IsPlatformWindow = 1 << 0, // Represent a Platform Window + ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet) + ImGuiViewportFlags_OwnedByApp = 1 << 2, // Platform Window: is created/managed by the application (rather than a dear imgui backend) + ImGuiViewportFlags_NoDecoration = 1 << 3, // Platform Window: Disable platform decorations: title bar, borders, etc. (generally set all windows, but if ImGuiConfigFlags_ViewportsDecoration is set we only set this on popups/tooltips) + ImGuiViewportFlags_NoTaskBarIcon = 1 << 4, // Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set) + ImGuiViewportFlags_NoFocusOnAppearing = 1 << 5, // Platform Window: Don't take focus when created. + ImGuiViewportFlags_NoFocusOnClick = 1 << 6, // Platform Window: Don't take focus when clicked on. + ImGuiViewportFlags_NoInputs = 1 << 7, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it. + ImGuiViewportFlags_NoRendererClear = 1 << 8, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely). + ImGuiViewportFlags_TopMost = 1 << 9, // Platform Window: Display on top (for tooltips only). + ImGuiViewportFlags_Minimized = 1 << 10, // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport. + ImGuiViewportFlags_NoAutoMerge = 1 << 11, // Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!). + ImGuiViewportFlags_CanHostOtherWindows = 1 << 12 // Main viewport: can host multiple imgui windows (secondary viewports are associated to a single window). +}; + +// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. +// - With multi-viewport enabled, we extend this concept to have multiple active viewports. +// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. +// - About Main Area vs Work Area: +// - Main Area = entire viewport. +// - Work Area = entire viewport minus sections used by main menu bars (for platform windows), or by task bar (for platform monitor). +// - Windows are generally trying to stay within the Work Area of their host viewport. +struct ImGuiViewport +{ + ImGuiID ID; // Unique identifier for the viewport + ImGuiViewportFlags Flags; // See ImGuiViewportFlags_ + ImVec2 Pos; // Main Area: Position of the viewport (Dear ImGui coordinates are the same as OS desktop/native coordinates) + ImVec2 Size; // Main Area: Size of the viewport. + ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos) + ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size) + float DpiScale; // 1.0f = 96 DPI = No extra scale. + ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows. + ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame(). + + // Platform/Backend Dependent Data + // Our design separate the Renderer and Platform backends to facilitate combining default backends with each others. + // When our create your own backend for a custom engine, it is possible that both Renderer and Platform will be handled + // by the same system and you may not need to use all the UserData/Handle fields. + // The library never uses those fields, they are merely storage to facilitate backend implementation. + void* RendererUserData; // void* to hold custom data structure for the renderer (e.g. swap chain, framebuffers etc.). generally set by your Renderer_CreateWindow function. + void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context). generally set by your Platform_CreateWindow function. + void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GLFWWindow*, SDL_Window*) + void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms), when using an abstraction layer like GLFW or SDL (where PlatformHandle would be a SDL_Window*) + bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position) + bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size) + bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4) + + ImGuiViewport() { memset(this, 0, sizeof(*this)); } + ~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); } + + // Helpers + ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } + ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Platform Dependent Interfaces (for e.g. multi-viewport support) +//----------------------------------------------------------------------------- +// [BETA] (Optional) This is completely optional, for advanced users! +// If you are new to Dear ImGui and trying to integrate it into your engine, you can probably ignore this for now. +// +// This feature allows you to seamlessly drag Dear ImGui windows outside of your application viewport. +// This is achieved by creating new Platform/OS windows on the fly, and rendering into them. +// Dear ImGui manages the viewport structures, and the backend create and maintain one Platform/OS window for each of those viewports. +// +// See Glossary https://github.com/ocornut/imgui/wiki/Glossary for details about some of the terminology. +// See Thread https://github.com/ocornut/imgui/issues/1542 for gifs, news and questions about this evolving feature. +// +// About the coordinates system: +// - When multi-viewports are enabled, all Dear ImGui coordinates become absolute coordinates (same as OS coordinates!) +// - So e.g. ImGui::SetNextWindowPos(ImVec2(0,0)) will position a window relative to your primary monitor! +// - If you want to position windows relative to your main application viewport, use ImGui::GetMainViewport()->Pos as a base position. +// +// Steps to use multi-viewports in your application, when using a default backend from the examples/ folder: +// - Application: Enable feature with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// - Backend: The backend initialization will setup all necessary ImGuiPlatformIO's functions and update monitors info every frame. +// - Application: In your main loop, call ImGui::UpdatePlatformWindows(), ImGui::RenderPlatformWindowsDefault() after EndFrame() or Render(). +// - Application: Fix absolute coordinates used in ImGui::SetWindowPos() or ImGui::SetNextWindowPos() calls. +// +// Steps to use multi-viewports in your application, when using a custom backend: +// - Important: THIS IS NOT EASY TO DO and comes with many subtleties not described here! +// It's also an experimental feature, so some of the requirements may evolve. +// Consider using default backends if you can. Either way, carefully follow and refer to examples/ backends for details. +// - Application: Enable feature with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// - Backend: Hook ImGuiPlatformIO's Platform_* and Renderer_* callbacks (see below). +// Set 'io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports' and 'io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports'. +// Update ImGuiPlatformIO's Monitors list every frame. +// Update MousePos every frame, in absolute coordinates. +// - Application: In your main loop, call ImGui::UpdatePlatformWindows(), ImGui::RenderPlatformWindowsDefault() after EndFrame() or Render(). +// You may skip calling RenderPlatformWindowsDefault() if its API is not convenient for your needs. Read comments below. +// - Application: Fix absolute coordinates used in ImGui::SetWindowPos() or ImGui::SetNextWindowPos() calls. +// +// About ImGui::RenderPlatformWindowsDefault(): +// - This function is a mostly a _helper_ for the common-most cases, and to facilitate using default backends. +// - You can check its simple source code to understand what it does. +// It basically iterates secondary viewports and call 4 functions that are setup in ImGuiPlatformIO, if available: +// Platform_RenderWindow(), Renderer_RenderWindow(), Platform_SwapBuffers(), Renderer_SwapBuffers() +// Those functions pointers exists only for the benefit of RenderPlatformWindowsDefault(). +// - If you have very specific rendering needs (e.g. flipping multiple swap-chain simultaneously, unusual sync/threading issues, etc.), +// you may be tempted to ignore RenderPlatformWindowsDefault() and write customized code to perform your renderingg. +// You may decide to setup the platform_io's *RenderWindow and *SwapBuffers pointers and call your functions through those pointers, +// or you may decide to never setup those pointers and call your code directly. They are a convenience, not an obligatory interface. +//----------------------------------------------------------------------------- + +// (Optional) Access via ImGui::GetPlatformIO() +struct ImGuiPlatformIO +{ + //------------------------------------------------------------------ + // Input - Backend interface/functions + Monitor List + //------------------------------------------------------------------ + + // (Optional) Platform functions (e.g. Win32, GLFW, SDL2) + // For reference, the second column shows which function are generally calling the Platform Functions: + // N = ImGui::NewFrame() ~ beginning of the dear imgui frame: read info from platform/OS windows (latest size/position) + // F = ImGui::Begin(), ImGui::EndFrame() ~ during the dear imgui frame + // U = ImGui::UpdatePlatformWindows() ~ after the dear imgui frame: create and update all platform/OS windows + // R = ImGui::RenderPlatformWindowsDefault() ~ render + // D = ImGui::DestroyPlatformWindows() ~ shutdown + // The general idea is that NewFrame() we will read the current Platform/OS state, and UpdatePlatformWindows() will write to it. + // + // The functions are designed so we can mix and match 2 imgui_impl_xxxx files, one for the Platform (~window/input handling), one for Renderer. + // Custom engine backends will often provide both Platform and Renderer interfaces and so may not need to use all functions. + // Platform functions are typically called before their Renderer counterpart, apart from Destroy which are called the other way. + + // Platform function --------------------------------------------------- Called by ----- + void (*Platform_CreateWindow)(ImGuiViewport* vp); // . . U . . // Create a new platform window for the given viewport + void (*Platform_DestroyWindow)(ImGuiViewport* vp); // N . U . D // + void (*Platform_ShowWindow)(ImGuiViewport* vp); // . . U . . // Newly created windows are initially hidden so SetWindowPos/Size/Title can be called on them before showing the window + void (*Platform_SetWindowPos)(ImGuiViewport* vp, ImVec2 pos); // . . U . . // Set platform window position (given the upper-left corner of client area) + ImVec2 (*Platform_GetWindowPos)(ImGuiViewport* vp); // N . . . . // + void (*Platform_SetWindowSize)(ImGuiViewport* vp, ImVec2 size); // . . U . . // Set platform window client area size (ignoring OS decorations such as OS title bar etc.) + ImVec2 (*Platform_GetWindowSize)(ImGuiViewport* vp); // N . . . . // Get platform window client area size + void (*Platform_SetWindowFocus)(ImGuiViewport* vp); // N . . . . // Move window to front and set input focus + bool (*Platform_GetWindowFocus)(ImGuiViewport* vp); // . . U . . // + bool (*Platform_GetWindowMinimized)(ImGuiViewport* vp); // N . . . . // Get platform window minimized state. When minimized, we generally won't attempt to get/set size and contents will be culled more easily + void (*Platform_SetWindowTitle)(ImGuiViewport* vp, const char* str); // . . U . . // Set platform window title (given an UTF-8 string) + void (*Platform_SetWindowAlpha)(ImGuiViewport* vp, float alpha); // . . U . . // (Optional) Setup global transparency (not per-pixel transparency) + void (*Platform_UpdateWindow)(ImGuiViewport* vp); // . . U . . // (Optional) Called by UpdatePlatformWindows(). Optional hook to allow the platform backend from doing general book-keeping every frame. + void (*Platform_RenderWindow)(ImGuiViewport* vp, void* render_arg); // . . . R . // (Optional) Main rendering (platform side! This is often unused, or just setting a "current" context for OpenGL bindings). 'render_arg' is the value passed to RenderPlatformWindowsDefault(). + void (*Platform_SwapBuffers)(ImGuiViewport* vp, void* render_arg); // . . . R . // (Optional) Call Present/SwapBuffers (platform side! This is often unused!). 'render_arg' is the value passed to RenderPlatformWindowsDefault(). + float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // N . . . . // (Optional) [BETA] FIXME-DPI: DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. + void (*Platform_OnChangedViewport)(ImGuiViewport* vp); // . F . . . // (Optional) [BETA] FIXME-DPI: DPI handling: Called during Begin() every time the viewport we are outputting into changes, so backend has a chance to swap fonts to adjust style. + int (*Platform_CreateVkSurface)(ImGuiViewport* vp, ImU64 vk_inst, const void* vk_allocators, ImU64* out_vk_surface); // (Optional) For a Vulkan Renderer to call into Platform code (since the surface creation needs to tie them both). + + // (Optional) Renderer functions (e.g. DirectX, OpenGL, Vulkan) + void (*Renderer_CreateWindow)(ImGuiViewport* vp); // . . U . . // Create swap chain, frame buffers etc. (called after Platform_CreateWindow) + void (*Renderer_DestroyWindow)(ImGuiViewport* vp); // N . U . D // Destroy swap chain, frame buffers etc. (called before Platform_DestroyWindow) + void (*Renderer_SetWindowSize)(ImGuiViewport* vp, ImVec2 size); // . . U . . // Resize swap chain, frame buffers etc. (called after Platform_SetWindowSize) + void (*Renderer_RenderWindow)(ImGuiViewport* vp, void* render_arg); // . . . R . // (Optional) Clear framebuffer, setup render target, then render the viewport->DrawData. 'render_arg' is the value passed to RenderPlatformWindowsDefault(). + void (*Renderer_SwapBuffers)(ImGuiViewport* vp, void* render_arg); // . . . R . // (Optional) Call Present/SwapBuffers. 'render_arg' is the value passed to RenderPlatformWindowsDefault(). + + // (Optional) Monitor list + // - Updated by: app/backend. Update every frame to dynamically support changing monitor or DPI configuration. + // - Used by: dear imgui to query DPI info, clamp popups/tooltips within same monitor and not have them straddle monitors. + ImVector Monitors; + + //------------------------------------------------------------------ + // Output - List of viewports to render into platform windows + //------------------------------------------------------------------ + + // Viewports list (the list is updated by calling ImGui::EndFrame or ImGui::Render) + // (in the future we will attempt to organize this feature to remove the need for a "main viewport") + ImVector Viewports; // Main viewports, followed by all secondary viewports. + ImGuiPlatformIO() { memset(this, 0, sizeof(*this)); } // Zero clear +}; + +// (Optional) This is required when enabling multi-viewport. Represent the bounds of each connected monitor/display and their DPI. +// We use this information for multiple DPI support + clamping the position of popups and tooltips so they don't straddle multiple monitors. +struct ImGuiPlatformMonitor +{ + ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) + ImVec2 WorkPos, WorkSize; // Coordinates without task bars / side bars / menu bars. Used to avoid positioning popups/tooltips inside this region. If you don't have this info, please copy the value for MainPos/MainSize. + float DpiScale; // 1.0f = 96 DPI + ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0, 0); DpiScale = 1.0f; } +}; + +// (Optional) Support for IME (Input Method Editor) via the io.SetPlatformImeDataFn() function. +struct ImGuiPlatformImeData +{ + bool WantVisible; // A widget wants the IME to be visible + ImVec2 InputPos; // Position of the input cursor + float InputLineHeight; // Line height + + ImGuiPlatformImeData() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Obsolete functions and types +// (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details) +// Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead. +//----------------------------------------------------------------------------- + +namespace ImGui +{ +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IMGUI_API int GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into legacy native key index. == io.KeyMap[key] +#else + static inline int GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END && "ImGuiKey and native_index was merged together and native_index is disabled by IMGUI_DISABLE_OBSOLETE_KEYIO. Please switch to ImGuiKey."); return key; } +#endif +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +namespace ImGui +{ + // OBSOLETED in 1.86 (from November 2021) + IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Calculate coarse clipping for large list of evenly sized items. Prefer using ImGuiListClipper. + // OBSOLETED in 1.85 (from August 2021) + static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } + // OBSOLETED in 1.81 (from February 2021) + IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items + static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } + static inline void ListBoxFooter() { EndListBox(); } + // OBSOLETED in 1.79 (from August 2020) + static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry! + // OBSOLETED in 1.78 (from June 2020) + // Old drag/sliders functions that took a 'float power = 1.0' argument instead of flags. + // For shared code, you can version check at compile-time with `#if IMGUI_VERSION_NUM >= 17704`. + IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power); + IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power); + static inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, power); } + static inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, power); } + static inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, power); } + static inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, power); } + IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power); + IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, float power); + static inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power) { return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, power); } + static inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, power); } + static inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, power); } + static inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, power); } + // OBSOLETED in 1.77 (from June 2020) + static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); } + + // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) + //static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); } // OBSOLETED in 1.72 (from July 2019) + //static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } // OBSOLETED in 1.71 (from June 2019) + //static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } // OBSOLETED in 1.70 (from May 2019) + //static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); } // OBSOLETED in 1.69 (from Mar 2019) + //static inline void SetScrollHere(float ratio = 0.5f) { SetScrollHereY(ratio); } // OBSOLETED in 1.66 (from Nov 2018) + //static inline bool IsItemDeactivatedAfterChange() { return IsItemDeactivatedAfterEdit(); } // OBSOLETED in 1.63 (from Aug 2018) + //static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } // OBSOLETED in 1.60 (from Apr 2018) + //static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } // OBSOLETED in 1.60 (between Dec 2017 and Apr 2018) + //static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) +} + +// OBSOLETED in 1.82 (from Mars 2021): flags for AddRect(), AddRectFilled(), AddImageRounded(), PathRect() +typedef ImDrawFlags ImDrawCornerFlags; +enum ImDrawCornerFlags_ +{ + ImDrawCornerFlags_None = ImDrawFlags_RoundCornersNone, // Was == 0 prior to 1.82, this is now == ImDrawFlags_RoundCornersNone which is != 0 and not implicit + ImDrawCornerFlags_TopLeft = ImDrawFlags_RoundCornersTopLeft, // Was == 0x01 (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally). + ImDrawCornerFlags_TopRight = ImDrawFlags_RoundCornersTopRight, // Was == 0x02 (1 << 1) prior to 1.82. + ImDrawCornerFlags_BotLeft = ImDrawFlags_RoundCornersBottomLeft, // Was == 0x04 (1 << 2) prior to 1.82. + ImDrawCornerFlags_BotRight = ImDrawFlags_RoundCornersBottomRight, // Was == 0x08 (1 << 3) prior to 1.82. + ImDrawCornerFlags_All = ImDrawFlags_RoundCornersAll, // Was == 0x0F prior to 1.82 + ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, + ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, + ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight +}; + +#endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +//----------------------------------------------------------------------------- + +#if defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +// Include imgui_user.h at the end of imgui.h (convenient for user to only explicitly include vanilla imgui.h) +#ifdef IMGUI_INCLUDE_IMGUI_USER_H +#include "imgui_user.h" +#endif + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui_demo.cpp b/libultraship/libultraship/Lib/ImGui/imgui_demo.cpp new file mode 100644 index 000000000..0c885ccd1 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui_demo.cpp @@ -0,0 +1,8212 @@ +// dear imgui, v1.87 +// (demo code) + +// Help: +// - Read FAQ at http://dearimgui.org/faq +// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. +// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. +// Read imgui.cpp for more details, documentation and comments. +// Get the latest version at https://github.com/ocornut/imgui + +// Message to the person tempted to delete this file when integrating Dear ImGui into their codebase: +// Do NOT remove this file from your project! Think again! It is the most useful reference code that you and other +// coders will want to refer to and call. Have the ImGui::ShowDemoWindow() function wired in an always-available +// debug menu of your game/app! Removing this file from your project is hindering access to documentation for everyone +// in your team, likely leading you to poorer usage of the library. +// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow(). +// If you want to link core Dear ImGui in your shipped builds but want a thorough guarantee that the demo will not be +// linked, you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty. +// In another situation, whenever you have Dear ImGui available you probably want this to be available for reference. +// Thank you, +// -Your beloved friend, imgui_demo.cpp (which you won't delete) + +// Message to beginner C/C++ programmers about the meaning of the 'static' keyword: +// In this demo code, we frequently use 'static' variables inside functions. A static variable persists across calls, +// so it is essentially like a global variable but declared inside the scope of the function. We do this as a way to +// gather code and data in the same place, to make the demo source code faster to read, faster to write, and smaller +// in size. It also happens to be a convenient way of storing simple UI related information as long as your function +// doesn't need to be reentrant or used in multiple threads. This might be a pattern you will want to use in your code, +// but most of the real data you would be editing is likely going to be stored outside your functions. + +// The Demo code in this file is designed to be easy to copy-and-paste into your application! +// Because of this: +// - We never omit the ImGui:: prefix when calling functions, even though most code here is in the same namespace. +// - We try to declare static variables in the local scope, as close as possible to the code using them. +// - We never use any of the helpers/facilities used internally by Dear ImGui, unless available in the public API. +// - We never use maths operators on ImVec2/ImVec4. For our other sources files we use them, and they are provided +// by imgui_internal.h using the IMGUI_DEFINE_MATH_OPERATORS define. For your own sources file they are optional +// and require you either enable those, either provide your own via IM_VEC2_CLASS_EXTRA in imconfig.h. +// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp. + +// Navigating this file: +// - In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. + +/* + +Index of this file: + +// [SECTION] Forward Declarations, Helpers +// [SECTION] Demo Window / ShowDemoWindow() +// - sub section: ShowDemoWindowWidgets() +// - sub section: ShowDemoWindowLayout() +// - sub section: ShowDemoWindowPopups() +// - sub section: ShowDemoWindowTables() +// - sub section: ShowDemoWindowMisc() +// [SECTION] About Window / ShowAboutWindow() +// [SECTION] Style Editor / ShowStyleEditor() +// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar() +// [SECTION] Example App: Debug Console / ShowExampleAppConsole() +// [SECTION] Example App: Debug Log / ShowExampleAppLog() +// [SECTION] Example App: Simple Layout / ShowExampleAppLayout() +// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor() +// [SECTION] Example App: Long Text / ShowExampleAppLongText() +// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize() +// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize() +// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay() +// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen() +// [SECTION] Example App: Manipulating window titles / ShowExampleAppWindowTitles() +// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering() +// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace() +// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments() + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#define IMGUI_DISABLE +#ifndef IMGUI_DISABLE + +// System includes +#include // toupper +#include // INT_MIN, INT_MAX +#include // sqrtf, powf, cosf, sinf, floorf, ceilf +#include // vsnprintf, sscanf, printf +#include // NULL, malloc, free, atoi +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code) +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type +#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal +#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 "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used. +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure) +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. +#endif + +// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!) +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" +#else +#define IM_NEWLINE "\n" +#endif + +// Helpers +#if defined(_MSC_VER) && !defined(snprintf) +#define snprintf _snprintf +#endif +#if defined(_MSC_VER) && !defined(vsnprintf) +#define vsnprintf _vsnprintf +#endif + +// Format specifiers, printing 64-bit hasn't been decently standardized... +// In a real application you should be using PRId64 and PRIu64 from (non-windows) and on Windows define them yourself. +#ifdef _MSC_VER +#define IM_PRId64 "I64d" +#define IM_PRIu64 "I64u" +#else +#define IM_PRId64 "lld" +#define IM_PRIu64 "llu" +#endif + +// Helpers macros +// We normally try to not use many helpers in imgui_demo.cpp in order to make code easier to copy and paste, +// but making an exception here as those are largely simplifying code... +// In other imgui sources we can use nicer internal functions from imgui_internal.h (ImMin/ImMax) but not in the demo. +#define IM_MIN(A, B) (((A) < (B)) ? (A) : (B)) +#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B)) +#define IM_CLAMP(V, MN, MX) ((V) < (MN) ? (MN) : (V) > (MX) ? (MX) : (V)) + +// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall +#ifndef IMGUI_CDECL +#ifdef _MSC_VER +#define IMGUI_CDECL __cdecl +#else +#define IMGUI_CDECL +#endif +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Forward Declarations, Helpers +//----------------------------------------------------------------------------- + +#if !defined(IMGUI_DISABLE_DEMO_WINDOWS) + +// Forward Declarations +static void ShowExampleAppDockSpace(bool* p_open); +static void ShowExampleAppDocuments(bool* p_open); +static void ShowExampleAppMainMenuBar(); +static void ShowExampleAppConsole(bool* p_open); +static void ShowExampleAppLog(bool* p_open); +static void ShowExampleAppLayout(bool* p_open); +static void ShowExampleAppPropertyEditor(bool* p_open); +static void ShowExampleAppLongText(bool* p_open); +static void ShowExampleAppAutoResize(bool* p_open); +static void ShowExampleAppConstrainedResize(bool* p_open); +static void ShowExampleAppSimpleOverlay(bool* p_open); +static void ShowExampleAppFullscreen(bool* p_open); +static void ShowExampleAppWindowTitles(bool* p_open); +static void ShowExampleAppCustomRendering(bool* p_open); +static void ShowExampleMenuFile(); + +// Helper to display a little (?) mark which shows a tooltip when hovered. +// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.md) +static void HelpMarker(const char* desc) +{ + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +static void ShowDockingDisabledMessage() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui::Text("ERROR: Docking is not enabled! See Demo > Configuration."); + ImGui::Text("Set io.ConfigFlags |= ImGuiConfigFlags_DockingEnable in your code, or "); + ImGui::SameLine(0.0f, 0.0f); + if (ImGui::SmallButton("click here")) + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; +} + +// Helper to wire demo markers located in code to a interactive browser +typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section, void* user_data); +extern ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback; +extern void* GImGuiDemoMarkerCallbackUserData; +ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback = NULL; +void* GImGuiDemoMarkerCallbackUserData = NULL; +#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback(__FILE__, __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0) + +// Helper to display basic user controls. +void ImGui::ShowUserGuide() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui::BulletText("Double-click on title bar to collapse window."); + ImGui::BulletText( + "Click and drag on lower corner to resize window\n" + "(double-click to auto fit window to its contents)."); + ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Tab to select a window."); + if (io.FontAllowUserScaling) + ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); + ImGui::BulletText("While inputing text:\n"); + ImGui::Indent(); + ImGui::BulletText("CTRL+Left/Right to word jump."); + ImGui::BulletText("CTRL+A or double-click to select all."); + ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste."); + ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); + ImGui::BulletText("ESCAPE to revert."); + ImGui::Unindent(); + ImGui::BulletText("With keyboard navigation enabled:"); + ImGui::Indent(); + ImGui::BulletText("Arrow keys to navigate."); + ImGui::BulletText("Space to activate a widget."); + ImGui::BulletText("Return to input text into a widget."); + ImGui::BulletText("Escape to deactivate a widget, close popup, exit child window."); + ImGui::BulletText("Alt to jump to the menu layer of a window."); + ImGui::Unindent(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Demo Window / ShowDemoWindow() +//----------------------------------------------------------------------------- +// - ShowDemoWindowWidgets() +// - ShowDemoWindowLayout() +// - ShowDemoWindowPopups() +// - ShowDemoWindowTables() +// - ShowDemoWindowColumns() +// - ShowDemoWindowMisc() +//----------------------------------------------------------------------------- + +// We split the contents of the big ShowDemoWindow() function into smaller functions +// (because the link time of very large functions grow non-linearly) +static void ShowDemoWindowWidgets(); +static void ShowDemoWindowLayout(); +static void ShowDemoWindowPopups(); +static void ShowDemoWindowTables(); +static void ShowDemoWindowColumns(); +static void ShowDemoWindowMisc(); + +// Demonstrate most Dear ImGui features (this is big function!) +// You may execute this function to experiment with the UI and understand what it does. +// You may then search for keywords in the code when you are interested by a specific feature. +void ImGui::ShowDemoWindow(bool* p_open) +{ + // Exceptionally add an extra assert here for people confused about initial Dear ImGui setup + // Most ImGui functions would normally just crash if the context is missing. + IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing dear imgui context. Refer to examples app!"); + + // Examples Apps (accessible from the "Examples" menu) + static bool show_app_main_menu_bar = false; + static bool show_app_dockspace = false; + static bool show_app_documents = false; + + static bool show_app_console = false; + static bool show_app_log = false; + static bool show_app_layout = false; + static bool show_app_property_editor = false; + static bool show_app_long_text = false; + static bool show_app_auto_resize = false; + static bool show_app_constrained_resize = false; + static bool show_app_simple_overlay = false; + static bool show_app_fullscreen = false; + static bool show_app_window_titles = false; + static bool show_app_custom_rendering = false; + + if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); + if (show_app_dockspace) ShowExampleAppDockSpace(&show_app_dockspace); // Process the Docking app first, as explicit DockSpace() nodes needs to be submitted early (read comments near the DockSpace function) + if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); // Process the Document app next, as it may also use a DockSpace() + + if (show_app_console) ShowExampleAppConsole(&show_app_console); + if (show_app_log) ShowExampleAppLog(&show_app_log); + if (show_app_layout) ShowExampleAppLayout(&show_app_layout); + if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); + if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); + if (show_app_simple_overlay) ShowExampleAppSimpleOverlay(&show_app_simple_overlay); + if (show_app_fullscreen) ShowExampleAppFullscreen(&show_app_fullscreen); + if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); + if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); + + // Dear ImGui Apps (accessible from the "Tools" menu) + static bool show_app_metrics = false; + static bool show_app_stack_tool = false; + static bool show_app_style_editor = false; + static bool show_app_about = false; + + if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); } + if (show_app_stack_tool) { ImGui::ShowStackToolWindow(&show_app_stack_tool); } + if (show_app_about) { ImGui::ShowAboutWindow(&show_app_about); } + if (show_app_style_editor) + { + ImGui::Begin("Dear ImGui Style Editor", &show_app_style_editor); + ImGui::ShowStyleEditor(); + ImGui::End(); + } + + // Demonstrate the various window flags. Typically you would just use the default! + static bool no_titlebar = false; + static bool no_scrollbar = false; + static bool no_menu = false; + static bool no_move = false; + static bool no_resize = false; + static bool no_collapse = false; + static bool no_close = false; + static bool no_nav = false; + static bool no_background = false; + static bool no_bring_to_front = false; + static bool no_docking = false; + static bool unsaved_document = false; + + ImGuiWindowFlags window_flags = 0; + if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; + if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; + if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (no_nav) window_flags |= ImGuiWindowFlags_NoNav; + if (no_background) window_flags |= ImGuiWindowFlags_NoBackground; + if (no_bring_to_front) window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus; + if (no_docking) window_flags |= ImGuiWindowFlags_NoDocking; + if (unsaved_document) window_flags |= ImGuiWindowFlags_UnsavedDocument; + if (no_close) p_open = NULL; // Don't pass our bool* to Begin + + // We specify a default position/size in case there's no data in the .ini file. + // We only do it to make the demo applications a little more welcoming, but typically this isn't required. + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); + + // Main body of the Demo window starts here. + if (!ImGui::Begin("Dear ImGui Demo", p_open, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + // Most "big" widgets share a common width settings by default. See 'Demo->Layout->Widgets Width' for details. + + // e.g. Use 2/3 of the space for widgets and 1/3 for labels (right align) + //ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.35f); + + // e.g. Leave a fixed amount of width for labels (by passing a negative value), the rest goes to widgets. + ImGui::PushItemWidth(ImGui::GetFontSize() * -12); + + // Menu Bar + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + IMGUI_DEMO_MARKER("Menu/File"); + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Examples")) + { + IMGUI_DEMO_MARKER("Menu/Examples"); + ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar); + ImGui::MenuItem("Console", NULL, &show_app_console); + ImGui::MenuItem("Log", NULL, &show_app_log); + ImGui::MenuItem("Simple layout", NULL, &show_app_layout); + ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); + ImGui::MenuItem("Long text display", NULL, &show_app_long_text); + ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); + ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); + ImGui::MenuItem("Simple overlay", NULL, &show_app_simple_overlay); + ImGui::MenuItem("Fullscreen window", NULL, &show_app_fullscreen); + ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); + ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); + ImGui::MenuItem("Dockspace", NULL, &show_app_dockspace); + ImGui::MenuItem("Documents", NULL, &show_app_documents); + ImGui::EndMenu(); + } + //if (ImGui::MenuItem("MenuItem")) {} // You can also use MenuItem() inside a menu bar! + if (ImGui::BeginMenu("Tools")) + { + IMGUI_DEMO_MARKER("Menu/Tools"); +#ifndef IMGUI_DISABLE_METRICS_WINDOW + ImGui::MenuItem("Metrics/Debugger", NULL, &show_app_metrics); + ImGui::MenuItem("Stack Tool", NULL, &show_app_stack_tool); +#endif + ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); + ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION); + ImGui::Spacing(); + + IMGUI_DEMO_MARKER("Help"); + if (ImGui::CollapsingHeader("Help")) + { + ImGui::Text("ABOUT THIS DEMO:"); + ImGui::BulletText("Sections below are demonstrating many aspects of the library."); + ImGui::BulletText("The \"Examples\" menu above leads to more demo contents."); + ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n" + "and Metrics/Debugger (general purpose Dear ImGui debugging tool)."); + ImGui::Separator(); + + ImGui::Text("PROGRAMMER GUIDE:"); + ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!"); + ImGui::BulletText("See comments in imgui.cpp."); + ImGui::BulletText("See example applications in the examples/ folder."); + ImGui::BulletText("Read the FAQ at http://www.dearimgui.org/faq/"); + ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls."); + ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls."); + ImGui::Separator(); + + ImGui::Text("USER GUIDE:"); + ImGui::ShowUserGuide(); + } + + IMGUI_DEMO_MARKER("Configuration"); + if (ImGui::CollapsingHeader("Configuration")) + { + ImGuiIO& io = ImGui::GetIO(); + + if (ImGui::TreeNode("Configuration##2")) + { + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); + ImGui::SameLine(); HelpMarker("Enable keyboard controls."); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); + ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); + ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); + ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) + { + // The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it: + if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f) + { + ImGui::SameLine(); + ImGui::Text("<>"); + } + if (ImGui::IsKeyPressed(ImGuiKey_Space)) + io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; + } + ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); + ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility."); + + ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", &io.ConfigFlags, ImGuiConfigFlags_DockingEnable); + ImGui::SameLine(); + if (io.ConfigDockingWithShift) + HelpMarker("Drag from window title bar or their tab to dock/undock. Hold SHIFT to enable docking.\n\nDrag from window menu button (upper-left button) to undock an entire node (all windows)."); + else + HelpMarker("Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.\n\nDrag from window menu button (upper-left button) to undock an entire node (all windows)."); + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) + { + ImGui::Indent(); + ImGui::Checkbox("io.ConfigDockingNoSplit", &io.ConfigDockingNoSplit); + ImGui::SameLine(); HelpMarker("Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars."); + ImGui::Checkbox("io.ConfigDockingWithShift", &io.ConfigDockingWithShift); + ImGui::SameLine(); HelpMarker("Enable docking when holding Shift only (allow to drop in wider space, reduce visual noise)"); + ImGui::Checkbox("io.ConfigDockingAlwaysTabBar", &io.ConfigDockingAlwaysTabBar); + ImGui::SameLine(); HelpMarker("Create a docking node and tab-bar on single floating windows."); + ImGui::Checkbox("io.ConfigDockingTransparentPayload", &io.ConfigDockingTransparentPayload); + ImGui::SameLine(); HelpMarker("Make window or viewport transparent when docking and only display docking boxes on the target viewport. Useful if rendering of multiple viewport cannot be synced. Best used with ConfigViewportsNoAutoMerge."); + ImGui::Unindent(); + } + + ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", &io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable); + ImGui::SameLine(); HelpMarker("[beta] Enable beta multi-viewports support. See ImGuiPlatformIO for details."); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::Indent(); + ImGui::Checkbox("io.ConfigViewportsNoAutoMerge", &io.ConfigViewportsNoAutoMerge); + ImGui::SameLine(); HelpMarker("Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it."); + ImGui::Checkbox("io.ConfigViewportsNoTaskBarIcon", &io.ConfigViewportsNoTaskBarIcon); + ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the task bar icon state right away)."); + ImGui::Checkbox("io.ConfigViewportsNoDecoration", &io.ConfigViewportsNoDecoration); + ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the decoration right away)."); + ImGui::Checkbox("io.ConfigViewportsNoDefaultParent", &io.ConfigViewportsNoDefaultParent); + ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the parenting right away)."); + ImGui::Unindent(); + } + + ImGui::Checkbox("io.ConfigInputTrickleEventQueue", &io.ConfigInputTrickleEventQueue); + ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates."); + ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); + ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)."); + ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText); + ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving)."); + ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); + ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); + ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); + ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); + ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); + ImGui::Text("Also see Style->Rendering for rendering options."); + ImGui::TreePop(); + ImGui::Separator(); + } + + IMGUI_DEMO_MARKER("Configuration/Backend Flags"); + if (ImGui::TreeNode("Backend Flags")) + { + HelpMarker( + "Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n" + "Here we expose them as read-only fields to avoid breaking interactions with your backend."); + + // Make a local copy to avoid modifying actual backend flags. + // FIXME: We don't use BeginDisabled() to keep label bright, maybe we need a BeginReadonly() equivalent.. + ImGuiBackendFlags backend_flags = io.BackendFlags; + ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &backend_flags, ImGuiBackendFlags_HasGamepad); + ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &backend_flags, ImGuiBackendFlags_HasMouseCursors); + ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &backend_flags, ImGuiBackendFlags_HasSetMousePos); + ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &backend_flags, ImGuiBackendFlags_PlatformHasViewports); + ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&backend_flags, ImGuiBackendFlags_HasMouseHoveredViewport); + ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset); + ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &backend_flags, ImGuiBackendFlags_RendererHasViewports); + ImGui::TreePop(); + ImGui::Separator(); + } + + IMGUI_DEMO_MARKER("Configuration/Style"); + if (ImGui::TreeNode("Style")) + { + HelpMarker("The same contents can be accessed in 'Tools->Style Editor' or by calling the ShowStyleEditor() function."); + ImGui::ShowStyleEditor(); + ImGui::TreePop(); + ImGui::Separator(); + } + + IMGUI_DEMO_MARKER("Configuration/Capture, Logging"); + if (ImGui::TreeNode("Capture/Logging")) + { + HelpMarker( + "The logging API redirects all text output so you can easily capture the content of " + "a window or a block. Tree nodes can be automatically expanded.\n" + "Try opening any of the contents below in this window and then click one of the \"Log To\" button."); + ImGui::LogButtons(); + + HelpMarker("You can also call ImGui::LogText() to output directly to the log without a visual output."); + if (ImGui::Button("Copy \"Hello, world!\" to clipboard")) + { + ImGui::LogToClipboard(); + ImGui::LogText("Hello, world!"); + ImGui::LogFinish(); + } + ImGui::TreePop(); + } + } + + IMGUI_DEMO_MARKER("Window options"); + if (ImGui::CollapsingHeader("Window options")) + { + if (ImGui::BeginTable("split", 3)) + { + ImGui::TableNextColumn(); ImGui::Checkbox("No titlebar", &no_titlebar); + ImGui::TableNextColumn(); ImGui::Checkbox("No scrollbar", &no_scrollbar); + ImGui::TableNextColumn(); ImGui::Checkbox("No menu", &no_menu); + ImGui::TableNextColumn(); ImGui::Checkbox("No move", &no_move); + ImGui::TableNextColumn(); ImGui::Checkbox("No resize", &no_resize); + ImGui::TableNextColumn(); ImGui::Checkbox("No collapse", &no_collapse); + ImGui::TableNextColumn(); ImGui::Checkbox("No close", &no_close); + ImGui::TableNextColumn(); ImGui::Checkbox("No nav", &no_nav); + ImGui::TableNextColumn(); ImGui::Checkbox("No background", &no_background); + ImGui::TableNextColumn(); ImGui::Checkbox("No bring to front", &no_bring_to_front); + ImGui::TableNextColumn(); ImGui::Checkbox("No docking", &no_docking); + ImGui::TableNextColumn(); ImGui::Checkbox("Unsaved document", &unsaved_document); + ImGui::EndTable(); + } + } + + // All demo contents + ShowDemoWindowWidgets(); + ShowDemoWindowLayout(); + ShowDemoWindowPopups(); + ShowDemoWindowTables(); + ShowDemoWindowMisc(); + + // End of ShowDemoWindow() + ImGui::PopItemWidth(); + ImGui::End(); +} + +static void ShowDemoWindowWidgets() +{ + IMGUI_DEMO_MARKER("Widgets"); + if (!ImGui::CollapsingHeader("Widgets")) + return; + + static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom + if (disable_all) + ImGui::BeginDisabled(); + + IMGUI_DEMO_MARKER("Widgets/Basic"); + if (ImGui::TreeNode("Basic")) + { + IMGUI_DEMO_MARKER("Widgets/Basic/Button"); + static int clicked = 0; + if (ImGui::Button("Button")) + clicked++; + if (clicked & 1) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + IMGUI_DEMO_MARKER("Widgets/Basic/Checkbox"); + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + IMGUI_DEMO_MARKER("Widgets/Basic/RadioButton"); + 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. + IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Colored)"); + for (int i = 0; i < 7; i++) + { + if (i > 0) + ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + // Use AlignTextToFramePadding() to align text baseline to the baseline of framed widgets elements + // (otherwise a Text+SameLine+Button sequence will have the text a little too high by default!) + // See 'Demo->Layout->Text Baseline Alignment' for details. + ImGui::AlignTextToFramePadding(); + ImGui::Text("Hold to repeat:"); + ImGui::SameLine(); + + // Arrow buttons with Repeater + IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Repeating)"); + static int counter = 0; + float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::PushButtonRepeat(true); + if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { counter--; } + ImGui::SameLine(0.0f, spacing); + if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { counter++; } + ImGui::PopButtonRepeat(); + ImGui::SameLine(); + ImGui::Text("%d", counter); + + IMGUI_DEMO_MARKER("Widgets/Basic/Tooltips"); + 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(); + } + + ImGui::Separator(); + ImGui::LabelText("label", "Value"); + + { + // Using the _simplified_ one-liner Combo() api here + // See "Combo" section for examples of how to use the more flexible BeginCombo()/EndCombo() api. + IMGUI_DEMO_MARKER("Widgets/Basic/Combo"); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIIIIII", "JJJJ", "KKKKKKK" }; + static int item_current = 0; + ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items)); + ImGui::SameLine(); HelpMarker( + "Using the simplified one-liner Combo API here.\nRefer to the \"Combo\" section below for an explanation of how to use the more flexible and general BeginCombo/EndCombo API."); + } + + { + // To wire InputText() with std::string or any other custom string type, + // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. + IMGUI_DEMO_MARKER("Widgets/Basic/InputText"); + static char str0[128] = "Hello, world!"; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::SameLine(); HelpMarker( + "USER:\n" + "Hold SHIFT or use mouse to select text.\n" + "CTRL+Left/Right to word jump.\n" + "CTRL+A or double-click to select all.\n" + "CTRL+X,CTRL+C,CTRL+V clipboard.\n" + "CTRL+Z,CTRL+Y undo/redo.\n" + "ESCAPE to revert.\n\n" + "PROGRAMMER:\n" + "You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() " + "to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated " + "in imgui_demo.cpp)."); + + static char str1[128] = ""; + ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1)); + + IMGUI_DEMO_MARKER("Widgets/Basic/InputInt, InputFloat"); + static int i0 = 123; + ImGui::InputInt("input int", &i0); + + static float f0 = 0.001f; + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f"); + + static double d0 = 999999.00000001; + ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f"); + + static float f1 = 1.e10f; + ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e"); + ImGui::SameLine(); HelpMarker( + "You can input value using the scientific notation,\n" + " e.g. \"1e+8\" becomes \"100000000\"."); + + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + ImGui::InputFloat3("input float3", vec4a); + } + + { + IMGUI_DEMO_MARKER("Widgets/Basic/DragInt, DragFloat"); + static int i1 = 50, i2 = 42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); HelpMarker( + "Click and drag to edit value.\n" + "Hold SHIFT/ALT for faster/slower edit.\n" + "Double-click or CTRL+click to input value."); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp); + + static float f1 = 1.00f, f2 = 0.0067f; + ImGui::DragFloat("drag float", &f1, 0.005f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + { + IMGUI_DEMO_MARKER("Widgets/Basic/SliderInt, SliderFloat"); + static int i1 = 0; + ImGui::SliderInt("slider int", &i1, -1, 3); + ImGui::SameLine(); HelpMarker("CTRL+click to input value."); + + static float f1 = 0.123f, f2 = 0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider float (log)", &f2, -10.0f, 10.0f, "%.4f", ImGuiSliderFlags_Logarithmic); + + IMGUI_DEMO_MARKER("Widgets/Basic/SliderAngle"); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + + // Using the format string to display a name instead of an integer. + // Here we completely omit '%d' from the format string, so it'll only display a name. + // This technique can also be used with DragInt(). + IMGUI_DEMO_MARKER("Widgets/Basic/Slider (enum)"); + enum Element { Element_Fire, Element_Earth, Element_Air, Element_Water, Element_COUNT }; + static int elem = Element_Fire; + const char* elems_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" }; + const char* elem_name = (elem >= 0 && elem < Element_COUNT) ? elems_names[elem] : "Unknown"; + ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); + ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer."); + } + + { + IMGUI_DEMO_MARKER("Widgets/Basic/ColorEdit3, ColorEdit4"); + 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::SameLine(); HelpMarker( + "Click on the color square to open a color picker.\n" + "Click and hold to use drag and drop.\n" + "Right-click on the color square to show options.\n" + "CTRL+click on individual component to input value.\n"); + + ImGui::ColorEdit4("color 2", col2); + } + + { + // Using the _simplified_ one-liner ListBox() api here + // See "List boxes" section for examples of how to use the more flexible BeginListBox()/EndListBox() api. + IMGUI_DEMO_MARKER("Widgets/Basic/ListBox"); + const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; + static int item_current = 1; + ImGui::ListBox("listbox", &item_current, items, IM_ARRAYSIZE(items), 4); + ImGui::SameLine(); HelpMarker( + "Using the simplified one-liner ListBox API here.\nRefer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API."); + } + + ImGui::TreePop(); + } + + // Testing ImGuiOnceUponAFrame helper. + //static ImGuiOnceUponAFrame once; + //for (int i = 0; i < 5; i++) + // if (once) + // ImGui::Text("This will be displayed only once."); + + IMGUI_DEMO_MARKER("Widgets/Trees"); + if (ImGui::TreeNode("Trees")) + { + IMGUI_DEMO_MARKER("Widgets/Trees/Basic trees"); + if (ImGui::TreeNode("Basic trees")) + { + for (int i = 0; i < 5; i++) + { + // Use SetNextItemOpen() so set the default state of a node to be open. We could + // also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing! + if (i == 0) + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + + if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + ImGui::TreePop(); + } + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Trees/Advanced, with Selectable nodes"); + if (ImGui::TreeNode("Advanced, with Selectable nodes")) + { + HelpMarker( + "This is a more typical looking tree with selectable nodes.\n" + "Click to select, CTRL+Click to toggle, click on arrows or double-click to open."); + static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + static bool align_label_with_current_x_position = false; + static bool test_drag_and_drop = false; + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); + ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); + ImGui::Text("Hello!"); + if (align_label_with_current_x_position) + ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); + + // 'selection_mask' is dumb representation of what may be user-side selection state. + // You may retain selection state inside or outside your objects in whatever format you see fit. + // 'node_clicked' is temporary storage of what node we have clicked to process selection at the end + /// of the loop. May be a pointer to your own node type, etc. + static int selection_mask = (1 << 2); + int node_clicked = -1; + for (int i = 0; i < 6; i++) + { + // Disable the default "open on single-click behavior" + set Selected flag according to our selection. + // To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection. + ImGuiTreeNodeFlags node_flags = base_flags; + const bool is_selected = (selection_mask & (1 << i)) != 0; + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + if (i < 3) + { + // Items 0..2 are Tree Node + bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + if (node_open) + { + ImGui::BulletText("Blah blah\nBlah Blah"); + ImGui::TreePop(); + } + } + else + { + // Items 3..5 are Tree Leaves + // The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can + // use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text(). + node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + } + } + if (node_clicked != -1) + { + // Update selection state + // (process outside of tree loop to avoid visual inconsistencies during the clicking frame) + if (ImGui::GetIO().KeyCtrl) + selection_mask ^= (1 << node_clicked); // CTRL+click to toggle + else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection + selection_mask = (1 << node_clicked); // Click to single-select + } + if (align_label_with_current_x_position) + ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Collapsing Headers"); + if (ImGui::TreeNode("Collapsing Headers")) + { + static bool closable_group = true; + ImGui::Checkbox("Show 2nd header", &closable_group); + if (ImGui::CollapsingHeader("Header", ImGuiTreeNodeFlags_None)) + { + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("Some content %d", i); + } + if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) + { + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("More content %d", i); + } + /* + if (ImGui::CollapsingHeader("Header with a bullet", ImGuiTreeNodeFlags_Bullet)) + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + */ + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Bullets"); + if (ImGui::TreeNode("Bullets")) + { + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + if (ImGui::TreeNode("Tree node")) + { + ImGui::BulletText("Another bullet point"); + ImGui::TreePop(); + } + ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); ImGui::SmallButton("Button"); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text"); + if (ImGui::TreeNode("Text")) + { + IMGUI_DEMO_MARKER("Widgets/Text/Colored Text"); + if (ImGui::TreeNode("Colorful 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::TextDisabled("Disabled"); + ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/Word Wrapping"); + 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 suitable for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + for (int n = 0; n < 2; n++) + { + ImGui::Text("Test paragraph %d:", n); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y); + ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + if (n == 0) + ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); + else + ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + + // Draw actual text bounding box, following by marker of our expected limit (should not overlap!) + draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255)); + ImGui::PopTextWrapPos(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/UTF-8 Text"); + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.) + // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 + // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you + // can save your source files as 'UTF-8 without signature'). + // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 + // CHARACTERS IN THIS SOURCE FILE. Instead we are encoding a few strings with hexadecimal constants. + // Don't do this in your application! Please use u8"text in any language" in your application! + // Note that characters values are preserved even by InputText() 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.Fonts->AddFontFromFileTTF() manually to load extra character ranges. " + "Read docs/FONTS.md for details."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string. + 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"; + //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Images"); + if (ImGui::TreeNode("Images")) + { + ImGuiIO& io = ImGui::GetIO(); + 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!"); + + // Below we are displaying the font texture because it is the only texture we have access to inside the demo! + // Remember that ImTextureID is just storage for whatever you want it to be. It is essentially a value that + // will be passed to the rendering backend via the ImDrawCmd structure. + // If you use one of the default imgui_impl_XXXX.cpp rendering backend, they all have comments at the top + // of their respective source file to specify what they expect to be stored in ImTextureID, for example: + // - The imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer + // - The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier, etc. + // More: + // - If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers + // to ImGui::Image(), and gather width/height through your own functions, etc. + // - You can use ShowMetricsWindow() to inspect the draw data that are being passed to your renderer, + // it will help you debug issues if you are confused about it. + // - Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). + // - Read https://github.com/ocornut/imgui/blob/master/docs/FAQ.md + // - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + ImTextureID my_tex_id = io.Fonts->TexID; + float my_tex_w = (float)io.Fonts->TexWidth; + float my_tex_h = (float)io.Fonts->TexHeight; + { + ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f); // 50% opaque white + ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + float region_sz = 32.0f; + float region_x = io.MousePos.x - pos.x - region_sz * 0.5f; + float region_y = io.MousePos.y - pos.y - region_sz * 0.5f; + float zoom = 4.0f; + if (region_x < 0.0f) { region_x = 0.0f; } + else if (region_x > my_tex_w - region_sz) { region_x = my_tex_w - region_sz; } + if (region_y < 0.0f) { region_y = 0.0f; } + else if (region_y > my_tex_h - region_sz) { region_y = my_tex_h - region_sz; } + ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y); + ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz); + ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h); + ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h); + ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, tint_col, border_col); + ImGui::EndTooltip(); + } + } + + IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons"); + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); + int frame_padding = -1 + i; // -1 == uses default padding (style.FramePadding) + ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible + ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left + ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h);// UV coordinates for (32,32) in our texture + ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + if (ImGui::ImageButton(my_tex_id, size, uv0, uv1, frame_padding, bg_col, tint_col)) + pressed_count += 1; + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::NewLine(); + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Combo"); + if (ImGui::TreeNode("Combo")) + { + // Expose flags as checkbox for the demo + static ImGuiComboFlags flags = 0; + ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft); + ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo"); + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton)) + flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview)) + flags &= ~ImGuiComboFlags_NoArrowButton; // Clear the other flag, as we cannot combine both + + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_current_idx = 0; // Here we store our selection data as an index. + const char* combo_preview_value = items[item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) + if (ImGui::BeginCombo("combo 1", combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + // Simplified one-liner Combo() API, using values packed in a single constant string + // This is a convenience for when the selection set is small and known at compile-time. + static int item_current_2 = 0; + ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + + // Simplified one-liner Combo() using an array of const char* + // This is not very useful (may obsolete): prefer using BeginCombo()/EndCombo() for full control. + static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview + ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items)); + + // Simplified one-liner Combo() using an accessor function + struct Funcs { static bool ItemGetter(void* data, int n, const char** out_str) { *out_str = ((const char**)data)[n]; return true; } }; + static int item_current_4 = 0; + ImGui::Combo("combo 4 (function)", &item_current_4, &Funcs::ItemGetter, items, IM_ARRAYSIZE(items)); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/List Boxes"); + if (ImGui::TreeNode("List boxes")) + { + // Using the generic BeginListBox() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_current_idx = 0; // Here we store our selection data as an index. + if (ImGui::BeginListBox("listbox 1")) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + // Custom size: use all width, 5 items tall + ImGui::Text("Full-width:"); + if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Selectables"); + if (ImGui::TreeNode("Selectables")) + { + // Selectable() has 2 overloads: + // - The one taking "bool selected" as a read-only selection information. + // When Selectable() has been clicked it returns true and you can alter selection state accordingly. + // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) + // The earlier is more flexible, as in real application your selection may be stored in many different ways + // and not necessarily inside a bool value (e.g. in flags within objects, as an external list, etc). + IMGUI_DEMO_MARKER("Widgets/Selectables/Basic"); + if (ImGui::TreeNode("Basic")) + { + static bool selection[5] = { false, true, false, false, false }; + ImGui::Selectable("1. I am selectable", &selection[0]); + ImGui::Selectable("2. I am selectable", &selection[1]); + ImGui::Text("(I am not selectable)"); + ImGui::Selectable("4. I am selectable", &selection[3]); + if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selection[4] = !selection[4]; + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Single Selection"); + if (ImGui::TreeNode("Selection State: Single Selection")) + { + static int selected = -1; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selected == n)) + selected = n; + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Multiple Selection"); + if (ImGui::TreeNode("Selection State: Multiple Selection")) + { + HelpMarker("Hold CTRL and click to select multiple items."); + static bool selection[5] = { false, false, false, false, false }; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selection[n])) + { + if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held + memset(selection, 0, sizeof(selection)); + selection[n] ^= 1; + } + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more text into the same line"); + if (ImGui::TreeNode("Rendering more text into the same line")) + { + // Using the Selectable() override that takes "bool* p_selected" parameter, + // this function toggle your bool value automatically. + 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(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/In columns"); + if (ImGui::TreeNode("In columns")) + { + static bool selected[10] = {}; + + if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap + } + ImGui::EndTable(); + } + ImGui::Spacing(); + if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns); + ImGui::TableNextColumn(); + ImGui::Text("Some other contents"); + ImGui::TableNextColumn(); + ImGui::Text("123456"); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Grid"); + if (ImGui::TreeNode("Grid")) + { + static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; + + // Add in a bit of silly fun... + const float time = (float)ImGui::GetTime(); + const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected... + if (winning_state) + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f))); + + for (int y = 0; y < 4; y++) + for (int x = 0; x < 4; x++) + { + if (x > 0) + ImGui::SameLine(); + ImGui::PushID(y * 4 + x); + if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50))) + { + // Toggle clicked cell + toggle neighbors + selected[y][x] ^= 1; + if (x > 0) { selected[y][x - 1] ^= 1; } + if (x < 3) { selected[y][x + 1] ^= 1; } + if (y > 0) { selected[y - 1][x] ^= 1; } + if (y < 3) { selected[y + 1][x] ^= 1; } + } + ImGui::PopID(); + } + + if (winning_state) + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment"); + if (ImGui::TreeNode("Alignment")) + { + HelpMarker( + "By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item " + "basis using PushStyleVar(). You'll probably want to always keep your default situation to " + "left-align otherwise it becomes difficult to layout multiple items on a same line"); + static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true }; + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f); + char name[32]; + sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y); + if (x > 0) ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment); + ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80)); + ImGui::PopStyleVar(); + } + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + // To wire InputText() with std::string or any other custom string type, + // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. + IMGUI_DEMO_MARKER("Widgets/Text Input"); + if (ImGui::TreeNode("Text Input")) + { + IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input"); + if (ImGui::TreeNode("Multi-line Text Input")) + { + // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize + // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings. + static char text[1024 * 16] = + "/*\n" + " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" + " the hexadecimal encoding of one offending instruction,\n" + " more formally, the invalid operand with locked CMPXCHG8B\n" + " instruction bug, is a design flaw in the majority of\n" + " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" + " processors (all in the P5 microarchitecture).\n" + "*/\n\n" + "label:\n" + "\tlock cmpxchg8b eax\n"; + + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; + HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include in here)"); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput); + ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); + ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input"); + if (ImGui::TreeNode("Filtered Text Input")) + { + struct TextFilters + { + // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i' + static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) + { + if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) + return 0; + return 1; + } + }; + + 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); + static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Password input"); + if (ImGui::TreeNode("Password Input")) + { + static char password[64] = "password123"; + ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Completion, History, Edit Callbacks")) + { + struct Funcs + { + static int MyCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion) + { + data->InsertChars(data->CursorPos, ".."); + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory) + { + if (data->EventKey == ImGuiKey_UpArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Up!"); + data->SelectAll(); + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Down!"); + data->SelectAll(); + } + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit) + { + // Toggle casing of first character + char c = data->Buf[0]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32; + data->BufDirty = true; + + // Increment a counter + int* p_int = (int*)data->UserData; + *p_int = *p_int + 1; + } + return 0; + } + }; + static char buf1[64]; + ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker("Here we append \"..\" each time Tab is pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf2[64]; + ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker("Here we replace and select text each time Up/Down are pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf3[64]; + static int edit_count = 0; + ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count); + ImGui::SameLine(); HelpMarker("Here we toggle the casing of the first character on every edits + count edits."); + ImGui::SameLine(); ImGui::Text("(%d)", edit_count); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback"); + if (ImGui::TreeNode("Resize Callback")) + { + // To wire InputText() with std::string or any other custom string type, + // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper + // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string. + HelpMarker( + "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n" + "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string."); + struct Funcs + { + static int MyResizeCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + ImVector* my_str = (ImVector*)data->UserData; + IM_ASSERT(my_str->begin() == data->Buf); + my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1 + data->Buf = my_str->begin(); + } + return 0; + } + + // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace. + // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)' + static bool MyInputTextMultiline(const char* label, ImVector* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) + { + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str); + } + }; + + // For this demo we are using ImVector as a string container. + // Note that because we need to store a terminating zero character, our size/capacity are 1 more + // than usually reported by a typical string class. + static ImVector my_str; + if (my_str.empty()) + my_str.push_back(0); + Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16)); + ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity()); + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + + // Tabs + IMGUI_DEMO_MARKER("Widgets/Tabs"); + if (ImGui::TreeNode("Tabs")) + { + IMGUI_DEMO_MARKER("Widgets/Tabs/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + if (ImGui::BeginTabItem("Avocado")) + { + ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Broccoli")) + { + ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Cucumber")) + { + ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button"); + if (ImGui::TreeNode("Advanced & Close Button")) + { + // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable; + ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs); + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton); + if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) + tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_; + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + // Tab Bar + const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" }; + static bool opened[4] = { true, true, true, true }; // Persistent user state + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + { + if (n > 0) { ImGui::SameLine(); } + ImGui::Checkbox(names[n], &opened[n]); + } + + // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): + // the underlying bool will be set to false when the tab is closed. + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", names[n]); + if (n & 1) + ImGui::Text("I am an odd tab."); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags"); + if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags")) + { + static ImVector active_tabs; + static int next_tab_id = 0; + if (next_tab_id == 0) // Initialize with some default tabs + for (int i = 0; i < 3; i++) + active_tabs.push_back(next_tab_id++); + + // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together. + // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags... + // but they tend to make more sense together) + static bool show_leading_button = true; + static bool show_trailing_button = true; + ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button); + ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button); + + // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown; + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + // Demo a Leading TabItemButton(): click the "?" button to open a menu + if (show_leading_button) + if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip)) + ImGui::OpenPopup("MyHelpMenu"); + if (ImGui::BeginPopup("MyHelpMenu")) + { + ImGui::Selectable("Hello!"); + ImGui::EndPopup(); + } + + // Demo Trailing Tabs: click the "+" button to add a new tab (in your app you may want to use a font icon instead of the "+") + // Note that we submit it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing flag it will always appear at the end. + if (show_trailing_button) + if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) + active_tabs.push_back(next_tab_id++); // Add new tab + + // Submit our regular tabs + for (int n = 0; n < active_tabs.Size; ) + { + bool open = true; + char name[16]; + snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]); + if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", name); + ImGui::EndTabItem(); + } + + if (!open) + active_tabs.erase(active_tabs.Data + n); + else + n++; + } + + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + // Plot/Graph widgets are not very good. + // Consider using a third-party library such as ImPlot: https://github.com/epezent/implot + // (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions) + IMGUI_DEMO_MARKER("Widgets/Plotting"); + if (ImGui::TreeNode("Plotting")) + { + static bool animate = true; + ImGui::Checkbox("Animate", &animate); + + // Plot as lines and plot as histogram + IMGUI_DEMO_MARKER("Widgets/Plotting/PlotLines, PlotHistogram"); + 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)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f)); + + // Fill an array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float + // and the sizeof() of your structure in the "stride" parameter. + static float values[90] = {}; + static int values_offset = 0; + static double refresh_time = 0.0; + if (!animate || refresh_time == 0.0) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset + 1) % IM_ARRAYSIZE(values); + phase += 0.10f * values_offset; + refresh_time += 1.0f / 60.0f; + } + + // Plots can display overlay texts + // (in this example, we will display an average value) + { + float average = 0.0f; + for (int n = 0; n < IM_ARRAYSIZE(values); n++) + average += values[n]; + average /= (float)IM_ARRAYSIZE(values); + char overlay[32]; + sprintf(overlay, "avg %f", average); + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f)); + } + + // Use functions to generate output + // FIXME: This is rather awkward because current plot API only pass in indices. + // We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::Separator(); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::Combo("func", &func_type, "Sin\0Saw\0"); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 400); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::Separator(); + + // Animate a simple progress bar + IMGUI_DEMO_MARKER("Widgets/Plotting/ProgressBar"); + static float progress = 0.0f, progress_dir = 1.0f; + if (animate) + { + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } + } + + // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, + // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f); + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Color"); + if (ImGui::TreeNode("Color/Picker Widgets")) + { + static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f); + + static bool alpha_preview = true; + static bool alpha_half_preview = false; + static bool drag_and_drop = true; + static bool options_menu = true; + static bool hdr = false; + ImGui::Checkbox("With Alpha Preview", &alpha_preview); + ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); + ImGui::Checkbox("With Drag and Drop", &drag_and_drop); + ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options."); + ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); + ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit"); + ImGui::Text("Color widget:"); + ImGui::SameLine(); HelpMarker( + "Click on the color square to open a color picker.\n" + "CTRL+click on individual component to input value.\n"); + ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)"); + ImGui::Text("Color widget HSV with Alpha:"); + ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)"); + ImGui::Text("Color widget with Float Display:"); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)"); + ImGui::Text("Color button with Picker:"); + ImGui::SameLine(); HelpMarker( + "With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n" + "With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only " + "be used for the tooltip and picker popup."); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)"); + ImGui::Text("Color button with Custom Picker Popup:"); + + // Generate a default palette. The palette will persist and can be edited. + static bool saved_palette_init = true; + static ImVec4 saved_palette[32] = {}; + if (saved_palette_init) + { + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, + saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); + saved_palette[n].w = 1.0f; // Alpha + } + saved_palette_init = false; + } + + static ImVec4 backup_color; + bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); + ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x); + open_popup |= ImGui::Button("Palette"); + if (open_popup) + { + ImGui::OpenPopup("mypicker"); + backup_color = color; + } + if (ImGui::BeginPopup("mypicker")) + { + ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); + ImGui::Separator(); + ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); + ImGui::SameLine(); + + ImGui::BeginGroup(); // Lock X position + ImGui::Text("Current"); + ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40)); + ImGui::Text("Previous"); + if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40))) + color = backup_color; + ImGui::Separator(); + ImGui::Text("Palette"); + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::PushID(n); + if ((n % 8) != 0) + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + + ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip; + if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags, ImVec2(20, 20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! + + // Allow user to drop colors into each palette entry. Note that ColorButton() is already a + // drag source by default, unless specifying the ImGuiColorEditFlags_NoDragDrop flag. + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + ImGui::EndDragDropTarget(); + } + + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::EndPopup(); + } + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (simple)"); + ImGui::Text("Color button only:"); + static bool no_border = false; + ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border); + ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80)); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker"); + ImGui::Text("Color picker:"); + static bool alpha = true; + static bool alpha_bar = true; + static bool side_preview = true; + static bool ref_color = false; + static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f); + static int display_mode = 0; + static int picker_mode = 0; + ImGui::Checkbox("With Alpha", &alpha); + ImGui::Checkbox("With Alpha Bar", &alpha_bar); + ImGui::Checkbox("With Side Preview", &side_preview); + if (side_preview) + { + ImGui::SameLine(); + ImGui::Checkbox("With Ref Color", &ref_color); + if (ref_color) + { + ImGui::SameLine(); + ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); + } + } + ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0"); + ImGui::SameLine(); HelpMarker( + "ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, " + "but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex " + "if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions()."); + ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); + ImGui::SameLine(); HelpMarker("User can right-click the picker to change mode."); + ImGuiColorEditFlags flags = misc_flags; + if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() + if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; + if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; + if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; + if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays + if (display_mode == 2) flags |= ImGuiColorEditFlags_DisplayRGB; // Override display mode + if (display_mode == 3) flags |= ImGuiColorEditFlags_DisplayHSV; + if (display_mode == 4) flags |= ImGuiColorEditFlags_DisplayHex; + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); + + ImGui::Text("Set defaults in code:"); + ImGui::SameLine(); HelpMarker( + "SetColorEditOptions() is designed to allow you to set boot-time default.\n" + "We don't have Push/Pop functions because you can force options on a per-widget basis if needed," + "and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid" + "encouraging you to persistently save values that aren't forward-compatible."); + if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar); + if (ImGui::Button("Default: Float + HDR + Hue Wheel")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel); + + // HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0) + static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV! + ImGui::Spacing(); + ImGui::Text("HSV encoded colors"); + ImGui::SameLine(); HelpMarker( + "By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV" + "allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the" + "added benefit that you can manipulate hue values with the picker even when saturation or value are zero."); + ImGui::Text("Color widget with InputHSV:"); + ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float); + ImGui::ColorEdit4("HSV shown as HSV##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float); + ImGui::DragFloat4("Raw HSV values", (float*)&color_hsv, 0.01f, 0.0f, 1.0f); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and Slider Flags"); + if (ImGui::TreeNode("Drag/Slider Flags")) + { + // Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same! + static ImGuiSliderFlags flags = ImGuiSliderFlags_None; + ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp); + ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click."); + ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic); + ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat); + ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); + ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); + + // Drags + static float drag_f = 0.5f; + static int drag_i = 50; + ImGui::Text("Underlying float value: %f", drag_f); + ImGui::DragFloat("DragFloat (0 -> 1)", &drag_f, 0.005f, 0.0f, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags); + ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags); + + // Sliders + static float slider_f = 0.5f; + static int slider_i = 50; + ImGui::Text("Underlying float value: %f", slider_f); + ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags); + ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Range Widgets"); + if (ImGui::TreeNode("Range Widgets")) + { + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags_AlwaysClamp); + ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Data Types"); + if (ImGui::TreeNode("Data Types")) + { + // DragScalar/InputScalar/SliderScalar functions allow various data types + // - signed/unsigned + // - 8/16/32/64-bits + // - integer/float/double + // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum + // to pass the type, and passing all arguments by pointer. + // This is the reason the test code below creates local variables to hold "zero" "one" etc. for each types. + // In practice, if you frequently use a given type that is not covered by the normal API entry points, + // you can wrap it yourself inside a 1 line function which can take typed argument as value instead of void*, + // and then pass their address to the generic function. For example: + // bool MySliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld") + // { + // return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format); + // } + + // Setup limits (as helper variables so we can take their address, as explained above) + // Note: SliderScalar() functions have a maximum usable range of half the natural type maximum, hence the /2. + #ifndef LLONG_MIN + ImS64 LLONG_MIN = -9223372036854775807LL - 1; + ImS64 LLONG_MAX = 9223372036854775807LL; + ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1); + #endif + const char s8_zero = 0, s8_one = 1, s8_fifty = 50, s8_min = -128, s8_max = 127; + const ImU8 u8_zero = 0, u8_one = 1, u8_fifty = 50, u8_min = 0, u8_max = 255; + const short s16_zero = 0, s16_one = 1, s16_fifty = 50, s16_min = -32768, s16_max = 32767; + const ImU16 u16_zero = 0, u16_one = 1, u16_fifty = 50, u16_min = 0, u16_max = 65535; + const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2; + const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2; + const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2; + const ImU64 u64_zero = 0, u64_one = 1, u64_fifty = 50, u64_min = 0, u64_max = ULLONG_MAX/2, u64_hi_a = ULLONG_MAX/2 - 100, u64_hi_b = ULLONG_MAX/2; + const float f32_zero = 0.f, f32_one = 1.f, f32_lo_a = -10000000000.0f, f32_hi_a = +10000000000.0f; + const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0; + + // State + static char s8_v = 127; + static ImU8 u8_v = 255; + static short s16_v = 32767; + static ImU16 u16_v = 65535; + static ImS32 s32_v = -1; + static ImU32 u32_v = (ImU32)-1; + static ImS64 s64_v = -1; + static ImU64 u64_v = (ImU64)-1; + static float f32_v = 0.123f; + static double f64_v = 90000.01234567890123456789; + + const float drag_speed = 0.2f; + static bool drag_clamp = false; + IMGUI_DEMO_MARKER("Widgets/Data Types/Drags"); + ImGui::Text("Drags:"); + ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); + ImGui::SameLine(); HelpMarker( + "As with every widgets in dear imgui, we never modify values unless there is a user interaction.\n" + "You can override the clamping limits by using CTRL+Click to input a value."); + ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL); + ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL); + ImGui::DragScalar("drag u16", ImGuiDataType_U16, &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL); + ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); + ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL); + ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f"); + ImGui::DragScalar("drag float log", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", ImGuiSliderFlags_Logarithmic); + ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams"); + ImGui::DragScalar("drag double log",ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", ImGuiSliderFlags_Logarithmic); + + IMGUI_DEMO_MARKER("Widgets/Data Types/Sliders"); + ImGui::Text("Sliders"); + ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d"); + ImGui::SliderScalar("slider u8 full", ImGuiDataType_U8, &u8_v, &u8_min, &u8_max, "%u"); + ImGui::SliderScalar("slider s16 full", ImGuiDataType_S16, &s16_v, &s16_min, &s16_max, "%d"); + ImGui::SliderScalar("slider u16 full", ImGuiDataType_U16, &u16_v, &u16_min, &u16_max, "%u"); + ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d"); + ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d"); + ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d"); + ImGui::SliderScalar("slider u32 low", ImGuiDataType_U32, &u32_v, &u32_zero, &u32_fifty,"%u"); + ImGui::SliderScalar("slider u32 high", ImGuiDataType_U32, &u32_v, &u32_hi_a, &u32_hi_b, "%u"); + ImGui::SliderScalar("slider u32 full", ImGuiDataType_U32, &u32_v, &u32_min, &u32_max, "%u"); + ImGui::SliderScalar("slider s64 low", ImGuiDataType_S64, &s64_v, &s64_zero, &s64_fifty,"%" IM_PRId64); + ImGui::SliderScalar("slider s64 high", ImGuiDataType_S64, &s64_v, &s64_hi_a, &s64_hi_b, "%" IM_PRId64); + ImGui::SliderScalar("slider s64 full", ImGuiDataType_S64, &s64_v, &s64_min, &s64_max, "%" IM_PRId64); + ImGui::SliderScalar("slider u64 low", ImGuiDataType_U64, &u64_v, &u64_zero, &u64_fifty,"%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider u64 high", ImGuiDataType_U64, &u64_v, &u64_hi_a, &u64_hi_b, "%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider u64 full", ImGuiDataType_U64, &u64_v, &u64_min, &u64_max, "%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider float low", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one); + ImGui::SliderScalar("slider float low log", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", ImGuiSliderFlags_Logarithmic); + ImGui::SliderScalar("slider float high", ImGuiDataType_Float, &f32_v, &f32_lo_a, &f32_hi_a, "%e"); + ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams"); + ImGui::SliderScalar("slider double low log",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", ImGuiSliderFlags_Logarithmic); + ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams"); + + ImGui::Text("Sliders (reverse)"); + ImGui::SliderScalar("slider s8 reverse", ImGuiDataType_S8, &s8_v, &s8_max, &s8_min, "%d"); + ImGui::SliderScalar("slider u8 reverse", ImGuiDataType_U8, &u8_v, &u8_max, &u8_min, "%u"); + ImGui::SliderScalar("slider s32 reverse", ImGuiDataType_S32, &s32_v, &s32_fifty, &s32_zero, "%d"); + ImGui::SliderScalar("slider u32 reverse", ImGuiDataType_U32, &u32_v, &u32_fifty, &u32_zero, "%u"); + ImGui::SliderScalar("slider s64 reverse", ImGuiDataType_S64, &s64_v, &s64_fifty, &s64_zero, "%" IM_PRId64); + ImGui::SliderScalar("slider u64 reverse", ImGuiDataType_U64, &u64_v, &u64_fifty, &u64_zero, "%" IM_PRIu64 " ms"); + + IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs"); + static bool inputs_step = true; + ImGui::Text("Inputs"); + ImGui::Checkbox("Show step buttons", &inputs_step); + ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d"); + ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u"); + ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d"); + ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u"); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Multi-component Widgets"); + if (ImGui::TreeNode("Multi-component Widgets")) + { + 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::InputInt2("input int2", vec4i); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + ImGui::Spacing(); + + 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::InputInt3("input int3", vec4i); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + ImGui::Spacing(); + + 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::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Vertical Sliders"); + if (ImGui::TreeNode("Vertical Sliders")) + { + 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, (ImVec4)ImColor::HSV(i / 7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)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, (float)(int)((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\nsec"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and drop"); + if (ImGui::TreeNode("Drag and Drop")) + { + IMGUI_DEMO_MARKER("Widgets/Drag and drop/Standard widgets"); + if (ImGui::TreeNode("Drag and drop in standard widgets")) + { + // ColorEdit widgets automatically act as drag source and drag target. + // They are using standardized payload strings IMGUI_PAYLOAD_TYPE_COLOR_3F and IMGUI_PAYLOAD_TYPE_COLOR_4F + // to allow your own widgets to use colors in their drag and drop interaction. + // Also see 'Demo->Widgets->Color/Picker Widgets->Palette' demo. + HelpMarker("You can drag from the color squares."); + 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); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and drop/Copy-swap items"); + if (ImGui::TreeNode("Drag and drop to copy/swap items")) + { + enum Mode + { + Mode_Copy, + Mode_Move, + Mode_Swap + }; + static int mode = 0; + if (ImGui::RadioButton("Copy", mode == Mode_Copy)) { mode = Mode_Copy; } ImGui::SameLine(); + if (ImGui::RadioButton("Move", mode == Mode_Move)) { mode = Mode_Move; } ImGui::SameLine(); + if (ImGui::RadioButton("Swap", mode == Mode_Swap)) { mode = Mode_Swap; } + static const char* names[9] = + { + "Bobby", "Beatrice", "Betty", + "Brianna", "Barry", "Bernard", + "Bibi", "Blaine", "Bryn" + }; + for (int n = 0; n < IM_ARRAYSIZE(names); n++) + { + ImGui::PushID(n); + if ((n % 3) != 0) + ImGui::SameLine(); + ImGui::Button(names[n], ImVec2(60, 60)); + + // Our buttons are both drag sources and drag targets here! + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) + { + // Set payload to carry the index of our item (could be anything) + ImGui::SetDragDropPayload("DND_DEMO_CELL", &n, sizeof(int)); + + // Display preview (could be anything, e.g. when dragging an image we could decide to display + // the filename and a small preview of the image, etc.) + if (mode == Mode_Copy) { ImGui::Text("Copy %s", names[n]); } + if (mode == Mode_Move) { ImGui::Text("Move %s", names[n]); } + if (mode == Mode_Swap) { ImGui::Text("Swap %s", names[n]); } + ImGui::EndDragDropSource(); + } + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL")) + { + IM_ASSERT(payload->DataSize == sizeof(int)); + int payload_n = *(const int*)payload->Data; + if (mode == Mode_Copy) + { + names[n] = names[payload_n]; + } + if (mode == Mode_Move) + { + names[n] = names[payload_n]; + names[payload_n] = ""; + } + if (mode == Mode_Swap) + { + const char* tmp = names[n]; + names[n] = names[payload_n]; + names[payload_n] = tmp; + } + } + ImGui::EndDragDropTarget(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and Drop/Drag to reorder items (simple)"); + if (ImGui::TreeNode("Drag to reorder items (simple)")) + { + // Simple reordering + HelpMarker( + "We don't use the drag and drop api at all here! " + "Instead we query when the item is held but not hovered, and order items accordingly."); + static const char* item_names[] = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" }; + for (int n = 0; n < IM_ARRAYSIZE(item_names); n++) + { + const char* item = item_names[n]; + ImGui::Selectable(item); + + if (ImGui::IsItemActive() && !ImGui::IsItemHovered()) + { + int n_next = n + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); + if (n_next >= 0 && n_next < IM_ARRAYSIZE(item_names)) + { + item_names[n] = item_names[n_next]; + item_names[n_next] = item; + ImGui::ResetMouseDragDelta(); + } + } + } + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Querying Item Status (Edited,Active,Hovered etc.)"); + if (ImGui::TreeNode("Querying Item Status (Edited/Active/Hovered etc.)")) + { + // Select an item type + const char* item_names[] = + { + "Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputTextMultiline", "InputFloat", + "InputFloat3", "ColorEdit4", "Selectable", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox" + }; + static int item_type = 4; + static bool item_disabled = false; + ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names)); + ImGui::SameLine(); + HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered()."); + ImGui::Checkbox("Item Disabled", &item_disabled); + + // Submit selected item item so we can query their status in the code following it. + bool ret = false; + static bool b = false; + static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f }; + static char str[16] = {}; + if (item_disabled) + ImGui::BeginDisabled(true); + if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction + if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button + if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater) + if (item_type == 3) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox + if (item_type == 4) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item + if (item_type == 5) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing) + if (item_type == 6) { ret = ImGui::InputTextMultiline("ITEM: InputTextMultiline", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which uses a child window) + if (item_type == 7) { ret = ImGui::InputFloat("ITEM: InputFloat", col4f, 1.0f); } // Testing +/- buttons on scalar input + if (item_type == 8) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) + if (item_type == 9) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) + if (item_type == 10){ ret = ImGui::Selectable("ITEM: Selectable"); } // Testing selectable item + if (item_type == 11){ ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy) + if (item_type == 12){ ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); } // Testing tree node + if (item_type == 13){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. + if (item_type == 14){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::Combo("ITEM: Combo", ¤t, items, IM_ARRAYSIZE(items)); } + if (item_type == 15){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } + + // Display the values of IsItemHovered() and other common item state functions. + // Note that the ImGuiHoveredFlags_XXX flags can be combined. + // Because BulletText is an item itself and that would affect the output of IsItemXXX functions, + // we query every state in a single call to avoid storing them and to simplify the code. + ImGui::BulletText( + "Return value = %d\n" + "IsItemFocused() = %d\n" + "IsItemHovered() = %d\n" + "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsItemHovered(_AllowWhenOverlapped) = %d\n" + "IsItemHovered(_AllowWhenDisabled) = %d\n" + "IsItemHovered(_RectOnly) = %d\n" + "IsItemActive() = %d\n" + "IsItemEdited() = %d\n" + "IsItemActivated() = %d\n" + "IsItemDeactivated() = %d\n" + "IsItemDeactivatedAfterEdit() = %d\n" + "IsItemVisible() = %d\n" + "IsItemClicked() = %d\n" + "IsItemToggledOpen() = %d\n" + "GetItemRectMin() = (%.1f, %.1f)\n" + "GetItemRectMax() = (%.1f, %.1f)\n" + "GetItemRectSize() = (%.1f, %.1f)", + ret, + ImGui::IsItemFocused(), + ImGui::IsItemHovered(), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled), + ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly), + ImGui::IsItemActive(), + ImGui::IsItemEdited(), + ImGui::IsItemActivated(), + ImGui::IsItemDeactivated(), + ImGui::IsItemDeactivatedAfterEdit(), + ImGui::IsItemVisible(), + ImGui::IsItemClicked(), + ImGui::IsItemToggledOpen(), + ImGui::GetItemRectMin().x, ImGui::GetItemRectMin().y, + ImGui::GetItemRectMax().x, ImGui::GetItemRectMax().y, + ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y + ); + + if (item_disabled) + ImGui::EndDisabled(); + + char buf[1] = ""; + ImGui::InputText("unused", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_ReadOnly); + ImGui::SameLine(); + HelpMarker("This widget is only here to be able to tab-out of the widgets above and see e.g. Deactivated() status."); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Querying Window Status (Focused,Hovered etc.)"); + if (ImGui::TreeNode("Querying Window Status (Focused/Hovered etc.)")) + { + static bool embed_all_inside_a_child_window = false; + ImGui::Checkbox("Embed everything inside a child window for testing _RootWindow flag.", &embed_all_inside_a_child_window); + if (embed_all_inside_a_child_window) + ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20.0f), true); + + // Testing IsWindowFocused() function with its various flags. + ImGui::BulletText( + "IsWindowFocused() = %d\n" + "IsWindowFocused(_ChildWindows) = %d\n" + "IsWindowFocused(_ChildWindows|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_ChildWindows|_DockHierarchy) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow|_DockHierarchy) = %d\n" + "IsWindowFocused(_RootWindow) = %d\n" + "IsWindowFocused(_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_RootWindow|_DockHierarchy) = %d\n" + "IsWindowFocused(_AnyWindow) = %d\n", + ImGui::IsWindowFocused(), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_DockHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_DockHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_DockHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)); + + // Testing IsWindowHovered() function with its various flags. + ImGui::BulletText( + "IsWindowHovered() = %d\n" + "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsWindowHovered(_ChildWindows) = %d\n" + "IsWindowHovered(_ChildWindows|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_DockHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow|_DockHierarchy) = %d\n" + "IsWindowHovered(_RootWindow) = %d\n" + "IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_RootWindow|_DockHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AnyWindow) = %d\n", + ImGui::IsWindowHovered(), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_DockHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)); + + ImGui::BeginChild("child", ImVec2(0, 50), true); + ImGui::Text("This is another child window for testing the _ChildWindows flag."); + ImGui::EndChild(); + if (embed_all_inside_a_child_window) + ImGui::EndChild(); + + // Calling IsItemHovered() after begin returns the hovered status of the title bar. + // This is useful in particular if you want to create a context menu associated to the title bar of a window. + // This will also work when docked into a Tab (the Tab replace the Title Bar and guarantee the same properties). + static bool test_window = false; + ImGui::Checkbox("Hovered/Active tests after Begin() for title bar testing", &test_window); + if (test_window) + { + // FIXME-DOCK: This window cannot be docked within the ImGui Demo window, this will cause a feedback loop and get them stuck. + // Could we fix this through an ImGuiWindowClass feature? Or an API call to tag our parent as "don't skip items"? + ImGui::Begin("Title bar Hovered/Active tests", &test_window); + if (ImGui::BeginPopupContextItem()) // <-- This is using IsItemHovered() + { + if (ImGui::MenuItem("Close")) { test_window = false; } + ImGui::EndPopup(); + } + ImGui::Text( + "IsItemHovered() after begin = %d (== is title bar hovered)\n" + "IsItemActive() after begin = %d (== is window being clicked/moved)\n", + ImGui::IsItemHovered(), ImGui::IsItemActive()); + ImGui::End(); + } + + ImGui::TreePop(); + } + + // Demonstrate BeginDisabled/EndDisabled using a checkbox located at the bottom of the section (which is a bit odd: + // logically we'd have this checkbox at the top of the section, but we don't want this feature to steal that space) + if (disable_all) + ImGui::EndDisabled(); + + IMGUI_DEMO_MARKER("Widgets/Disable Block"); + if (ImGui::TreeNode("Disable block")) + { + ImGui::Checkbox("Disable entire section above", &disable_all); + ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section."); + ImGui::TreePop(); + } +} + +static void ShowDemoWindowLayout() +{ + IMGUI_DEMO_MARKER("Layout"); + if (!ImGui::CollapsingHeader("Layout & Scrolling")) + return; + + IMGUI_DEMO_MARKER("Layout/Child windows"); + if (ImGui::TreeNode("Child windows")) + { + HelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window."); + static bool disable_mouse_wheel = false; + static bool disable_menu = false; + ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); + ImGui::Checkbox("Disable Menu", &disable_menu); + + // Child 1: no border, enable horizontal scrollbar + { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + if (disable_mouse_wheel) + window_flags |= ImGuiWindowFlags_NoScrollWithMouse; + ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 260), false, window_flags); + for (int i = 0; i < 100; i++) + ImGui::Text("%04d: scrollable region", i); + ImGui::EndChild(); + } + + ImGui::SameLine(); + + // Child 2: rounded border + { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; + if (disable_mouse_wheel) + window_flags |= ImGuiWindowFlags_NoScrollWithMouse; + if (!disable_menu) + window_flags |= ImGuiWindowFlags_MenuBar; + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("ChildR", ImVec2(0, 260), true, window_flags); + if (!disable_menu && ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + if (ImGui::BeginTable("split", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) + { + for (int i = 0; i < 100; i++) + { + char buf[32]; + sprintf(buf, "%03d", i); + ImGui::TableNextColumn(); + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + + ImGui::Separator(); + + // Demonstrate a few extra things + // - Changing ImGuiCol_ChildBg (which is transparent black in default styles) + // - Using SetCursorPos() to position child window (the child window is an item from the POV of parent window) + // You can also call SetNextWindowPos() to position the child window. The parent window will effectively + // layout from this position. + // - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from + // the POV of the parent window). See 'Demo->Querying Status (Edited/Active/Hovered etc.)' for details. + { + static int offset_x = 0; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x); + ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100)); + ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None); + for (int n = 0; n < 50; n++) + ImGui::Text("Some test %d", n); + ImGui::EndChild(); + bool child_is_hovered = ImGui::IsItemHovered(); + ImVec2 child_rect_min = ImGui::GetItemRectMin(); + ImVec2 child_rect_max = ImGui::GetItemRectMax(); + ImGui::PopStyleColor(); + ImGui::Text("Hovered: %d", child_is_hovered); + ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Widgets Width"); + if (ImGui::TreeNode("Widgets Width")) + { + static float f = 0.0f; + static bool show_indented_items = true; + ImGui::Checkbox("Show indented items", &show_indented_items); + + // Use SetNextItemWidth() to set the width of a single upcoming item. + // Use PushItemWidth()/PopItemWidth() to set the width of a group of items. + // In real code use you'll probably want to choose width values that are proportional to your font size + // e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc. + + ImGui::Text("SetNextItemWidth/PushItemWidth(100)"); + ImGui::SameLine(); HelpMarker("Fixed width."); + ImGui::PushItemWidth(100); + ImGui::DragFloat("float##1b", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##1b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(-100)"); + ImGui::SameLine(); HelpMarker("Align to right edge minus 100"); + ImGui::PushItemWidth(-100); + ImGui::DragFloat("float##2a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##2b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)"); + ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::DragFloat("float##3a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##3b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(-GetContentRegionAvail().x * 0.5f)"); + ImGui::SameLine(); HelpMarker("Align to right edge minus half"); + ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::DragFloat("float##4a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##4b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + // Demonstrate using PushItemWidth to surround three items. + // Calling SetNextItemWidth() before each of them would have the same effect. + ImGui::Text("SetNextItemWidth/PushItemWidth(-FLT_MIN)"); + ImGui::SameLine(); HelpMarker("Align to right edge"); + ImGui::PushItemWidth(-FLT_MIN); + ImGui::DragFloat("##float5a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##5b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout"); + if (ImGui::TreeNode("Basic Horizontal Layout")) + { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)"); + + // Text + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine"); + ImGui::Text("Two items: Hello"); ImGui::SameLine(); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Adjust spacing + ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Button + ImGui::AlignTextToFramePadding(); + 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_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (with offset)"); + 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 + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (more)"); + 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(); + + // Dummy + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Dummy"); + ImVec2 button_sz(40, 40); + ImGui::Button("A", button_sz); ImGui::SameLine(); + ImGui::Dummy(button_sz); ImGui::SameLine(); + ImGui::Button("B", button_sz); + + // Manually wrapping + // (we should eventually provide this as an automatic layout feature, but for now you can do it manually) + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Manual wrapping"); + ImGui::Text("Manual wrapping:"); + ImGuiStyle& style = ImGui::GetStyle(); + int buttons_count = 20; + float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x; + for (int n = 0; n < buttons_count; n++) + { + ImGui::PushID(n); + ImGui::Button("Box", button_sz); + float last_button_x2 = ImGui::GetItemRectMax().x; + float next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_sz.x; // Expected position if next button was on same line + if (n + 1 < buttons_count && next_button_x2 < window_visible_x2) + ImGui::SameLine(); + ImGui::PopID(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Groups"); + if (ImGui::TreeNode("Groups")) + { + HelpMarker( + "BeginGroup() basically locks the horizontal position for new line. " + "EndGroup() bundles the whole group so that you can use \"item\" functions such as " + "IsItemHovered()/IsItemActive() or SameLine() etc. on the whole group."); + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("First group hovered"); + } + // Capture the group size and create widgets using the same size + ImVec2 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(); + + if (ImGui::BeginListBox("List", size)) + { + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::EndListBox(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Text Baseline Alignment"); + if (ImGui::TreeNode("Text Baseline Alignment")) + { + { + ImGui::BulletText("Text baseline:"); + ImGui::SameLine(); HelpMarker( + "This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. " + "Lines only composed of text or \"small\" widgets use less vertical space than lines with framed widgets."); + ImGui::Indent(); + + ImGui::Text("KO Blahblah"); ImGui::SameLine(); + ImGui::Button("Some framed item"); ImGui::SameLine(); + HelpMarker("Baseline of button will look misaligned with text.."); + + // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets. + // (because we don't know what's coming after the Text() statement, we need to move the text baseline + // down by FramePadding.y ahead of time) + ImGui::AlignTextToFramePadding(); + ImGui::Text("OK Blahblah"); ImGui::SameLine(); + ImGui::Button("Some framed item"); ImGui::SameLine(); + HelpMarker("We call AlignTextToFramePadding() to vertically align the text baseline by +FramePadding.y"); + + // SmallButton() uses the same vertical padding as Text + ImGui::Button("TEST##1"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST##2"); + + // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets. + ImGui::AlignTextToFramePadding(); + ImGui::Text("Text aligned to framed item"); ImGui::SameLine(); + ImGui::Button("Item##1"); ImGui::SameLine(); + ImGui::Text("Item"); ImGui::SameLine(); + ImGui::SmallButton("Item##2"); ImGui::SameLine(); + ImGui::Button("Item##3"); + + ImGui::Unindent(); + } + + ImGui::Spacing(); + + { + ImGui::BulletText("Multi-line text:"); + ImGui::Indent(); + 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##1"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP##2"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + ImGui::Unindent(); + } + + ImGui::Spacing(); + + { + ImGui::BulletText("Misc items:"); + ImGui::Indent(); + + // SmallButton() sets FramePadding to zero. Text baseline is aligned to match baseline of previous Button. + ImGui::Button("80x80", ImVec2(80, 80)); + ImGui::SameLine(); + ImGui::Button("50x50", ImVec2(50, 50)); + ImGui::SameLine(); + ImGui::Button("Button()"); + ImGui::SameLine(); + ImGui::SmallButton("SmallButton()"); + + // Tree + const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::Button("Button##1"); + ImGui::SameLine(0.0f, spacing); + if (ImGui::TreeNode("Node##1")) + { + // Placeholder tree data + for (int i = 0; i < 6; i++) + ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } + + // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. + // Otherwise you can use SmallButton() (smaller fit). + ImGui::AlignTextToFramePadding(); + + // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add + // other contents below the node. + bool node_open = ImGui::TreeNode("Node##2"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); + if (node_open) + { + // Placeholder tree data + for (int i = 0; i < 6; i++) + ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } + + // Bullet + ImGui::Button("Button##3"); + ImGui::SameLine(0.0f, spacing); + ImGui::BulletText("Bullet text"); + + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Node"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); + ImGui::Unindent(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Scrolling"); + if (ImGui::TreeNode("Scrolling")) + { + // Vertical scroll functions + IMGUI_DEMO_MARKER("Layout/Scrolling/Vertical"); + HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given vertical position."); + + static int track_item = 50; + static bool enable_track = true; + static bool enable_extra_decorations = false; + static float scroll_to_off_px = 0.0f; + static float scroll_to_pos_px = 200.0f; + + ImGui::Checkbox("Decoration", &enable_extra_decorations); + + ImGui::Checkbox("Track", &enable_track); + ImGui::PushItemWidth(100); + ImGui::SameLine(140); enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d"); + + bool scroll_to_off = ImGui::Button("Scroll Offset"); + ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px"); + + bool scroll_to_pos = ImGui::Button("Scroll To Pos"); + ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px"); + ImGui::PopItemWidth(); + + if (scroll_to_off || scroll_to_pos) + enable_track = false; + + ImGuiStyle& style = ImGui::GetStyle(); + float child_w = (ImGui::GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5; + if (child_w < 1.0f) + child_w = 1.0f; + ImGui::PushID("##VerticalScrolling"); + for (int i = 0; i < 5; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + const char* names[] = { "Top", "25%", "Center", "75%", "Bottom" }; + ImGui::TextUnformatted(names[i]); + + const ImGuiWindowFlags child_flags = enable_extra_decorations ? ImGuiWindowFlags_MenuBar : 0; + const ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + const bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(child_w, 200.0f), true, child_flags); + if (ImGui::BeginMenuBar()) + { + ImGui::TextUnformatted("abc"); + ImGui::EndMenuBar(); + } + if (scroll_to_off) + ImGui::SetScrollY(scroll_to_off_px); + if (scroll_to_pos) + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f); + if (child_is_visible) // Avoid calling SetScrollHereY when running with culled items + { + for (int item = 0; item < 100; item++) + { + if (enable_track && item == track_item) + { + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item); + ImGui::SetScrollHereY(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom + } + else + { + ImGui::Text("Item %d", item); + } + } + } + float scroll_y = ImGui::GetScrollY(); + float scroll_max_y = ImGui::GetScrollMaxY(); + ImGui::EndChild(); + ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y); + ImGui::EndGroup(); + } + ImGui::PopID(); + + // Horizontal scroll functions + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal"); + ImGui::Spacing(); + HelpMarker( + "Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n" + "Because the clipping rectangle of most window hides half worth of WindowPadding on the " + "left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the " + "equivalent SetScrollFromPosY(+1) wouldn't."); + ImGui::PushID("##HorizontalScrolling"); + for (int i = 0; i < 5; i++) + { + float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f; + ImGuiWindowFlags child_flags = ImGuiWindowFlags_HorizontalScrollbar | (enable_extra_decorations ? ImGuiWindowFlags_AlwaysVerticalScrollbar : 0); + ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(-100, child_height), true, child_flags); + if (scroll_to_off) + ImGui::SetScrollX(scroll_to_off_px); + if (scroll_to_pos) + ImGui::SetScrollFromPosX(ImGui::GetCursorStartPos().x + scroll_to_pos_px, i * 0.25f); + if (child_is_visible) // Avoid calling SetScrollHereY when running with culled items + { + for (int item = 0; item < 100; item++) + { + if (item > 0) + ImGui::SameLine(); + if (enable_track && item == track_item) + { + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item); + ImGui::SetScrollHereX(i * 0.25f); // 0.0f:left, 0.5f:center, 1.0f:right + } + else + { + ImGui::Text("Item %d", item); + } + } + } + float scroll_x = ImGui::GetScrollX(); + float scroll_max_x = ImGui::GetScrollMaxX(); + ImGui::EndChild(); + ImGui::SameLine(); + const char* names[] = { "Left", "25%", "Center", "75%", "Right" }; + ImGui::Text("%s\n%.0f/%.0f", names[i], scroll_x, scroll_max_x); + ImGui::Spacing(); + } + ImGui::PopID(); + + // Miscellaneous Horizontal Scrolling Demo + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal (more)"); + HelpMarker( + "Horizontal scrolling for a window is enabled via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\n" + "You may want to also explicitly specify content width by using SetNextWindowContentWidth() before Begin()."); + static int lines = 7; + ImGui::SliderInt("Lines", &lines, 1, 15); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); + ImVec2 scrolling_child_size = ImVec2(0, ImGui::GetFrameHeightWithSpacing() * 7 + 30); + ImGui::BeginChild("scrolling", scrolling_child_size, true, ImGuiWindowFlags_HorizontalScrollbar); + for (int line = 0; line < lines; line++) + { + // Display random stuff. For the sake of this trivial demo we are using basic Button() + SameLine() + // If you want to create your own time line for a real application you may be better off manipulating + // the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets + // yourself. You may also want to use the lower-level ImDrawList API. + int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); + for (int n = 0; n < num_buttons; n++) + { + if (n > 0) ImGui::SameLine(); + ImGui::PushID(n + line * 1000); + char num_buf[16]; + sprintf(num_buf, "%d", n); + const char* label = (!(n % 15)) ? "FizzBuzz" : (!(n % 3)) ? "Fizz" : (!(n % 5)) ? "Buzz" : num_buf; + float hue = n * 0.05f; + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f)); + ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + } + float scroll_x = ImGui::GetScrollX(); + float scroll_max_x = ImGui::GetScrollMaxX(); + ImGui::EndChild(); + ImGui::PopStyleVar(2); + float scroll_x_delta = 0.0f; + ImGui::SmallButton("<<"); + if (ImGui::IsItemActive()) + scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("Scroll from code"); ImGui::SameLine(); + ImGui::SmallButton(">>"); + if (ImGui::IsItemActive()) + scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x); + if (scroll_x_delta != 0.0f) + { + // Demonstrate a trick: you can use Begin to set yourself in the context of another window + // (here we are already out of your child window) + ImGui::BeginChild("scrolling"); + ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); + ImGui::EndChild(); + } + ImGui::Spacing(); + + static bool show_horizontal_contents_size_demo_window = false; + ImGui::Checkbox("Show Horizontal contents size demo window", &show_horizontal_contents_size_demo_window); + + if (show_horizontal_contents_size_demo_window) + { + static bool show_h_scrollbar = true; + static bool show_button = true; + static bool show_tree_nodes = true; + static bool show_text_wrapped = false; + static bool show_columns = true; + static bool show_tab_bar = true; + static bool show_child = false; + static bool explicit_content_size = false; + static float contents_size_x = 300.0f; + if (explicit_content_size) + ImGui::SetNextWindowContentSize(ImVec2(contents_size_x, 0.0f)); + ImGui::Begin("Horizontal contents size demo window", &show_horizontal_contents_size_demo_window, show_h_scrollbar ? ImGuiWindowFlags_HorizontalScrollbar : 0); + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal contents size demo window"); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 0)); + HelpMarker("Test of different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\nUse 'Metrics->Tools->Show windows rectangles' to visualize rectangles."); + ImGui::Checkbox("H-scrollbar", &show_h_scrollbar); + ImGui::Checkbox("Button", &show_button); // Will grow contents size (unless explicitly overwritten) + ImGui::Checkbox("Tree nodes", &show_tree_nodes); // Will grow contents size and display highlight over full width + ImGui::Checkbox("Text wrapped", &show_text_wrapped);// Will grow and use contents size + ImGui::Checkbox("Columns", &show_columns); // Will use contents size + ImGui::Checkbox("Tab bar", &show_tab_bar); // Will use contents size + ImGui::Checkbox("Child", &show_child); // Will grow and use contents size + ImGui::Checkbox("Explicit content size", &explicit_content_size); + ImGui::Text("Scroll %.1f/%.1f %.1f/%.1f", ImGui::GetScrollX(), ImGui::GetScrollMaxX(), ImGui::GetScrollY(), ImGui::GetScrollMaxY()); + if (explicit_content_size) + { + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::DragFloat("##csx", &contents_size_x); + ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + 10, p.y + 10), IM_COL32_WHITE); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(p.x + contents_size_x - 10, p.y), ImVec2(p.x + contents_size_x, p.y + 10), IM_COL32_WHITE); + ImGui::Dummy(ImVec2(0, 10)); + } + ImGui::PopStyleVar(2); + ImGui::Separator(); + if (show_button) + { + ImGui::Button("this is a 300-wide button", ImVec2(300, 0)); + } + if (show_tree_nodes) + { + bool open = true; + if (ImGui::TreeNode("this is a tree node")) + { + if (ImGui::TreeNode("another one of those tree node...")) + { + ImGui::Text("Some tree contents"); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + ImGui::CollapsingHeader("CollapsingHeader", &open); + } + if (show_text_wrapped) + { + ImGui::TextWrapped("This text should automatically wrap on the edge of the work rectangle."); + } + if (show_columns) + { + ImGui::Text("Tables:"); + if (ImGui::BeginTable("table", 4, ImGuiTableFlags_Borders)) + { + for (int n = 0; n < 4; n++) + { + ImGui::TableNextColumn(); + ImGui::Text("Width %.2f", ImGui::GetContentRegionAvail().x); + } + ImGui::EndTable(); + } + ImGui::Text("Columns:"); + ImGui::Columns(4); + for (int n = 0; n < 4; n++) + { + ImGui::Text("Width %.2f", ImGui::GetColumnWidth()); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + if (show_tab_bar && ImGui::BeginTabBar("Hello")) + { + if (ImGui::BeginTabItem("OneOneOne")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("TwoTwoTwo")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("ThreeThreeThree")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("FourFourFour")) { ImGui::EndTabItem(); } + ImGui::EndTabBar(); + } + if (show_child) + { + ImGui::BeginChild("child", ImVec2(0, 0), true); + ImGui::EndChild(); + } + ImGui::End(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Clipping"); + if (ImGui::TreeNode("Clipping")) + { + static ImVec2 size(100.0f, 100.0f); + static ImVec2 offset(30.0f, 30.0f); + ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f"); + ImGui::TextWrapped("(Click and drag to scroll)"); + + for (int n = 0; n < 3; n++) + { + if (n > 0) + ImGui::SameLine(); + ImGui::PushID(n); + ImGui::BeginGroup(); // Lock X position + + ImGui::InvisibleButton("##empty", size); + if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + { + offset.x += ImGui::GetIO().MouseDelta.x; + offset.y += ImGui::GetIO().MouseDelta.y; + } + const ImVec2 p0 = ImGui::GetItemRectMin(); + const ImVec2 p1 = ImGui::GetItemRectMax(); + const char* text_str = "Line 1 hello\nLine 2 clip me!"; + const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + switch (n) + { + case 0: + HelpMarker( + "Using ImGui::PushClipRect():\n" + "Will alter ImGui hit-testing logic + ImDrawList rendering.\n" + "(use this if you want your clipping rectangle to affect interactions)"); + ImGui::PushClipRect(p0, p1, true); + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(text_pos, IM_COL32_WHITE, text_str); + ImGui::PopClipRect(); + break; + case 1: + HelpMarker( + "Using ImDrawList::PushClipRect():\n" + "Will alter ImDrawList rendering only.\n" + "(use this as a shortcut if you are only using ImDrawList calls)"); + draw_list->PushClipRect(p0, p1, true); + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(text_pos, IM_COL32_WHITE, text_str); + draw_list->PopClipRect(); + break; + case 2: + HelpMarker( + "Using ImDrawList::AddText() with a fine ClipRect:\n" + "Will alter only this specific ImDrawList::AddText() rendering.\n" + "(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)"); + ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert. + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect); + break; + } + ImGui::EndGroup(); + ImGui::PopID(); + } + + ImGui::TreePop(); + } +} + +static void ShowDemoWindowPopups() +{ + IMGUI_DEMO_MARKER("Popups"); + if (!ImGui::CollapsingHeader("Popups & Modal windows")) + return; + + // The properties of popups windows are: + // - They block normal mouse hovering detection outside them. (*) + // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as + // we are used to with regular Begin() calls. User can manipulate the visibility state by calling OpenPopup(). + // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even + // when normally blocked by a popup. + // Those three properties are connected. The library needs to hold their visibility state BECAUSE it can close + // popups at any time. + + // Typical use for regular windows: + // bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End(); + // Typical use for popups: + // if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup") { [...] EndPopup(); } + + // With popups we have to go through a library call (here OpenPopup) to manipulate the visibility state. + // This may be a bit confusing at first but it should quickly make sense. Follow on the examples below. + + IMGUI_DEMO_MARKER("Popups/Popups"); + if (ImGui::TreeNode("Popups")) + { + ImGui::TextWrapped( + "When a popup is active, it inhibits interacting with windows that are behind the popup. " + "Clicking outside the popup closes it."); + + static int selected_fish = -1; + const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; + static bool toggles[] = { true, false, false, false, false }; + + // Simple selection popup (if you want to show the current selection inside the Button itself, + // you may want to build a string using the "###" operator to preserve a constant ID with a variable label) + if (ImGui::Button("Select..")) + ImGui::OpenPopup("my_select_popup"); + ImGui::SameLine(); + ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); + if (ImGui::BeginPopup("my_select_popup")) + { + ImGui::Text("Aquarium"); + ImGui::Separator(); + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + if (ImGui::Selectable(names[i])) + selected_fish = i; + ImGui::EndPopup(); + } + + // Showing a menu with toggles + if (ImGui::Button("Toggle..")) + ImGui::OpenPopup("my_toggle_popup"); + if (ImGui::BeginPopup("my_toggle_popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + + ImGui::Separator(); + ImGui::Text("Tooltip here"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip over a popup"); + + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + ImGui::Text("I am the last one here."); + ImGui::EndPopup(); + } + ImGui::EndMenu(); + } + ImGui::EndPopup(); + } + ImGui::EndPopup(); + } + + // Call the more complete ShowExampleMenuFile which we use in various places of this demo + if (ImGui::Button("With a menu..")) + ImGui::OpenPopup("my_file_popup"); + if (ImGui::BeginPopup("my_file_popup", ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + ImGui::MenuItem("Dummy"); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + ImGui::Text("Hello from popup!"); + ImGui::Button("This is a dummy button.."); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Context menus"); + if (ImGui::TreeNode("Context menus")) + { + HelpMarker("\"Context\" functions are simple helpers to associate a Popup to a given Item or Window identifier."); + + // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: + // if (id == 0) + // id = GetItemID(); // Use last item id + // if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right)) + // OpenPopup(id); + // return BeginPopup(id); + // For advanced advanced uses you may want to replicate and customize this code. + // See more details in BeginPopupContextItem(). + + // Example 1 + // When used after an item that has an ID (e.g. Button), we can skip providing an ID to BeginPopupContextItem(), + // and BeginPopupContextItem() will use the last item ID as the popup ID. + { + const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" }; + for (int n = 0; n < 5; n++) + { + ImGui::Selectable(names[n]); + if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id + { + ImGui::Text("This a popup for \"%s\"!", names[n]); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Right-click to open popup"); + } + } + + // Example 2 + // Popup on a Text() element which doesn't have an identifier: we need to provide an identifier to BeginPopupContextItem(). + // Using an explicit identifier is also convenient if you want to activate the popups from different locations. + { + HelpMarker("Text() elements don't have stable identifiers so we need to provide one."); + static float value = 0.5f; + ImGui::Text("Value = %.3f <-- (1) right-click this value", value); + if (ImGui::BeginPopupContextItem("my popup")) + { + if (ImGui::Selectable("Set to zero")) value = 0.0f; + if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::SetNextItemWidth(-FLT_MIN); + ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::EndPopup(); + } + + // We can also use OpenPopupOnItemClick() to toggle the visibility of a given popup. + // Here we make it that right-clicking this other text element opens the same popup as above. + // The popup itself will be submitted by the code above. + ImGui::Text("(2) Or right-click this text"); + ImGui::OpenPopupOnItemClick("my popup", ImGuiPopupFlags_MouseButtonRight); + + // Back to square one: manually open the same popup. + if (ImGui::Button("(3) Or click this button")) + ImGui::OpenPopup("my popup"); + } + + // Example 3 + // When using BeginPopupContextItem() with an implicit identifier (NULL == use last item ID), + // we need to make sure your item identifier is stable. + // In this example we showcase altering the item label while preserving its identifier, using the ### operator (see FAQ). + { + HelpMarker("Showcase using a popup ID linked to item ID, with the item having a changing label + stable ID using the ### operator."); + static char name[32] = "Label1"; + char buf[64]; + sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label + ImGui::Button(buf); + if (ImGui::BeginPopupContextItem()) + { + ImGui::Text("Edit name:"); + ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::SameLine(); ImGui::Text("(<-- right-click here)"); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Modals"); + if (ImGui::TreeNode("Modals")) + { + ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside."); + + if (ImGui::Button("Delete..")) + ImGui::OpenPopup("Delete?"); + + // Always center this window when appearing + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + + if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); + ImGui::Separator(); + + //static int unused_i = 0; + //ImGui::Combo("Combo", &unused_i, "Delete\0Delete harder\0"); + + static bool dont_ask_me_next_time = false; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); + ImGui::PopStyleVar(); + + if (ImGui::Button("OK", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } + ImGui::EndPopup(); + } + + if (ImGui::Button("Stacked modals..")) + ImGui::OpenPopup("Stacked 1"); + if (ImGui::BeginPopupModal("Stacked 1", NULL, ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Some menu item")) {} + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDimBg] behind it."); + + // Testing behavior of widgets stacking their own regular popups over the modal. + static int item = 1; + static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; + ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + ImGui::ColorEdit4("color", color); + + if (ImGui::Button("Add another modal..")) + ImGui::OpenPopup("Stacked 2"); + + // Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which + // will close the popup. Note that the visibility state of popups is owned by imgui, so the input value + // of the bool actually doesn't matter here. + bool unused_open = true; + if (ImGui::BeginPopupModal("Stacked 2", &unused_open)) + { + ImGui::Text("Hello from Stacked The Second!"); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Menus inside a regular window"); + if (ImGui::TreeNode("Menus inside a regular window")) + { + ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); + ImGui::Separator(); + + // Note: As a quirk in this very specific example, we want to differentiate the parent of this menu from the + // parent of the various popup menus above. To do so we are encloding the items in a PushID()/PopID() block + // to make them two different menusets. If we don't, opening any popup above and hovering our menu here would + // open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, + // which is the desired behavior for regular menus. + ImGui::PushID("foo"); + ImGui::MenuItem("Menu item", "CTRL+M"); + if (ImGui::BeginMenu("Menu inside a regular window")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::PopID(); + ImGui::Separator(); + ImGui::TreePop(); + } +} + +// Dummy data structure that we use for the Table demo. +// (pre-C++11 doesn't allow us to instantiate ImVector template if this structure if defined inside the demo function) +namespace +{ +// We are passing our own identifier to TableSetupColumn() to facilitate identifying columns in the sorting code. +// This identifier will be passed down into ImGuiTableSortSpec::ColumnUserID. +// But it is possible to omit the user id parameter of TableSetupColumn() and just use the column index instead! (ImGuiTableSortSpec::ColumnIndex) +// If you don't use sorting, you will generally never care about giving column an ID! +enum MyItemColumnID +{ + MyItemColumnID_ID, + MyItemColumnID_Name, + MyItemColumnID_Action, + MyItemColumnID_Quantity, + MyItemColumnID_Description +}; + +struct MyItem +{ + int ID; + const char* Name; + int Quantity; + + // We have a problem which is affecting _only this demo_ and should not affect your code: + // As we don't rely on std:: or other third-party library to compile dear imgui, we only have reliable access to qsort(), + // however qsort doesn't allow passing user data to comparing function. + // As a workaround, we are storing the sort specs in a static/global for the comparing function to access. + // In your own use case you would probably pass the sort specs to your sorting/comparing functions directly and not use a global. + // We could technically call ImGui::TableGetSortSpecs() in CompareWithSortSpecs(), but considering that this function is called + // very often by the sorting algorithm it would be a little wasteful. + static const ImGuiTableSortSpecs* s_current_sort_specs; + + // Compare function to be used by qsort() + static int IMGUI_CDECL CompareWithSortSpecs(const void* lhs, const void* rhs) + { + const MyItem* a = (const MyItem*)lhs; + const MyItem* b = (const MyItem*)rhs; + for (int n = 0; n < s_current_sort_specs->SpecsCount; n++) + { + // Here we identify columns using the ColumnUserID value that we ourselves passed to TableSetupColumn() + // We could also choose to identify columns based on their index (sort_spec->ColumnIndex), which is simpler! + const ImGuiTableColumnSortSpecs* sort_spec = &s_current_sort_specs->Specs[n]; + int delta = 0; + switch (sort_spec->ColumnUserID) + { + case MyItemColumnID_ID: delta = (a->ID - b->ID); break; + case MyItemColumnID_Name: delta = (strcmp(a->Name, b->Name)); break; + case MyItemColumnID_Quantity: delta = (a->Quantity - b->Quantity); break; + case MyItemColumnID_Description: delta = (strcmp(a->Name, b->Name)); break; + default: IM_ASSERT(0); break; + } + if (delta > 0) + return (sort_spec->SortDirection == ImGuiSortDirection_Ascending) ? +1 : -1; + if (delta < 0) + return (sort_spec->SortDirection == ImGuiSortDirection_Ascending) ? -1 : +1; + } + + // qsort() is instable so always return a way to differenciate items. + // Your own compare function may want to avoid fallback on implicit sort specs e.g. a Name compare if it wasn't already part of the sort specs. + return (a->ID - b->ID); + } +}; +const ImGuiTableSortSpecs* MyItem::s_current_sort_specs = NULL; +} + +// Make the UI compact because there are so many fields +static void PushStyleCompact() +{ + ImGuiStyle& style = ImGui::GetStyle(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, (float)(int)(style.FramePadding.y * 0.60f))); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x, (float)(int)(style.ItemSpacing.y * 0.60f))); +} + +static void PopStyleCompact() +{ + ImGui::PopStyleVar(2); +} + +// Show a combo box with a choice of sizing policies +static void EditTableSizingFlags(ImGuiTableFlags* p_flags) +{ + struct EnumDesc { ImGuiTableFlags Value; const char* Name; const char* Tooltip; }; + static const EnumDesc policies[] = + { + { ImGuiTableFlags_None, "Default", "Use default sizing policy:\n- ImGuiTableFlags_SizingFixedFit if ScrollX is on or if host window has ImGuiWindowFlags_AlwaysAutoResize.\n- ImGuiTableFlags_SizingStretchSame otherwise." }, + { ImGuiTableFlags_SizingFixedFit, "ImGuiTableFlags_SizingFixedFit", "Columns default to _WidthFixed (if resizable) or _WidthAuto (if not resizable), matching contents width." }, + { ImGuiTableFlags_SizingFixedSame, "ImGuiTableFlags_SizingFixedSame", "Columns are all the same width, matching the maximum contents width.\nImplicitly disable ImGuiTableFlags_Resizable and enable ImGuiTableFlags_NoKeepColumnsVisible." }, + { ImGuiTableFlags_SizingStretchProp, "ImGuiTableFlags_SizingStretchProp", "Columns default to _WidthStretch with weights proportional to their widths." }, + { ImGuiTableFlags_SizingStretchSame, "ImGuiTableFlags_SizingStretchSame", "Columns default to _WidthStretch with same weights." } + }; + int idx; + for (idx = 0; idx < IM_ARRAYSIZE(policies); idx++) + if (policies[idx].Value == (*p_flags & ImGuiTableFlags_SizingMask_)) + break; + const char* preview_text = (idx < IM_ARRAYSIZE(policies)) ? policies[idx].Name + (idx > 0 ? strlen("ImGuiTableFlags") : 0) : ""; + if (ImGui::BeginCombo("Sizing Policy", preview_text)) + { + for (int n = 0; n < IM_ARRAYSIZE(policies); n++) + if (ImGui::Selectable(policies[n].Name, idx == n)) + *p_flags = (*p_flags & ~ImGuiTableFlags_SizingMask_) | policies[n].Value; + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 50.0f); + for (int m = 0; m < IM_ARRAYSIZE(policies); m++) + { + ImGui::Separator(); + ImGui::Text("%s:", policies[m].Name); + ImGui::Separator(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().IndentSpacing * 0.5f); + ImGui::TextUnformatted(policies[m].Tooltip); + } + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags) +{ + ImGui::CheckboxFlags("_Disabled", p_flags, ImGuiTableColumnFlags_Disabled); ImGui::SameLine(); HelpMarker("Master disable flag (also hide from context menu)"); + ImGui::CheckboxFlags("_DefaultHide", p_flags, ImGuiTableColumnFlags_DefaultHide); + ImGui::CheckboxFlags("_DefaultSort", p_flags, ImGuiTableColumnFlags_DefaultSort); + if (ImGui::CheckboxFlags("_WidthStretch", p_flags, ImGuiTableColumnFlags_WidthStretch)) + *p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthStretch); + if (ImGui::CheckboxFlags("_WidthFixed", p_flags, ImGuiTableColumnFlags_WidthFixed)) + *p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthFixed); + ImGui::CheckboxFlags("_NoResize", p_flags, ImGuiTableColumnFlags_NoResize); + ImGui::CheckboxFlags("_NoReorder", p_flags, ImGuiTableColumnFlags_NoReorder); + ImGui::CheckboxFlags("_NoHide", p_flags, ImGuiTableColumnFlags_NoHide); + ImGui::CheckboxFlags("_NoClip", p_flags, ImGuiTableColumnFlags_NoClip); + ImGui::CheckboxFlags("_NoSort", p_flags, ImGuiTableColumnFlags_NoSort); + ImGui::CheckboxFlags("_NoSortAscending", p_flags, ImGuiTableColumnFlags_NoSortAscending); + ImGui::CheckboxFlags("_NoSortDescending", p_flags, ImGuiTableColumnFlags_NoSortDescending); + ImGui::CheckboxFlags("_NoHeaderLabel", p_flags, ImGuiTableColumnFlags_NoHeaderLabel); + ImGui::CheckboxFlags("_NoHeaderWidth", p_flags, ImGuiTableColumnFlags_NoHeaderWidth); + ImGui::CheckboxFlags("_PreferSortAscending", p_flags, ImGuiTableColumnFlags_PreferSortAscending); + ImGui::CheckboxFlags("_PreferSortDescending", p_flags, ImGuiTableColumnFlags_PreferSortDescending); + ImGui::CheckboxFlags("_IndentEnable", p_flags, ImGuiTableColumnFlags_IndentEnable); ImGui::SameLine(); HelpMarker("Default for column 0"); + ImGui::CheckboxFlags("_IndentDisable", p_flags, ImGuiTableColumnFlags_IndentDisable); ImGui::SameLine(); HelpMarker("Default for column >0"); +} + +static void ShowTableColumnsStatusFlags(ImGuiTableColumnFlags flags) +{ + ImGui::CheckboxFlags("_IsEnabled", &flags, ImGuiTableColumnFlags_IsEnabled); + ImGui::CheckboxFlags("_IsVisible", &flags, ImGuiTableColumnFlags_IsVisible); + ImGui::CheckboxFlags("_IsSorted", &flags, ImGuiTableColumnFlags_IsSorted); + ImGui::CheckboxFlags("_IsHovered", &flags, ImGuiTableColumnFlags_IsHovered); +} + +static void ShowDemoWindowTables() +{ + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); + IMGUI_DEMO_MARKER("Tables"); + if (!ImGui::CollapsingHeader("Tables & Columns")) + return; + + // Using those as a base value to create width/height that are factor of the size of our font + const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; + const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); + + ImGui::PushID("Tables"); + + int open_action = -1; + if (ImGui::Button("Open all")) + open_action = 1; + ImGui::SameLine(); + if (ImGui::Button("Close all")) + open_action = 0; + ImGui::SameLine(); + + // Options + static bool disable_indent = false; + ImGui::Checkbox("Disable tree indentation", &disable_indent); + ImGui::SameLine(); + HelpMarker("Disable the indenting of tree nodes so demo tables can use the full window width."); + ImGui::Separator(); + if (disable_indent) + ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0.0f); + + // About Styling of tables + // Most settings are configured on a per-table basis via the flags passed to BeginTable() and TableSetupColumns APIs. + // There are however a few settings that a shared and part of the ImGuiStyle structure: + // style.CellPadding // Padding within each cell + // style.Colors[ImGuiCol_TableHeaderBg] // Table header background + // style.Colors[ImGuiCol_TableBorderStrong] // Table outer and header borders + // style.Colors[ImGuiCol_TableBorderLight] // Table inner borders + // style.Colors[ImGuiCol_TableRowBg] // Table row background when ImGuiTableFlags_RowBg is enabled (even rows) + // style.Colors[ImGuiCol_TableRowBgAlt] // Table row background when ImGuiTableFlags_RowBg is enabled (odds rows) + + // Demos + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Basic"); + if (ImGui::TreeNode("Basic")) + { + // Here we will showcase three different ways to output a table. + // They are very simple variations of a same thing! + + // [Method 1] Using TableNextRow() to create a new row, and TableSetColumnIndex() to select the column. + // In many situations, this is the most flexible and easy to use pattern. + HelpMarker("Using TableNextRow() + calling TableSetColumnIndex() _before_ each cell, in a loop."); + if (ImGui::BeginTable("table1", 3)) + { + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Row %d Column %d", row, column); + } + } + ImGui::EndTable(); + } + + // [Method 2] Using TableNextColumn() called multiple times, instead of using a for loop + TableSetColumnIndex(). + // This is generally more convenient when you have code manually submitting the contents of each columns. + HelpMarker("Using TableNextRow() + calling TableNextColumn() _before_ each cell, manually."); + if (ImGui::BeginTable("table2", 3)) + { + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("Row %d", row); + ImGui::TableNextColumn(); + ImGui::Text("Some contents"); + ImGui::TableNextColumn(); + ImGui::Text("123.456"); + } + ImGui::EndTable(); + } + + // [Method 3] We call TableNextColumn() _before_ each cell. We never call TableNextRow(), + // as TableNextColumn() will automatically wrap around and create new roes as needed. + // This is generally more convenient when your cells all contains the same type of data. + HelpMarker( + "Only using TableNextColumn(), which tends to be convenient for tables where every cells contains the same type of contents.\n" + "This is also more similar to the old NextColumn() function of the Columns API, and provided to facilitate the Columns->Tables API transition."); + if (ImGui::BeginTable("table3", 3)) + { + for (int item = 0; item < 14; item++) + { + ImGui::TableNextColumn(); + ImGui::Text("Item %d", item); + } + ImGui::EndTable(); + } + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Borders, background"); + if (ImGui::TreeNode("Borders, background")) + { + // Expose a few Borders related flags interactively + enum ContentsType { CT_Text, CT_FillButton }; + static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + static bool display_headers = false; + static int contents_type = CT_Text; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags, ImGuiTableFlags_Borders); + ImGui::SameLine(); HelpMarker("ImGuiTableFlags_Borders\n = ImGuiTableFlags_BordersInnerV\n | ImGuiTableFlags_BordersOuterV\n | ImGuiTableFlags_BordersInnerV\n | ImGuiTableFlags_BordersOuterH"); + ImGui::Indent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags, ImGuiTableFlags_BordersH); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH); + ImGui::Unindent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV); + ImGui::Unindent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuter", &flags, ImGuiTableFlags_BordersOuter); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInner", &flags, ImGuiTableFlags_BordersInner); + ImGui::Unindent(); + + ImGui::AlignTextToFramePadding(); ImGui::Text("Cell contents:"); + ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text); + ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton); + ImGui::Checkbox("Display headers", &display_headers); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appears in Headers"); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + // Display headers so we can inspect their interaction with borders. + // (Headers are not the main purpose of this section of the demo, so we are not elaborating on them too much. See other sections for details) + if (display_headers) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + char buf[32]; + sprintf(buf, "Hello %d,%d", column, row); + if (contents_type == CT_Text) + ImGui::TextUnformatted(buf); + else if (contents_type) + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, stretch"); + if (ImGui::TreeNode("Resizable, stretch")) + { + // By default, if we don't enable ScrollX the sizing policy for each columns is "Stretch" + // Each columns maintain a sizing weight, and they will occupy all available width. + static ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersInnerV flag as well, this is why the resize borders are still showing when unchecking this."); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, fixed"); + if (ImGui::TreeNode("Resizable, fixed")) + { + // Here we use ImGuiTableFlags_SizingFixedFit (even though _ScrollX is not set) + // So columns will adopt the "Fixed" policy and will maintain a fixed width regardless of the whole available width (unless table is small) + // If there is not enough available width to fit all columns, they will however be resized down. + // FIXME-TABLE: Providing a stretch-on-init would make sense especially for tables which don't have saved settings + HelpMarker( + "Using _Resizable + _SizingFixedFit flags.\n" + "Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\n" + "Double-click a column border to auto-fit the column to its contents."); + PushStyleCompact(); + static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody; + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, mixed"); + if (ImGui::TreeNode("Resizable, mixed")) + { + HelpMarker( + "Using TableSetupColumn() to alter resizing policy on a per-column basis.\n\n" + "When combining Fixed and Stretch columns, generally you only want one, maybe two trailing columns to use _WidthStretch."); + static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + + if (ImGui::BeginTable("table1", 3, flags)) + { + ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CCC", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableHeadersRow(); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %d,%d", (column == 2) ? "Stretch" : "Fixed", column, row); + } + } + ImGui::EndTable(); + } + if (ImGui::BeginTable("table2", 6, flags)) + { + ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CCC", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_DefaultHide); + ImGui::TableSetupColumn("DDD", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("EEE", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("FFF", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_DefaultHide); + ImGui::TableHeadersRow(); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 6; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %d,%d", (column >= 3) ? "Stretch" : "Fixed", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Reorderable, hideable, with headers"); + if (ImGui::TreeNode("Reorderable, hideable, with headers")) + { + HelpMarker( + "Click and drag column headers to reorder columns.\n\n" + "Right-click on a header to open a context menu."); + static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_Reorderable", &flags, ImGuiTableFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTableFlags_Hideable", &flags, ImGuiTableFlags_Hideable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers)"); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + // Submit columns name with TableSetupColumn() and call TableHeadersRow() to create a row with a header in each column. + // (Later we will show how TableSetupColumn() has other uses, optional flags, sizing weight etc.) + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + // Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column) + if (ImGui::BeginTable("table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f))) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Fixed %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Padding"); + if (ImGui::TreeNode("Padding")) + { + // First example: showcase use of padding flags and effect of BorderOuterV/BorderInnerV on X padding. + // We don't expose BorderOuterH/BorderInnerH here because they have no effect on X padding. + HelpMarker( + "We often want outer padding activated when any using features which makes the edges of a column visible:\n" + "e.g.:\n" + "- BorderOuterV\n" + "- any form of row selection\n" + "Because of this, activating BorderOuterV sets the default to PadOuterX. Using PadOuterX or NoPadOuterX you can override the default.\n\n" + "Actual padding values are using style.CellPadding.\n\n" + "In this demo we don't show horizontal borders to emphasis how they don't affect default horizontal padding."); + + static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags1, ImGuiTableFlags_PadOuterX); + ImGui::SameLine(); HelpMarker("Enable outer-most padding (default if ImGuiTableFlags_BordersOuterV is set)"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", &flags1, ImGuiTableFlags_NoPadOuterX); + ImGui::SameLine(); HelpMarker("Disable outer-most padding (default if ImGuiTableFlags_BordersOuterV is not set)"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", &flags1, ImGuiTableFlags_NoPadInnerX); + ImGui::SameLine(); HelpMarker("Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off)"); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags1, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags1, ImGuiTableFlags_BordersInnerV); + static bool show_headers = false; + ImGui::Checkbox("show_headers", &show_headers); + PopStyleCompact(); + + if (ImGui::BeginTable("table_padding", 3, flags1)) + { + if (show_headers) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + { + ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x); + } + else + { + char buf[32]; + sprintf(buf, "Hello %d,%d", column, row); + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + //if (ImGui::TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) + // ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, IM_COL32(0, 100, 0, 255)); + } + } + ImGui::EndTable(); + } + + // Second example: set style.CellPadding to (0.0) or a custom value. + // FIXME-TABLE: Vertical border effectively not displayed the same way as horizontal one... + HelpMarker("Setting style.CellPadding to (0,0) or a custom value."); + static ImGuiTableFlags flags2 = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + static ImVec2 cell_padding(0.0f, 0.0f); + static bool show_widget_frame_bg = true; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags2, ImGuiTableFlags_Borders); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags2, ImGuiTableFlags_BordersH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags2, ImGuiTableFlags_BordersV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInner", &flags2, ImGuiTableFlags_BordersInner); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuter", &flags2, ImGuiTableFlags_BordersOuter); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags2, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags2, ImGuiTableFlags_Resizable); + ImGui::Checkbox("show_widget_frame_bg", &show_widget_frame_bg); + ImGui::SliderFloat2("CellPadding", &cell_padding.x, 0.0f, 10.0f, "%.0f"); + PopStyleCompact(); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cell_padding); + if (ImGui::BeginTable("table_padding_2", 3, flags2)) + { + static char text_bufs[3 * 5][16]; // Mini text storage for 3x5 cells + static bool init = true; + if (!show_widget_frame_bg) + ImGui::PushStyleColor(ImGuiCol_FrameBg, 0); + for (int cell = 0; cell < 3 * 5; cell++) + { + ImGui::TableNextColumn(); + if (init) + strcpy(text_bufs[cell], "edit me"); + ImGui::SetNextItemWidth(-FLT_MIN); + ImGui::PushID(cell); + ImGui::InputText("##cell", text_bufs[cell], IM_ARRAYSIZE(text_bufs[cell])); + ImGui::PopID(); + } + if (!show_widget_frame_bg) + ImGui::PopStyleColor(); + init = false; + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Explicit widths"); + if (ImGui::TreeNode("Sizing policies")) + { + static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags1, ImGuiTableFlags_NoHostExtendX); + PopStyleCompact(); + + static ImGuiTableFlags sizing_policy_flags[4] = { ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingFixedSame, ImGuiTableFlags_SizingStretchProp, ImGuiTableFlags_SizingStretchSame }; + for (int table_n = 0; table_n < 4; table_n++) + { + ImGui::PushID(table_n); + ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 30); + EditTableSizingFlags(&sizing_policy_flags[table_n]); + + // To make it easier to understand the different sizing policy, + // For each policy: we display one table where the columns have equal contents width, and one where the columns have different contents width. + if (ImGui::BeginTable("table1", 3, sizing_policy_flags[table_n] | flags1)) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + } + ImGui::EndTable(); + } + if (ImGui::BeginTable("table2", 3, sizing_policy_flags[table_n] | flags1)) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); ImGui::Text("AAAA"); + ImGui::TableNextColumn(); ImGui::Text("BBBBBBBB"); + ImGui::TableNextColumn(); ImGui::Text("CCCCCCCCCCCC"); + } + ImGui::EndTable(); + } + ImGui::PopID(); + } + + ImGui::Spacing(); + ImGui::TextUnformatted("Advanced"); + ImGui::SameLine(); + HelpMarker("This section allows you to interact and see the effect of various sizing policies depending on whether Scroll is enabled and the contents of your columns."); + + enum ContentsType { CT_ShowWidth, CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText }; + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable; + static int contents_type = CT_ShowWidth; + static int column_count = 3; + + PushStyleCompact(); + ImGui::PushID("Advanced"); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30); + EditTableSizingFlags(&flags); + ImGui::Combo("Contents", &contents_type, "Show width\0Short Text\0Long Text\0Button\0Fill Button\0InputText\0"); + if (contents_type == CT_FillButton) + { + ImGui::SameLine(); + HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width."); + } + ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths); + ImGui::SameLine(); HelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth."); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip); + ImGui::PopItemWidth(); + ImGui::PopID(); + PopStyleCompact(); + + if (ImGui::BeginTable("table2", column_count, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 7))) + { + for (int cell = 0; cell < 10 * column_count; cell++) + { + ImGui::TableNextColumn(); + int column = ImGui::TableGetColumnIndex(); + int row = ImGui::TableGetRowIndex(); + + ImGui::PushID(cell); + char label[32]; + static char text_buf[32] = ""; + sprintf(label, "Hello %d,%d", column, row); + switch (contents_type) + { + case CT_ShortText: ImGui::TextUnformatted(label); break; + case CT_LongText: ImGui::Text("Some %s text %d,%d\nOver two lines..", column == 0 ? "long" : "longeeer", column, row); break; + case CT_ShowWidth: ImGui::Text("W: %.1f", ImGui::GetContentRegionAvail().x); break; + case CT_Button: ImGui::Button(label); break; + case CT_FillButton: ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); break; + case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText("##", text_buf, IM_ARRAYSIZE(text_buf)); break; + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Vertical scrolling, with clipping"); + if (ImGui::TreeNode("Vertical scrolling, with clipping")) + { + HelpMarker("Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\nWe also demonstrate using ImGuiListClipper to virtualize the submission of many items."); + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + PopStyleCompact(); + + // When using ScrollX or ScrollY we need to specify a size for our table container! + // Otherwise by default the table will fit all available space, like a BeginChild() call. + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8); + if (ImGui::BeginTable("table_scrolly", 3, flags, outer_size)) + { + ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible + ImGui::TableSetupColumn("One", ImGuiTableColumnFlags_None); + ImGui::TableSetupColumn("Two", ImGuiTableColumnFlags_None); + ImGui::TableSetupColumn("Three", ImGuiTableColumnFlags_None); + ImGui::TableHeadersRow(); + + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(1000); + while (clipper.Step()) + { + for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Horizontal scrolling"); + if (ImGui::TreeNode("Horizontal scrolling")) + { + HelpMarker( + "When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingFixedFit, " + "as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n" + "Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX," + "because the container window won't automatically extend vertically to fix contents (this may be improved in future versions)."); + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + static int freeze_cols = 1; + static int freeze_rows = 1; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_cols", &freeze_cols, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_rows", &freeze_rows, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + PopStyleCompact(); + + // When using ScrollX or ScrollY we need to specify a size for our table container! + // Otherwise by default the table will fit all available space, like a BeginChild() call. + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8); + if (ImGui::BeginTable("table_scrollx", 7, flags, outer_size)) + { + ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows); + ImGui::TableSetupColumn("Line #", ImGuiTableColumnFlags_NoHide); // Make the first column not hideable to match our use of TableSetupScrollFreeze() + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableSetupColumn("Four"); + ImGui::TableSetupColumn("Five"); + ImGui::TableSetupColumn("Six"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 20; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 7; column++) + { + // Both TableNextColumn() and TableSetColumnIndex() return true when a column is visible or performing width measurement. + // Because here we know that: + // - A) all our columns are contributing the same to row height + // - B) column 0 is always visible, + // We only always submit this one column and can skip others. + // More advanced per-column clipping behaviors may benefit from polling the status flags via TableGetColumnFlags(). + if (!ImGui::TableSetColumnIndex(column) && column > 0) + continue; + if (column == 0) + ImGui::Text("Line %d", row); + else + ImGui::Text("Hello world %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + ImGui::Spacing(); + ImGui::TextUnformatted("Stretch + ScrollX"); + ImGui::SameLine(); + HelpMarker( + "Showcase using Stretch columns + ScrollX together: " + "this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n" + "Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense."); + static ImGuiTableFlags flags2 = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody; + static float inner_width = 1000.0f; + PushStyleCompact(); + ImGui::PushID("flags3"); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags2, ImGuiTableFlags_ScrollX); + ImGui::DragFloat("inner_width", &inner_width, 1.0f, 0.0f, FLT_MAX, "%.1f"); + ImGui::PopItemWidth(); + ImGui::PopID(); + PopStyleCompact(); + if (ImGui::BeginTable("table2", 7, flags2, outer_size, inner_width)) + { + for (int cell = 0; cell < 20 * 7; cell++) + { + ImGui::TableNextColumn(); + ImGui::Text("Hello world %d,%d", ImGui::TableGetColumnIndex(), ImGui::TableGetRowIndex()); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Columns flags"); + if (ImGui::TreeNode("Columns flags")) + { + // Create a first table just to show all the options/flags we want to make visible in our example! + const int column_count = 3; + const char* column_names[column_count] = { "One", "Two", "Three" }; + static ImGuiTableColumnFlags column_flags[column_count] = { ImGuiTableColumnFlags_DefaultSort, ImGuiTableColumnFlags_None, ImGuiTableColumnFlags_DefaultHide }; + static ImGuiTableColumnFlags column_flags_out[column_count] = { 0, 0, 0 }; // Output from TableGetColumnFlags() + + if (ImGui::BeginTable("table_columns_flags_checkboxes", column_count, ImGuiTableFlags_None)) + { + PushStyleCompact(); + for (int column = 0; column < column_count; column++) + { + ImGui::TableNextColumn(); + ImGui::PushID(column); + ImGui::AlignTextToFramePadding(); // FIXME-TABLE: Workaround for wrong text baseline propagation + ImGui::Text("'%s'", column_names[column]); + ImGui::Spacing(); + ImGui::Text("Input flags:"); + EditTableColumnsFlags(&column_flags[column]); + ImGui::Spacing(); + ImGui::Text("Output flags:"); + ShowTableColumnsStatusFlags(column_flags_out[column]); + ImGui::PopID(); + } + PopStyleCompact(); + ImGui::EndTable(); + } + + // Create the real table we care about for the example! + // We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above, otherwise in + // a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible + resizing the parent window down) + const ImGuiTableFlags flags + = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY + | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV + | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable; + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 9); + if (ImGui::BeginTable("table_columns_flags", column_count, flags, outer_size)) + { + for (int column = 0; column < column_count; column++) + ImGui::TableSetupColumn(column_names[column], column_flags[column]); + ImGui::TableHeadersRow(); + for (int column = 0; column < column_count; column++) + column_flags_out[column] = ImGui::TableGetColumnFlags(column); + float indent_step = (float)((int)TEXT_BASE_WIDTH / 2); + for (int row = 0; row < 8; row++) + { + ImGui::Indent(indent_step); // Add some indentation to demonstrate usage of per-column IndentEnable/IndentDisable flags. + ImGui::TableNextRow(); + for (int column = 0; column < column_count; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %s", (column == 0) ? "Indented" : "Hello", ImGui::TableGetColumnName(column)); + } + } + ImGui::Unindent(indent_step * 8.0f); + + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Columns widths"); + if (ImGui::TreeNode("Columns widths")) + { + HelpMarker("Using TableSetupColumn() to setup default width."); + + static ImGuiTableFlags flags1 = ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBodyUntilResize; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags1, ImGuiTableFlags_NoBordersInBodyUntilResize); + PopStyleCompact(); + if (ImGui::BeginTable("table1", 3, flags1)) + { + // We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. + ImGui::TableSetupColumn("one", ImGuiTableColumnFlags_WidthFixed, 100.0f); // Default to 100.0f + ImGui::TableSetupColumn("two", ImGuiTableColumnFlags_WidthFixed, 200.0f); // Default to 200.0f + ImGui::TableSetupColumn("three", ImGuiTableColumnFlags_WidthFixed); // Default to auto + ImGui::TableHeadersRow(); + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x); + else + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + HelpMarker("Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, fixed columns with set width may still be shrunk down if there's not enough space in the host."); + + static ImGuiTableFlags flags2 = ImGuiTableFlags_None; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags2, ImGuiTableFlags_NoKeepColumnsVisible); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags2, ImGuiTableFlags_BordersInnerV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags2, ImGuiTableFlags_BordersOuterV); + PopStyleCompact(); + if (ImGui::BeginTable("table2", 4, flags2)) + { + // We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 4; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x); + else + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Nested tables"); + if (ImGui::TreeNode("Nested tables")) + { + HelpMarker("This demonstrate embedding a table into another table cell."); + + if (ImGui::BeginTable("table_nested1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("A0"); + ImGui::TableSetupColumn("A1"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + ImGui::Text("A0 Row 0"); + { + float rows_height = TEXT_BASE_HEIGHT * 2; + if (ImGui::BeginTable("table_nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("B0"); + ImGui::TableSetupColumn("B1"); + ImGui::TableHeadersRow(); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height); + ImGui::TableNextColumn(); + ImGui::Text("B0 Row 0"); + ImGui::TableNextColumn(); + ImGui::Text("B1 Row 0"); + ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height); + ImGui::TableNextColumn(); + ImGui::Text("B0 Row 1"); + ImGui::TableNextColumn(); + ImGui::Text("B1 Row 1"); + + ImGui::EndTable(); + } + } + ImGui::TableNextColumn(); ImGui::Text("A1 Row 0"); + ImGui::TableNextColumn(); ImGui::Text("A0 Row 1"); + ImGui::TableNextColumn(); ImGui::Text("A1 Row 1"); + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Row height"); + if (ImGui::TreeNode("Row height")) + { + HelpMarker("You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\nWe cannot honor a _maximum_ row height as that would requires a unique clipping rectangle per row."); + if (ImGui::BeginTable("table_row_height", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerV)) + { + for (int row = 0; row < 10; row++) + { + float min_row_height = (float)(int)(TEXT_BASE_HEIGHT * 0.30f * row); + ImGui::TableNextRow(ImGuiTableRowFlags_None, min_row_height); + ImGui::TableNextColumn(); + ImGui::Text("min_row_height = %.2f", min_row_height); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Outer size"); + if (ImGui::TreeNode("Outer size")) + { + // Showcasing use of ImGuiTableFlags_NoHostExtendX and ImGuiTableFlags_NoHostExtendY + // Important to that note how the two flags have slightly different behaviors! + ImGui::Text("Using NoHostExtendX and NoHostExtendY:"); + PushStyleCompact(); + static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX; + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY); + ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible."); + PopStyleCompact(); + + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f); + if (ImGui::BeginTable("table1", 3, flags, outer_size)) + { + for (int row = 0; row < 10; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::SameLine(); + ImGui::Text("Hello!"); + + ImGui::Spacing(); + + ImGui::Text("Using explicit size:"); + if (ImGui::BeginTable("table2", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f))) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::SameLine(); + if (ImGui::BeginTable("table3", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f))) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(0, TEXT_BASE_HEIGHT * 1.5f); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Background color"); + if (ImGui::TreeNode("Background color")) + { + static ImGuiTableFlags flags = ImGuiTableFlags_RowBg; + static int row_bg_type = 1; + static int row_bg_target = 1; + static int cell_bg_type = 1; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags, ImGuiTableFlags_Borders); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::SameLine(); HelpMarker("ImGuiTableFlags_RowBg automatically sets RowBg0 to alternative colors pulled from the Style."); + ImGui::Combo("row bg type", (int*)&row_bg_type, "None\0Red\0Gradient\0"); + ImGui::Combo("row bg target", (int*)&row_bg_target, "RowBg0\0RowBg1\0"); ImGui::SameLine(); HelpMarker("Target RowBg0 to override the alternating odd/even colors,\nTarget RowBg1 to blend with them."); + ImGui::Combo("cell bg type", (int*)&cell_bg_type, "None\0Blue\0"); ImGui::SameLine(); HelpMarker("We are colorizing cells to B1->C2 here."); + IM_ASSERT(row_bg_type >= 0 && row_bg_type <= 2); + IM_ASSERT(row_bg_target >= 0 && row_bg_target <= 1); + IM_ASSERT(cell_bg_type >= 0 && cell_bg_type <= 1); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 5, flags)) + { + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + + // Demonstrate setting a row background color with 'ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBgX, ...)' + // We use a transparent color so we can see the one behind in case our target is RowBg1 and RowBg0 was already targeted by the ImGuiTableFlags_RowBg flag. + if (row_bg_type != 0) + { + ImU32 row_bg_color = ImGui::GetColorU32(row_bg_type == 1 ? ImVec4(0.7f, 0.3f, 0.3f, 0.65f) : ImVec4(0.2f + row * 0.1f, 0.2f, 0.2f, 0.65f)); // Flat or Gradient? + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0 + row_bg_target, row_bg_color); + } + + // Fill cells + for (int column = 0; column < 5; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%c%c", 'A' + row, '0' + column); + + // Change background of Cells B1->C2 + // Demonstrate setting a cell background color with 'ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ...)' + // (the CellBg color will be blended over the RowBg and ColumnBg colors) + // We can also pass a column number as a third parameter to TableSetBgColor() and do this outside the column loop. + if (row >= 1 && row <= 2 && column >= 1 && column <= 2 && cell_bg_type == 1) + { + ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 0.65f)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color); + } + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Tree view"); + if (ImGui::TreeNode("Tree view")) + { + static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; + + if (ImGui::BeginTable("3ways", 3, flags)) + { + // The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 18.0f); + ImGui::TableHeadersRow(); + + // Simple storage to output a dummy file-system. + struct MyTreeNode + { + const char* Name; + const char* Type; + int Size; + int ChildIdx; + int ChildCount; + static void DisplayNode(const MyTreeNode* node, const MyTreeNode* all_nodes) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + const bool is_folder = (node->ChildCount > 0); + if (is_folder) + { + bool open = ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::TextDisabled("--"); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + if (open) + { + for (int child_n = 0; child_n < node->ChildCount; child_n++) + DisplayNode(&all_nodes[node->ChildIdx + child_n], all_nodes); + ImGui::TreePop(); + } + } + else + { + ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::Text("%d", node->Size); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + } + } + }; + static const MyTreeNode nodes[] = + { + { "Root", "Folder", -1, 1, 3 }, // 0 + { "Music", "Folder", -1, 4, 2 }, // 1 + { "Textures", "Folder", -1, 6, 3 }, // 2 + { "desktop.ini", "System file", 1024, -1,-1 }, // 3 + { "File1_a.wav", "Audio file", 123000, -1,-1 }, // 4 + { "File1_b.wav", "Audio file", 456000, -1,-1 }, // 5 + { "Image001.png", "Image file", 203128, -1,-1 }, // 6 + { "Copy of Image001.png", "Image file", 203256, -1,-1 }, // 7 + { "Copy of Image001 (Final2).png","Image file", 203512, -1,-1 }, // 8 + }; + + MyTreeNode::DisplayNode(&nodes[0], nodes); + + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Item width"); + if (ImGui::TreeNode("Item width")) + { + HelpMarker( + "Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n" + "Note that on auto-resizing non-resizable fixed columns, querying the content width for e.g. right-alignment doesn't make sense."); + if (ImGui::BeginTable("table_item_width", 3, ImGuiTableFlags_Borders)) + { + ImGui::TableSetupColumn("small"); + ImGui::TableSetupColumn("half"); + ImGui::TableSetupColumn("right-align"); + ImGui::TableHeadersRow(); + + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + if (row == 0) + { + // Setup ItemWidth once (instead of setting up every time, which is also possible but less efficient) + ImGui::TableSetColumnIndex(0); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 3.0f); // Small + ImGui::TableSetColumnIndex(1); + ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::TableSetColumnIndex(2); + ImGui::PushItemWidth(-FLT_MIN); // Right-aligned + } + + // Draw our contents + static float dummy_f = 0.0f; + ImGui::PushID(row); + ImGui::TableSetColumnIndex(0); + ImGui::SliderFloat("float0", &dummy_f, 0.0f, 1.0f); + ImGui::TableSetColumnIndex(1); + ImGui::SliderFloat("float1", &dummy_f, 0.0f, 1.0f); + ImGui::TableSetColumnIndex(2); + ImGui::SliderFloat("float2", &dummy_f, 0.0f, 1.0f); + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // Demonstrate using TableHeader() calls instead of TableHeadersRow() + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Custom headers"); + if (ImGui::TreeNode("Custom headers")) + { + const int COLUMNS_COUNT = 3; + if (ImGui::BeginTable("table_custom_headers", COLUMNS_COUNT, ImGuiTableFlags_Borders | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("Apricot"); + ImGui::TableSetupColumn("Banana"); + ImGui::TableSetupColumn("Cherry"); + + // Dummy entire-column selection storage + // FIXME: It would be nice to actually demonstrate full-featured selection using those checkbox. + static bool column_selected[3] = {}; + + // Instead of calling TableHeadersRow() we'll submit custom headers ourselves + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + ImGui::TableSetColumnIndex(column); + const char* column_name = ImGui::TableGetColumnName(column); // Retrieve name passed to TableSetupColumn() + ImGui::PushID(column); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("##checkall", &column_selected[column]); + ImGui::PopStyleVar(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::TableHeader(column_name); + ImGui::PopID(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + char buf[32]; + sprintf(buf, "Cell %d,%d", column, row); + ImGui::TableSetColumnIndex(column); + ImGui::Selectable(buf, column_selected[column]); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // Demonstrate creating custom context menus inside columns, while playing it nice with context menus provided by TableHeadersRow()/TableHeader() + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Context menus"); + if (ImGui::TreeNode("Context menus")) + { + HelpMarker("By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\nUsing ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body."); + static ImGuiTableFlags flags1 = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ContextMenuInBody; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", &flags1, ImGuiTableFlags_ContextMenuInBody); + PopStyleCompact(); + + // Context Menus: first example + // [1.1] Right-click on the TableHeadersRow() line to open the default table context menu. + // [1.2] Right-click in columns also open the default table context menu (if ImGuiTableFlags_ContextMenuInBody is set) + const int COLUMNS_COUNT = 3; + if (ImGui::BeginTable("table_context_menu", COLUMNS_COUNT, flags1)) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + + // [1.1]] Right-click on the TableHeadersRow() line to open the default table context menu. + ImGui::TableHeadersRow(); + + // Submit dummy contents + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + // Context Menus: second example + // [2.1] Right-click on the TableHeadersRow() line to open the default table context menu. + // [2.2] Right-click on the ".." to open a custom popup + // [2.3] Right-click in columns to open another custom popup + HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body)."); + ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders; + if (ImGui::BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2)) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + + // [2.1] Right-click on the TableHeadersRow() line to open the default table context menu. + ImGui::TableHeadersRow(); + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + // Submit dummy contents + ImGui::TableSetColumnIndex(column); + ImGui::Text("Cell %d,%d", column, row); + ImGui::SameLine(); + + // [2.2] Right-click on the ".." to open a custom popup + ImGui::PushID(row * COLUMNS_COUNT + column); + ImGui::SmallButton(".."); + if (ImGui::BeginPopupContextItem()) + { + ImGui::Text("This is the popup for Button(\"..\") in Cell %d,%d", column, row); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::PopID(); + } + } + + // [2.3] Right-click anywhere in columns to open another custom popup + // (instead of testing for !IsAnyItemHovered() we could also call OpenPopup() with ImGuiPopupFlags_NoOpenOverExistingPopup + // to manage popup priority as the popups triggers, here "are we hovering a column" are overlapping) + int hovered_column = -1; + for (int column = 0; column < COLUMNS_COUNT + 1; column++) + { + ImGui::PushID(column); + if (ImGui::TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered) + hovered_column = column; + if (hovered_column == column && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(1)) + ImGui::OpenPopup("MyPopup"); + if (ImGui::BeginPopup("MyPopup")) + { + if (column == COLUMNS_COUNT) + ImGui::Text("This is a custom popup for unused space after the last column."); + else + ImGui::Text("This is a custom popup for Column %d", column); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::PopID(); + } + + ImGui::EndTable(); + ImGui::Text("Hovered column: %d", hovered_column); + } + ImGui::TreePop(); + } + + // Demonstrate creating multiple tables with the same ID + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Synced instances"); + if (ImGui::TreeNode("Synced instances")) + { + HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc."); + for (int n = 0; n < 3; n++) + { + char buf[32]; + sprintf(buf, "Synced Table %d", n); + bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen); + if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings)) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + for (int cell = 0; cell < 9; cell++) + { + ImGui::TableNextColumn(); + ImGui::Text("this cell %d", cell); + } + ImGui::EndTable(); + } + } + ImGui::TreePop(); + } + + // Demonstrate using Sorting facilities + // This is a simplified version of the "Advanced" example, where we mostly focus on the code necessary to handle sorting. + // Note that the "Advanced" example also showcase manually triggering a sort (e.g. if item quantities have been modified) + static const char* template_items_names[] = + { + "Banana", "Apple", "Cherry", "Watermelon", "Grapefruit", "Strawberry", "Mango", + "Kiwi", "Orange", "Pineapple", "Blueberry", "Plum", "Coconut", "Pear", "Apricot" + }; + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Sorting"); + if (ImGui::TreeNode("Sorting")) + { + // Create item list + static ImVector items; + if (items.Size == 0) + { + items.resize(50, MyItem()); + for (int n = 0; n < items.Size; n++) + { + const int template_n = n % IM_ARRAYSIZE(template_items_names); + MyItem& item = items[n]; + item.ID = n; + item.Name = template_items_names[template_n]; + item.Quantity = (n * n - n) % 20; // Assign default quantities + } + } + + // Options + static ImGuiTableFlags flags = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti + | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody + | ImGuiTableFlags_ScrollY; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_SortMulti", &flags, ImGuiTableFlags_SortMulti); + ImGui::SameLine(); HelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1)."); + ImGui::CheckboxFlags("ImGuiTableFlags_SortTristate", &flags, ImGuiTableFlags_SortTristate); + ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0)."); + PopStyleCompact(); + + if (ImGui::BeginTable("table_sorting", 4, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 15), 0.0f)) + { + // Declare columns + // We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications. + // This is so our sort function can identify a column given our own identifier. We could also identify them based on their index! + // Demonstrate using a mixture of flags among available sort-related flags: + // - ImGuiTableColumnFlags_DefaultSort + // - ImGuiTableColumnFlags_NoSort / ImGuiTableColumnFlags_NoSortAscending / ImGuiTableColumnFlags_NoSortDescending + // - ImGuiTableColumnFlags_PreferSortAscending / ImGuiTableColumnFlags_PreferSortDescending + ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_ID); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name); + ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action); + ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Quantity); + ImGui::TableSetupScrollFreeze(0, 1); // Make row always visible + ImGui::TableHeadersRow(); + + // Sort our data if sort specs have been changed! + if (ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs()) + if (sorts_specs->SpecsDirty) + { + MyItem::s_current_sort_specs = sorts_specs; // Store in variable accessible by the sort function. + if (items.Size > 1) + qsort(&items[0], (size_t)items.Size, sizeof(items[0]), MyItem::CompareWithSortSpecs); + MyItem::s_current_sort_specs = NULL; + sorts_specs->SpecsDirty = false; + } + + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(items.Size); + while (clipper.Step()) + for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++) + { + // Display a data item + MyItem* item = &items[row_n]; + ImGui::PushID(item->ID); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%04d", item->ID); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(item->Name); + ImGui::TableNextColumn(); + ImGui::SmallButton("None"); + ImGui::TableNextColumn(); + ImGui::Text("%d", item->Quantity); + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // In this example we'll expose most table flags and settings. + // For specific flags and settings refer to the corresponding section for more detailed explanation. + // This section is mostly useful to experiment with combining certain flags or settings with each others. + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG] + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Advanced"); + if (ImGui::TreeNode("Advanced")) + { + static ImGuiTableFlags flags = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable + | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti + | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody + | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY + | ImGuiTableFlags_SizingFixedFit; + + enum ContentsType { CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow }; + static int contents_type = CT_SelectableSpanRow; + const char* contents_type_names[] = { "Text", "Button", "SmallButton", "FillButton", "Selectable", "Selectable (span row)" }; + static int freeze_cols = 1; + static int freeze_rows = 1; + static int items_count = IM_ARRAYSIZE(template_items_names) * 2; + static ImVec2 outer_size_value = ImVec2(0.0f, TEXT_BASE_HEIGHT * 12); + static float row_min_height = 0.0f; // Auto + static float inner_width_with_scroll = 0.0f; // Auto-extend + static bool outer_size_enabled = true; + static bool show_headers = true; + static bool show_wrapped_text = false; + //static ImGuiTextFilter filter; + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // FIXME-TABLE: Enabling this results in initial clipped first pass on table which tend to affects column sizing + if (ImGui::TreeNode("Options")) + { + // Make the UI compact because there are so many fields + PushStyleCompact(); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 28.0f); + + if (ImGui::TreeNodeEx("Features:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_Reorderable", &flags, ImGuiTableFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTableFlags_Hideable", &flags, ImGuiTableFlags_Hideable); + ImGui::CheckboxFlags("ImGuiTableFlags_Sortable", &flags, ImGuiTableFlags_Sortable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoSavedSettings", &flags, ImGuiTableFlags_NoSavedSettings); + ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", &flags, ImGuiTableFlags_ContextMenuInBody); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Decorations:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags, ImGuiTableFlags_BordersH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appears in Headers"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers)"); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Sizing:", ImGuiTreeNodeFlags_DefaultOpen)) + { + EditTableSizingFlags(&flags); + ImGui::SameLine(); HelpMarker("In the Advanced demo we override the policy of each column so those table-wide settings have less effect that typical."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY); + ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible); + ImGui::SameLine(); HelpMarker("Only available if ScrollX is disabled."); + ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths); + ImGui::SameLine(); HelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip); + ImGui::SameLine(); HelpMarker("Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with ScrollFreeze options."); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Padding:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags, ImGuiTableFlags_PadOuterX); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", &flags, ImGuiTableFlags_NoPadOuterX); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", &flags, ImGuiTableFlags_NoPadInnerX); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Scrolling:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_cols", &freeze_cols, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_rows", &freeze_rows, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Sorting:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_SortMulti", &flags, ImGuiTableFlags_SortMulti); + ImGui::SameLine(); HelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1)."); + ImGui::CheckboxFlags("ImGuiTableFlags_SortTristate", &flags, ImGuiTableFlags_SortTristate); + ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0)."); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Other:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::Checkbox("show_headers", &show_headers); + ImGui::Checkbox("show_wrapped_text", &show_wrapped_text); + + ImGui::DragFloat2("##OuterSize", &outer_size_value.x); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Checkbox("outer_size", &outer_size_enabled); + ImGui::SameLine(); + HelpMarker("If scrolling is disabled (ScrollX and ScrollY not set):\n" + "- The table is output directly in the parent window.\n" + "- OuterSize.x < 0.0f will right-align the table.\n" + "- OuterSize.x = 0.0f will narrow fit the table unless there are any Stretch column.\n" + "- OuterSize.y then becomes the minimum size for the table, which will extend vertically if there are more rows (unless NoHostExtendY is set)."); + + // From a user point of view we will tend to use 'inner_width' differently depending on whether our table is embedding scrolling. + // To facilitate toying with this demo we will actually pass 0.0f to the BeginTable() when ScrollX is disabled. + ImGui::DragFloat("inner_width (when ScrollX active)", &inner_width_with_scroll, 1.0f, 0.0f, FLT_MAX); + + ImGui::DragFloat("row_min_height", &row_min_height, 1.0f, 0.0f, FLT_MAX); + ImGui::SameLine(); HelpMarker("Specify height of the Selectable item."); + + ImGui::DragInt("items_count", &items_count, 0.1f, 0, 9999); + ImGui::Combo("items_type (first column)", &contents_type, contents_type_names, IM_ARRAYSIZE(contents_type_names)); + //filter.Draw("filter"); + ImGui::TreePop(); + } + + ImGui::PopItemWidth(); + PopStyleCompact(); + ImGui::Spacing(); + ImGui::TreePop(); + } + + // Update item list if we changed the number of items + static ImVector items; + static ImVector selection; + static bool items_need_sort = false; + if (items.Size != items_count) + { + items.resize(items_count, MyItem()); + for (int n = 0; n < items_count; n++) + { + const int template_n = n % IM_ARRAYSIZE(template_items_names); + MyItem& item = items[n]; + item.ID = n; + item.Name = template_items_names[template_n]; + item.Quantity = (template_n == 3) ? 10 : (template_n == 4) ? 20 : 0; // Assign default quantities + } + } + + const ImDrawList* parent_draw_list = ImGui::GetWindowDrawList(); + const int parent_draw_list_draw_cmd_count = parent_draw_list->CmdBuffer.Size; + ImVec2 table_scroll_cur, table_scroll_max; // For debug display + const ImDrawList* table_draw_list = NULL; // " + + // Submit table + const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f; + if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use)) + { + // Declare columns + // We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications. + // This is so our sort function can identify a column given our own identifier. We could also identify them based on their index! + ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, 0.0f, MyItemColumnID_ID); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name); + ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action); + ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity); + ImGui::TableSetupColumn("Description", (flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description); + ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort); + ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows); + + // Sort our data if sort specs have been changed! + ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs(); + if (sorts_specs && sorts_specs->SpecsDirty) + items_need_sort = true; + if (sorts_specs && items_need_sort && items.Size > 1) + { + MyItem::s_current_sort_specs = sorts_specs; // Store in variable accessible by the sort function. + qsort(&items[0], (size_t)items.Size, sizeof(items[0]), MyItem::CompareWithSortSpecs); + MyItem::s_current_sort_specs = NULL; + sorts_specs->SpecsDirty = false; + } + items_need_sort = false; + + // Take note of whether we are currently sorting based on the Quantity field, + // we will use this to trigger sorting when we know the data of this column has been modified. + const bool sorts_specs_using_quantity = (ImGui::TableGetColumnFlags(3) & ImGuiTableColumnFlags_IsSorted) != 0; + + // Show headers + if (show_headers) + ImGui::TableHeadersRow(); + + // Show data + // FIXME-TABLE FIXME-NAV: How we can get decent up/down even though we have the buttons here? + ImGui::PushButtonRepeat(true); +#if 1 + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(items.Size); + while (clipper.Step()) + { + for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++) +#else + // Without clipper + { + for (int row_n = 0; row_n < items.Size; row_n++) +#endif + { + MyItem* item = &items[row_n]; + //if (!filter.PassFilter(item->Name)) + // continue; + + const bool item_is_selected = selection.contains(item->ID); + ImGui::PushID(item->ID); + ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height); + + // For the demo purpose we can select among different type of items submitted in the first column + ImGui::TableSetColumnIndex(0); + char label[32]; + sprintf(label, "%04d", item->ID); + if (contents_type == CT_Text) + ImGui::TextUnformatted(label); + else if (contents_type == CT_Button) + ImGui::Button(label); + else if (contents_type == CT_SmallButton) + ImGui::SmallButton(label); + else if (contents_type == CT_FillButton) + ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); + else if (contents_type == CT_Selectable || contents_type == CT_SelectableSpanRow) + { + ImGuiSelectableFlags selectable_flags = (contents_type == CT_SelectableSpanRow) ? ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap : ImGuiSelectableFlags_None; + if (ImGui::Selectable(label, item_is_selected, selectable_flags, ImVec2(0, row_min_height))) + { + if (ImGui::GetIO().KeyCtrl) + { + if (item_is_selected) + selection.find_erase_unsorted(item->ID); + else + selection.push_back(item->ID); + } + else + { + selection.clear(); + selection.push_back(item->ID); + } + } + } + + if (ImGui::TableSetColumnIndex(1)) + ImGui::TextUnformatted(item->Name); + + // Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity, + // and we are currently sorting on the column showing the Quantity. + // To avoid triggering a sort while holding the button, we only trigger it when the button has been released. + // You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes. + if (ImGui::TableSetColumnIndex(2)) + { + if (ImGui::SmallButton("Chop")) { item->Quantity += 1; } + if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } + ImGui::SameLine(); + if (ImGui::SmallButton("Eat")) { item->Quantity -= 1; } + if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } + } + + if (ImGui::TableSetColumnIndex(3)) + ImGui::Text("%d", item->Quantity); + + ImGui::TableSetColumnIndex(4); + if (show_wrapped_text) + ImGui::TextWrapped("Lorem ipsum dolor sit amet"); + else + ImGui::Text("Lorem ipsum dolor sit amet"); + + if (ImGui::TableSetColumnIndex(5)) + ImGui::Text("1234"); + + ImGui::PopID(); + } + } + ImGui::PopButtonRepeat(); + + // Store some info to display debug details below + table_scroll_cur = ImVec2(ImGui::GetScrollX(), ImGui::GetScrollY()); + table_scroll_max = ImVec2(ImGui::GetScrollMaxX(), ImGui::GetScrollMaxY()); + table_draw_list = ImGui::GetWindowDrawList(); + ImGui::EndTable(); + } + static bool show_debug_details = false; + ImGui::Checkbox("Debug details", &show_debug_details); + if (show_debug_details && table_draw_list) + { + ImGui::SameLine(0.0f, 0.0f); + const int table_draw_list_draw_cmd_count = table_draw_list->CmdBuffer.Size; + if (table_draw_list == parent_draw_list) + ImGui::Text(": DrawCmd: +%d (in same window)", + table_draw_list_draw_cmd_count - parent_draw_list_draw_cmd_count); + else + ImGui::Text(": DrawCmd: +%d (in child window), Scroll: (%.f/%.f) (%.f/%.f)", + table_draw_list_draw_cmd_count - 1, table_scroll_cur.x, table_scroll_max.x, table_scroll_cur.y, table_scroll_max.y); + } + ImGui::TreePop(); + } + + ImGui::PopID(); + + ShowDemoWindowColumns(); + + if (disable_indent) + ImGui::PopStyleVar(); +} + +// Demonstrate old/legacy Columns API! +// [2020: Columns are under-featured and not maintained. Prefer using the more flexible and powerful BeginTable() API!] +static void ShowDemoWindowColumns() +{ + IMGUI_DEMO_MARKER("Columns (legacy API)"); + bool open = ImGui::TreeNode("Legacy Columns API"); + ImGui::SameLine(); + HelpMarker("Columns() is an old API! Prefer using the more flexible and powerful BeginTable() API!"); + if (!open) + return; + + // Basic columns + IMGUI_DEMO_MARKER("Columns (legacy API)/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGui::Text("Without border:"); + ImGui::Columns(3, "mycolumns3", false); // 3-ways, no border + ImGui::Separator(); + for (int n = 0; n < 14; n++) + { + char label[32]; + sprintf(label, "Item %d", n); + if (ImGui::Selectable(label)) {} + //if (ImGui::Button(label, ImVec2(-FLT_MIN,0.0f))) {} + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + ImGui::Text("With border:"); + ImGui::Columns(4, "mycolumns"); // 4-ways, with border + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Hovered"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + bool hovered = ImGui::IsItemHovered(); + ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("%d", hovered); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Borders"); + if (ImGui::TreeNode("Borders")) + { + // NB: Future columns API should allow automatic horizontal borders. + static bool h_borders = true; + static bool v_borders = true; + static int columns_count = 4; + const int lines_count = 3; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragInt("##columns_count", &columns_count, 0.1f, 2, 10, "%d columns"); + if (columns_count < 2) + columns_count = 2; + ImGui::SameLine(); + ImGui::Checkbox("horizontal", &h_borders); + ImGui::SameLine(); + ImGui::Checkbox("vertical", &v_borders); + ImGui::Columns(columns_count, NULL, v_borders); + for (int i = 0; i < columns_count * lines_count; i++) + { + if (h_borders && ImGui::GetColumnIndex() == 0) + ImGui::Separator(); + ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i); + ImGui::Text("Width %.2f", ImGui::GetColumnWidth()); + ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x); + ImGui::Text("Offset %.2f", ImGui::GetColumnOffset()); + ImGui::Text("Long text that is likely to clip"); + ImGui::Button("Button", ImVec2(-FLT_MIN, 0.0f)); + ImGui::NextColumn(); + } + ImGui::Columns(1); + if (h_borders) + ImGui::Separator(); + ImGui::TreePop(); + } + + // Create multiple items in a same cell before switching to next column + IMGUI_DEMO_MARKER("Columns (legacy API)/Mixed items"); + if (ImGui::TreeNode("Mixed items")) + { + ImGui::Columns(3, "mixed"); + ImGui::Separator(); + + ImGui::Text("Hello"); + ImGui::Button("Banana"); + ImGui::NextColumn(); + + ImGui::Text("ImGui"); + ImGui::Button("Apple"); + static float foo = 1.0f; + ImGui::InputFloat("red", &foo, 0.05f, 0, "%.3f"); + ImGui::Text("An extra line here."); + ImGui::NextColumn(); + + ImGui::Text("Sailor"); + ImGui::Button("Corniflower"); + static float bar = 1.0f; + ImGui::InputFloat("blue", &bar, 0.05f, 0, "%.3f"); + 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::TreePop(); + } + + // Word wrapping + IMGUI_DEMO_MARKER("Columns (legacy API)/Word-wrapping"); + if (ImGui::TreeNode("Word-wrapping")) + { + ImGui::Columns(2, "word-wrapping"); + ImGui::Separator(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Left"); + ImGui::NextColumn(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Right"); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Horizontal Scrolling"); + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f)); + ImVec2 child_size = ImVec2(0, ImGui::GetFontSize() * 20.0f); + ImGui::BeginChild("##ScrollingRegion", child_size, false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::Columns(10); + + // Also demonstrate using clipper for large vertical lists + int ITEMS_COUNT = 2000; + ImGuiListClipper clipper; + clipper.Begin(ITEMS_COUNT); + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + for (int j = 0; j < 10; j++) + { + ImGui::Text("Line %d Column %d...", i, j); + ImGui::NextColumn(); + } + } + ImGui::Columns(1); + ImGui::EndChild(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Tree"); + if (ImGui::TreeNode("Tree")) + { + ImGui::Columns(2, "tree", true); + for (int x = 0; x < 3; x++) + { + bool open1 = ImGui::TreeNode((void*)(intptr_t)x, "Node%d", x); + ImGui::NextColumn(); + ImGui::Text("Node contents"); + ImGui::NextColumn(); + if (open1) + { + for (int y = 0; y < 3; y++) + { + bool open2 = ImGui::TreeNode((void*)(intptr_t)y, "Node%d.%d", x, y); + ImGui::NextColumn(); + ImGui::Text("Node contents"); + if (open2) + { + ImGui::Text("Even more contents"); + if (ImGui::TreeNode("Tree in column")) + { + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::TreePop(); + } + } + ImGui::NextColumn(); + if (open2) + ImGui::TreePop(); + } + ImGui::TreePop(); + } + } + ImGui::Columns(1); + ImGui::TreePop(); + } + + ImGui::TreePop(); +} + +namespace ImGui { extern ImGuiKeyData* GetKeyData(ImGuiKey key); } + +static void ShowDemoWindowMisc() +{ + IMGUI_DEMO_MARKER("Filtering"); + if (ImGui::CollapsingHeader("Filtering")) + { + // Helper class to easy setup a text filter. + // You may want to implement a more feature-full filtering scheme in your own application. + 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 (int i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + } + + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus"); + if (ImGui::CollapsingHeader("Inputs, Navigation & Focus")) + { + ImGuiIO& io = ImGui::GetIO(); + + // Display ImGuiIO output flags + ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); + ImGui::Text("WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose); + ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); + ImGui::Text("WantTextInput: %d", io.WantTextInput); + ImGui::Text("WantSetMousePos: %d", io.WantSetMousePos); + ImGui::Text("NavActive: %d, NavVisible: %d", io.NavActive, io.NavVisible); + + // Display Mouse state + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Mouse State"); + if (ImGui::TreeNode("Mouse State")) + { + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse pos: "); + ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y); + + int count = IM_ARRAYSIZE(io.MouseDown); + ImGui::Text("Mouse down:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } + ImGui::Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d (%d)", i, ImGui::GetMouseClickedCount(i)); } + ImGui::Text("Mouse released:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); + ImGui::Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused + ImGui::TreePop(); + } + + // Display Keyboard/Mouse state + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Keyboard, Gamepad & Navigation State"); + if (ImGui::TreeNode("Keyboard, Gamepad & Navigation State")) + { + // We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allow displaying the data for old/new backends. + // User code should never have to go through such hoops: old code may use native keycodes, new code may use ImGuiKey codes. +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } }; + const ImGuiKey key_first = ImGuiKey_NamedKey_BEGIN; +#else + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array + const ImGuiKey key_first = 0; +#endif + ImGui::Text("Keys down:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyDown(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d (%.02f secs)", ImGui::GetKeyName(key), key, ImGui::GetKeyData(key)->DownDuration); } } + ImGui::Text("Keys pressed:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyPressed(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } } + ImGui::Text("Keys released:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyReleased(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } } + ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public. + ImGui::Text("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f) { ImGui::SameLine(); ImGui::Text("[%d] %.2f (%.02f secs)", i, io.NavInputs[i], io.NavInputsDownDuration[i]); } + ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f) { ImGui::SameLine(); ImGui::Text("[%d]", i); } + + // Draw an arbitrary US keyboard layout to visualize translated keys + { + const ImVec2 key_size = ImVec2(35.0f, 35.0f); + const float key_rounding = 3.0f; + const ImVec2 key_face_size = ImVec2(25.0f, 25.0f); + const ImVec2 key_face_pos = ImVec2(5.0f, 3.0f); + const float key_face_rounding = 2.0f; + const ImVec2 key_label_pos = ImVec2(7.0f, 4.0f); + const ImVec2 key_step = ImVec2(key_size.x - 1.0f, key_size.y - 1.0f); + const float key_row_offset = 9.0f; + + ImVec2 board_min = ImGui::GetCursorScreenPos(); + ImVec2 board_max = ImVec2(board_min.x + 3 * key_step.x + 2 * key_row_offset + 10.0f, board_min.y + 3 * key_step.y + 10.0f); + ImVec2 start_pos = ImVec2(board_min.x + 5.0f - key_step.x, board_min.y); + + struct KeyLayoutData { int Row, Col; const char* Label; ImGuiKey Key; }; + const KeyLayoutData keys_to_display[] = + { + { 0, 0, "", ImGuiKey_Tab }, { 0, 1, "Q", ImGuiKey_Q }, { 0, 2, "W", ImGuiKey_W }, { 0, 3, "E", ImGuiKey_E }, { 0, 4, "R", ImGuiKey_R }, + { 1, 0, "", ImGuiKey_CapsLock }, { 1, 1, "A", ImGuiKey_A }, { 1, 2, "S", ImGuiKey_S }, { 1, 3, "D", ImGuiKey_D }, { 1, 4, "F", ImGuiKey_F }, + { 2, 0, "", ImGuiKey_LeftShift },{ 2, 1, "Z", ImGuiKey_Z }, { 2, 2, "X", ImGuiKey_X }, { 2, 3, "C", ImGuiKey_C }, { 2, 4, "V", ImGuiKey_V } + }; + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->PushClipRect(board_min, board_max, true); + for (int n = 0; n < IM_ARRAYSIZE(keys_to_display); n++) + { + const KeyLayoutData* key_data = &keys_to_display[n]; + ImVec2 key_min = ImVec2(start_pos.x + key_data->Col * key_step.x + key_data->Row * key_row_offset, start_pos.y + key_data->Row * key_step.y); + ImVec2 key_max = ImVec2(key_min.x + key_size.x, key_min.y + key_size.y); + draw_list->AddRectFilled(key_min, key_max, IM_COL32(204, 204, 204, 255), key_rounding); + draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding); + ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y); + ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y); + draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f); + draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding); + ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y); + draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label); + if (ImGui::IsKeyDown(key_data->Key)) + draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding); + } + draw_list->PopClipRect(); + ImGui::Dummy(ImVec2(board_max.x - board_min.x, board_max.y - board_min.y)); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Capture override")) + { + ImGui::Button("Hovering me sets the\nkeyboard capture flag"); + if (ImGui::IsItemHovered()) + ImGui::CaptureKeyboardFromApp(true); + ImGui::SameLine(); + ImGui::Button("Holding me clears the\nthe keyboard capture flag"); + if (ImGui::IsItemActive()) + ImGui::CaptureKeyboardFromApp(false); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Tabbing"); + if (ImGui::TreeNode("Tabbing")) + { + ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); + static char buf[32] = "hello"; + 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(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab."); + ImGui::PopAllowKeyboardFocus(); + ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Focus from code"); + 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::SameLine(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab."); + ImGui::PopAllowKeyboardFocus(); + + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + + // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item + static float f3[3] = { 0.0f, 0.0f, 0.0f }; + int focus_ahead = -1; + if (ImGui::Button("Focus on X")) { focus_ahead = 0; } ImGui::SameLine(); + if (ImGui::Button("Focus on Y")) { focus_ahead = 1; } ImGui::SameLine(); + if (ImGui::Button("Focus on Z")) { focus_ahead = 2; } + if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); + ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); + + ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Dragging"); + if (ImGui::TreeNode("Dragging")) + { + ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); + for (int button = 0; button < 3; button++) + { + ImGui::Text("IsMouseDragging(%d):", button); + ImGui::Text(" w/ default threshold: %d,", ImGui::IsMouseDragging(button)); + ImGui::Text(" w/ zero threshold: %d,", ImGui::IsMouseDragging(button, 0.0f)); + ImGui::Text(" w/ large threshold: %d,", ImGui::IsMouseDragging(button, 20.0f)); + } + + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + ImGui::GetForegroundDrawList()->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); // Draw a line between the button and the mouse cursor + + // Drag operations gets "unlocked" when the mouse has moved past a certain threshold + // (the default threshold is stored in io.MouseDragThreshold). You can request a lower or higher + // threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta(). + ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); + ImVec2 mouse_delta = io.MouseDelta; + ImGui::Text("GetMouseDragDelta(0):"); + ImGui::Text(" w/ default threshold: (%.1f, %.1f)", value_with_lock_threshold.x, value_with_lock_threshold.y); + ImGui::Text(" w/ zero threshold: (%.1f, %.1f)", value_raw.x, value_raw.y); + ImGui::Text("io.MouseDelta: (%.1f, %.1f)", mouse_delta.x, mouse_delta.y); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Mouse cursors"); + if (ImGui::TreeNode("Mouse cursors")) + { + const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" }; + IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT); + + ImGuiMouseCursor current = ImGui::GetMouseCursor(); + ImGui::Text("Current mouse cursor = %d: %s", current, mouse_cursors_names[current]); + ImGui::Text("Hover to see mouse cursors:"); + ImGui::SameLine(); HelpMarker( + "Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. " + "If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, " + "otherwise your backend needs to handle it."); + for (int i = 0; i < ImGuiMouseCursor_COUNT; i++) + { + char label[32]; + sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); + ImGui::Bullet(); ImGui::Selectable(label, false); + if (ImGui::IsItemHovered()) + ImGui::SetMouseCursor(i); + } + ImGui::TreePop(); + } + } +} + +//----------------------------------------------------------------------------- +// [SECTION] About Window / ShowAboutWindow() +// Access from Dear ImGui Demo -> Tools -> About +//----------------------------------------------------------------------------- + +void ImGui::ShowAboutWindow(bool* p_open) +{ + if (!ImGui::Begin("About Dear ImGui", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Tools/About Dear ImGui"); + ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); + ImGui::Separator(); + ImGui::Text("By Omar Cornut and all Dear ImGui contributors."); + ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); + + static bool show_config_info = false; + ImGui::Checkbox("Config/Build Information", &show_config_info); + if (show_config_info) + { + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle& style = ImGui::GetStyle(); + + bool copy_to_clipboard = ImGui::Button("Copy to clipboard"); + ImVec2 child_size = ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 18); + ImGui::BeginChildFrame(ImGui::GetID("cfg_infos"), child_size, ImGuiWindowFlags_NoMove); + if (copy_to_clipboard) + { + ImGui::LogToClipboard(); + ImGui::LogText("```\n"); // Back quotes will make text appears without formatting when pasting on GitHub + } + + ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM); + ImGui::Separator(); + ImGui::Text("sizeof(size_t): %d, sizeof(ImDrawIdx): %d, sizeof(ImDrawVert): %d", (int)sizeof(size_t), (int)sizeof(ImDrawIdx), (int)sizeof(ImDrawVert)); + ImGui::Text("define: __cplusplus=%d", (int)__cplusplus); +#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_KEYIO"); +#endif +#ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_WIN32_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_FILE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_FILE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_ALLOCATORS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_ALLOCATORS"); +#endif +#ifdef IMGUI_USE_BGRA_PACKED_COLOR + ImGui::Text("define: IMGUI_USE_BGRA_PACKED_COLOR"); +#endif +#ifdef _WIN32 + ImGui::Text("define: _WIN32"); +#endif +#ifdef _WIN64 + ImGui::Text("define: _WIN64"); +#endif +#ifdef __linux__ + ImGui::Text("define: __linux__"); +#endif +#ifdef __APPLE__ + ImGui::Text("define: __APPLE__"); +#endif +#ifdef _MSC_VER + ImGui::Text("define: _MSC_VER=%d", _MSC_VER); +#endif +#ifdef _MSVC_LANG + ImGui::Text("define: _MSVC_LANG=%d", (int)_MSVC_LANG); +#endif +#ifdef __MINGW32__ + ImGui::Text("define: __MINGW32__"); +#endif +#ifdef __MINGW64__ + ImGui::Text("define: __MINGW64__"); +#endif +#ifdef __GNUC__ + ImGui::Text("define: __GNUC__=%d", (int)__GNUC__); +#endif +#ifdef __clang_version__ + ImGui::Text("define: __clang_version__=%s", __clang_version__); +#endif +#ifdef IMGUI_HAS_VIEWPORT + ImGui::Text("define: IMGUI_HAS_VIEWPORT"); +#endif +#ifdef IMGUI_HAS_DOCK + ImGui::Text("define: IMGUI_HAS_DOCK"); +#endif + ImGui::Separator(); + ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL"); + ImGui::Text("io.BackendRendererName: %s", io.BackendRendererName ? io.BackendRendererName : "NULL"); + ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard"); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad"); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) ImGui::Text(" NavEnableSetMousePos"); + if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard"); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse"); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange"); + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) ImGui::Text(" DockingEnable"); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui::Text(" ViewportsEnable"); + if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) ImGui::Text(" DpiEnableScaleViewports"); + if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ImGui::Text(" DpiEnableScaleFonts"); + if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor"); + if (io.ConfigViewportsNoAutoMerge) ImGui::Text("io.ConfigViewportsNoAutoMerge"); + if (io.ConfigViewportsNoTaskBarIcon) ImGui::Text("io.ConfigViewportsNoTaskBarIcon"); + if (io.ConfigViewportsNoDecoration) ImGui::Text("io.ConfigViewportsNoDecoration"); + if (io.ConfigViewportsNoDefaultParent) ImGui::Text("io.ConfigViewportsNoDefaultParent"); + if (io.ConfigDockingNoSplit) ImGui::Text("io.ConfigDockingNoSplit"); + if (io.ConfigDockingWithShift) ImGui::Text("io.ConfigDockingWithShift"); + if (io.ConfigDockingAlwaysTabBar) ImGui::Text("io.ConfigDockingAlwaysTabBar"); + if (io.ConfigDockingTransparentPayload) ImGui::Text("io.ConfigDockingTransparentPayload"); + if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors"); + if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink"); + if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges"); + if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly"); + if (io.ConfigMemoryCompactTimer >= 0.0f) ImGui::Text("io.ConfigMemoryCompactTimer = %.1f", io.ConfigMemoryCompactTimer); + ImGui::Text("io.BackendFlags: 0x%08X", io.BackendFlags); + if (io.BackendFlags & ImGuiBackendFlags_HasGamepad) ImGui::Text(" HasGamepad"); + if (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) ImGui::Text(" HasMouseCursors"); + if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos"); + if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) ImGui::Text(" PlatformHasViewports"); + if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)ImGui::Text(" HasMouseHoveredViewport"); + if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset"); + if (io.BackendFlags & ImGuiBackendFlags_RendererHasViewports) ImGui::Text(" RendererHasViewports"); + ImGui::Separator(); + ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexWidth, io.Fonts->TexHeight); + ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y); + ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + ImGui::Separator(); + ImGui::Text("style.WindowPadding: %.2f,%.2f", style.WindowPadding.x, style.WindowPadding.y); + ImGui::Text("style.WindowBorderSize: %.2f", style.WindowBorderSize); + ImGui::Text("style.FramePadding: %.2f,%.2f", style.FramePadding.x, style.FramePadding.y); + ImGui::Text("style.FrameRounding: %.2f", style.FrameRounding); + ImGui::Text("style.FrameBorderSize: %.2f", style.FrameBorderSize); + ImGui::Text("style.ItemSpacing: %.2f,%.2f", style.ItemSpacing.x, style.ItemSpacing.y); + ImGui::Text("style.ItemInnerSpacing: %.2f,%.2f", style.ItemInnerSpacing.x, style.ItemInnerSpacing.y); + + if (copy_to_clipboard) + { + ImGui::LogText("\n```\n"); + ImGui::LogFinish(); + } + ImGui::EndChildFrame(); + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Style Editor / ShowStyleEditor() +//----------------------------------------------------------------------------- +// - ShowFontSelector() +// - ShowStyleSelector() +// - ShowStyleEditor() +//----------------------------------------------------------------------------- + +// Forward declare ShowFontAtlas() which isn't worth putting in public API yet +namespace ImGui { IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); } + +// Demo helper function to select among loaded fonts. +// Here we use the regular BeginCombo()/EndCombo() api which is the more flexible one. +void ImGui::ShowFontSelector(const char* label) +{ + ImGuiIO& io = ImGui::GetIO(); + ImFont* font_current = ImGui::GetFont(); + if (ImGui::BeginCombo(label, font_current->GetDebugName())) + { + for (int n = 0; n < io.Fonts->Fonts.Size; n++) + { + ImFont* font = io.Fonts->Fonts[n]; + ImGui::PushID((void*)font); + if (ImGui::Selectable(font->GetDebugName(), font == font_current)) + io.FontDefault = font; + ImGui::PopID(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + HelpMarker( + "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" + "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" + "- Read FAQ and docs/FONTS.md for more details.\n" + "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); +} + +// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options. +// Here we use the simplified Combo() api that packs items into a single literal string. +// Useful for quick combo boxes where the choices are known locally. +bool ImGui::ShowStyleSelector(const char* label) +{ + static int style_idx = -1; + if (ImGui::Combo(label, &style_idx, "Dark\0Light\0Classic\0")) + { + switch (style_idx) + { + case 0: ImGui::StyleColorsDark(); break; + case 1: ImGui::StyleColorsLight(); break; + case 2: ImGui::StyleColorsClassic(); break; + } + return true; + } + return false; +} + +void ImGui::ShowStyleEditor(ImGuiStyle* ref) +{ + IMGUI_DEMO_MARKER("Tools/Style Editor"); + // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to + // (without a reference style pointer, we will use one compared locally as a reference) + ImGuiStyle& style = ImGui::GetStyle(); + static ImGuiStyle ref_saved_style; + + // Default to using internal storage as reference + static bool init = true; + if (init && ref == NULL) + ref_saved_style = style; + init = false; + if (ref == NULL) + ref = &ref_saved_style; + + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); + + if (ImGui::ShowStyleSelector("Colors##Selector")) + ref_saved_style = style; + ImGui::ShowFontSelector("Fonts##Selector"); + + // Simplified Settings (expose floating-pointer border sizes as boolean representing 0.0f or 1.0f) + if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) + style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding + { bool border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &border)) { style.WindowBorderSize = border ? 1.0f : 0.0f; } } + ImGui::SameLine(); + { bool border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &border)) { style.FrameBorderSize = border ? 1.0f : 0.0f; } } + ImGui::SameLine(); + { bool border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &border)) { style.PopupBorderSize = border ? 1.0f : 0.0f; } } + + // Save/Revert button + if (ImGui::Button("Save Ref")) + *ref = ref_saved_style = style; + ImGui::SameLine(); + if (ImGui::Button("Revert Ref")) + style = *ref; + ImGui::SameLine(); + HelpMarker( + "Save/Revert in local non-persistent storage. Default Colors definition are not affected. " + "Use \"Export\" below to save them somewhere."); + + ImGui::Separator(); + + if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Sizes")) + { + ImGui::Text("Main"); + ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.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, 30.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); + ImGui::Text("Borders"); + ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::Text("Rounding"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f"); + ImGui::Text("Alignment"); + ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); + int window_menu_button_position = style.WindowMenuButtonPosition + 1; + if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0")) + style.WindowMenuButtonPosition = window_menu_button_position - 1; + ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0"); + ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); + ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content."); + ImGui::Text("Safe Area Padding"); + ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); + ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Colors")) + { + static int output_dest = 0; + static bool output_only_modified = true; + if (ImGui::Button("Export")) + { + if (output_dest == 0) + ImGui::LogToClipboard(); + else + ImGui::LogToTTY(); + ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const ImVec4& col = style.Colors[i]; + const char* name = ImGui::GetStyleColorName(i); + if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) + ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, + name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + } + ImGui::LogFinish(); + } + ImGui::SameLine(); ImGui::SetNextItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); + ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified); + + static ImGuiTextFilter filter; + filter.Draw("Filter colors", ImGui::GetFontSize() * 16); + + static ImGuiColorEditFlags alpha_flags = 0; + if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine(); + if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine(); + if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine(); + HelpMarker( + "In the color list:\n" + "Left-click on color square to open color picker,\n" + "Right-click to open edit options menu."); + + ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); + ImGui::PushItemWidth(-160); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName(i); + if (!filter.PassFilter(name)) + continue; + ImGui::PushID(i); + ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); + if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) + { + // Tips: in a real user application, you may want to merge and use an icon font into the main font, + // so instead of "Save"/"Revert" you'd use icons! + // Read the FAQ and docs/FONTS.md about using icon fonts. It's really easy and super convenient! + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) { ref->Colors[i] = style.Colors[i]; } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) { style.Colors[i] = ref->Colors[i]; } + } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(name); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::EndChild(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Fonts")) + { + ImGuiIO& io = ImGui::GetIO(); + ImFontAtlas* atlas = io.Fonts; + HelpMarker("Read FAQ and docs/FONTS.md for details on font loading."); + ImGui::ShowFontAtlas(atlas); + + // Post-baking font scaling. Note that this is NOT the nice way of scaling fonts, read below. + // (we enforce hard clamping manually as by default DragFloat/SliderFloat allows CTRL+Click text to get out of bounds). + const float MIN_SCALE = 0.3f; + const float MAX_SCALE = 2.0f; + HelpMarker( + "Those are old settings provided for convenience.\n" + "However, the _correct_ way of scaling your UI is currently to reload your font at the designed size, " + "rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.\n" + "Using those settings here will give you poor quality results."); + static float window_scale = 1.0f; + ImGui::PushItemWidth(ImGui::GetFontSize() * 8); + if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp)) // Scale only this window + ImGui::SetWindowFontScale(window_scale); + ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp); // Scale everything + ImGui::PopItemWidth(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Rendering")) + { + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); + ImGui::SameLine(); + HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); + + ImGui::Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex); + ImGui::SameLine(); + HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering)."); + + ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); + ImGui::PushItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); + if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; + + // When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles. + ImGui::DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 5.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); + if (ImGui::IsItemActive()) + { + ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos()); + ImGui::BeginTooltip(); + ImGui::TextUnformatted("(R = radius, N = number of segments)"); + ImGui::Spacing(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x; + for (int n = 0; n < 8; n++) + { + const float RAD_MIN = 5.0f; + const float RAD_MAX = 70.0f; + const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f); + + ImGui::BeginGroup(); + + ImGui::Text("R: %.f\nN: %d", rad, draw_list->_CalcCircleAutoSegmentCount(rad)); + + const float canvas_width = IM_MAX(min_widget_width, rad * 2.0f); + const float offset_x = floorf(canvas_width * 0.5f); + const float offset_y = floorf(RAD_MAX); + + const ImVec2 p1 = ImGui::GetCursorScreenPos(); + draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + + /* + const ImVec2 p2 = ImGui::GetCursorScreenPos(); + draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + */ + + ImGui::EndGroup(); + ImGui::SameLine(); + } + ImGui::EndTooltip(); + } + ImGui::SameLine(); + HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically."); + + ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. + ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha)."); + ImGui::PopItemWidth(); + + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::PopItemWidth(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar() +//----------------------------------------------------------------------------- +// - ShowExampleAppMainMenuBar() +// - ShowExampleMenuFile() +//----------------------------------------------------------------------------- + +// Demonstrate creating a "main" fullscreen menu bar and populating it. +// Note the difference between BeginMainMenuBar() and BeginMenuBar(): +// - BeginMenuBar() = menu-bar inside current window (which needs the ImGuiWindowFlags_MenuBar flag!) +// - BeginMainMenuBar() = helper to create menu-bar-sized window at the top of the main viewport + call BeginMenuBar() into it. +static void ShowExampleAppMainMenuBar() +{ + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Undo", "CTRL+Z")) {} + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "CTRL+X")) {} + if (ImGui::MenuItem("Copy", "CTRL+C")) {} + if (ImGui::MenuItem("Paste", "CTRL+V")) {} + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } +} + +// Note that shortcuts are currently provided for display only +// (future version will add explicit flags to BeginMenu() to request processing shortcuts) +static void ShowExampleMenuFile() +{ + IMGUI_DEMO_MARKER("Examples/Menu"); + ImGui::MenuItem("(demo menu)", NULL, false, false); + if (ImGui::MenuItem("New")) {} + if (ImGui::MenuItem("Open", "Ctrl+O")) {} + if (ImGui::BeginMenu("Open Recent")) + { + ImGui::MenuItem("fish_hat.c"); + ImGui::MenuItem("fish_hat.inl"); + ImGui::MenuItem("fish_hat.h"); + if (ImGui::BeginMenu("More..")) + { + ImGui::MenuItem("Hello"); + ImGui::MenuItem("Sailor"); + if (ImGui::BeginMenu("Recurse..")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Save", "Ctrl+S")) {} + if (ImGui::MenuItem("Save As..")) {} + + ImGui::Separator(); + IMGUI_DEMO_MARKER("Examples/Menu/Options"); + if (ImGui::BeginMenu("Options")) + { + static bool enabled = true; + ImGui::MenuItem("Enabled", "", &enabled); + ImGui::BeginChild("child", ImVec2(0, 60), true); + for (int i = 0; i < 10; i++) + ImGui::Text("Scrolling Text %d", i); + ImGui::EndChild(); + static float f = 0.5f; + static int n = 0; + ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); + ImGui::InputFloat("Input", &f, 0.1f); + ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::EndMenu(); + } + + IMGUI_DEMO_MARKER("Examples/Menu/Colors"); + if (ImGui::BeginMenu("Colors")) + { + float sz = ImGui::GetTextLineHeight(); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName((ImGuiCol)i); + ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + sz, p.y + sz), ImGui::GetColorU32((ImGuiCol)i)); + ImGui::Dummy(ImVec2(sz, sz)); + ImGui::SameLine(); + ImGui::MenuItem(name); + } + ImGui::EndMenu(); + } + + // Here we demonstrate appending again to the "Options" menu (which we already created above) + // Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice. + // In a real code-base using it would make senses to use this feature from very different code locations. + if (ImGui::BeginMenu("Options")) // <-- Append! + { + IMGUI_DEMO_MARKER("Examples/Menu/Append to an existing menu"); + static bool b = true; + ImGui::Checkbox("SomeOption", &b); + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Disabled", false)) // Disabled + { + IM_ASSERT(0); + } + if (ImGui::MenuItem("Checked", NULL, true)) {} + if (ImGui::MenuItem("Quit", "Alt+F4")) {} +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Debug Console / ShowExampleAppConsole() +//----------------------------------------------------------------------------- + +// Demonstrate creating a simple console window, with scrolling, filtering, completion and history. +// For the console example, we are using a more C++ like approach of declaring a class to hold both data and functions. +struct ExampleAppConsole +{ + char InputBuf[256]; + ImVector Items; + ImVector Commands; + ImVector History; + int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. + ImGuiTextFilter Filter; + bool AutoScroll; + bool ScrollToBottom; + + ExampleAppConsole() + { + IMGUI_DEMO_MARKER("Examples/Console"); + ClearLog(); + memset(InputBuf, 0, sizeof(InputBuf)); + HistoryPos = -1; + + // "CLASSIFY" is here to provide the test case where "C"+[tab] completes to "CL" and display multiple matches. + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); + AutoScroll = true; + ScrollToBottom = false; + AddLog("Welcome to Dear ImGui!"); + } + ~ExampleAppConsole() + { + ClearLog(); + for (int i = 0; i < History.Size; i++) + free(History[i]); + } + + // Portable helpers + static int Stricmp(const char* s1, const char* s2) { int d; while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; } return d; } + static int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; n--; } return d; } + static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); } + static void Strtrim(char* s) { char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; } + + void ClearLog() + { + for (int i = 0; i < Items.Size; i++) + free(Items[i]); + Items.clear(); + } + + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + // FIXME-OPT + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf)-1] = 0; + va_end(args); + Items.push_back(Strdup(buf)); + } + + void Draw(const char* title, bool* p_open) + { + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } + + // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. + // So e.g. IsItemHovered() will return true when hovering the title bar. + // Here we create a context menu only available from the title bar. + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Close Console")) + *p_open = false; + ImGui::EndPopup(); + } + + ImGui::TextWrapped( + "This example implements a console with basic coloring, completion (TAB key) and history (Up/Down keys). A more elaborate " + "implementation may want to store entries along with extra data such as timestamp, emitter, etc."); + ImGui::TextWrapped("Enter 'HELP' for help."); + + // TODO: display items starting from the bottom + + if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } + ImGui::SameLine(); + if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); } + ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) { ClearLog(); } + ImGui::SameLine(); + bool copy_to_clipboard = ImGui::SmallButton("Copy"); + //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } + + ImGui::Separator(); + + // Options menu + if (ImGui::BeginPopup("Options")) + { + ImGui::Checkbox("Auto-scroll", &AutoScroll); + ImGui::EndPopup(); + } + + // Options, Filter + if (ImGui::Button("Options")) + ImGui::OpenPopup("Options"); + ImGui::SameLine(); + Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); + ImGui::Separator(); + + // Reserve enough left-over height for 1 separator + 1 input text + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::Selectable("Clear")) ClearLog(); + ImGui::EndPopup(); + } + + // 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 and may require user-side clipping + // to only process visible items. The clipper will automatically measure the height of your first item and then + // "seek" to display only items in the visible area. + // To use the clipper we can replace your standard loop: + // for (int i = 0; i < Items.Size; i++) + // With: + // ImGuiListClipper clipper; + // clipper.Begin(Items.Size); + // while (clipper.Step()) + // for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + // - That your items are evenly spaced (same height) + // - That you have cheap random access to your elements (you can access them given their index, + // without processing all the ones before) + // You cannot this code as-is if a filter is active because it breaks the 'cheap random-access' property. + // We would need random-access on the post-filtered list. + // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices + // or offsets of items that passed the filtering test, recomputing this array when user changes the filter, + // and appending newly elements as they are inserted. This is left as a task to the user until we can manage + // to improve this example code! + // If your items are of variable height: + // - Split them into same height items would be simpler and facilitate random-seeking into your list. + // - Consider using manual call to IsRectVisible() and skipping extraneous decoration from your items. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing + if (copy_to_clipboard) + ImGui::LogToClipboard(); + for (int i = 0; i < Items.Size; i++) + { + const char* item = Items[i]; + if (!Filter.PassFilter(item)) + continue; + + // Normally you would store more information in your item than just a string. + // (e.g. make Items[] an array of structure, store color/type etc.) + ImVec4 color; + bool has_color = false; + if (strstr(item, "[error]")) { color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f); has_color = true; } + else if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.0f, 0.8f, 0.6f, 1.0f); has_color = true; } + if (has_color) + ImGui::PushStyleColor(ImGuiCol_Text, color); + ImGui::TextUnformatted(item); + if (has_color) + ImGui::PopStyleColor(); + } + if (copy_to_clipboard) + ImGui::LogFinish(); + + if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) + ImGui::SetScrollHereY(1.0f); + ScrollToBottom = false; + + ImGui::PopStyleVar(); + ImGui::EndChild(); + ImGui::Separator(); + + // Command-line + bool reclaim_focus = false; + ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; + if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) + { + char* s = InputBuf; + Strtrim(s); + if (s[0]) + ExecCommand(s); + strcpy(s, ""); + reclaim_focus = true; + } + + // Auto-focus on window apparition + ImGui::SetItemDefaultFocus(); + if (reclaim_focus) + ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget + + 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 = History.Size - 1; i >= 0; i--) + if (Stricmp(History[i], command_line) == 0) + { + free(History[i]); + History.erase(History.begin() + i); + break; + } + History.push_back(Strdup(command_line)); + + // Process command + if (Stricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (Stricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (int i = 0; i < Commands.Size; i++) + AddLog("- %s", Commands[i]); + } + else if (Stricmp(command_line, "HISTORY") == 0) + { + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) + AddLog("%3d: %s\n", i, History[i]); + } + else + { + AddLog("Unknown command: '%s'\n", command_line); + } + + // On command input, we scroll to bottom even if AutoScroll==false + ScrollToBottom = true; + } + + // In C++11 you'd be better off using lambdas for this sort of forwarding callbacks + static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) + { + ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; + return console->TextEditCallback(data); + } + + int TextEditCallback(ImGuiInputTextCallbackData* 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 (c == ' ' || c == '\t' || c == ',' || c == ';') + break; + word_start--; + } + + // Build a list of candidates + ImVector candidates; + for (int i = 0; i < Commands.Size; i++) + if (Strnicmp(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", (int)(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"+Tab will complete to "CL" then display "CLEAR" and "CLASSIFY" as matches. + int match_len = (int)(word_end - word_start); + for (;;) + { + int c = 0; + bool all_candidates_matches = true; + for (int i = 0; i < candidates.Size && all_candidates_matches; i++) + if (i == 0) + c = toupper(candidates[i][match_len]); + else if (c == 0 || 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 (int 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 = History.Size - 1; + else if (HistoryPos > 0) + HistoryPos--; + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) + if (++HistoryPos >= 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) + { + const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : ""; + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, history_str); + } + } + } + return 0; + } +}; + +static void ShowExampleAppConsole(bool* p_open) +{ + static ExampleAppConsole console; + console.Draw("Example: Console", p_open); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Debug Log / ShowExampleAppLog() +//----------------------------------------------------------------------------- + +// Usage: +// static ExampleAppLog my_log; +// my_log.AddLog("Hello %d world\n", 123); +// my_log.Draw("title"); +struct ExampleAppLog +{ + ImGuiTextBuffer Buf; + ImGuiTextFilter Filter; + ImVector LineOffsets; // Index to lines offset. We maintain this with AddLog() calls. + bool AutoScroll; // Keep scrolling if already at the bottom. + + ExampleAppLog() + { + AutoScroll = true; + Clear(); + } + + void Clear() + { + Buf.clear(); + LineOffsets.clear(); + LineOffsets.push_back(0); + } + + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + int old_size = Buf.size(); + va_list args; + va_start(args, fmt); + Buf.appendfv(fmt, args); + va_end(args); + for (int new_size = Buf.size(); old_size < new_size; old_size++) + if (Buf[old_size] == '\n') + LineOffsets.push_back(old_size + 1); + } + + void Draw(const char* title, bool* p_open = NULL) + { + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } + + // Options menu + if (ImGui::BeginPopup("Options")) + { + ImGui::Checkbox("Auto-scroll", &AutoScroll); + ImGui::EndPopup(); + } + + // Main window + if (ImGui::Button("Options")) + ImGui::OpenPopup("Options"); + ImGui::SameLine(); + bool clear = ImGui::Button("Clear"); + ImGui::SameLine(); + bool copy = ImGui::Button("Copy"); + ImGui::SameLine(); + Filter.Draw("Filter", -100.0f); + + ImGui::Separator(); + ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar); + + if (clear) + Clear(); + if (copy) + ImGui::LogToClipboard(); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + const char* buf = Buf.begin(); + const char* buf_end = Buf.end(); + if (Filter.IsActive()) + { + // In this example we don't use the clipper when Filter is enabled. + // This is because we don't have a random access on the result on our filter. + // A real application processing logs with ten of thousands of entries may want to store the result of + // search/filter.. especially if the filtering function is not trivial (e.g. reg-exp). + for (int line_no = 0; line_no < LineOffsets.Size; line_no++) + { + const char* line_start = buf + LineOffsets[line_no]; + const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end; + if (Filter.PassFilter(line_start, line_end)) + ImGui::TextUnformatted(line_start, line_end); + } + } + else + { + // The simplest and easy way to display the entire buffer: + // ImGui::TextUnformatted(buf_begin, buf_end); + // And it'll just work. TextUnformatted() has specialization for large blob of text and will fast-forward + // to skip non-visible lines. Here we instead demonstrate using the clipper to only process lines that are + // within the visible area. + // If you have tens of thousands of items and their processing cost is non-negligible, coarse clipping them + // on your side is recommended. Using ImGuiListClipper requires + // - A) random access into your data + // - B) items all being the same height, + // both of which we can handle since we an array pointing to the beginning of each line of text. + // When using the filter (in the block of code above) we don't have random access into the data to display + // anymore, which is why we don't use the clipper. Storing or skimming through the search result would make + // it possible (and would be recommended if you want to search through tens of thousands of entries). + ImGuiListClipper clipper; + clipper.Begin(LineOffsets.Size); + while (clipper.Step()) + { + for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) + { + const char* line_start = buf + LineOffsets[line_no]; + const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end; + ImGui::TextUnformatted(line_start, line_end); + } + } + clipper.End(); + } + ImGui::PopStyleVar(); + + if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + ImGui::SetScrollHereY(1.0f); + + ImGui::EndChild(); + ImGui::End(); + } +}; + +// Demonstrate creating a simple log window with basic filtering. +static void ShowExampleAppLog(bool* p_open) +{ + static ExampleAppLog log; + + // For the demo: add a debug button _BEFORE_ the normal log window contents + // We take advantage of a rarely used feature: multiple calls to Begin()/End() are appending to the _same_ window. + // Most of the contents of the window will be added by the log.Draw() call. + ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver); + ImGui::Begin("Example: Log", p_open); + IMGUI_DEMO_MARKER("Examples/Log"); + if (ImGui::SmallButton("[Debug] Add 5 entries")) + { + static int counter = 0; + const char* categories[3] = { "info", "warn", "error" }; + const char* words[] = { "Bumfuzzled", "Cattywampus", "Snickersnee", "Abibliophobia", "Absquatulate", "Nincompoop", "Pauciloquent" }; + for (int n = 0; n < 5; n++) + { + const char* category = categories[counter % IM_ARRAYSIZE(categories)]; + const char* word = words[counter % IM_ARRAYSIZE(words)]; + log.AddLog("[%05d] [%s] Hello, current time is %.1f, here's a word: '%s'\n", + ImGui::GetFrameCount(), category, ImGui::GetTime(), word); + counter++; + } + } + ImGui::End(); + + // Actually call in the regular Log helper (which will Begin() into the same window as we just did) + log.Draw("Example: Log", p_open); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Simple Layout / ShowExampleAppLayout() +//----------------------------------------------------------------------------- + +// Demonstrate create a window with multiple child windows. +static void ShowExampleAppLayout(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver); + if (ImGui::Begin("Example: Simple layout", p_open, ImGuiWindowFlags_MenuBar)) + { + IMGUI_DEMO_MARKER("Examples/Simple layout"); + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + // Left + static int selected = 0; + { + ImGui::BeginChild("left pane", ImVec2(150, 0), true); + for (int i = 0; i < 100; i++) + { + // FIXME: Good candidate to use ImGuiSelectableFlags_SelectOnNav + char label[128]; + sprintf(label, "MyObject %d", i); + if (ImGui::Selectable(label, selected == i)) + selected = i; + } + ImGui::EndChild(); + } + ImGui::SameLine(); + + // Right + { + ImGui::BeginGroup(); + ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us + ImGui::Text("MyObject: %d", selected); + ImGui::Separator(); + if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Description")) + { + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Details")) + { + ImGui::Text("ID: 0123456789"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::EndChild(); + if (ImGui::Button("Revert")) {} + ImGui::SameLine(); + if (ImGui::Button("Save")) {} + ImGui::EndGroup(); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor() +//----------------------------------------------------------------------------- + +static void ShowPlaceholderObject(const char* prefix, int uid) +{ + // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. + ImGui::PushID(uid); + + // Text and Tree nodes are less high than framed widgets, using AlignTextToFramePadding() we add vertical spacing to make the tree lines equal high. + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::AlignTextToFramePadding(); + bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + ImGui::TableSetColumnIndex(1); + ImGui::Text("my sailor is rich"); + + if (node_open) + { + static float placeholder_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f }; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); // Use field index as identifier. + if (i < 2) + { + ShowPlaceholderObject("Child", 424242); + } + else + { + // Here we use a TreeNode to highlight on hover (we could use e.g. Selectable as well) + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::AlignTextToFramePadding(); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_Bullet; + ImGui::TreeNodeEx("Field", flags, "Field_%d", i); + + ImGui::TableSetColumnIndex(1); + ImGui::SetNextItemWidth(-FLT_MIN); + if (i >= 5) + ImGui::InputFloat("##value", &placeholder_members[i], 1.0f); + else + ImGui::DragFloat("##value", &placeholder_members[i], 0.01f); + ImGui::NextColumn(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::PopID(); +} + +// Demonstrate create a simple property editor. +static void ShowExampleAppPropertyEditor(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(430, 450), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Property editor", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Property Editor"); + + HelpMarker( + "This example shows how you may implement a property editor using two columns.\n" + "All objects/fields data are dummies here.\n" + "Remember that in many simple cases, you can use ImGui::SameLine(xxx) to position\n" + "your cursor horizontally instead of using the Columns() API."); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + if (ImGui::BeginTable("split", 2, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_Resizable)) + { + // Iterate placeholder objects (all the same data) + for (int obj_i = 0; obj_i < 4; obj_i++) + { + ShowPlaceholderObject("Object", obj_i); + //ImGui::Separator(); + } + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Long Text / ShowExampleAppLongText() +//----------------------------------------------------------------------------- + +// Demonstrate/test rendering huge amount of text, and the incidence of clipping. +static void ShowExampleAppLongText(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Long text display", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Long text display"); + + 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()\0" + "Multiple calls to Text(), clipped\0" + "Multiple calls to Text(), not clipped (slow)\0"); + 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.appendf("%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 ImGuiListClipper helper. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGuiListClipper clipper; + clipper.Begin(lines); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + case 2: + // Multiple calls to Text(), not clipped (slow) + 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", i); + ImGui::PopStyleVar(); + break; + } + ImGui::EndChild(); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window which gets auto-resized according to its content. +static void ShowExampleAppAutoResize(bool* p_open) +{ + if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Auto-resizing window"); + + static int lines = 10; + ImGui::TextUnformatted( + "Window will resize every-frame to the size of its content.\n" + "Note that you probably don't want to query the window size to\n" + "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(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window with custom resize constraints. +static void ShowExampleAppConstrainedResize(bool* p_open) +{ + struct CustomConstraints + { + // Helper functions to demonstrate programmatic constraints + static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize.x = data->DesiredSize.y = IM_MAX(data->DesiredSize.x, data->DesiredSize.y); } + static void Step(ImGuiSizeCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } + }; + + const char* test_desc[] = + { + "Resize vertical only", + "Resize horizontal only", + "Width > 100, Height > 100", + "Width 400-500", + "Height 400-500", + "Custom: Always Square", + "Custom: Fixed Steps (100)", + }; + + static bool auto_resize = false; + static int type = 0; + static int display_lines = 10; + if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only + if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only + if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 + if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500 + if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500 + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square + if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)(intptr_t)100); // Fixed Step + + ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0; + if (ImGui::Begin("Example: Constrained Resize", p_open, flags)) + { + IMGUI_DEMO_MARKER("Examples/Constrained Resizing window"); + if (ImGui::IsWindowDocked()) + ImGui::Text("Warning: Sizing Constraints won't work if the window is docked!"); + if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine(); + if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine(); + if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); } + ImGui::SetNextItemWidth(200); + ImGui::Combo("Constraint", &type, test_desc, IM_ARRAYSIZE(test_desc)); + ImGui::SetNextItemWidth(200); + ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100); + ImGui::Checkbox("Auto-resize", &auto_resize); + for (int i = 0; i < display_lines; i++) + ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, ""); + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay() +//----------------------------------------------------------------------------- + +// Demonstrate creating a simple static window with no decoration +// + a context-menu to choose which corner of the screen to use. +static void ShowExampleAppSimpleOverlay(bool* p_open) +{ + static int corner = 0; + ImGuiIO& io = ImGui::GetIO(); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; + if (corner != -1) + { + const float PAD = 10.0f; + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImVec2 work_pos = viewport->WorkPos; // Use work area to avoid menu-bar/task-bar, if any! + ImVec2 work_size = viewport->WorkSize; + ImVec2 window_pos, window_pos_pivot; + window_pos.x = (corner & 1) ? (work_pos.x + work_size.x - PAD) : (work_pos.x + PAD); + window_pos.y = (corner & 2) ? (work_pos.y + work_size.y - PAD) : (work_pos.y + PAD); + window_pos_pivot.x = (corner & 1) ? 1.0f : 0.0f; + window_pos_pivot.y = (corner & 2) ? 1.0f : 0.0f; + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + ImGui::SetNextWindowViewport(viewport->ID); + window_flags |= ImGuiWindowFlags_NoMove; + } + ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background + if (ImGui::Begin("Example: Simple overlay", p_open, window_flags)) + { + IMGUI_DEMO_MARKER("Examples/Simple Overlay"); + ImGui::Text("Simple overlay\n" "in the corner of the screen.\n" "(right-click to change position)"); + ImGui::Separator(); + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse Position: (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse Position: "); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1; + if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; + if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; + if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; + if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + if (p_open && ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndPopup(); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window covering the entire screen/viewport +static void ShowExampleAppFullscreen(bool* p_open) +{ + static bool use_work_area = true; + static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; + + // We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.) + // Based on your use case you may want one of the other. + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos); + ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size); + + if (ImGui::Begin("Example: Fullscreen window", p_open, flags)) + { + ImGui::Checkbox("Use work area instead of main area", &use_work_area); + ImGui::SameLine(); + HelpMarker("Main Area = entire viewport,\nWork Area = entire viewport minus sections used by the main menu bars, task bars etc.\n\nEnable the main-menu bar in Examples menu to see the difference."); + + ImGui::CheckboxFlags("ImGuiWindowFlags_NoBackground", &flags, ImGuiWindowFlags_NoBackground); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoDecoration", &flags, ImGuiWindowFlags_NoDecoration); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoTitleBar", &flags, ImGuiWindowFlags_NoTitleBar); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoCollapse", &flags, ImGuiWindowFlags_NoCollapse); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoScrollbar", &flags, ImGuiWindowFlags_NoScrollbar); + ImGui::Unindent(); + + if (p_open && ImGui::Button("Close this window")) + *p_open = false; + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles() +//----------------------------------------------------------------------------- + +// Demonstrate using "##" and "###" in identifiers to manipulate ID generation. +// This apply to all regular items as well. +// Read FAQ section "How can I have multiple widgets with the same label?" for details. +static void ShowExampleAppWindowTitles(bool*) +{ + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + const ImVec2 base_pos = viewport->Pos; + + // By default, Windows are uniquely identified by their title. + // You can use the "##" and "###" markers to manipulate the display/ID. + + // Using "##" to display same title but have unique identifier. + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 100), ImGuiCond_FirstUseEver); + ImGui::Begin("Same title as another window##1"); + IMGUI_DEMO_MARKER("Examples/Manipulating window titles"); + ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 200), ImGuiCond_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]; + sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime() / 0.25f) & 3], ImGui::GetFrameCount()); + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 300), ImGuiCond_FirstUseEver); + ImGui::Begin(buf); + ImGui::Text("This window has a changing title."); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering() +//----------------------------------------------------------------------------- + +// Demonstrate using the low-level ImDrawList to draw custom shapes. +static void ShowExampleAppCustomRendering(bool* p_open) +{ + if (!ImGui::Begin("Example: Custom rendering", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Custom Rendering"); + + // 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. Dear 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 are not using the maths operators! + + if (ImGui::BeginTabBar("##TabBar")) + { + if (ImGui::BeginTabItem("Primitives")) + { + ImGui::PushItemWidth(-ImGui::GetFontSize() * 15); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Draw gradients + // (note that those are currently exacerbating our sRGB/Linear issues) + // Calling ImGui::GetColorU32() multiplies the given colors by the current Style Alpha, but you may pass the IM_COL32() directly as well.. + ImGui::Text("Gradients"); + ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight()); + { + ImVec2 p0 = ImGui::GetCursorScreenPos(); + ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y); + ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255)); + ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255)); + draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a); + ImGui::InvisibleButton("##gradient1", gradient_size); + } + { + ImVec2 p0 = ImGui::GetCursorScreenPos(); + ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y); + ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255)); + ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255)); + draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a); + ImGui::InvisibleButton("##gradient2", gradient_size); + } + + // Draw a bunch of primitives + ImGui::Text("All primitives"); + static float sz = 36.0f; + static float thickness = 3.0f; + static int ngon_sides = 6; + static bool circle_segments_override = false; + static int circle_segments_override_v = 12; + static bool curve_segments_override = false; + static int curve_segments_override_v = 8; + static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f); + ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 100.0f, "%.0f"); + ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f"); + ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12); + ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + circle_segments_override |= ImGui::SliderInt("Circle segments override", &circle_segments_override_v, 3, 40); + ImGui::Checkbox("##curvessegmentoverride", &curve_segments_override); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 40); + ImGui::ColorEdit4("Color", &colf.x); + + const ImVec2 p = ImGui::GetCursorScreenPos(); + const ImU32 col = ImColor(colf); + const float spacing = 10.0f; + const ImDrawFlags corners_tl_br = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomRight; + const float rounding = sz / 5.0f; + const int circle_segments = circle_segments_override ? circle_segments_override_v : 0; + const int curve_segments = curve_segments_override ? curve_segments_override_v : 0; + float x = p.x + 4.0f; + float y = p.y + 4.0f; + for (int n = 0; n < 2; n++) + { + // First line uses a thickness of 1.0f, second line uses the configurable thickness + float th = (n == 0) ? 1.0f : thickness; + draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon + draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners + draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle + //draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line + + // Quadratic Bezier Curve (3 control points) + ImVec2 cp3[3] = { ImVec2(x, y + sz * 0.6f), ImVec2(x + sz * 0.5f, y - sz * 0.4f), ImVec2(x + sz, y + sz) }; + draw_list->AddBezierQuadratic(cp3[0], cp3[1], cp3[2], col, th, curve_segments); x += sz + spacing; + + // Cubic Bezier Curve (4 control points) + ImVec2 cp4[4] = { ImVec2(x, y), ImVec2(x + sz * 1.3f, y + sz * 0.3f), ImVec2(x + sz - sz * 1.3f, y + sz - sz * 0.3f), ImVec2(x + sz, y + sz) }; + draw_list->AddBezierCubic(cp4[0], cp4[1], cp4[2], cp4[3], col, th, curve_segments); + + x = p.x + 4; + y += sz + spacing; + } + draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon + draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners + draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle + //draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine) + draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); + + ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (sz + spacing) * 3.0f)); + ImGui::PopItemWidth(); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Canvas")) + { + static ImVector points; + static ImVec2 scrolling(0.0f, 0.0f); + static bool opt_enable_grid = true; + static bool opt_enable_context_menu = true; + static bool adding_line = false; + + ImGui::Checkbox("Enable grid", &opt_enable_grid); + ImGui::Checkbox("Enable context menu", &opt_enable_context_menu); + ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu."); + + // Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling. + // Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls. + // To use a child window instead we could use, e.g: + // ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding + // ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color + // ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_NoMove); + // ImGui::PopStyleColor(); + // ImGui::PopStyleVar(); + // [...] + // ImGui::EndChild(); + + // Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive() + ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! + ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); // Resize canvas to what's available + if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f; + if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f; + ImVec2 canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y); + + // Draw border and background color + ImGuiIO& io = ImGui::GetIO(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(50, 50, 50, 255)); + draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255)); + + // This will catch our interactions + ImGui::InvisibleButton("canvas", canvas_sz, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); + const bool is_hovered = ImGui::IsItemHovered(); // Hovered + const bool is_active = ImGui::IsItemActive(); // Held + const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y); // Lock scrolled origin + const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, io.MousePos.y - origin.y); + + // Add first and second point + if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) + { + points.push_back(mouse_pos_in_canvas); + points.push_back(mouse_pos_in_canvas); + adding_line = true; + } + if (adding_line) + { + points.back() = mouse_pos_in_canvas; + if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) + adding_line = false; + } + + // Pan (we use a zero mouse threshold when there's no context menu) + // You may decide to make that threshold dynamic based on whether the mouse is hovering something etc. + const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f; + if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan)) + { + scrolling.x += io.MouseDelta.x; + scrolling.y += io.MouseDelta.y; + } + + // Context menu (under default mouse threshold) + ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); + if (opt_enable_context_menu && drag_delta.x == 0.0f && drag_delta.y == 0.0f) + ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + if (ImGui::BeginPopup("context")) + { + if (adding_line) + points.resize(points.size() - 2); + adding_line = false; + if (ImGui::MenuItem("Remove one", NULL, false, points.Size > 0)) { points.resize(points.size() - 2); } + if (ImGui::MenuItem("Remove all", NULL, false, points.Size > 0)) { points.clear(); } + ImGui::EndPopup(); + } + + // Draw grid + all lines in the canvas + draw_list->PushClipRect(canvas_p0, canvas_p1, true); + if (opt_enable_grid) + { + const float GRID_STEP = 64.0f; + for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP) + draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40)); + for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP) + draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40)); + } + for (int n = 0; n < points.Size; n += 2) + draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); + draw_list->PopClipRect(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("BG/FG draw lists")) + { + static bool draw_bg = true; + static bool draw_fg = true; + ImGui::Checkbox("Draw in Background draw list", &draw_bg); + ImGui::SameLine(); HelpMarker("The Background draw list will be rendered below every Dear ImGui windows."); + ImGui::Checkbox("Draw in Foreground draw list", &draw_fg); + ImGui::SameLine(); HelpMarker("The Foreground draw list will be rendered over every Dear ImGui windows."); + ImVec2 window_pos = ImGui::GetWindowPos(); + ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_center = ImVec2(window_pos.x + window_size.x * 0.5f, window_pos.y + window_size.y * 0.5f); + if (draw_bg) + ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 0, 10 + 4); + if (draw_fg) + ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 0, 10); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace() +//----------------------------------------------------------------------------- + +// Demonstrate using DockSpace() to create an explicit docking node within an existing window. +// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking! +// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking. +// - Drag from window menu button (upper-left button) to undock an entire node (all windows). +// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to _enable_ docking/undocking. +// About dockspaces: +// - Use DockSpace() to create an explicit dock node _within_ an existing window. +// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport. +// This is often used with ImGuiDockNodeFlags_PassthruCentralNode. +// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! (*) +// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked. +// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly. +// (*) because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node, +// because that window is submitted as part of the part of the NewFrame() call. An easy workaround is that you can create +// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use. +void ShowExampleAppDockSpace(bool* p_open) +{ + // If you strip some features of, this demo is pretty much equivalent to calling DockSpaceOverViewport()! + // In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below! + // In this specific demo, we are not using DockSpaceOverViewport() because: + // - we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false) + // - we allow the host window to have padding (when opt_padding == true) + // - we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport() in your code!) + // TL;DR; this demo is more complicated than what you would normally use. + // If we removed all the options we are showcasing, this demo would become: + // void ShowExampleAppDockSpace() + // { + // ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); + // } + + static bool opt_fullscreen = true; + static bool opt_padding = false; + static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; + + // We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into, + // because it would be confusing to have two docking targets within each others. + ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + if (opt_fullscreen) + { + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); + ImGui::SetNextWindowViewport(viewport->ID); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + } + else + { + dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode; + } + + // When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background + // and handle the pass-thru hole, so we ask Begin() to not render a background. + if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) + window_flags |= ImGuiWindowFlags_NoBackground; + + // Important: note that we proceed even if Begin() returns false (aka window is collapsed). + // This is because we want to keep our DockSpace() active. If a DockSpace() is inactive, + // all active windows docked into it will lose their parent and become undocked. + // We cannot preserve the docking relationship between an active window and an inactive docking, otherwise + // any change of dockspace/settings would lead to windows being stuck in limbo and never being visible. + if (!opt_padding) + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::Begin("DockSpace Demo", p_open, window_flags); + if (!opt_padding) + ImGui::PopStyleVar(); + + if (opt_fullscreen) + ImGui::PopStyleVar(2); + + // Submit the DockSpace + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) + { + ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); + } + else + { + ShowDockingDisabledMessage(); + } + + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Options")) + { + // Disabling fullscreen would allow the window to be moved to the front of other windows, + // which we can't undo at the moment without finer window depth/z control. + ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen); + ImGui::MenuItem("Padding", NULL, &opt_padding); + ImGui::Separator(); + + if (ImGui::MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; } + if (ImGui::MenuItem("Flag: NoResize", "", (dockspace_flags & ImGuiDockNodeFlags_NoResize) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoResize; } + if (ImGui::MenuItem("Flag: NoDockingInCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoDockingInCentralNode; } + if (ImGui::MenuItem("Flag: AutoHideTabBar", "", (dockspace_flags & ImGuiDockNodeFlags_AutoHideTabBar) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_AutoHideTabBar; } + if (ImGui::MenuItem("Flag: PassthruCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0, opt_fullscreen)) { dockspace_flags ^= ImGuiDockNodeFlags_PassthruCentralNode; } + ImGui::Separator(); + + if (ImGui::MenuItem("Close", NULL, false, p_open != NULL)) + *p_open = false; + ImGui::EndMenu(); + } + HelpMarker( + "When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n" + "- Drag from window title bar or their tab to dock/undock." "\n" + "- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n" + "- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n" + "- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)" "\n" + "This demo app has nothing to do with enabling docking!" "\n\n" + "This demo app only demonstrate the use of ImGui::DockSpace() which allows you to manually create a docking node _within_ another window." "\n\n" + "Read comments in ShowExampleAppDockSpace() for more details."); + + ImGui::EndMenuBar(); + } + + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments() +//----------------------------------------------------------------------------- + +// Simplified structure to mimic a Document model +struct MyDocument +{ + const char* Name; // Document title + bool Open; // Set when open (we keep an array of all available documents to simplify demo code!) + bool OpenPrev; // Copy of Open from last update. + bool Dirty; // Set when the document has been modified + bool WantClose; // Set when the document + ImVec4 Color; // An arbitrary variable associated to the document + + MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f)) + { + Name = name; + Open = OpenPrev = open; + Dirty = false; + WantClose = false; + Color = color; + } + void DoOpen() { Open = true; } + void DoQueueClose() { WantClose = true; } + void DoForceClose() { Open = false; Dirty = false; } + void DoSave() { Dirty = false; } + + // Display placeholder contents for the Document + static void DisplayContents(MyDocument* doc) + { + ImGui::PushID(doc); + ImGui::Text("Document \"%s\"", doc->Name); + ImGui::PushStyleColor(ImGuiCol_Text, doc->Color); + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + ImGui::PopStyleColor(); + if (ImGui::Button("Modify", ImVec2(100, 0))) + doc->Dirty = true; + ImGui::SameLine(); + if (ImGui::Button("Save", ImVec2(100, 0))) + doc->DoSave(); + ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior. + ImGui::PopID(); + } + + // Display context menu for the Document + static void DisplayContextMenu(MyDocument* doc) + { + if (!ImGui::BeginPopupContextItem()) + return; + + char buf[256]; + sprintf(buf, "Save %s", doc->Name); + if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open)) + doc->DoSave(); + if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open)) + doc->DoQueueClose(); + ImGui::EndPopup(); + } +}; + +struct ExampleAppDocuments +{ + ImVector Documents; + + ExampleAppDocuments() + { + Documents.push_back(MyDocument("Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f))); + Documents.push_back(MyDocument("Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f))); + Documents.push_back(MyDocument("Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f))); + Documents.push_back(MyDocument("Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f))); + Documents.push_back(MyDocument("A Rather Long Title", false)); + Documents.push_back(MyDocument("Some Document", false)); + } +}; + +// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface. +// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo, +// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for +// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has +// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively +// give the impression of a flicker for one frame. +// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch. +// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag. +static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app) +{ + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open && doc->OpenPrev) + ImGui::SetTabItemClosed(doc->Name); + doc->OpenPrev = doc->Open; + } +} + +void ShowExampleAppDocuments(bool* p_open) +{ + static ExampleAppDocuments app; + + // Options + enum Target + { + Target_None, + Target_Tab, // Create documents as local tab into a local tab bar + Target_DockSpaceAndWindow // Create documents as regular windows, and create an embedded dockspace + }; + static Target opt_target = Target_Tab; + static bool opt_reorderable = true; + static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_; + + // When (opt_target == Target_DockSpaceAndWindow) there is the possibily that one of our child Document window (e.g. "Eggplant") + // that we emit gets docked into the same spot as the parent window ("Example: Documents"). + // This would create a problematic feedback loop because selecting the "Eggplant" tab would make the "Example: Documents" tab + // not visible, which in turn would stop submitting the "Eggplant" window. + // We avoid this problem by submitting our documents window even if our parent window is not currently visible. + // Another solution may be to make the "Example: Documents" window use the ImGuiWindowFlags_NoDocking. + + bool window_contents_visible = ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar); + if (!window_contents_visible && opt_target != Target_DockSpaceAndWindow) + { + ImGui::End(); + return; + } + + // Menu + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + int open_count = 0; + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + open_count += app.Documents[doc_n].Open ? 1 : 0; + + if (ImGui::BeginMenu("Open", open_count < app.Documents.Size)) + { + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open) + if (ImGui::MenuItem(doc->Name)) + doc->DoOpen(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0)) + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + app.Documents[doc_n].DoQueueClose(); + if (ImGui::MenuItem("Exit", "Alt+F4")) {} + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + // [Debug] List documents with one checkbox for each + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (doc_n > 0) + ImGui::SameLine(); + ImGui::PushID(doc); + if (ImGui::Checkbox(doc->Name, &doc->Open)) + if (!doc->Open) + doc->DoForceClose(); + ImGui::PopID(); + } + ImGui::PushItemWidth(ImGui::GetFontSize() * 12); + ImGui::Combo("Output", (int*)&opt_target, "None\0TabBar+Tabs\0DockSpace+Window\0"); + ImGui::PopItemWidth(); + bool redock_all = false; + if (opt_target == Target_Tab) { ImGui::SameLine(); ImGui::Checkbox("Reorderable Tabs", &opt_reorderable); } + if (opt_target == Target_DockSpaceAndWindow) { ImGui::SameLine(); redock_all = ImGui::Button("Redock all"); } + + ImGui::Separator(); + + // About the ImGuiWindowFlags_UnsavedDocument / ImGuiTabItemFlags_UnsavedDocument flags. + // They have multiple effects: + // - Display a dot next to the title. + // - Tab is selected when clicking the X close button. + // - Closure is not assumed (will wait for user to stop submitting the tab). + // Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar. + // We need to assume closure by default otherwise waiting for "lack of submission" on the next frame would leave an empty + // hole for one-frame, both in the tab-bar and in tab-contents when closing a tab/window. + // The rarely used SetTabItemClosed() function is a way to notify of programmatic closure to avoid the one-frame hole. + + // Tabs + if (opt_target == Target_Tab) + { + ImGuiTabBarFlags tab_bar_flags = (opt_fitting_flags) | (opt_reorderable ? ImGuiTabBarFlags_Reorderable : 0); + if (ImGui::BeginTabBar("##tabs", tab_bar_flags)) + { + if (opt_reorderable) + NotifyOfDocumentsClosedElsewhere(app); + + // [DEBUG] Stress tests + //if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1; // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on. + //if (ImGui::GetIO().KeyCtrl) ImGui::SetTabItemSelected(docs[1].Name); // [DEBUG] Test SetTabItemSelected(), probably not very useful as-is anyway.. + + // Submit Tabs + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open) + continue; + + ImGuiTabItemFlags tab_flags = (doc->Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0); + bool visible = ImGui::BeginTabItem(doc->Name, &doc->Open, tab_flags); + + // Cancel attempt to close when unsaved add to save queue so we can display a popup. + if (!doc->Open && doc->Dirty) + { + doc->Open = true; + doc->DoQueueClose(); + } + + MyDocument::DisplayContextMenu(doc); + if (visible) + { + MyDocument::DisplayContents(doc); + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + } + } + else if (opt_target == Target_DockSpaceAndWindow) + { + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DockingEnable) + { + NotifyOfDocumentsClosedElsewhere(app); + + // Create a DockSpace node where any window can be docked + ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + ImGui::DockSpace(dockspace_id); + + // Create Windows + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open) + continue; + + ImGui::SetNextWindowDockID(dockspace_id, redock_all ? ImGuiCond_Always : ImGuiCond_FirstUseEver); + ImGuiWindowFlags window_flags = (doc->Dirty ? ImGuiWindowFlags_UnsavedDocument : 0); + bool visible = ImGui::Begin(doc->Name, &doc->Open, window_flags); + + // Cancel attempt to close when unsaved add to save queue so we can display a popup. + if (!doc->Open && doc->Dirty) + { + doc->Open = true; + doc->DoQueueClose(); + } + + MyDocument::DisplayContextMenu(doc); + if (visible) + MyDocument::DisplayContents(doc); + + ImGui::End(); + } + } + else + { + ShowDockingDisabledMessage(); + } + } + + // Early out other contents + if (!window_contents_visible) + { + ImGui::End(); + return; + } + + // Update closing queue + static ImVector close_queue; + if (close_queue.empty()) + { + // Close queue is locked once we started a popup + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (doc->WantClose) + { + doc->WantClose = false; + close_queue.push_back(doc); + } + } + } + + // Display closing confirmation UI + if (!close_queue.empty()) + { + int close_queue_unsaved_documents = 0; + for (int n = 0; n < close_queue.Size; n++) + if (close_queue[n]->Dirty) + close_queue_unsaved_documents++; + + if (close_queue_unsaved_documents == 0) + { + // Close documents when all are unsaved + for (int n = 0; n < close_queue.Size; n++) + close_queue[n]->DoForceClose(); + close_queue.clear(); + } + else + { + if (!ImGui::IsPopupOpen("Save?")) + ImGui::OpenPopup("Save?"); + if (ImGui::BeginPopupModal("Save?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Save change to the following items?"); + float item_height = ImGui::GetTextLineHeightWithSpacing(); + if (ImGui::BeginChildFrame(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height))) + { + for (int n = 0; n < close_queue.Size; n++) + if (close_queue[n]->Dirty) + ImGui::Text("%s", close_queue[n]->Name); + ImGui::EndChildFrame(); + } + + ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f); + if (ImGui::Button("Yes", button_size)) + { + for (int n = 0; n < close_queue.Size; n++) + { + if (close_queue[n]->Dirty) + close_queue[n]->DoSave(); + close_queue[n]->DoForceClose(); + } + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("No", button_size)) + { + for (int n = 0; n < close_queue.Size; n++) + close_queue[n]->DoForceClose(); + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel", button_size)) + { + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } + } + + ImGui::End(); +} + +// End of Demo code +#else + +void ImGui::ShowAboutWindow(bool*) {} +void ImGui::ShowDemoWindow(bool*) {} +void ImGui::ShowUserGuide() {} +void ImGui::ShowStyleEditor(ImGuiStyle*) {} + +#endif + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui_draw.cpp b/libultraship/libultraship/Lib/ImGui/imgui_draw.cpp new file mode 100644 index 000000000..40d5f2d74 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui_draw.cpp @@ -0,0 +1,4190 @@ +// dear imgui, v1.87 +// (drawing and font code) + +/* + +Index of this file: + +// [SECTION] STB libraries implementation +// [SECTION] Style functions +// [SECTION] ImDrawList +// [SECTION] ImDrawListSplitter +// [SECTION] ImDrawData +// [SECTION] Helpers ShadeVertsXXX functions +// [SECTION] ImFontConfig +// [SECTION] ImFontAtlas +// [SECTION] ImFontAtlas glyph ranges helpers +// [SECTION] ImFontGlyphRangesBuilder +// [SECTION] ImFont +// [SECTION] ImGui Internal Render Helpers +// [SECTION] Decompression code +// [SECTION] Default font data (ProggyClean.ttf) + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif + +#include "imgui_internal.h" +#ifdef IMGUI_ENABLE_FREETYPE +#include "misc/freetype/imgui_freetype.h" +#endif + +#include // vsnprintf, sscanf, printf +#if !defined(alloca) +#if defined(__GLIBC__) || defined(__sun) || defined(__APPLE__) || defined(__NEWLIB__) +#include // alloca (glibc uses . Note that Cygwin may have _WIN32 defined, so the order matters here) +#elif defined(_WIN32) +#include // alloca +#if !defined(alloca) +#define alloca _alloca // for clang with MS Codegen +#endif +#else +#include // alloca +#endif +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#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 +#pragma warning (disable: 6255) // [Static Analyzer] _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead. +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer) +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#if __has_warning("-Walloca") +#pragma clang diagnostic ignored "-Walloca" // warning: use of function '__builtin_alloca' is discouraged +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#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 "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wcomma" // warning: possible misuse of comma operator here +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +//------------------------------------------------------------------------- +// [SECTION] STB libraries implementation +//------------------------------------------------------------------------- + +// Compile time options: +//#define IMGUI_STB_NAMESPACE ImStb +//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" +//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" +//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION +//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION + +#ifdef IMGUI_STB_NAMESPACE +namespace IMGUI_STB_NAMESPACE +{ +#endif + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration +#pragma warning (disable: 6011) // (stb_rectpack) Dereferencing NULL pointer 'cur->next'. +#pragma warning (disable: 6385) // (stb_truetype) Reading invalid data from 'buffer': the readable size is '_Old_3`kernel_width' bytes, but '3' bytes may be read. +#pragma warning (disable: 28182) // (stb_rectpack) Dereferencing NULL pointer. 'cur' contains the same NULL value as 'cur->next' did. +#endif + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" +#pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wimplicit-fallthrough" +#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier +#endif + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers +#endif + +#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) +#ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in another compilation unit +#define STBRP_STATIC +#define STBRP_ASSERT(x) do { IM_ASSERT(x); } while (0) +#define STBRP_SORT ImQsort +#define STB_RECT_PACK_IMPLEMENTATION +#endif +#ifdef IMGUI_STB_RECT_PACK_FILENAME +#include IMGUI_STB_RECT_PACK_FILENAME +#else +#include "imstb_rectpack.h" +#endif +#endif + +#ifdef IMGUI_ENABLE_STB_TRUETYPE +#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) +#ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in another compilation unit +#define STBTT_malloc(x,u) ((void)(u), IM_ALLOC(x)) +#define STBTT_free(x,u) ((void)(u), IM_FREE(x)) +#define STBTT_assert(x) do { IM_ASSERT(x); } while(0) +#define STBTT_fmod(x,y) ImFmod(x,y) +#define STBTT_sqrt(x) ImSqrt(x) +#define STBTT_pow(x,y) ImPow(x,y) +#define STBTT_fabs(x) ImFabs(x) +#define STBTT_ifloor(x) ((int)ImFloorSigned(x)) +#define STBTT_iceil(x) ((int)ImCeil(x)) +#define STBTT_STATIC +#define STB_TRUETYPE_IMPLEMENTATION +#else +#define STBTT_DEF extern +#endif +#ifdef IMGUI_STB_TRUETYPE_FILENAME +#include IMGUI_STB_TRUETYPE_FILENAME +#else +#include "imstb_truetype.h" +#endif +#endif +#endif // IMGUI_ENABLE_STB_TRUETYPE + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif + +#ifdef IMGUI_STB_NAMESPACE +} // namespace ImStb +using namespace IMGUI_STB_NAMESPACE; +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Style functions +//----------------------------------------------------------------------------- + +void ImGui::StyleColorsDark(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); + colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 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_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); +} + +void ImGui::StyleColorsClassic(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); + colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.47f, 0.47f, 0.69f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.41f, 0.64f, 0.69f); + colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + 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.41f, 0.39f, 0.80f, 0.60f); + 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.41f, 0.39f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.40f, 0.48f, 0.71f, 0.79f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.46f, 0.54f, 0.80f, 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_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); + colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 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_TableHeaderBg] = ImVec4(0.27f, 0.27f, 0.38f, 1.00f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.45f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableBorderLight] = ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + +// Those light colors are better suited with a thicker font than the default one + FrameBorder +void ImGui::StyleColorsLight(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f); + colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f); + colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = ImVec4(0.78f, 0.87f, 0.98f, 1.00f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.57f, 0.57f, 0.64f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableBorderLight] = ImVec4(0.68f, 0.68f, 0.74f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.30f, 0.30f, 0.30f, 0.09f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + +//----------------------------------------------------------------------------- +// [SECTION] ImDrawList +//----------------------------------------------------------------------------- + +ImDrawListSharedData::ImDrawListSharedData() +{ + memset(this, 0, sizeof(*this)); + for (int i = 0; i < IM_ARRAYSIZE(ArcFastVtx); i++) + { + const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(ArcFastVtx); + ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a)); + } + ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError); +} + +void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) +{ + if (CircleSegmentMaxError == max_error) + return; + + IM_ASSERT(max_error > 0.0f); + CircleSegmentMaxError = max_error; + for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++) + { + const float radius = (float)i; + CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0); + } + ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError); +} + +// Initialize before use in a new frame. We always have a command ready in the buffer. +void ImDrawList::_ResetForNewFrame() +{ + // Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory. + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0); + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4)); + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); + if (_Splitter._Count > 1) + _Splitter.Merge(this); + + CmdBuffer.resize(0); + IdxBuffer.resize(0); + VtxBuffer.resize(0); + Flags = _Data->InitialFlags; + memset(&_CmdHeader, 0, sizeof(_CmdHeader)); + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.resize(0); + _TextureIdStack.resize(0); + _Path.resize(0); + _Splitter.Clear(); + CmdBuffer.push_back(ImDrawCmd()); + _FringeScale = 1.0f; +} + +void ImDrawList::_ClearFreeMemory() +{ + CmdBuffer.clear(); + IdxBuffer.clear(); + VtxBuffer.clear(); + Flags = ImDrawListFlags_None; + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.clear(); + _TextureIdStack.clear(); + _Path.clear(); + _Splitter.ClearFreeMemory(); +} + +ImDrawList* ImDrawList::CloneOutput() const +{ + ImDrawList* dst = IM_NEW(ImDrawList(_Data)); + dst->CmdBuffer = CmdBuffer; + dst->IdxBuffer = IdxBuffer; + dst->VtxBuffer = VtxBuffer; + dst->Flags = Flags; + return dst; +} + +void ImDrawList::AddDrawCmd() +{ + ImDrawCmd draw_cmd; + draw_cmd.ClipRect = _CmdHeader.ClipRect; // Same as calling ImDrawCmd_HeaderCopy() + draw_cmd.TextureId = _CmdHeader.TextureId; + draw_cmd.VtxOffset = _CmdHeader.VtxOffset; + draw_cmd.IdxOffset = IdxBuffer.Size; + + IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); + CmdBuffer.push_back(draw_cmd); +} + +// Pop trailing draw command (used before merging or presenting to user) +// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL +void ImDrawList::_PopUnusedDrawCmd() +{ + if (CmdBuffer.Size == 0) + return; + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); +} + +void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) +{ + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + IM_ASSERT(curr_cmd->UserCallback == NULL); + if (curr_cmd->ElemCount != 0) + { + AddDrawCmd(); + curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + } + curr_cmd->UserCallback = callback; + curr_cmd->UserCallbackData = callback_data; + + AddDrawCmd(); // Force a new command after us (see comment below) +} + +// Compare ClipRect, TextureId and VtxOffset with a single memcmp() +#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) +#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset +#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset +#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset) + +// Try to merge two last draw commands +void ImDrawList::_TryMergeDrawCmds() +{ + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + ImDrawCmd* prev_cmd = curr_cmd - 1; + if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL) + { + prev_cmd->ElemCount += curr_cmd->ElemCount; + CmdBuffer.pop_back(); + } +} + +// Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack. +// The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only. +void ImDrawList::_OnChangedClipRect() +{ + // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &_CmdHeader.ClipRect, sizeof(ImVec4)) != 0) + { + AddDrawCmd(); + return; + } + IM_ASSERT(curr_cmd->UserCallback == NULL); + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = curr_cmd - 1; + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL) + { + CmdBuffer.pop_back(); + return; + } + + curr_cmd->ClipRect = _CmdHeader.ClipRect; +} + +void ImDrawList::_OnChangedTextureID() +{ + // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != _CmdHeader.TextureId) + { + AddDrawCmd(); + return; + } + IM_ASSERT(curr_cmd->UserCallback == NULL); + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = curr_cmd - 1; + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL) + { + CmdBuffer.pop_back(); + return; + } + + curr_cmd->TextureId = _CmdHeader.TextureId; +} + +void ImDrawList::_OnChangedVtxOffset() +{ + // We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this. + _VtxCurrentIdx = 0; + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + //IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349 + if (curr_cmd->ElemCount != 0) + { + AddDrawCmd(); + return; + } + IM_ASSERT(curr_cmd->UserCallback == NULL); + curr_cmd->VtxOffset = _CmdHeader.VtxOffset; +} + +int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const +{ + // Automatic segment count + const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy + if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) + return _Data->CircleSegmentCounts[radius_idx]; // Use cached value + else + return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); +} + +// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) +void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) +{ + ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); + if (intersect_with_current_clip_rect) + { + ImVec4 current = _CmdHeader.ClipRect; + if (cr.x < current.x) cr.x = current.x; + if (cr.y < current.y) cr.y = current.y; + if (cr.z > current.z) cr.z = current.z; + if (cr.w > current.w) cr.w = current.w; + } + cr.z = ImMax(cr.x, cr.z); + cr.w = ImMax(cr.y, cr.w); + + _ClipRectStack.push_back(cr); + _CmdHeader.ClipRect = cr; + _OnChangedClipRect(); +} + +void ImDrawList::PushClipRectFullScreen() +{ + PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w)); +} + +void ImDrawList::PopClipRect() +{ + _ClipRectStack.pop_back(); + _CmdHeader.ClipRect = (_ClipRectStack.Size == 0) ? _Data->ClipRectFullscreen : _ClipRectStack.Data[_ClipRectStack.Size - 1]; + _OnChangedClipRect(); +} + +void ImDrawList::PushTextureID(ImTextureID texture_id) +{ + _TextureIdStack.push_back(texture_id); + _CmdHeader.TextureId = texture_id; + _OnChangedTextureID(); +} + +void ImDrawList::PopTextureID() +{ + _TextureIdStack.pop_back(); + _CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? (ImTextureID)NULL : _TextureIdStack.Data[_TextureIdStack.Size - 1]; + _OnChangedTextureID(); +} + +// Reserve space for a number of vertices and indices. +// You must finish filling your reserved data before calling PrimReserve() again, as it may reallocate or +// submit the intermediate results. PrimUnreserve() can be used to release unused allocations. +void ImDrawList::PrimReserve(int idx_count, int vtx_count) +{ + // Large mesh support (when enabled) + IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0); + if (sizeof(ImDrawIdx) == 2 && (_VtxCurrentIdx + vtx_count >= (1 << 16)) && (Flags & ImDrawListFlags_AllowVtxOffset)) + { + // FIXME: In theory we should be testing that vtx_count <64k here. + // In practice, RenderText() relies on reserving ahead for a worst case scenario so it is currently useful for us + // to not make that check until we rework the text functions to handle clipping and large horizontal lines better. + _CmdHeader.VtxOffset = VtxBuffer.Size; + _OnChangedVtxOffset(); + } + + ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + draw_cmd->ElemCount += idx_count; + + int vtx_buffer_old_size = VtxBuffer.Size; + VtxBuffer.resize(vtx_buffer_old_size + vtx_count); + _VtxWritePtr = VtxBuffer.Data + vtx_buffer_old_size; + + int idx_buffer_old_size = IdxBuffer.Size; + IdxBuffer.resize(idx_buffer_old_size + idx_count); + _IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size; +} + +// Release the a number of reserved vertices/indices from the end of the last reservation made with PrimReserve(). +void ImDrawList::PrimUnreserve(int idx_count, int vtx_count) +{ + IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0); + + ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + draw_cmd->ElemCount -= idx_count; + VtxBuffer.shrink(VtxBuffer.Size - vtx_count); + IdxBuffer.shrink(IdxBuffer.Size - idx_count); +} + +// Fully unrolled with inline call to keep our debug builds decently fast. +void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) +{ + ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) +{ + ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) +{ + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); + _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); + _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; +} + +// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superfluous function calls to optimize debug/non-inlined builds. +// - Those macros expects l-values and need to be used as their own statement. +// - Those macros are intentionally not surrounded by the 'do {} while (0)' idiom because even that translates to runtime with debug compilers. +#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = ImRsqrt(d2); VX *= inv_len; VY *= inv_len; } } (void)0 +#define IM_FIXNORMAL2F_MAX_INVLEN2 100.0f // 500.0f (see #4053, #3366) +#define IM_FIXNORMAL2F(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.000001f) { float inv_len2 = 1.0f / d2; if (inv_len2 > IM_FIXNORMAL2F_MAX_INVLEN2) inv_len2 = IM_FIXNORMAL2F_MAX_INVLEN2; VX *= inv_len2; VY *= inv_len2; } } (void)0 + +// TODO: Thickness anti-aliased lines cap are missing their AA fringe. +// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. +void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness) +{ + if (points_count < 2) + return; + + const bool closed = (flags & ImDrawFlags_Closed) != 0; + const ImVec2 opaque_uv = _Data->TexUvWhitePixel; + const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw + const bool thick_line = (thickness > _FringeScale); + + if (Flags & ImDrawListFlags_AntiAliasedLines) + { + // Anti-aliased stroke + const float AA_SIZE = _FringeScale; + const ImU32 col_trans = col & ~IM_COL32_A_MASK; + + // Thicknesses <1.0 should behave like thickness 1.0 + thickness = ImMax(thickness, 1.0f); + const int integer_thickness = (int)thickness; + const float fractional_thickness = thickness - integer_thickness; + + // Do we want to draw this line using a texture? + // - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved. + // - If AA_SIZE is not 1.0f we cannot use the texture path. + const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f); + + // We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off + IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)); + + const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12); + const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3); + PrimReserve(idx_count, vtx_count); + + // Temporary buffer + // The first items are normals at each line point, then after that there are either 2 or 4 temp points for each line point + ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630 + ImVec2* temp_points = temp_normals + points_count; + + // Calculate normals (tangents) for each line segment + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + float dx = points[i2].x - points[i1].x; + float dy = points[i2].y - points[i1].y; + IM_NORMALIZE2F_OVER_ZERO(dx, dy); + temp_normals[i1].x = dy; + temp_normals[i1].y = -dx; + } + if (!closed) + temp_normals[points_count - 1] = temp_normals[points_count - 2]; + + // If we are drawing a one-pixel-wide line without a texture, or a textured line of any width, we only need 2 or 3 vertices per point + if (use_texture || !thick_line) + { + // [PATH 1] Texture-based lines (thick or non-thick) + // [PATH 2] Non texture-based lines (non-thick) + + // The width of the geometry we need to draw - this is essentially pixels for the line itself, plus "one pixel" for AA. + // - In the texture-based path, we don't use AA_SIZE here because the +1 is tied to the generated texture + // (see ImFontAtlasBuildRenderLinesTexData() function), and so alternate values won't work without changes to that code. + // - In the non texture-based paths, we would allow AA_SIZE to potentially be != 1.0f with a patch (e.g. fringe_scale patch to + // allow scaling geometry while preserving one-screen-pixel AA fringe). + const float half_draw_size = use_texture ? ((thickness * 0.5f) + 1) : AA_SIZE; + + // If line is not closed, the first and last points need to be generated differently as there are no normals to blend + if (!closed) + { + temp_points[0] = points[0] + temp_normals[0] * half_draw_size; + temp_points[1] = points[0] - temp_normals[0] * half_draw_size; + temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * half_draw_size; + temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * half_draw_size; + } + + // Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges + // This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps) + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment + for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; // i2 is the second point of the line segment + const unsigned int idx2 = ((i1 + 1) == points_count) ? _VtxCurrentIdx : (idx1 + (use_texture ? 2 : 3)); // Vertex index for end of segment + + // Average normals + float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; + float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; + IM_FIXNORMAL2F(dm_x, dm_y); + dm_x *= half_draw_size; // dm_x, dm_y are offset to the outer edge of the AA area + dm_y *= half_draw_size; + + // Add temporary vertexes for the outer edges + ImVec2* out_vtx = &temp_points[i2 * 2]; + out_vtx[0].x = points[i2].x + dm_x; + out_vtx[0].y = points[i2].y + dm_y; + out_vtx[1].x = points[i2].x - dm_x; + out_vtx[1].y = points[i2].y - dm_y; + + if (use_texture) + { + // Add indices for two triangles + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 1); // Right tri + _IdxWritePtr[3] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[4] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Left tri + _IdxWritePtr += 6; + } + else + { + // Add indexes for four triangles + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); // Right tri 1 + _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); // Right tri 2 + _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); // Left tri 1 + _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); // Left tri 2 + _IdxWritePtr += 12; + } + + idx1 = idx2; + } + + // Add vertexes for each point on the line + if (use_texture) + { + // If we're using textures we only need to emit the left/right edge vertices + ImVec4 tex_uvs = _Data->TexUvLines[integer_thickness]; + /*if (fractional_thickness != 0.0f) // Currently always zero when use_texture==false! + { + const ImVec4 tex_uvs_1 = _Data->TexUvLines[integer_thickness + 1]; + tex_uvs.x = tex_uvs.x + (tex_uvs_1.x - tex_uvs.x) * fractional_thickness; // inlined ImLerp() + tex_uvs.y = tex_uvs.y + (tex_uvs_1.y - tex_uvs.y) * fractional_thickness; + tex_uvs.z = tex_uvs.z + (tex_uvs_1.z - tex_uvs.z) * fractional_thickness; + tex_uvs.w = tex_uvs.w + (tex_uvs_1.w - tex_uvs.w) * fractional_thickness; + }*/ + ImVec2 tex_uv0(tex_uvs.x, tex_uvs.y); + ImVec2 tex_uv1(tex_uvs.z, tex_uvs.w); + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = temp_points[i * 2 + 0]; _VtxWritePtr[0].uv = tex_uv0; _VtxWritePtr[0].col = col; // Left-side outer edge + _VtxWritePtr[1].pos = temp_points[i * 2 + 1]; _VtxWritePtr[1].uv = tex_uv1; _VtxWritePtr[1].col = col; // Right-side outer edge + _VtxWritePtr += 2; + } + } + else + { + // If we're not using a texture, we need the center vertex as well + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; // Center of line + _VtxWritePtr[1].pos = temp_points[i * 2 + 0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; // Left-side outer edge + _VtxWritePtr[2].pos = temp_points[i * 2 + 1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; // Right-side outer edge + _VtxWritePtr += 3; + } + } + } + else + { + // [PATH 2] Non texture-based lines (thick): we need to draw the solid line core and thus require four vertices per point + const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; + + // If line is not closed, the first and last points need to be generated differently as there are no normals to blend + if (!closed) + { + const int points_last = points_count - 1; + temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); + temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); + temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[points_last * 4 + 0] = points[points_last] + temp_normals[points_last] * (half_inner_thickness + AA_SIZE); + temp_points[points_last * 4 + 1] = points[points_last] + temp_normals[points_last] * (half_inner_thickness); + temp_points[points_last * 4 + 2] = points[points_last] - temp_normals[points_last] * (half_inner_thickness); + temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE); + } + + // Generate the indices to form a number of triangles for each line segment, and the vertices for the line edges + // This takes points n and n+1 and writes into n+1, with the first point in a closed line being generated from the final one (as n+1 wraps) + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; // Vertex index for start of line segment + for (int i1 = 0; i1 < count; i1++) // i1 is the first point of the line segment + { + const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment + const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment + + // Average normals + float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; + float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; + IM_FIXNORMAL2F(dm_x, dm_y); + float dm_out_x = dm_x * (half_inner_thickness + AA_SIZE); + float dm_out_y = dm_y * (half_inner_thickness + AA_SIZE); + float dm_in_x = dm_x * half_inner_thickness; + float dm_in_y = dm_y * half_inner_thickness; + + // Add temporary vertices + ImVec2* out_vtx = &temp_points[i2 * 4]; + out_vtx[0].x = points[i2].x + dm_out_x; + out_vtx[0].y = points[i2].y + dm_out_y; + out_vtx[1].x = points[i2].x + dm_in_x; + out_vtx[1].y = points[i2].y + dm_in_y; + out_vtx[2].x = points[i2].x - dm_in_x; + out_vtx[2].y = points[i2].y - dm_in_y; + out_vtx[3].x = points[i2].x - dm_out_x; + out_vtx[3].y = points[i2].y - dm_out_y; + + // Add indexes + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[12] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[13] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[14] = (ImDrawIdx)(idx1 + 3); + _IdxWritePtr[15] = (ImDrawIdx)(idx1 + 3); _IdxWritePtr[16] = (ImDrawIdx)(idx2 + 3); _IdxWritePtr[17] = (ImDrawIdx)(idx2 + 2); + _IdxWritePtr += 18; + + idx1 = idx2; + } + + // Add vertices + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = temp_points[i * 4 + 0]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col_trans; + _VtxWritePtr[1].pos = temp_points[i * 4 + 1]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = temp_points[i * 4 + 2]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = temp_points[i * 4 + 3]; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col_trans; + _VtxWritePtr += 4; + } + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // [PATH 4] Non texture-based, Non anti-aliased lines + const int idx_count = count * 6; + const int vtx_count = count * 4; // FIXME-OPT: Not sharing edges + PrimReserve(idx_count, vtx_count); + + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + const ImVec2& p1 = points[i1]; + const ImVec2& p2 = points[i2]; + + float dx = p2.x - p1.x; + float dy = p2.y - p1.y; + IM_NORMALIZE2F_OVER_ZERO(dx, dy); + dx *= (thickness * 0.5f); + dy *= (thickness * 0.5f); + + _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2); + _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3); + _IdxWritePtr += 6; + _VtxCurrentIdx += 4; + } + } +} + +// We intentionally avoid using ImVec2 and its math operators here to reduce cost to a minimum for debug/non-inlined builds. +void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) +{ + if (points_count < 3) + return; + + const ImVec2 uv = _Data->TexUvWhitePixel; + + if (Flags & ImDrawListFlags_AntiAliasedFill) + { + // Anti-aliased Fill + const float AA_SIZE = _FringeScale; + const ImU32 col_trans = col & ~IM_COL32_A_MASK; + const int idx_count = (points_count - 2)*3 + points_count * 6; + const int vtx_count = (points_count * 2); + PrimReserve(idx_count, vtx_count); + + // Add indexes for fill + unsigned int vtx_inner_idx = _VtxCurrentIdx; + unsigned int vtx_outer_idx = _VtxCurrentIdx + 1; + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + ((i - 1) << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (i << 1)); + _IdxWritePtr += 3; + } + + // Compute normals + ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630 + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + const ImVec2& p0 = points[i0]; + const ImVec2& p1 = points[i1]; + float dx = p1.x - p0.x; + float dy = p1.y - p0.y; + IM_NORMALIZE2F_OVER_ZERO(dx, dy); + temp_normals[i0].x = dy; + temp_normals[i0].y = -dx; + } + + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + // Average normals + const ImVec2& n0 = temp_normals[i0]; + const ImVec2& n1 = temp_normals[i1]; + float dm_x = (n0.x + n1.x) * 0.5f; + float dm_y = (n0.y + n1.y) * 0.5f; + IM_FIXNORMAL2F(dm_x, dm_y); + dm_x *= AA_SIZE * 0.5f; + dm_y *= AA_SIZE * 0.5f; + + // Add vertices + _VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer + _VtxWritePtr += 2; + + // Add indexes for fringes + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); + _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); + _IdxWritePtr += 6; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Fill + const int idx_count = (points_count - 2)*3; + const int vtx_count = points_count; + PrimReserve(idx_count, vtx_count); + for (int i = 0; i < vtx_count; i++) + { + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr++; + } + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + i - 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + i); + _IdxWritePtr += 3; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } +} + +void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step) +{ + if (radius <= 0.0f) + { + _Path.push_back(center); + return; + } + + // Calculate arc auto segment step size + if (a_step <= 0) + a_step = IM_DRAWLIST_ARCFAST_SAMPLE_MAX / _CalcCircleAutoSegmentCount(radius); + + // Make sure we never do steps larger than one quarter of the circle + a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4); + + const int sample_range = ImAbs(a_max_sample - a_min_sample); + const int a_next_step = a_step; + + int samples = sample_range + 1; + bool extra_max_sample = false; + if (a_step > 1) + { + samples = sample_range / a_step + 1; + const int overstep = sample_range % a_step; + + if (overstep > 0) + { + extra_max_sample = true; + samples++; + + // When we have overstep to avoid awkwardly looking one long line and one tiny one at the end, + // distribute first step range evenly between them by reducing first step size. + if (sample_range > 0) + a_step -= (a_step - overstep) / 2; + } + } + + _Path.resize(_Path.Size + samples); + ImVec2* out_ptr = _Path.Data + (_Path.Size - samples); + + int sample_index = a_min_sample; + if (sample_index < 0 || sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) + { + sample_index = sample_index % IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + if (sample_index < 0) + sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + } + + if (a_max_sample >= a_min_sample) + { + for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step) + { + // a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more + if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) + sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + + const ImVec2 s = _Data->ArcFastVtx[sample_index]; + out_ptr->x = center.x + s.x * radius; + out_ptr->y = center.y + s.y * radius; + out_ptr++; + } + } + else + { + for (int a = a_min_sample; a >= a_max_sample; a -= a_step, sample_index -= a_step, a_step = a_next_step) + { + // a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more + if (sample_index < 0) + sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + + const ImVec2 s = _Data->ArcFastVtx[sample_index]; + out_ptr->x = center.x + s.x * radius; + out_ptr->y = center.y + s.y * radius; + out_ptr++; + } + } + + if (extra_max_sample) + { + int normalized_max_sample = a_max_sample % IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + if (normalized_max_sample < 0) + normalized_max_sample += IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + + const ImVec2 s = _Data->ArcFastVtx[normalized_max_sample]; + out_ptr->x = center.x + s.x * radius; + out_ptr->y = center.y + s.y * radius; + out_ptr++; + } + + IM_ASSERT_PARANOID(_Path.Data + _Path.Size == out_ptr); +} + +void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) +{ + if (radius <= 0.0f) + { + _Path.push_back(center); + return; + } + + // Note that we are adding a point at both a_min and a_max. + // If you are trying to draw a full closed circle you don't want the overlapping points! + _Path.reserve(_Path.Size + (num_segments + 1)); + for (int i = 0; i <= num_segments; i++) + { + const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); + _Path.push_back(ImVec2(center.x + ImCos(a) * radius, center.y + ImSin(a) * radius)); + } +} + +// 0: East, 3: South, 6: West, 9: North, 12: East +void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12) +{ + if (radius <= 0.0f) + { + _Path.push_back(center); + return; + } + _PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0); +} + +void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) +{ + if (radius <= 0.0f) + { + _Path.push_back(center); + return; + } + + if (num_segments > 0) + { + _PathArcToN(center, radius, a_min, a_max, num_segments); + return; + } + + // Automatic segment count + if (radius <= _Data->ArcFastRadiusCutoff) + { + const bool a_is_reverse = a_max < a_min; + + // We are going to use precomputed values for mid samples. + // Determine first and last sample in lookup table that belong to the arc. + const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f); + const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f); + + const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f); + const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f); + const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0); + + const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; + const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f; + const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f; + + _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); + if (a_emit_start) + _Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius)); + if (a_mid_samples > 0) + _PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0); + if (a_emit_end) + _Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius)); + } + else + { + const float arc_length = ImAbs(a_max - a_min); + const int circle_segment_count = _CalcCircleAutoSegmentCount(radius); + const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length)); + _PathArcToN(center, radius, a_min, a_max, arc_segment_count); + } +} + +ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t) +{ + float u = 1.0f - t; + float w1 = u * u * u; + float w2 = 3 * u * u * t; + float w3 = 3 * u * t * t; + float w4 = t * t * t; + return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x, w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y); +} + +ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t) +{ + float u = 1.0f - t; + float w1 = u * u; + float w2 = 2 * u * t; + float w3 = t * t; + return ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x, w1 * p1.y + w2 * p2.y + w3 * p3.y); +} + +// Closely mimics ImBezierCubicClosestPointCasteljau() in imgui.cpp +static void PathBezierCubicCurveToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) +{ + float dx = x4 - x1; + float dy = y4 - y1; + float d2 = (x2 - x4) * dy - (y2 - y4) * dx; + float d3 = (x3 - x4) * dy - (y3 - y4) * dx; + d2 = (d2 >= 0) ? d2 : -d2; + d3 = (d3 >= 0) ? d3 : -d3; + if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) + { + path->push_back(ImVec2(x4, y4)); + } + else if (level < 10) + { + float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; + float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f; + float x34 = (x3 + x4) * 0.5f, y34 = (y3 + y4) * 0.5f; + float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; + float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f; + float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f; + PathBezierCubicCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); + PathBezierCubicCurveToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + } +} + +static void PathBezierQuadraticCurveToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float tess_tol, int level) +{ + float dx = x3 - x1, dy = y3 - y1; + float det = (x2 - x3) * dy - (y2 - y3) * dx; + if (det * det * 4.0f < tess_tol * (dx * dx + dy * dy)) + { + path->push_back(ImVec2(x3, y3)); + } + else if (level < 10) + { + float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; + float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f; + float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; + PathBezierQuadraticCurveToCasteljau(path, x1, y1, x12, y12, x123, y123, tess_tol, level + 1); + PathBezierQuadraticCurveToCasteljau(path, x123, y123, x23, y23, x3, y3, tess_tol, level + 1); + } +} + +void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) +{ + ImVec2 p1 = _Path.back(); + if (num_segments == 0) + { + PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated + } + else + { + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + _Path.push_back(ImBezierCubicCalc(p1, p2, p3, p4, t_step * i_step)); + } +} + +void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments) +{ + ImVec2 p1 = _Path.back(); + if (num_segments == 0) + { + PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated + } + else + { + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + _Path.push_back(ImBezierQuadraticCalc(p1, p2, p3, t_step * i_step)); + } +} + +IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4)); +static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags) +{ +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All) + // ~0 --> ImDrawFlags_RoundCornersAll or 0 + if (flags == ~0) + return ImDrawFlags_RoundCornersAll; + + // Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations) + // 0x01 --> ImDrawFlags_RoundCornersTopLeft (VALUE 0x01 OVERLAPS ImDrawFlags_Closed but ImDrawFlags_Closed is never valid in this path!) + // 0x02 --> ImDrawFlags_RoundCornersTopRight + // 0x03 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight + // 0x04 --> ImDrawFlags_RoundCornersBotLeft + // 0x05 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBotLeft + // ... + // 0x0F --> ImDrawFlags_RoundCornersAll or 0 + // (See all values in ImDrawCornerFlags_) + if (flags >= 0x01 && flags <= 0x0F) + return (flags << 4); + + // We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f' +#endif + + // If this triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values. + // Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc... + IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!"); + + if ((flags & ImDrawFlags_RoundCornersMask_) == 0) + flags |= ImDrawFlags_RoundCornersAll; + + return flags; +} + +void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags) +{ + flags = FixRectCornerFlags(flags); + rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f ) - 1.0f); + + if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + { + PathLineTo(a); + PathLineTo(ImVec2(b.x, a.y)); + PathLineTo(b); + PathLineTo(ImVec2(a.x, b.y)); + } + else + { + const float rounding_tl = (flags & ImDrawFlags_RoundCornersTopLeft) ? rounding : 0.0f; + const float rounding_tr = (flags & ImDrawFlags_RoundCornersTopRight) ? rounding : 0.0f; + const float rounding_br = (flags & ImDrawFlags_RoundCornersBottomRight) ? rounding : 0.0f; + const float rounding_bl = (flags & ImDrawFlags_RoundCornersBottomLeft) ? rounding : 0.0f; + PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9); + PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12); + PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3); + PathArcToFast(ImVec2(a.x + rounding_bl, b.y - rounding_bl), rounding_bl, 3, 6); + } +} + +void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + PathLineTo(p1 + ImVec2(0.5f, 0.5f)); + PathLineTo(p2 + ImVec2(0.5f, 0.5f)); + PathStroke(col, 0, thickness); +} + +// p_min = upper-left, p_max = lower-right +// Note we don't render 1 pixels sized rectangles properly. +void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + if (Flags & ImDrawListFlags_AntiAliasedLines) + PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.50f, 0.50f), rounding, flags); + else + PathRect(p_min + ImVec2(0.50f, 0.50f), p_max - ImVec2(0.49f, 0.49f), rounding, flags); // Better looking lower-right corner and rounded non-AA shapes. + PathStroke(col, ImDrawFlags_Closed, thickness); +} + +void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + { + PrimReserve(6, 4); + PrimRect(p_min, p_max, col); + } + else + { + PathRect(p_min, p_max, rounding, flags); + PathFillConvex(col); + } +} + +// p_min = upper-left, p_max = lower-right +void ImDrawList::AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) +{ + if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0) + return; + + const ImVec2 uv = _Data->TexUvWhitePixel; + PrimReserve(6, 4); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 2)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 3)); + PrimWriteVtx(p_min, uv, col_upr_left); + PrimWriteVtx(ImVec2(p_max.x, p_min.y), uv, col_upr_right); + PrimWriteVtx(p_max, uv, col_bot_right); + PrimWriteVtx(ImVec2(p_min.x, p_max.y), uv, col_bot_left); +} + +void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathLineTo(p2); + PathLineTo(p3); + PathLineTo(p4); + PathStroke(col, ImDrawFlags_Closed, thickness); +} + +void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathLineTo(p2); + PathLineTo(p3); + PathLineTo(p4); + PathFillConvex(col); +} + +void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathLineTo(p2); + PathLineTo(p3); + PathStroke(col, ImDrawFlags_Closed, thickness); +} + +void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathLineTo(p2); + PathLineTo(p3); + PathFillConvex(col); +} + +void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f) + return; + + if (num_segments <= 0) + { + // Use arc with automatic segment count + _PathArcToFastEx(center, radius - 0.5f, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0); + _Path.Size--; + } + else + { + // Explicit segment count (still clamp to avoid drawing insanely tessellated shapes) + num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX); + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); + } + + PathStroke(col, ImDrawFlags_Closed, thickness); +} + +void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f) + return; + + if (num_segments <= 0) + { + // Use arc with automatic segment count + _PathArcToFastEx(center, radius, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0); + _Path.Size--; + } + else + { + // Explicit segment count (still clamp to avoid drawing insanely tessellated shapes) + num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX); + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius, 0.0f, a_max, num_segments - 1); + } + + PathFillConvex(col); +} + +// Guaranteed to honor 'num_segments' +void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2) + return; + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); + PathStroke(col, ImDrawFlags_Closed, thickness); +} + +// Guaranteed to honor 'num_segments' +void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2) + return; + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius, 0.0f, a_max, num_segments - 1); + PathFillConvex(col); +} + +// Cubic Bezier takes 4 controls points +void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathBezierCubicCurveTo(p2, p3, p4, num_segments); + PathStroke(col, 0, thickness); +} + +// Quadratic Bezier takes 3 controls points +void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + PathLineTo(p1); + PathBezierQuadraticCurveTo(p2, p3, num_segments); + PathStroke(col, 0, thickness); +} + +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 ImVec4* cpu_fine_clip_rect) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + if (text_end == NULL) + text_end = text_begin + strlen(text_begin); + if (text_begin == text_end) + return; + + // Pull default font/size from the shared ImDrawListSharedData instance + if (font == NULL) + font = _Data->Font; + if (font_size == 0.0f) + font_size = _Data->FontSize; + + IM_ASSERT(font->ContainerAtlas->TexID == _CmdHeader.TextureId); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. + + ImVec4 clip_rect = _CmdHeader.ClipRect; + if (cpu_fine_clip_rect) + { + clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); + clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); + clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); + clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); + } + font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL); +} + +void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) +{ + AddText(NULL, 0.0f, pos, col, text_begin, text_end); +} + +void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + const bool push_texture_id = user_texture_id != _CmdHeader.TextureId; + if (push_texture_id) + PushTextureID(user_texture_id); + + PrimReserve(6, 4); + PrimRectUV(p_min, p_max, uv_min, uv_max, col); + + if (push_texture_id) + PopTextureID(); +} + +void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1, const ImVec2& uv2, const ImVec2& uv3, const ImVec2& uv4, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + const bool push_texture_id = user_texture_id != _CmdHeader.TextureId; + if (push_texture_id) + PushTextureID(user_texture_id); + + PrimReserve(6, 4); + PrimQuadUV(p1, p2, p3, p4, uv1, uv2, uv3, uv4, col); + + if (push_texture_id) + PopTextureID(); +} + +void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + flags = FixRectCornerFlags(flags); + if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + { + AddImage(user_texture_id, p_min, p_max, uv_min, uv_max, col); + return; + } + + const bool push_texture_id = user_texture_id != _CmdHeader.TextureId; + if (push_texture_id) + PushTextureID(user_texture_id); + + int vert_start_idx = VtxBuffer.Size; + PathRect(p_min, p_max, rounding, flags); + PathFillConvex(col); + int vert_end_idx = VtxBuffer.Size; + ImGui::ShadeVertsLinearUV(this, vert_start_idx, vert_end_idx, p_min, p_max, uv_min, uv_max, true); + + if (push_texture_id) + PopTextureID(); +} + + +//----------------------------------------------------------------------------- +// [SECTION] ImDrawListSplitter +//----------------------------------------------------------------------------- +// FIXME: This may be a little confusing, trying to be a little too low-level/optimal instead of just doing vector swap.. +//----------------------------------------------------------------------------- + +void ImDrawListSplitter::ClearFreeMemory() +{ + for (int i = 0; i < _Channels.Size; i++) + { + if (i == _Current) + memset(&_Channels[i], 0, sizeof(_Channels[i])); // Current channel is a copy of CmdBuffer/IdxBuffer, don't destruct again + _Channels[i]._CmdBuffer.clear(); + _Channels[i]._IdxBuffer.clear(); + } + _Current = 0; + _Count = 1; + _Channels.clear(); +} + +void ImDrawListSplitter::Split(ImDrawList* draw_list, int channels_count) +{ + IM_UNUSED(draw_list); + IM_ASSERT(_Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter."); + int old_channels_count = _Channels.Size; + if (old_channels_count < channels_count) + { + _Channels.reserve(channels_count); // Avoid over reserving since this is likely to stay stable + _Channels.resize(channels_count); + } + _Count = channels_count; + + // Channels[] (24/32 bytes each) hold storage that we'll swap with draw_list->_CmdBuffer/_IdxBuffer + // The content of Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to. + // When we switch to the next channel, we'll copy draw_list->_CmdBuffer/_IdxBuffer into Channels[0] and then Channels[1] into draw_list->CmdBuffer/_IdxBuffer + memset(&_Channels[0], 0, sizeof(ImDrawChannel)); + for (int i = 1; i < channels_count; i++) + { + if (i >= old_channels_count) + { + IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel(); + } + else + { + _Channels[i]._CmdBuffer.resize(0); + _Channels[i]._IdxBuffer.resize(0); + } + } +} + +void ImDrawListSplitter::Merge(ImDrawList* draw_list) +{ + // Note that we never use or rely on _Channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use. + if (_Count <= 1) + return; + + SetCurrentChannel(draw_list, 0); + draw_list->_PopUnusedDrawCmd(); + + // Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command. + int new_cmd_buffer_count = 0; + int new_idx_buffer_count = 0; + ImDrawCmd* last_cmd = (_Count > 0 && draw_list->CmdBuffer.Size > 0) ? &draw_list->CmdBuffer.back() : NULL; + int idx_offset = last_cmd ? last_cmd->IdxOffset + last_cmd->ElemCount : 0; + for (int i = 1; i < _Count; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0 && ch._CmdBuffer.back().UserCallback == NULL) // Equivalent of PopUnusedDrawCmd() + ch._CmdBuffer.pop_back(); + + if (ch._CmdBuffer.Size > 0 && last_cmd != NULL) + { + // Do not include ImDrawCmd_AreSequentialIdxOffset() in the compare as we rebuild IdxOffset values ourselves. + // Manipulating IdxOffset (e.g. by reordering draw commands like done by RenderDimmedBackgroundBehindWindow()) is not supported within a splitter. + ImDrawCmd* next_cmd = &ch._CmdBuffer[0]; + if (ImDrawCmd_HeaderCompare(last_cmd, next_cmd) == 0 && last_cmd->UserCallback == NULL && next_cmd->UserCallback == NULL) + { + // Merge previous channel last draw command with current channel first draw command if matching. + last_cmd->ElemCount += next_cmd->ElemCount; + idx_offset += next_cmd->ElemCount; + ch._CmdBuffer.erase(ch._CmdBuffer.Data); // FIXME-OPT: Improve for multiple merges. + } + } + if (ch._CmdBuffer.Size > 0) + last_cmd = &ch._CmdBuffer.back(); + new_cmd_buffer_count += ch._CmdBuffer.Size; + new_idx_buffer_count += ch._IdxBuffer.Size; + for (int cmd_n = 0; cmd_n < ch._CmdBuffer.Size; cmd_n++) + { + ch._CmdBuffer.Data[cmd_n].IdxOffset = idx_offset; + idx_offset += ch._CmdBuffer.Data[cmd_n].ElemCount; + } + } + draw_list->CmdBuffer.resize(draw_list->CmdBuffer.Size + new_cmd_buffer_count); + draw_list->IdxBuffer.resize(draw_list->IdxBuffer.Size + new_idx_buffer_count); + + // Write commands and indices in order (they are fairly small structures, we don't copy vertices only indices) + ImDrawCmd* cmd_write = draw_list->CmdBuffer.Data + draw_list->CmdBuffer.Size - new_cmd_buffer_count; + ImDrawIdx* idx_write = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size - new_idx_buffer_count; + for (int i = 1; i < _Count; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (int sz = ch._CmdBuffer.Size) { memcpy(cmd_write, ch._CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; } + if (int sz = ch._IdxBuffer.Size) { memcpy(idx_write, ch._IdxBuffer.Data, sz * sizeof(ImDrawIdx)); idx_write += sz; } + } + draw_list->_IdxWritePtr = idx_write; + + // Ensure there's always a non-callback draw command trailing the command-buffer + if (draw_list->CmdBuffer.Size == 0 || draw_list->CmdBuffer.back().UserCallback != NULL) + draw_list->AddDrawCmd(); + + // If current command is used with different settings we need to add a new command + ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount == 0) + ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset + else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0) + draw_list->AddDrawCmd(); + + _Count = 1; +} + +void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx) +{ + IM_ASSERT(idx >= 0 && idx < _Count); + if (_Current == idx) + return; + + // Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap() + memcpy(&_Channels.Data[_Current]._CmdBuffer, &draw_list->CmdBuffer, sizeof(draw_list->CmdBuffer)); + memcpy(&_Channels.Data[_Current]._IdxBuffer, &draw_list->IdxBuffer, sizeof(draw_list->IdxBuffer)); + _Current = idx; + memcpy(&draw_list->CmdBuffer, &_Channels.Data[idx]._CmdBuffer, sizeof(draw_list->CmdBuffer)); + memcpy(&draw_list->IdxBuffer, &_Channels.Data[idx]._IdxBuffer, sizeof(draw_list->IdxBuffer)); + draw_list->_IdxWritePtr = draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size; + + // If current command is used with different settings we need to add a new command + ImDrawCmd* curr_cmd = (draw_list->CmdBuffer.Size == 0) ? NULL : &draw_list->CmdBuffer.Data[draw_list->CmdBuffer.Size - 1]; + if (curr_cmd == NULL) + draw_list->AddDrawCmd(); + else if (curr_cmd->ElemCount == 0) + ImDrawCmd_HeaderCopy(curr_cmd, &draw_list->_CmdHeader); // Copy ClipRect, TextureId, VtxOffset + else if (ImDrawCmd_HeaderCompare(curr_cmd, &draw_list->_CmdHeader) != 0) + draw_list->AddDrawCmd(); +} + +//----------------------------------------------------------------------------- +// [SECTION] ImDrawData +//----------------------------------------------------------------------------- + +// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! +void ImDrawData::DeIndexAllBuffers() +{ + ImVector new_vtx_buffer; + TotalVtxCount = TotalIdxCount = 0; + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + if (cmd_list->IdxBuffer.empty()) + continue; + new_vtx_buffer.resize(cmd_list->IdxBuffer.Size); + for (int j = 0; j < cmd_list->IdxBuffer.Size; j++) + new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]]; + cmd_list->VtxBuffer.swap(new_vtx_buffer); + cmd_list->IdxBuffer.resize(0); + TotalVtxCount += cmd_list->VtxBuffer.Size; + } +} + +// Helper to scale the ClipRect field of each ImDrawCmd. +// Use if your final output buffer is at a different scale than draw_data->DisplaySize, +// or if there is a difference between your window resolution and framebuffer resolution. +void ImDrawData::ScaleClipRects(const ImVec2& fb_scale) +{ + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i]; + cmd->ClipRect = ImVec4(cmd->ClipRect.x * fb_scale.x, cmd->ClipRect.y * fb_scale.y, cmd->ClipRect.z * fb_scale.x, cmd->ClipRect.w * fb_scale.y); + } + } +} + +//----------------------------------------------------------------------------- +// [SECTION] Helpers ShadeVertsXXX functions +//----------------------------------------------------------------------------- + +// Generic linear color gradient, write to RGB fields, leave A untouched. +void ImGui::ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) +{ + ImVec2 gradient_extent = gradient_p1 - gradient_p0; + float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); + ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx; + ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx; + const int col0_r = (int)(col0 >> IM_COL32_R_SHIFT) & 0xFF; + const int col0_g = (int)(col0 >> IM_COL32_G_SHIFT) & 0xFF; + const int col0_b = (int)(col0 >> IM_COL32_B_SHIFT) & 0xFF; + const int col_delta_r = ((int)(col1 >> IM_COL32_R_SHIFT) & 0xFF) - col0_r; + const int col_delta_g = ((int)(col1 >> IM_COL32_G_SHIFT) & 0xFF) - col0_g; + const int col_delta_b = ((int)(col1 >> IM_COL32_B_SHIFT) & 0xFF) - col0_b; + for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) + { + float d = ImDot(vert->pos - gradient_p0, gradient_extent); + float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); + int r = (int)(col0_r + col_delta_r * t); + int g = (int)(col0_g + col_delta_g * t); + int b = (int)(col0_b + col_delta_b * t); + vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); + } +} + +// Distribute UV over (a, b) rectangle +void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp) +{ + const ImVec2 size = b - a; + const ImVec2 uv_size = uv_b - uv_a; + const ImVec2 scale = ImVec2( + size.x != 0.0f ? (uv_size.x / size.x) : 0.0f, + size.y != 0.0f ? (uv_size.y / size.y) : 0.0f); + + ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx; + ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx; + if (clamp) + { + const ImVec2 min = ImMin(uv_a, uv_b); + const ImVec2 max = ImMax(uv_a, uv_b); + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = ImClamp(uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale), min, max); + } + else + { + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] ImFontConfig +//----------------------------------------------------------------------------- + +ImFontConfig::ImFontConfig() +{ + memset(this, 0, sizeof(*this)); + FontDataOwnedByAtlas = true; + OversampleH = 3; // FIXME: 2 may be a better default? + OversampleV = 1; + GlyphMaxAdvanceX = FLT_MAX; + RasterizerMultiply = 1.0f; + EllipsisChar = (ImWchar)-1; +} + +//----------------------------------------------------------------------------- +// [SECTION] ImFontAtlas +//----------------------------------------------------------------------------- + +// A work of art lies ahead! (. = white layer, X = black layer, others are blank) +// The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes. +// (This is used when io.MouseDrawCursor = true) +const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 122; // Actual texture will be 2 times that + 1 spacing. +const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; +static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = +{ + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX - XX XX " + "..- -X.....X- X.X - X.X -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 - 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...X " + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X- X..XXX - X.....X " + "X..X - X.X - X.X - X.X -XX X.X - X.X XX- X..X..XXX - X...X " + "X...X - X.X - X.X - XX X.X XX - X.X - X.X - X..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 -XXX X..X..X..X..X- X.....X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.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...XXXXXX.XXXXXX...X - X.X..X-X..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..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X - X.............X- XX XX " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X - X............X--------------" + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX - X...........X - " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------- X..........X - " + "X.X X..X - -X.......X- X.......X - XX 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 - " + " XX - - X.X - X.X - X...XXXXXXXXXXXXX...X - - XXXXXXXXXX - " + "------------- - X - X -X.....................X- ------------------- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - " +}; + +static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3] = +{ + // Pos ........ Size ......... Offset ...... + { ImVec2( 0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow + { ImVec2(13,0), ImVec2( 7,16), ImVec2( 1, 8) }, // ImGuiMouseCursor_TextInput + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_ResizeAll + { ImVec2(21,0), ImVec2( 9,23), ImVec2( 4,11) }, // ImGuiMouseCursor_ResizeNS + { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 4) }, // ImGuiMouseCursor_ResizeEW + { ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW + { ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE + { ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand + { ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed +}; + +ImFontAtlas::ImFontAtlas() +{ + memset(this, 0, sizeof(*this)); + TexGlyphPadding = 1; + PackIdMouseCursors = PackIdLines = -1; +} + +ImFontAtlas::~ImFontAtlas() +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + Clear(); +} + +void ImFontAtlas::ClearInputData() +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + for (int i = 0; i < ConfigData.Size; i++) + if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas) + { + IM_FREE(ConfigData[i].FontData); + ConfigData[i].FontData = NULL; + } + + // When clearing this we lose access to the font name and other information used to build the font. + for (int i = 0; i < Fonts.Size; i++) + if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) + { + Fonts[i]->ConfigData = NULL; + Fonts[i]->ConfigDataCount = 0; + } + ConfigData.clear(); + CustomRects.clear(); + PackIdMouseCursors = PackIdLines = -1; + // Important: we leave TexReady untouched +} + +void ImFontAtlas::ClearTexData() +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + if (TexPixelsAlpha8) + IM_FREE(TexPixelsAlpha8); + if (TexPixelsRGBA32) + IM_FREE(TexPixelsRGBA32); + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; + TexPixelsUseColors = false; + // Important: we leave TexReady untouched +} + +void ImFontAtlas::ClearFonts() +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + Fonts.clear_delete(); + TexReady = false; +} + +void ImFontAtlas::Clear() +{ + ClearInputData(); + ClearTexData(); + ClearFonts(); +} + +void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +{ + // Build atlas on demand + if (TexPixelsAlpha8 == NULL) + 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) +{ + // Convert to RGBA32 format on demand + // Although it is likely to be the most commonly used format, our font rendering is 1 channel / 8 bpp + if (!TexPixelsRGBA32) + { + unsigned char* pixels = NULL; + GetTexDataAsAlpha8(&pixels, NULL, NULL); + if (pixels) + { + TexPixelsRGBA32 = (unsigned int*)IM_ALLOC((size_t)TexWidth * (size_t)TexHeight * 4); + const unsigned char* src = pixels; + unsigned int* dst = TexPixelsRGBA32; + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); + } + } + + *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; +} + +ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0); + IM_ASSERT(font_cfg->SizePixels > 0.0f); + + // Create new font + if (!font_cfg->MergeMode) + Fonts.push_back(IM_NEW(ImFont)); + else + IM_ASSERT(!Fonts.empty() && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. + + ConfigData.push_back(*font_cfg); + ImFontConfig& new_font_cfg = ConfigData.back(); + if (new_font_cfg.DstFont == NULL) + new_font_cfg.DstFont = Fonts.back(); + if (!new_font_cfg.FontDataOwnedByAtlas) + { + new_font_cfg.FontData = IM_ALLOC(new_font_cfg.FontDataSize); + new_font_cfg.FontDataOwnedByAtlas = true; + memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize); + } + + if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1) + new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar; + + // Invalidate texture + TexReady = false; + ClearTexData(); + return new_font_cfg.DstFont; +} + +// Default font TTF is compressed with stb_compress then base85 encoded (see misc/fonts/binary_to_compressed_c.cpp for encoder) +static unsigned int stb_decompress_length(const unsigned char* input); +static unsigned int stb_decompress(unsigned char* output, const unsigned char* input, unsigned int length); +static const char* GetDefaultCompressedFontDataTTFBase85(); +static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; } +static void Decode85(const unsigned char* src, unsigned char* dst) +{ + while (*src) + { + unsigned int tmp = Decode85Byte(src[0]) + 85 * (Decode85Byte(src[1]) + 85 * (Decode85Byte(src[2]) + 85 * (Decode85Byte(src[3]) + 85 * Decode85Byte(src[4])))); + dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness. + src += 5; + dst += 4; + } +} + +// Load embedded ProggyClean.ttf at size 13, disable oversampling +ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) +{ + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (!font_cfg_template) + { + font_cfg.OversampleH = font_cfg.OversampleV = 1; + font_cfg.PixelSnapH = true; + } + if (font_cfg.SizePixels <= 0.0f) + font_cfg.SizePixels = 13.0f * 1.0f; + if (font_cfg.Name[0] == '\0') + ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels); + font_cfg.EllipsisChar = (ImWchar)0x0085; + font_cfg.GlyphOffset.y = 1.0f * IM_FLOOR(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units + + const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); + const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault(); + ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_cfg.SizePixels, &font_cfg, glyph_ranges); + return font; +} + +ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + size_t data_size = 0; + void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0); + if (!data) + { + IM_ASSERT_USER_ERROR(0, "Could not load font file!"); + return NULL; + } + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (font_cfg.Name[0] == '\0') + { + // Store a short copy of filename into into the font name for convenience + const char* p; + for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} + ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); + } + return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges); +} + +// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). +ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontData = ttf_data; + font_cfg.FontDataSize = ttf_size; + font_cfg.SizePixels = size_pixels > 0.0f ? size_pixels : font_cfg.SizePixels; + if (glyph_ranges) + font_cfg.GlyphRanges = glyph_ranges; + return AddFont(&font_cfg); +} + +ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) +{ + const unsigned int buf_decompressed_size = stb_decompress_length((const unsigned char*)compressed_ttf_data); + unsigned char* buf_decompressed_data = (unsigned char*)IM_ALLOC(buf_decompressed_size); + stb_decompress(buf_decompressed_data, (const unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); + + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontDataOwnedByAtlas = true; + return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, &font_cfg, glyph_ranges); +} + +ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) +{ + int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; + void* compressed_ttf = IM_ALLOC((size_t)compressed_ttf_size); + Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); + ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); + IM_FREE(compressed_ttf); + return font; +} + +int ImFontAtlas::AddCustomRectRegular(int width, int height) +{ + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + ImFontAtlasCustomRect r; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index +} + +int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset) +{ +#ifdef IMGUI_USE_WCHAR32 + IM_ASSERT(id <= IM_UNICODE_CODEPOINT_MAX); +#endif + IM_ASSERT(font != NULL); + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + ImFontAtlasCustomRect r; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + r.GlyphID = id; + r.GlyphAdvanceX = advance_x; + r.GlyphOffset = offset; + r.Font = font; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index +} + +void ImFontAtlas::CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) const +{ + IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates + IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed + *out_uv_min = ImVec2((float)rect->X * TexUvScale.x, (float)rect->Y * TexUvScale.y); + *out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y); +} + +bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) +{ + if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_COUNT) + return false; + if (Flags & ImFontAtlasFlags_NoMouseCursors) + return false; + + IM_ASSERT(PackIdMouseCursors != -1); + ImFontAtlasCustomRect* r = GetCustomRectByIndex(PackIdMouseCursors); + ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r->X, (float)r->Y); + ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; + *out_size = size; + *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; + out_uv_border[0] = (pos) * TexUvScale; + out_uv_border[1] = (pos + size) * TexUvScale; + pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1; + out_uv_fill[0] = (pos) * TexUvScale; + out_uv_fill[1] = (pos + size) * TexUvScale; + return true; +} + +bool ImFontAtlas::Build() +{ + IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"); + + // Default font is none are specified + if (ConfigData.Size == 0) + AddFontDefault(); + + // Select builder + // - Note that we do not reassign to atlas->FontBuilderIO, since it is likely to point to static data which + // may mess with some hot-reloading schemes. If you need to assign to this (for dynamic selection) AND are + // using a hot-reloading scheme that messes up static data, store your own instance of ImFontBuilderIO somewhere + // and point to it instead of pointing directly to return value of the GetBuilderXXX functions. + const ImFontBuilderIO* builder_io = FontBuilderIO; + if (builder_io == NULL) + { +#ifdef IMGUI_ENABLE_FREETYPE + builder_io = ImGuiFreeType::GetBuilderForFreeType(); +#elif defined(IMGUI_ENABLE_STB_TRUETYPE) + builder_io = ImFontAtlasGetBuilderForStbTruetype(); +#else + IM_ASSERT(0); // Invalid Build function +#endif + } + + // Build + return builder_io->FontBuilder_Build(this); +} + +void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor) +{ + for (unsigned int i = 0; i < 256; i++) + { + unsigned int value = (unsigned int)(i * in_brighten_factor); + out_table[i] = value > 255 ? 255 : (value & 0xFF); + } +} + +void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride) +{ + unsigned char* data = pixels + x + y * stride; + for (int j = h; j > 0; j--, data += stride) + for (int i = 0; i < w; i++) + data[i] = table[data[i]]; +} + +#ifdef IMGUI_ENABLE_STB_TRUETYPE +// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont) +// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.) +struct ImFontBuildSrcData +{ + stbtt_fontinfo FontInfo; + stbtt_pack_range PackRange; // Hold the list of codepoints to pack (essentially points to Codepoints.Data) + stbrp_rect* Rects; // Rectangle to pack. We first fill in their size and the packer will give us their position. + stbtt_packedchar* PackedChars; // Output glyphs + const ImWchar* SrcRanges; // Ranges as requested by user (user is allowed to request too much, e.g. 0x0020..0xFFFF) + int DstIndex; // Index into atlas->Fonts[] and dst_tmp_array[] + int GlyphsHighest; // Highest requested codepoint + int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font) + ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB) + ImVector GlyphsList; // Glyph codepoints list (flattened version of GlyphsMap) +}; + +// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont) +struct ImFontBuildDstData +{ + int SrcCount; // Number of source fonts targeting this destination font. + int GlyphsHighest; + int GlyphsCount; + ImBitVector GlyphsSet; // This is used to resolve collision when multiple sources are merged into a same destination font. +}; + +static void UnpackBitVectorToFlatIndexList(const ImBitVector* in, ImVector* out) +{ + IM_ASSERT(sizeof(in->Storage.Data[0]) == sizeof(int)); + const ImU32* it_begin = in->Storage.begin(); + const ImU32* it_end = in->Storage.end(); + for (const ImU32* it = it_begin; it < it_end; it++) + if (ImU32 entries_32 = *it) + for (ImU32 bit_n = 0; bit_n < 32; bit_n++) + if (entries_32 & ((ImU32)1 << bit_n)) + out->push_back((int)(((it - it_begin) << 5) + bit_n)); +} + +static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) +{ + IM_ASSERT(atlas->ConfigData.Size > 0); + + ImFontAtlasBuildInit(atlas); + + // Clear atlas + atlas->TexID = (ImTextureID)NULL; + atlas->TexWidth = atlas->TexHeight = 0; + atlas->TexUvScale = ImVec2(0.0f, 0.0f); + atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); + atlas->ClearTexData(); + + // Temporary storage for building + ImVector src_tmp_array; + ImVector dst_tmp_array; + src_tmp_array.resize(atlas->ConfigData.Size); + dst_tmp_array.resize(atlas->Fonts.Size); + memset(src_tmp_array.Data, 0, (size_t)src_tmp_array.size_in_bytes()); + memset(dst_tmp_array.Data, 0, (size_t)dst_tmp_array.size_in_bytes()); + + // 1. Initialize font loading structure, check font data validity + for (int src_i = 0; src_i < atlas->ConfigData.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + ImFontConfig& cfg = atlas->ConfigData[src_i]; + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + + // Find index from cfg.DstFont (we allow the user to set cfg.DstFont. Also it makes casual debugging nicer than when storing indices) + src_tmp.DstIndex = -1; + for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++) + if (cfg.DstFont == atlas->Fonts[output_i]) + src_tmp.DstIndex = output_i; + if (src_tmp.DstIndex == -1) + { + IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array? + return false; + } + // Initialize helper structure for font loading and verify that the TTF/OTF data is correct + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found."); + if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + return false; + + // Measure highest codepoints + ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; + src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault(); + for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) + src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]); + dst_tmp.SrcCount++; + dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest); + } + + // 2. For every requested codepoint, check for their presence in the font data, and handle redundancy or overlaps between source fonts to avoid unused glyphs. + int total_glyphs_count = 0; + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; + src_tmp.GlyphsSet.Create(src_tmp.GlyphsHighest + 1); + if (dst_tmp.GlyphsSet.Storage.empty()) + dst_tmp.GlyphsSet.Create(dst_tmp.GlyphsHighest + 1); + + for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) + for (unsigned int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++) + { + if (dst_tmp.GlyphsSet.TestBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true) + continue; + if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font? + continue; + + // Add to avail set/counters + src_tmp.GlyphsCount++; + dst_tmp.GlyphsCount++; + src_tmp.GlyphsSet.SetBit(codepoint); + dst_tmp.GlyphsSet.SetBit(codepoint); + total_glyphs_count++; + } + } + + // 3. Unpack our bit map into a flat list (we now have all the Unicode points that we know are requested _and_ available _and_ not overlapping another) + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + src_tmp.GlyphsList.reserve(src_tmp.GlyphsCount); + UnpackBitVectorToFlatIndexList(&src_tmp.GlyphsSet, &src_tmp.GlyphsList); + src_tmp.GlyphsSet.Clear(); + IM_ASSERT(src_tmp.GlyphsList.Size == src_tmp.GlyphsCount); + } + for (int dst_i = 0; dst_i < dst_tmp_array.Size; dst_i++) + dst_tmp_array[dst_i].GlyphsSet.Clear(); + dst_tmp_array.clear(); + + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) + // (We technically don't need to zero-clear buf_rects, but let's do it for the sake of sanity) + ImVector buf_rects; + ImVector buf_packedchars; + buf_rects.resize(total_glyphs_count); + buf_packedchars.resize(total_glyphs_count); + memset(buf_rects.Data, 0, (size_t)buf_rects.size_in_bytes()); + memset(buf_packedchars.Data, 0, (size_t)buf_packedchars.size_in_bytes()); + + // 4. Gather glyphs sizes so we can pack them in our virtual canvas. + int total_surface = 0; + int buf_rects_out_n = 0; + int buf_packedchars_out_n = 0; + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + src_tmp.Rects = &buf_rects[buf_rects_out_n]; + src_tmp.PackedChars = &buf_packedchars[buf_packedchars_out_n]; + buf_rects_out_n += src_tmp.GlyphsCount; + buf_packedchars_out_n += src_tmp.GlyphsCount; + + // Convert our ranges in the format stb_truetype wants + ImFontConfig& cfg = atlas->ConfigData[src_i]; + src_tmp.PackRange.font_size = cfg.SizePixels; + src_tmp.PackRange.first_unicode_codepoint_in_range = 0; + src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data; + src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size; + src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars; + src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH; + src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV; + + // Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects) + const float scale = (cfg.SizePixels > 0) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels); + const int padding = atlas->TexGlyphPadding; + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++) + { + int x0, y0, x1, y1; + const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]); + IM_ASSERT(glyph_index_in_font != 0); + stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1); + src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + padding + cfg.OversampleH - 1); + src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + padding + cfg.OversampleV - 1); + total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h; + } + } + + // We need a width for the skyline algorithm, any width! + // The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. + // User can override TexDesiredWidth and TexGlyphPadding if they wish, otherwise we use a simple heuristic to select the width based on expected surface. + const int surface_sqrt = (int)ImSqrt((float)total_surface) + 1; + atlas->TexHeight = 0; + if (atlas->TexDesiredWidth > 0) + atlas->TexWidth = atlas->TexDesiredWidth; + else + atlas->TexWidth = (surface_sqrt >= 4096 * 0.7f) ? 4096 : (surface_sqrt >= 2048 * 0.7f) ? 2048 : (surface_sqrt >= 1024 * 0.7f) ? 1024 : 512; + + // 5. Start packing + // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). + const int TEX_HEIGHT_MAX = 1024 * 32; + stbtt_pack_context spc = {}; + stbtt_PackBegin(&spc, NULL, atlas->TexWidth, TEX_HEIGHT_MAX, 0, atlas->TexGlyphPadding, NULL); + ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info); + + // 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point. + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + stbrp_pack_rects((stbrp_context*)spc.pack_info, src_tmp.Rects, src_tmp.GlyphsCount); + + // Extend texture height and mark missing glyphs as non-packed so we won't render them. + // FIXME: We are not handling packing failure here (would happen if we got off TEX_HEIGHT_MAX or if a single if larger than TexWidth?) + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) + if (src_tmp.Rects[glyph_i].was_packed) + atlas->TexHeight = ImMax(atlas->TexHeight, src_tmp.Rects[glyph_i].y + src_tmp.Rects[glyph_i].h); + } + + // 7. Allocate texture + atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); + atlas->TexPixelsAlpha8 = (unsigned char*)IM_ALLOC(atlas->TexWidth * atlas->TexHeight); + memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); + spc.pixels = atlas->TexPixelsAlpha8; + spc.height = atlas->TexHeight; + + // 8. Render/rasterize font characters into the texture + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + stbtt_PackFontRangesRenderIntoRects(&spc, &src_tmp.FontInfo, &src_tmp.PackRange, 1, src_tmp.Rects); + + // Apply multiply operator + if (cfg.RasterizerMultiply != 1.0f) + { + unsigned char multiply_table[256]; + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + stbrp_rect* r = &src_tmp.Rects[0]; + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++, r++) + if (r->was_packed) + ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, atlas->TexPixelsAlpha8, r->x, r->y, r->w, r->h, atlas->TexWidth * 1); + } + src_tmp.Rects = NULL; + } + + // End packing + stbtt_PackEnd(&spc); + buf_rects.clear(); + + // 9. Setup ImFont and glyphs for runtime + for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) + { + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; + if (src_tmp.GlyphsCount == 0) + continue; + + // When merging fonts with MergeMode=true: + // - We can have multiple input fonts writing into a same destination font. + // - dst_font->ConfigData is != from cfg which is our source configuration. + ImFontConfig& cfg = atlas->ConfigData[src_i]; + ImFont* dst_font = cfg.DstFont; + + const float font_scale = stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels); + int unscaled_ascent, unscaled_descent, unscaled_line_gap; + stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); + + const float ascent = ImFloor(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1)); + const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1)); + ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); + const float font_off_x = cfg.GlyphOffset.x; + const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); + + for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++) + { + // Register glyph + const int codepoint = src_tmp.GlyphsList[glyph_i]; + const stbtt_packedchar& pc = src_tmp.PackedChars[glyph_i]; + stbtt_aligned_quad q; + float unused_x = 0.0f, unused_y = 0.0f; + stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0); + dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); + } + } + + // Cleanup + src_tmp_array.clear_destruct(); + + ImFontAtlasBuildFinish(atlas); + return true; +} + +const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype() +{ + static ImFontBuilderIO io; + io.FontBuilder_Build = ImFontAtlasBuildWithStbTruetype; + return &io; +} + +#endif // IMGUI_ENABLE_STB_TRUETYPE + +void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) +{ + if (!font_config->MergeMode) + { + font->ClearOutputData(); + font->FontSize = font_config->SizePixels; + font->ConfigData = font_config; + font->ConfigDataCount = 0; + font->ContainerAtlas = atlas; + font->Ascent = ascent; + font->Descent = descent; + } + font->ConfigDataCount++; +} + +void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque) +{ + stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque; + IM_ASSERT(pack_context != NULL); + + ImVector& user_rects = atlas->CustomRects; + IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. + + ImVector pack_rects; + pack_rects.resize(user_rects.Size); + memset(pack_rects.Data, 0, (size_t)pack_rects.size_in_bytes()); + for (int i = 0; i < user_rects.Size; i++) + { + pack_rects[i].w = user_rects[i].Width; + pack_rects[i].h = user_rects[i].Height; + } + stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size); + for (int i = 0; i < pack_rects.Size; i++) + if (pack_rects[i].was_packed) + { + user_rects[i].X = pack_rects[i].x; + user_rects[i].Y = pack_rects[i].y; + IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height); + atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h); + } +} + +void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value) +{ + IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth); + IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight); + unsigned char* out_pixel = atlas->TexPixelsAlpha8 + x + (y * atlas->TexWidth); + for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w) + for (int off_x = 0; off_x < w; off_x++) + out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : 0x00; +} + +void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value) +{ + IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth); + IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight); + unsigned int* out_pixel = atlas->TexPixelsRGBA32 + x + (y * atlas->TexWidth); + for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w) + for (int off_x = 0; off_x < w; off_x++) + out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : IM_COL32_BLACK_TRANS; +} + +static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) +{ + ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors); + IM_ASSERT(r->IsPacked()); + + const int w = atlas->TexWidth; + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) + { + // Render/copy pixels + IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); + const int x_for_white = r->X; + const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1; + if (atlas->TexPixelsAlpha8 != NULL) + { + ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF); + ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF); + } + else + { + ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', IM_COL32_WHITE); + ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', IM_COL32_WHITE); + } + } + else + { + // Render 4 white pixels + IM_ASSERT(r->Width == 2 && r->Height == 2); + const int offset = (int)r->X + (int)r->Y * w; + if (atlas->TexPixelsAlpha8 != NULL) + { + atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; + } + else + { + atlas->TexPixelsRGBA32[offset] = atlas->TexPixelsRGBA32[offset + 1] = atlas->TexPixelsRGBA32[offset + w] = atlas->TexPixelsRGBA32[offset + w + 1] = IM_COL32_WHITE; + } + } + atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y); +} + +static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas) +{ + if (atlas->Flags & ImFontAtlasFlags_NoBakedLines) + return; + + // This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them + ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdLines); + IM_ASSERT(r->IsPacked()); + for (unsigned int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row + { + // Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle + unsigned int y = n; + unsigned int line_width = n; + unsigned int pad_left = (r->Width - line_width) / 2; + unsigned int pad_right = r->Width - (pad_left + line_width); + + // Write each slice + IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels + if (atlas->TexPixelsAlpha8 != NULL) + { + unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)]; + for (unsigned int i = 0; i < pad_left; i++) + *(write_ptr + i) = 0x00; + + for (unsigned int i = 0; i < line_width; i++) + *(write_ptr + pad_left + i) = 0xFF; + + for (unsigned int i = 0; i < pad_right; i++) + *(write_ptr + pad_left + line_width + i) = 0x00; + } + else + { + unsigned int* write_ptr = &atlas->TexPixelsRGBA32[r->X + ((r->Y + y) * atlas->TexWidth)]; + for (unsigned int i = 0; i < pad_left; i++) + *(write_ptr + i) = IM_COL32_BLACK_TRANS; + + for (unsigned int i = 0; i < line_width; i++) + *(write_ptr + pad_left + i) = IM_COL32_WHITE; + + for (unsigned int i = 0; i < pad_right; i++) + *(write_ptr + pad_left + line_width + i) = IM_COL32_BLACK_TRANS; + } + + // Calculate UVs for this line + ImVec2 uv0 = ImVec2((float)(r->X + pad_left - 1), (float)(r->Y + y)) * atlas->TexUvScale; + ImVec2 uv1 = ImVec2((float)(r->X + pad_left + line_width + 1), (float)(r->Y + y + 1)) * atlas->TexUvScale; + float half_v = (uv0.y + uv1.y) * 0.5f; // Calculate a constant V in the middle of the row to avoid sampling artifacts + atlas->TexUvLines[n] = ImVec4(uv0.x, half_v, uv1.x, half_v); + } +} + +// Note: this is called / shared by both the stb_truetype and the FreeType builder +void ImFontAtlasBuildInit(ImFontAtlas* atlas) +{ + // Register texture region for mouse cursors or standard white pixels + if (atlas->PackIdMouseCursors < 0) + { + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) + atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + else + atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2); + } + + // Register texture region for thick lines + // The +2 here is to give space for the end caps, whilst height +1 is to accommodate the fact we have a zero-width row + if (atlas->PackIdLines < 0) + { + if (!(atlas->Flags & ImFontAtlasFlags_NoBakedLines)) + atlas->PackIdLines = atlas->AddCustomRectRegular(IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 2, IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1); + } +} + +// This is called/shared by both the stb_truetype and the FreeType builder. +void ImFontAtlasBuildFinish(ImFontAtlas* atlas) +{ + // Render into our custom data blocks + IM_ASSERT(atlas->TexPixelsAlpha8 != NULL || atlas->TexPixelsRGBA32 != NULL); + ImFontAtlasBuildRenderDefaultTexData(atlas); + ImFontAtlasBuildRenderLinesTexData(atlas); + + // Register custom rectangle glyphs + for (int i = 0; i < atlas->CustomRects.Size; i++) + { + const ImFontAtlasCustomRect* r = &atlas->CustomRects[i]; + if (r->Font == NULL || r->GlyphID == 0) + continue; + + // Will ignore ImFontConfig settings: GlyphMinAdvanceX, GlyphMinAdvanceY, GlyphExtraSpacing, PixelSnapH + IM_ASSERT(r->Font->ContainerAtlas == atlas); + ImVec2 uv0, uv1; + atlas->CalcCustomRectUV(r, &uv0, &uv1); + r->Font->AddGlyph(NULL, (ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX); + } + + // Build all fonts lookup tables + for (int i = 0; i < atlas->Fonts.Size; i++) + if (atlas->Fonts[i]->DirtyLookupTables) + atlas->Fonts[i]->BuildLookupTable(); + + atlas->TexReady = true; +} + +// 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::GetGlyphRangesKorean() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3131, 0x3163, // Korean alphabets + 0xAC00, 0xD7A3, // Korean characters + 0xFFFD, 0xFFFD, // Invalid + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesChineseFull() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x2000, 0x206F, // General Punctuation + 0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + 0xFFFD, 0xFFFD, // Invalid + 0x4e00, 0x9FAF, // CJK Ideograms + 0, + }; + return &ranges[0]; +} + +static void UnpackAccumulativeOffsetsIntoRanges(int base_codepoint, const short* accumulative_offsets, int accumulative_offsets_count, ImWchar* out_ranges) +{ + for (int n = 0; n < accumulative_offsets_count; n++, out_ranges += 2) + { + out_ranges[0] = out_ranges[1] = (ImWchar)(base_codepoint + accumulative_offsets[n]); + base_codepoint += accumulative_offsets[n]; + } + out_ranges[0] = 0; +} + +//------------------------------------------------------------------------- +// [SECTION] ImFontAtlas glyph ranges helpers +//------------------------------------------------------------------------- + +const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon() +{ + // Store 2500 regularly used characters for Simplified Chinese. + // Sourced from https://zh.wiktionary.org/wiki/%E9%99%84%E5%BD%95:%E7%8E%B0%E4%BB%A3%E6%B1%89%E8%AF%AD%E5%B8%B8%E7%94%A8%E5%AD%97%E8%A1%A8 + // This table covers 97.97% of all characters used during the month in July, 1987. + // You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters. + // (Stored as accumulative offsets from the initial unicode codepoint 0x4E00. This encoding is designed to helps us compact the source code size.) + static const short accumulative_offsets_from_0x4E00[] = + { + 0,1,2,4,1,1,1,1,2,1,3,2,1,2,2,1,1,1,1,1,5,2,1,2,3,3,3,2,2,4,1,1,1,2,1,5,2,3,1,2,1,2,1,1,2,1,1,2,2,1,4,1,1,1,1,5,10,1,2,19,2,1,2,1,2,1,2,1,2, + 1,5,1,6,3,2,1,2,2,1,1,1,4,8,5,1,1,4,1,1,3,1,2,1,5,1,2,1,1,1,10,1,1,5,2,4,6,1,4,2,2,2,12,2,1,1,6,1,1,1,4,1,1,4,6,5,1,4,2,2,4,10,7,1,1,4,2,4, + 2,1,4,3,6,10,12,5,7,2,14,2,9,1,1,6,7,10,4,7,13,1,5,4,8,4,1,1,2,28,5,6,1,1,5,2,5,20,2,2,9,8,11,2,9,17,1,8,6,8,27,4,6,9,20,11,27,6,68,2,2,1,1, + 1,2,1,2,2,7,6,11,3,3,1,1,3,1,2,1,1,1,1,1,3,1,1,8,3,4,1,5,7,2,1,4,4,8,4,2,1,2,1,1,4,5,6,3,6,2,12,3,1,3,9,2,4,3,4,1,5,3,3,1,3,7,1,5,1,1,1,1,2, + 3,4,5,2,3,2,6,1,1,2,1,7,1,7,3,4,5,15,2,2,1,5,3,22,19,2,1,1,1,1,2,5,1,1,1,6,1,1,12,8,2,9,18,22,4,1,1,5,1,16,1,2,7,10,15,1,1,6,2,4,1,2,4,1,6, + 1,1,3,2,4,1,6,4,5,1,2,1,1,2,1,10,3,1,3,2,1,9,3,2,5,7,2,19,4,3,6,1,1,1,1,1,4,3,2,1,1,1,2,5,3,1,1,1,2,2,1,1,2,1,1,2,1,3,1,1,1,3,7,1,4,1,1,2,1, + 1,2,1,2,4,4,3,8,1,1,1,2,1,3,5,1,3,1,3,4,6,2,2,14,4,6,6,11,9,1,15,3,1,28,5,2,5,5,3,1,3,4,5,4,6,14,3,2,3,5,21,2,7,20,10,1,2,19,2,4,28,28,2,3, + 2,1,14,4,1,26,28,42,12,40,3,52,79,5,14,17,3,2,2,11,3,4,6,3,1,8,2,23,4,5,8,10,4,2,7,3,5,1,1,6,3,1,2,2,2,5,28,1,1,7,7,20,5,3,29,3,17,26,1,8,4, + 27,3,6,11,23,5,3,4,6,13,24,16,6,5,10,25,35,7,3,2,3,3,14,3,6,2,6,1,4,2,3,8,2,1,1,3,3,3,4,1,1,13,2,2,4,5,2,1,14,14,1,2,2,1,4,5,2,3,1,14,3,12, + 3,17,2,16,5,1,2,1,8,9,3,19,4,2,2,4,17,25,21,20,28,75,1,10,29,103,4,1,2,1,1,4,2,4,1,2,3,24,2,2,2,1,1,2,1,3,8,1,1,1,2,1,1,3,1,1,1,6,1,5,3,1,1, + 1,3,4,1,1,5,2,1,5,6,13,9,16,1,1,1,1,3,2,3,2,4,5,2,5,2,2,3,7,13,7,2,2,1,1,1,1,2,3,3,2,1,6,4,9,2,1,14,2,14,2,1,18,3,4,14,4,11,41,15,23,15,23, + 176,1,3,4,1,1,1,1,5,3,1,2,3,7,3,1,1,2,1,2,4,4,6,2,4,1,9,7,1,10,5,8,16,29,1,1,2,2,3,1,3,5,2,4,5,4,1,1,2,2,3,3,7,1,6,10,1,17,1,44,4,6,2,1,1,6, + 5,4,2,10,1,6,9,2,8,1,24,1,2,13,7,8,8,2,1,4,1,3,1,3,3,5,2,5,10,9,4,9,12,2,1,6,1,10,1,1,7,7,4,10,8,3,1,13,4,3,1,6,1,3,5,2,1,2,17,16,5,2,16,6, + 1,4,2,1,3,3,6,8,5,11,11,1,3,3,2,4,6,10,9,5,7,4,7,4,7,1,1,4,2,1,3,6,8,7,1,6,11,5,5,3,24,9,4,2,7,13,5,1,8,82,16,61,1,1,1,4,2,2,16,10,3,8,1,1, + 6,4,2,1,3,1,1,1,4,3,8,4,2,2,1,1,1,1,1,6,3,5,1,1,4,6,9,2,1,1,1,2,1,7,2,1,6,1,5,4,4,3,1,8,1,3,3,1,3,2,2,2,2,3,1,6,1,2,1,2,1,3,7,1,8,2,1,2,1,5, + 2,5,3,5,10,1,2,1,1,3,2,5,11,3,9,3,5,1,1,5,9,1,2,1,5,7,9,9,8,1,3,3,3,6,8,2,3,2,1,1,32,6,1,2,15,9,3,7,13,1,3,10,13,2,14,1,13,10,2,1,3,10,4,15, + 2,15,15,10,1,3,9,6,9,32,25,26,47,7,3,2,3,1,6,3,4,3,2,8,5,4,1,9,4,2,2,19,10,6,2,3,8,1,2,2,4,2,1,9,4,4,4,6,4,8,9,2,3,1,1,1,1,3,5,5,1,3,8,4,6, + 2,1,4,12,1,5,3,7,13,2,5,8,1,6,1,2,5,14,6,1,5,2,4,8,15,5,1,23,6,62,2,10,1,1,8,1,2,2,10,4,2,2,9,2,1,1,3,2,3,1,5,3,3,2,1,3,8,1,1,1,11,3,1,1,4, + 3,7,1,14,1,2,3,12,5,2,5,1,6,7,5,7,14,11,1,3,1,8,9,12,2,1,11,8,4,4,2,6,10,9,13,1,1,3,1,5,1,3,2,4,4,1,18,2,3,14,11,4,29,4,2,7,1,3,13,9,2,2,5, + 3,5,20,7,16,8,5,72,34,6,4,22,12,12,28,45,36,9,7,39,9,191,1,1,1,4,11,8,4,9,2,3,22,1,1,1,1,4,17,1,7,7,1,11,31,10,2,4,8,2,3,2,1,4,2,16,4,32,2, + 3,19,13,4,9,1,5,2,14,8,1,1,3,6,19,6,5,1,16,6,2,10,8,5,1,2,3,1,5,5,1,11,6,6,1,3,3,2,6,3,8,1,1,4,10,7,5,7,7,5,8,9,2,1,3,4,1,1,3,1,3,3,2,6,16, + 1,4,6,3,1,10,6,1,3,15,2,9,2,10,25,13,9,16,6,2,2,10,11,4,3,9,1,2,6,6,5,4,30,40,1,10,7,12,14,33,6,3,6,7,3,1,3,1,11,14,4,9,5,12,11,49,18,51,31, + 140,31,2,2,1,5,1,8,1,10,1,4,4,3,24,1,10,1,3,6,6,16,3,4,5,2,1,4,2,57,10,6,22,2,22,3,7,22,6,10,11,36,18,16,33,36,2,5,5,1,1,1,4,10,1,4,13,2,7, + 5,2,9,3,4,1,7,43,3,7,3,9,14,7,9,1,11,1,1,3,7,4,18,13,1,14,1,3,6,10,73,2,2,30,6,1,11,18,19,13,22,3,46,42,37,89,7,3,16,34,2,2,3,9,1,7,1,1,1,2, + 2,4,10,7,3,10,3,9,5,28,9,2,6,13,7,3,1,3,10,2,7,2,11,3,6,21,54,85,2,1,4,2,2,1,39,3,21,2,2,5,1,1,1,4,1,1,3,4,15,1,3,2,4,4,2,3,8,2,20,1,8,7,13, + 4,1,26,6,2,9,34,4,21,52,10,4,4,1,5,12,2,11,1,7,2,30,12,44,2,30,1,1,3,6,16,9,17,39,82,2,2,24,7,1,7,3,16,9,14,44,2,1,2,1,2,3,5,2,4,1,6,7,5,3, + 2,6,1,11,5,11,2,1,18,19,8,1,3,24,29,2,1,3,5,2,2,1,13,6,5,1,46,11,3,5,1,1,5,8,2,10,6,12,6,3,7,11,2,4,16,13,2,5,1,1,2,2,5,2,28,5,2,23,10,8,4, + 4,22,39,95,38,8,14,9,5,1,13,5,4,3,13,12,11,1,9,1,27,37,2,5,4,4,63,211,95,2,2,2,1,3,5,2,1,1,2,2,1,1,1,3,2,4,1,2,1,1,5,2,2,1,1,2,3,1,3,1,1,1, + 3,1,4,2,1,3,6,1,1,3,7,15,5,3,2,5,3,9,11,4,2,22,1,6,3,8,7,1,4,28,4,16,3,3,25,4,4,27,27,1,4,1,2,2,7,1,3,5,2,28,8,2,14,1,8,6,16,25,3,3,3,14,3, + 3,1,1,2,1,4,6,3,8,4,1,1,1,2,3,6,10,6,2,3,18,3,2,5,5,4,3,1,5,2,5,4,23,7,6,12,6,4,17,11,9,5,1,1,10,5,12,1,1,11,26,33,7,3,6,1,17,7,1,5,12,1,11, + 2,4,1,8,14,17,23,1,2,1,7,8,16,11,9,6,5,2,6,4,16,2,8,14,1,11,8,9,1,1,1,9,25,4,11,19,7,2,15,2,12,8,52,7,5,19,2,16,4,36,8,1,16,8,24,26,4,6,2,9, + 5,4,36,3,28,12,25,15,37,27,17,12,59,38,5,32,127,1,2,9,17,14,4,1,2,1,1,8,11,50,4,14,2,19,16,4,17,5,4,5,26,12,45,2,23,45,104,30,12,8,3,10,2,2, + 3,3,1,4,20,7,2,9,6,15,2,20,1,3,16,4,11,15,6,134,2,5,59,1,2,2,2,1,9,17,3,26,137,10,211,59,1,2,4,1,4,1,1,1,2,6,2,3,1,1,2,3,2,3,1,3,4,4,2,3,3, + 1,4,3,1,7,2,2,3,1,2,1,3,3,3,2,2,3,2,1,3,14,6,1,3,2,9,6,15,27,9,34,145,1,1,2,1,1,1,1,2,1,1,1,1,2,2,2,3,1,2,1,1,1,2,3,5,8,3,5,2,4,1,3,2,2,2,12, + 4,1,1,1,10,4,5,1,20,4,16,1,15,9,5,12,2,9,2,5,4,2,26,19,7,1,26,4,30,12,15,42,1,6,8,172,1,1,4,2,1,1,11,2,2,4,2,1,2,1,10,8,1,2,1,4,5,1,2,5,1,8, + 4,1,3,4,2,1,6,2,1,3,4,1,2,1,1,1,1,12,5,7,2,4,3,1,1,1,3,3,6,1,2,2,3,3,3,2,1,2,12,14,11,6,6,4,12,2,8,1,7,10,1,35,7,4,13,15,4,3,23,21,28,52,5, + 26,5,6,1,7,10,2,7,53,3,2,1,1,1,2,163,532,1,10,11,1,3,3,4,8,2,8,6,2,2,23,22,4,2,2,4,2,1,3,1,3,3,5,9,8,2,1,2,8,1,10,2,12,21,20,15,105,2,3,1,1, + 3,2,3,1,1,2,5,1,4,15,11,19,1,1,1,1,5,4,5,1,1,2,5,3,5,12,1,2,5,1,11,1,1,15,9,1,4,5,3,26,8,2,1,3,1,1,15,19,2,12,1,2,5,2,7,2,19,2,20,6,26,7,5, + 2,2,7,34,21,13,70,2,128,1,1,2,1,1,2,1,1,3,2,2,2,15,1,4,1,3,4,42,10,6,1,49,85,8,1,2,1,1,4,4,2,3,6,1,5,7,4,3,211,4,1,2,1,2,5,1,2,4,2,2,6,5,6, + 10,3,4,48,100,6,2,16,296,5,27,387,2,2,3,7,16,8,5,38,15,39,21,9,10,3,7,59,13,27,21,47,5,21,6 + }; + static ImWchar base_ranges[] = // not zero-terminated + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x2000, 0x206F, // General Punctuation + 0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + 0xFFFD, 0xFFFD // Invalid + }; + static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 }; + if (!full_ranges[0]) + { + memcpy(full_ranges, base_ranges, sizeof(base_ranges)); + UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges)); + } + return &full_ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() +{ + // 2999 ideograms code points for Japanese + // - 2136 Joyo (meaning "for regular use" or "for common use") Kanji code points + // - 863 Jinmeiyo (meaning "for personal name") Kanji code points + // - Sourced from the character information database of the Information-technology Promotion Agency, Japan + // - https://mojikiban.ipa.go.jp/mji/ + // - Available under the terms of the Creative Commons Attribution-ShareAlike 2.1 Japan (CC BY-SA 2.1 JP). + // - https://creativecommons.org/licenses/by-sa/2.1/jp/deed.en + // - https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode + // - You can generate this code by the script at: + // - https://github.com/vaiorabbit/everyday_use_kanji + // - References: + // - List of Joyo Kanji + // - (Official list by the Agency for Cultural Affairs) https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kakuki/14/tosin02/index.html + // - (Wikipedia) https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji + // - List of Jinmeiyo Kanji + // - (Official list by the Ministry of Justice) http://www.moj.go.jp/MINJI/minji86.html + // - (Wikipedia) https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji + // - Missing 1 Joyo Kanji: U+20B9F (Kun'yomi: Shikaru, On'yomi: Shitsu,shichi), see https://github.com/ocornut/imgui/pull/3627 for details. + // You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters. + // (Stored as accumulative offsets from the initial unicode codepoint 0x4E00. This encoding is designed to helps us compact the source code size.) + static const short accumulative_offsets_from_0x4E00[] = + { + 0,1,2,4,1,1,1,1,2,1,3,3,2,2,1,5,3,5,7,5,6,1,2,1,7,2,6,3,1,8,1,1,4,1,1,18,2,11,2,6,2,1,2,1,5,1,2,1,3,1,2,1,2,3,3,1,1,2,3,1,1,1,12,7,9,1,4,5,1, + 1,2,1,10,1,1,9,2,2,4,5,6,9,3,1,1,1,1,9,3,18,5,2,2,2,2,1,6,3,7,1,1,1,1,2,2,4,2,1,23,2,10,4,3,5,2,4,10,2,4,13,1,6,1,9,3,1,1,6,6,7,6,3,1,2,11,3, + 2,2,3,2,15,2,2,5,4,3,6,4,1,2,5,2,12,16,6,13,9,13,2,1,1,7,16,4,7,1,19,1,5,1,2,2,7,7,8,2,6,5,4,9,18,7,4,5,9,13,11,8,15,2,1,1,1,2,1,2,2,1,2,2,8, + 2,9,3,3,1,1,4,4,1,1,1,4,9,1,4,3,5,5,2,7,5,3,4,8,2,1,13,2,3,3,1,14,1,1,4,5,1,3,6,1,5,2,1,1,3,3,3,3,1,1,2,7,6,6,7,1,4,7,6,1,1,1,1,1,12,3,3,9,5, + 2,6,1,5,6,1,2,3,18,2,4,14,4,1,3,6,1,1,6,3,5,5,3,2,2,2,2,12,3,1,4,2,3,2,3,11,1,7,4,1,2,1,3,17,1,9,1,24,1,1,4,2,2,4,1,2,7,1,1,1,3,1,2,2,4,15,1, + 1,2,1,1,2,1,5,2,5,20,2,5,9,1,10,8,7,6,1,1,1,1,1,1,6,2,1,2,8,1,1,1,1,5,1,1,3,1,1,1,1,3,1,1,12,4,1,3,1,1,1,1,1,10,3,1,7,5,13,1,2,3,4,6,1,1,30, + 2,9,9,1,15,38,11,3,1,8,24,7,1,9,8,10,2,1,9,31,2,13,6,2,9,4,49,5,2,15,2,1,10,2,1,1,1,2,2,6,15,30,35,3,14,18,8,1,16,10,28,12,19,45,38,1,3,2,3, + 13,2,1,7,3,6,5,3,4,3,1,5,7,8,1,5,3,18,5,3,6,1,21,4,24,9,24,40,3,14,3,21,3,2,1,2,4,2,3,1,15,15,6,5,1,1,3,1,5,6,1,9,7,3,3,2,1,4,3,8,21,5,16,4, + 5,2,10,11,11,3,6,3,2,9,3,6,13,1,2,1,1,1,1,11,12,6,6,1,4,2,6,5,2,1,1,3,3,6,13,3,1,1,5,1,2,3,3,14,2,1,2,2,2,5,1,9,5,1,1,6,12,3,12,3,4,13,2,14, + 2,8,1,17,5,1,16,4,2,2,21,8,9,6,23,20,12,25,19,9,38,8,3,21,40,25,33,13,4,3,1,4,1,2,4,1,2,5,26,2,1,1,2,1,3,6,2,1,1,1,1,1,1,2,3,1,1,1,9,2,3,1,1, + 1,3,6,3,2,1,1,6,6,1,8,2,2,2,1,4,1,2,3,2,7,3,2,4,1,2,1,2,2,1,1,1,1,1,3,1,2,5,4,10,9,4,9,1,1,1,1,1,1,5,3,2,1,6,4,9,6,1,10,2,31,17,8,3,7,5,40,1, + 7,7,1,6,5,2,10,7,8,4,15,39,25,6,28,47,18,10,7,1,3,1,1,2,1,1,1,3,3,3,1,1,1,3,4,2,1,4,1,3,6,10,7,8,6,2,2,1,3,3,2,5,8,7,9,12,2,15,1,1,4,1,2,1,1, + 1,3,2,1,3,3,5,6,2,3,2,10,1,4,2,8,1,1,1,11,6,1,21,4,16,3,1,3,1,4,2,3,6,5,1,3,1,1,3,3,4,6,1,1,10,4,2,7,10,4,7,4,2,9,4,3,1,1,1,4,1,8,3,4,1,3,1, + 6,1,4,2,1,4,7,2,1,8,1,4,5,1,1,2,2,4,6,2,7,1,10,1,1,3,4,11,10,8,21,4,6,1,3,5,2,1,2,28,5,5,2,3,13,1,2,3,1,4,2,1,5,20,3,8,11,1,3,3,3,1,8,10,9,2, + 10,9,2,3,1,1,2,4,1,8,3,6,1,7,8,6,11,1,4,29,8,4,3,1,2,7,13,1,4,1,6,2,6,12,12,2,20,3,2,3,6,4,8,9,2,7,34,5,1,18,6,1,1,4,4,5,7,9,1,2,2,4,3,4,1,7, + 2,2,2,6,2,3,25,5,3,6,1,4,6,7,4,2,1,4,2,13,6,4,4,3,1,5,3,4,4,3,2,1,1,4,1,2,1,1,3,1,11,1,6,3,1,7,3,6,2,8,8,6,9,3,4,11,3,2,10,12,2,5,11,1,6,4,5, + 3,1,8,5,4,6,6,3,5,1,1,3,2,1,2,2,6,17,12,1,10,1,6,12,1,6,6,19,9,6,16,1,13,4,4,15,7,17,6,11,9,15,12,6,7,2,1,2,2,15,9,3,21,4,6,49,18,7,3,2,3,1, + 6,8,2,2,6,2,9,1,3,6,4,4,1,2,16,2,5,2,1,6,2,3,5,3,1,2,5,1,2,1,9,3,1,8,6,4,8,11,3,1,1,1,1,3,1,13,8,4,1,3,2,2,1,4,1,11,1,5,2,1,5,2,5,8,6,1,1,7, + 4,3,8,3,2,7,2,1,5,1,5,2,4,7,6,2,8,5,1,11,4,5,3,6,18,1,2,13,3,3,1,21,1,1,4,1,4,1,1,1,8,1,2,2,7,1,2,4,2,2,9,2,1,1,1,4,3,6,3,12,5,1,1,1,5,6,3,2, + 4,8,2,2,4,2,7,1,8,9,5,2,3,2,1,3,2,13,7,14,6,5,1,1,2,1,4,2,23,2,1,1,6,3,1,4,1,15,3,1,7,3,9,14,1,3,1,4,1,1,5,8,1,3,8,3,8,15,11,4,14,4,4,2,5,5, + 1,7,1,6,14,7,7,8,5,15,4,8,6,5,6,2,1,13,1,20,15,11,9,2,5,6,2,11,2,6,2,5,1,5,8,4,13,19,25,4,1,1,11,1,34,2,5,9,14,6,2,2,6,1,1,14,1,3,14,13,1,6, + 12,21,14,14,6,32,17,8,32,9,28,1,2,4,11,8,3,1,14,2,5,15,1,1,1,1,3,6,4,1,3,4,11,3,1,1,11,30,1,5,1,4,1,5,8,1,1,3,2,4,3,17,35,2,6,12,17,3,1,6,2, + 1,1,12,2,7,3,3,2,1,16,2,8,3,6,5,4,7,3,3,8,1,9,8,5,1,2,1,3,2,8,1,2,9,12,1,1,2,3,8,3,24,12,4,3,7,5,8,3,3,3,3,3,3,1,23,10,3,1,2,2,6,3,1,16,1,16, + 22,3,10,4,11,6,9,7,7,3,6,2,2,2,4,10,2,1,1,2,8,7,1,6,4,1,3,3,3,5,10,12,12,2,3,12,8,15,1,1,16,6,6,1,5,9,11,4,11,4,2,6,12,1,17,5,13,1,4,9,5,1,11, + 2,1,8,1,5,7,28,8,3,5,10,2,17,3,38,22,1,2,18,12,10,4,38,18,1,4,44,19,4,1,8,4,1,12,1,4,31,12,1,14,7,75,7,5,10,6,6,13,3,2,11,11,3,2,5,28,15,6,18, + 18,5,6,4,3,16,1,7,18,7,36,3,5,3,1,7,1,9,1,10,7,2,4,2,6,2,9,7,4,3,32,12,3,7,10,2,23,16,3,1,12,3,31,4,11,1,3,8,9,5,1,30,15,6,12,3,2,2,11,19,9, + 14,2,6,2,3,19,13,17,5,3,3,25,3,14,1,1,1,36,1,3,2,19,3,13,36,9,13,31,6,4,16,34,2,5,4,2,3,3,5,1,1,1,4,3,1,17,3,2,3,5,3,1,3,2,3,5,6,3,12,11,1,3, + 1,2,26,7,12,7,2,14,3,3,7,7,11,25,25,28,16,4,36,1,2,1,6,2,1,9,3,27,17,4,3,4,13,4,1,3,2,2,1,10,4,2,4,6,3,8,2,1,18,1,1,24,2,2,4,33,2,3,63,7,1,6, + 40,7,3,4,4,2,4,15,18,1,16,1,1,11,2,41,14,1,3,18,13,3,2,4,16,2,17,7,15,24,7,18,13,44,2,2,3,6,1,1,7,5,1,7,1,4,3,3,5,10,8,2,3,1,8,1,1,27,4,2,1, + 12,1,2,1,10,6,1,6,7,5,2,3,7,11,5,11,3,6,6,2,3,15,4,9,1,1,2,1,2,11,2,8,12,8,5,4,2,3,1,5,2,2,1,14,1,12,11,4,1,11,17,17,4,3,2,5,5,7,3,1,5,9,9,8, + 2,5,6,6,13,13,2,1,2,6,1,2,2,49,4,9,1,2,10,16,7,8,4,3,2,23,4,58,3,29,1,14,19,19,11,11,2,7,5,1,3,4,6,2,18,5,12,12,17,17,3,3,2,4,1,6,2,3,4,3,1, + 1,1,1,5,1,1,9,1,3,1,3,6,1,8,1,1,2,6,4,14,3,1,4,11,4,1,3,32,1,2,4,13,4,1,2,4,2,1,3,1,11,1,4,2,1,4,4,6,3,5,1,6,5,7,6,3,23,3,5,3,5,3,3,13,3,9,10, + 1,12,10,2,3,18,13,7,160,52,4,2,2,3,2,14,5,4,12,4,6,4,1,20,4,11,6,2,12,27,1,4,1,2,2,7,4,5,2,28,3,7,25,8,3,19,3,6,10,2,2,1,10,2,5,4,1,3,4,1,5, + 3,2,6,9,3,6,2,16,3,3,16,4,5,5,3,2,1,2,16,15,8,2,6,21,2,4,1,22,5,8,1,1,21,11,2,1,11,11,19,13,12,4,2,3,2,3,6,1,8,11,1,4,2,9,5,2,1,11,2,9,1,1,2, + 14,31,9,3,4,21,14,4,8,1,7,2,2,2,5,1,4,20,3,3,4,10,1,11,9,8,2,1,4,5,14,12,14,2,17,9,6,31,4,14,1,20,13,26,5,2,7,3,6,13,2,4,2,19,6,2,2,18,9,3,5, + 12,12,14,4,6,2,3,6,9,5,22,4,5,25,6,4,8,5,2,6,27,2,35,2,16,3,7,8,8,6,6,5,9,17,2,20,6,19,2,13,3,1,1,1,4,17,12,2,14,7,1,4,18,12,38,33,2,10,1,1, + 2,13,14,17,11,50,6,33,20,26,74,16,23,45,50,13,38,33,6,6,7,4,4,2,1,3,2,5,8,7,8,9,3,11,21,9,13,1,3,10,6,7,1,2,2,18,5,5,1,9,9,2,68,9,19,13,2,5, + 1,4,4,7,4,13,3,9,10,21,17,3,26,2,1,5,2,4,5,4,1,7,4,7,3,4,2,1,6,1,1,20,4,1,9,2,2,1,3,3,2,3,2,1,1,1,20,2,3,1,6,2,3,6,2,4,8,1,3,2,10,3,5,3,4,4, + 3,4,16,1,6,1,10,2,4,2,1,1,2,10,11,2,2,3,1,24,31,4,10,10,2,5,12,16,164,15,4,16,7,9,15,19,17,1,2,1,1,5,1,1,1,1,1,3,1,4,3,1,3,1,3,1,2,1,1,3,3,7, + 2,8,1,2,2,2,1,3,4,3,7,8,12,92,2,10,3,1,3,14,5,25,16,42,4,7,7,4,2,21,5,27,26,27,21,25,30,31,2,1,5,13,3,22,5,6,6,11,9,12,1,5,9,7,5,5,22,60,3,5, + 13,1,1,8,1,1,3,3,2,1,9,3,3,18,4,1,2,3,7,6,3,1,2,3,9,1,3,1,3,2,1,3,1,1,1,2,1,11,3,1,6,9,1,3,2,3,1,2,1,5,1,1,4,3,4,1,2,2,4,4,1,7,2,1,2,2,3,5,13, + 18,3,4,14,9,9,4,16,3,7,5,8,2,6,48,28,3,1,1,4,2,14,8,2,9,2,1,15,2,4,3,2,10,16,12,8,7,1,1,3,1,1,1,2,7,4,1,6,4,38,39,16,23,7,15,15,3,2,12,7,21, + 37,27,6,5,4,8,2,10,8,8,6,5,1,2,1,3,24,1,16,17,9,23,10,17,6,1,51,55,44,13,294,9,3,6,2,4,2,2,15,1,1,1,13,21,17,68,14,8,9,4,1,4,9,3,11,7,1,1,1, + 5,6,3,2,1,1,1,2,3,8,1,2,2,4,1,5,5,2,1,4,3,7,13,4,1,4,1,3,1,1,1,5,5,10,1,6,1,5,2,1,5,2,4,1,4,5,7,3,18,2,9,11,32,4,3,3,2,4,7,11,16,9,11,8,13,38, + 32,8,4,2,1,1,2,1,2,4,4,1,1,1,4,1,21,3,11,1,16,1,1,6,1,3,2,4,9,8,57,7,44,1,3,3,13,3,10,1,1,7,5,2,7,21,47,63,3,15,4,7,1,16,1,1,2,8,2,3,42,15,4, + 1,29,7,22,10,3,78,16,12,20,18,4,67,11,5,1,3,15,6,21,31,32,27,18,13,71,35,5,142,4,10,1,2,50,19,33,16,35,37,16,19,27,7,1,133,19,1,4,8,7,20,1,4, + 4,1,10,3,1,6,1,2,51,5,40,15,24,43,22928,11,1,13,154,70,3,1,1,7,4,10,1,2,1,1,2,1,2,1,2,2,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1, + 3,2,1,1,1,1,2,1,1, + }; + static ImWchar base_ranges[] = // not zero-terminated + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + 0xFFFD, 0xFFFD // Invalid + }; + static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 }; + if (!full_ranges[0]) + { + memcpy(full_ranges, base_ranges, sizeof(base_ranges)); + UnpackAccumulativeOffsetsIntoRanges(0x4E00, accumulative_offsets_from_0x4E00, IM_ARRAYSIZE(accumulative_offsets_from_0x4E00), full_ranges + IM_ARRAYSIZE(base_ranges)); + } + return &full_ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x0400, 0x052F, // Cyrillic + Cyrillic Supplement + 0x2DE0, 0x2DFF, // Cyrillic Extended-A + 0xA640, 0xA69F, // Cyrillic Extended-B + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesThai() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + 0x2010, 0x205E, // Punctuations + 0x0E00, 0x0E7F, // Thai + 0, + }; + return &ranges[0]; +} + +const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + 0x0102, 0x0103, + 0x0110, 0x0111, + 0x0128, 0x0129, + 0x0168, 0x0169, + 0x01A0, 0x01A1, + 0x01AF, 0x01B0, + 0x1EA0, 0x1EF9, + 0, + }; + return &ranges[0]; +} + +//----------------------------------------------------------------------------- +// [SECTION] ImFontGlyphRangesBuilder +//----------------------------------------------------------------------------- + +void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end) +{ + while (text_end ? (text < text_end) : *text) + { + unsigned int c = 0; + int c_len = ImTextCharFromUtf8(&c, text, text_end); + text += c_len; + if (c_len == 0) + break; + AddChar((ImWchar)c); + } +} + +void ImFontGlyphRangesBuilder::AddRanges(const ImWchar* ranges) +{ + for (; ranges[0]; ranges += 2) + for (unsigned int c = ranges[0]; c <= ranges[1] && c <= IM_UNICODE_CODEPOINT_MAX; c++) //-V560 + AddChar((ImWchar)c); +} + +void ImFontGlyphRangesBuilder::BuildRanges(ImVector* out_ranges) +{ + const int max_codepoint = IM_UNICODE_CODEPOINT_MAX; + for (int n = 0; n <= max_codepoint; n++) + if (GetBit(n)) + { + out_ranges->push_back((ImWchar)n); + while (n < max_codepoint && GetBit(n + 1)) + n++; + out_ranges->push_back((ImWchar)n); + } + out_ranges->push_back(0); +} + +//----------------------------------------------------------------------------- +// [SECTION] ImFont +//----------------------------------------------------------------------------- + +ImFont::ImFont() +{ + FontSize = 0.0f; + FallbackAdvanceX = 0.0f; + FallbackChar = (ImWchar)-1; + EllipsisChar = (ImWchar)-1; + DotChar = (ImWchar)-1; + FallbackGlyph = NULL; + ContainerAtlas = NULL; + ConfigData = NULL; + ConfigDataCount = 0; + DirtyLookupTables = false; + Scale = 1.0f; + Ascent = Descent = 0.0f; + MetricsTotalSurface = 0; + memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap)); +} + +ImFont::~ImFont() +{ + ClearOutputData(); +} + +void ImFont::ClearOutputData() +{ + FontSize = 0.0f; + FallbackAdvanceX = 0.0f; + Glyphs.clear(); + IndexAdvanceX.clear(); + IndexLookup.clear(); + FallbackGlyph = NULL; + ContainerAtlas = NULL; + DirtyLookupTables = true; + Ascent = Descent = 0.0f; + MetricsTotalSurface = 0; +} + +static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count) +{ + for (int n = 0; n < candidate_chars_count; n++) + if (font->FindGlyphNoFallback(candidate_chars[n]) != NULL) + return candidate_chars[n]; + return (ImWchar)-1; +} + +void ImFont::BuildLookupTable() +{ + int max_codepoint = 0; + for (int i = 0; i != Glyphs.Size; i++) + max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); + + // Build lookup table + IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved + IndexAdvanceX.clear(); + IndexLookup.clear(); + DirtyLookupTables = false; + memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap)); + GrowIndex(max_codepoint + 1); + for (int i = 0; i < Glyphs.Size; i++) + { + int codepoint = (int)Glyphs[i].Codepoint; + IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; + IndexLookup[codepoint] = (ImWchar)i; + + // Mark 4K page as used + const int page_n = codepoint / 4096; + Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7); + } + + // Create a glyph to handle TAB + // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) + if (FindGlyph((ImWchar)' ')) + { + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times (FIXME: Flaky) + Glyphs.resize(Glyphs.Size + 1); + ImFontGlyph& tab_glyph = Glyphs.back(); + tab_glyph = *FindGlyph((ImWchar)' '); + tab_glyph.Codepoint = '\t'; + tab_glyph.AdvanceX *= IM_TABSIZE; + IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; + IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1); + } + + // Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons) + SetGlyphVisible((ImWchar)' ', false); + SetGlyphVisible((ImWchar)'\t', false); + + // Ellipsis character is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). + // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. + // FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots. + const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 }; + const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E }; + if (EllipsisChar == (ImWchar)-1) + EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars)); + if (DotChar == (ImWchar)-1) + DotChar = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars)); + + // Setup fallback character + const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' }; + FallbackGlyph = FindGlyphNoFallback(FallbackChar); + if (FallbackGlyph == NULL) + { + FallbackChar = FindFirstExistingGlyph(this, fallback_chars, IM_ARRAYSIZE(fallback_chars)); + FallbackGlyph = FindGlyphNoFallback(FallbackChar); + if (FallbackGlyph == NULL) + { + FallbackGlyph = &Glyphs.back(); + FallbackChar = (ImWchar)FallbackGlyph->Codepoint; + } + } + + FallbackAdvanceX = FallbackGlyph->AdvanceX; + for (int i = 0; i < max_codepoint + 1; i++) + if (IndexAdvanceX[i] < 0.0f) + IndexAdvanceX[i] = FallbackAdvanceX; +} + +// API is designed this way to avoid exposing the 4K page size +// e.g. use with IsGlyphRangeUnused(0, 255) +bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last) +{ + unsigned int page_begin = (c_begin / 4096); + unsigned int page_last = (c_last / 4096); + for (unsigned int page_n = page_begin; page_n <= page_last; page_n++) + if ((page_n >> 3) < sizeof(Used4kPagesMap)) + if (Used4kPagesMap[page_n >> 3] & (1 << (page_n & 7))) + return false; + return true; +} + +void ImFont::SetGlyphVisible(ImWchar c, bool visible) +{ + if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c)) + glyph->Visible = visible ? 1 : 0; +} + +void ImFont::GrowIndex(int new_size) +{ + IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); + if (new_size <= IndexLookup.Size) + return; + IndexAdvanceX.resize(new_size, -1.0f); + IndexLookup.resize(new_size, (ImWchar)-1); +} + +// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero. +// Not to be mistaken with texture coordinates, which are held by u0/v0/u1/v1 in normalized format (0.0..1.0 on each texture axis). +// 'cfg' is not necessarily == 'this->ConfigData' because multiple source fonts+configs can be used to build one target font. +void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) +{ + if (cfg != NULL) + { + // Clamp & recenter if needed + const float advance_x_original = advance_x; + advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX); + if (advance_x != advance_x_original) + { + float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f; + x0 += char_off_x; + x1 += char_off_x; + } + + // Snap to pixel + if (cfg->PixelSnapH) + advance_x = IM_ROUND(advance_x); + + // Bake spacing + advance_x += cfg->GlyphExtraSpacing.x; + } + + Glyphs.resize(Glyphs.Size + 1); + ImFontGlyph& glyph = Glyphs.back(); + glyph.Codepoint = (unsigned int)codepoint; + glyph.Visible = (x0 != x1) && (y0 != y1); + glyph.Colored = false; + glyph.X0 = x0; + glyph.Y0 = y0; + glyph.X1 = x1; + glyph.Y1 = y1; + glyph.U0 = u0; + glyph.V0 = v0; + glyph.U1 = u1; + glyph.V1 = v1; + glyph.AdvanceX = advance_x; + + // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) + // We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling. + float pad = ContainerAtlas->TexGlyphPadding + 0.99f; + DirtyLookupTables = true; + MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + pad) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + pad); +} + +void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) +{ + IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. + unsigned int index_size = (unsigned int)IndexLookup.Size; + + if (dst < index_size && IndexLookup.Data[dst] == (ImWchar)-1 && !overwrite_dst) // 'dst' already exists + return; + if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op + return; + + GrowIndex(dst + 1); + IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImWchar)-1; + IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; +} + +const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const +{ + if (c >= (size_t)IndexLookup.Size) + return FallbackGlyph; + const ImWchar i = IndexLookup.Data[c]; + if (i == (ImWchar)-1) + return FallbackGlyph; + return &Glyphs.Data[i]; +} + +const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const +{ + if (c >= (size_t)IndexLookup.Size) + return NULL; + const ImWchar i = IndexLookup.Data[c]; + if (i == (ImWchar)-1) + return NULL; + return &Glyphs.Data[i]; +} + +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; + wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters + + 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 < 32) + { + if (c == '\n') + { + line_width = word_width = blank_width = 0.0f; + inside_word = true; + s = next_s; + continue; + } + if (c == '\r') + { + s = next_s; + continue; + } + } + + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX); + if (ImCharIsBlankW(c)) + { + if (inside_word) + { + line_width += blank_width; + blank_width = 0.0f; + word_end = s; + } + 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 line_height = size; + const float scale = size / FontSize; + + 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 (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source + 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) // Malformed UTF-8? + break; + } + + if (c < 32) + { + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + if (c == '\r') + continue; + } + + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale; + if (line_width + char_width >= max_width) + { + s = prev_s; + break; + } + + line_width += char_width; + } + + if (text_size.x < line_width) + text_size.x = line_width; + + if (line_width > 0 || text_size.y == 0.0f) + text_size.y += line_height; + + if (remaining) + *remaining = s; + + return text_size; +} + +// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. +void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const +{ + const ImFontGlyph* glyph = FindGlyph(c); + if (!glyph || !glyph->Visible) + return; + if (glyph->Colored) + col |= ~IM_COL32_A_MASK; + float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; + pos.x = IM_FLOOR(pos.x); + pos.y = IM_FLOOR(pos.y); + draw_list->PrimReserve(6, 4); + draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); +} + +// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. +void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const +{ + if (!text_end) + text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. + + // Align to be pixel perfect + pos.x = IM_FLOOR(pos.x); + pos.y = IM_FLOOR(pos.y); + float x = pos.x; + float y = pos.y; + if (y > clip_rect.w) + return; + + const float scale = size / FontSize; + const float line_height = FontSize * scale; + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; + + // Fast-forward to first visible line + const char* s = text_begin; + if (y + line_height < clip_rect.y && !word_wrap_enabled) + while (y + line_height < clip_rect.y && s < text_end) + { + s = (const char*)memchr(s, '\n', text_end - s); + s = s ? s + 1 : text_end; + y += line_height; + } + + // For large text, scan for the last visible line in order to avoid over-reserving in the call to PrimReserve() + // Note that very large horizontal line will still be affected by the issue (e.g. a one megabyte string buffer without a newline will likely crash atm) + if (text_end - s > 10000 && !word_wrap_enabled) + { + const char* s_end = s; + float y_end = y; + while (y_end < clip_rect.w && s_end < text_end) + { + s_end = (const char*)memchr(s_end, '\n', text_end - s_end); + s_end = s_end ? s_end + 1 : text_end; + y_end += line_height; + } + text_end = s_end; + } + if (s == text_end) + return; + + // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized) + const int vtx_count_max = (int)(text_end - s) * 4; + const int idx_count_max = (int)(text_end - s) * 6; + const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; + draw_list->PrimReserve(idx_count_max, vtx_count_max); + + ImDrawVert* vtx_write = draw_list->_VtxWritePtr; + ImDrawIdx* idx_write = draw_list->_IdxWritePtr; + unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx; + + const ImU32 col_untinted = col | ~IM_COL32_A_MASK; + + 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 (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + } + continue; + } + } + + // Decode and advance source + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) // Malformed UTF-8? + break; + } + + if (c < 32) + { + if (c == '\n') + { + x = pos.x; + y += line_height; + if (y > clip_rect.w) + break; // break out of main loop + continue; + } + if (c == '\r') + continue; + } + + const ImFontGlyph* glyph = FindGlyph((ImWchar)c); + if (glyph == NULL) + continue; + + float char_width = glyph->AdvanceX * scale; + if (glyph->Visible) + { + // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w + float x1 = x + glyph->X0 * scale; + float x2 = x + glyph->X1 * scale; + float y1 = y + glyph->Y0 * scale; + float y2 = y + glyph->Y1 * 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 quads. + if (cpu_fine_clip) + { + if (x1 < clip_rect.x) + { + u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); + x1 = clip_rect.x; + } + if (y1 < clip_rect.y) + { + v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); + y1 = clip_rect.y; + } + if (x2 > clip_rect.z) + { + u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); + x2 = clip_rect.z; + } + if (y2 > clip_rect.w) + { + v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); + y2 = clip_rect.w; + } + if (y1 >= y2) + { + x += char_width; + continue; + } + } + + // Support for untinted glyphs + ImU32 glyph_col = glyph->Colored ? col_untinted : col; + + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: + { + idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); + idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); + vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; + vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; + vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; + vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; + vtx_write += 4; + vtx_current_idx += 4; + idx_write += 6; + } + } + } + x += char_width; + } + + // Give back unused vertices (clipped ones, blanks) ~ this is essentially a PrimUnreserve() action. + draw_list->VtxBuffer.Size = (int)(vtx_write - draw_list->VtxBuffer.Data); // Same as calling shrink() + draw_list->IdxBuffer.Size = (int)(idx_write - draw_list->IdxBuffer.Data); + draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); + draw_list->_VtxWritePtr = vtx_write; + draw_list->_IdxWritePtr = idx_write; + draw_list->_VtxCurrentIdx = vtx_current_idx; +} + +//----------------------------------------------------------------------------- +// [SECTION] ImGui Internal Render Helpers +//----------------------------------------------------------------------------- +// Vaguely redesigned to stop accessing ImGui global state: +// - RenderArrow() +// - RenderBullet() +// - RenderCheckMark() +// - RenderArrowDockMenu() +// - RenderArrowPointingAt() +// - RenderRectFilledRangeH() +// - RenderRectFilledWithHole() +//----------------------------------------------------------------------------- +// Function in need of a redesign (legacy mess) +// - RenderColorRectWithAlphaCheckerboard() +//----------------------------------------------------------------------------- + +// Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state +void ImGui::RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale) +{ + const float h = draw_list->_Data->FontSize * 1.00f; + float r = h * 0.40f * scale; + ImVec2 center = pos + ImVec2(h * 0.50f, h * 0.50f * scale); + + ImVec2 a, b, c; + switch (dir) + { + case ImGuiDir_Up: + case ImGuiDir_Down: + if (dir == ImGuiDir_Up) r = -r; + a = ImVec2(+0.000f, +0.750f) * r; + b = ImVec2(-0.866f, -0.750f) * r; + c = ImVec2(+0.866f, -0.750f) * r; + break; + case ImGuiDir_Left: + case ImGuiDir_Right: + if (dir == ImGuiDir_Left) r = -r; + a = ImVec2(+0.750f, +0.000f) * r; + b = ImVec2(-0.750f, +0.866f) * r; + c = ImVec2(-0.750f, -0.866f) * r; + break; + case ImGuiDir_None: + case ImGuiDir_COUNT: + IM_ASSERT(0); + break; + } + draw_list->AddTriangleFilled(center + a, center + b, center + c, col); +} + +void ImGui::RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col) +{ + draw_list->AddCircleFilled(pos, draw_list->_Data->FontSize * 0.20f, col, 8); +} + +void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz) +{ + float thickness = ImMax(sz / 5.0f, 1.0f); + sz -= thickness * 0.5f; + pos += ImVec2(thickness * 0.25f, thickness * 0.25f); + + float third = sz / 3.0f; + float bx = pos.x + third; + float by = pos.y + sz - third * 0.5f; + draw_list->PathLineTo(ImVec2(bx - third, by - third)); + draw_list->PathLineTo(ImVec2(bx, by)); + draw_list->PathLineTo(ImVec2(bx + third * 2.0f, by - third * 2.0f)); + draw_list->PathStroke(col, 0, thickness); +} + +// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side. +void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col) +{ + switch (direction) + { + case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return; + case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; + case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; + case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; + case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings + } +} + +// This is less wide than RenderArrow() and we use in dock nodes instead of the regular RenderArrow() to denote a change of functionality, +// and because the saved space means that the left-most tab label can stay at exactly the same position as the label of a loose window. +void ImGui::RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col) +{ + draw_list->AddRectFilled(p_min + ImVec2(sz * 0.20f, sz * 0.15f), p_min + ImVec2(sz * 0.80f, sz * 0.30f), col); + RenderArrowPointingAt(draw_list, p_min + ImVec2(sz * 0.50f, sz * 0.85f), ImVec2(sz * 0.30f, sz * 0.40f), ImGuiDir_Down, col); +} + +static inline float ImAcos01(float x) +{ + if (x <= 0.0f) return IM_PI * 0.5f; + if (x >= 1.0f) return 0.0f; + return ImAcos(x); + //return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, may be enough for what we do. +} + +// FIXME: Cleanup and move code to ImDrawList. +void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding) +{ + if (x_end_norm == x_start_norm) + return; + if (x_start_norm > x_end_norm) + ImSwap(x_start_norm, x_end_norm); + + ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y); + ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y); + if (rounding == 0.0f) + { + draw_list->AddRectFilled(p0, p1, col, 0.0f); + return; + } + + rounding = ImClamp(ImMin((rect.Max.x - rect.Min.x) * 0.5f, (rect.Max.y - rect.Min.y) * 0.5f) - 1.0f, 0.0f, rounding); + const float inv_rounding = 1.0f / rounding; + const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding); + const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding); + const float half_pi = IM_PI * 0.5f; // We will == compare to this because we know this is the exact value ImAcos01 can return. + const float x0 = ImMax(p0.x, rect.Min.x + rounding); + if (arc0_b == arc0_e) + { + draw_list->PathLineTo(ImVec2(x0, p1.y)); + draw_list->PathLineTo(ImVec2(x0, p0.y)); + } + else if (arc0_b == 0.0f && arc0_e == half_pi) + { + draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL + draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR + } + else + { + draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL + draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR + } + if (p1.x > rect.Min.x + rounding) + { + const float arc1_b = ImAcos01(1.0f - (rect.Max.x - p1.x) * inv_rounding); + const float arc1_e = ImAcos01(1.0f - (rect.Max.x - p0.x) * inv_rounding); + const float x1 = ImMin(p1.x, rect.Max.x - rounding); + if (arc1_b == arc1_e) + { + draw_list->PathLineTo(ImVec2(x1, p0.y)); + draw_list->PathLineTo(ImVec2(x1, p1.y)); + } + else if (arc1_b == 0.0f && arc1_e == half_pi) + { + draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR + draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR + } + else + { + draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR + draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR + } + } + draw_list->PathFillConvex(col); +} + +void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding) +{ + const bool fill_L = (inner.Min.x > outer.Min.x); + const bool fill_R = (inner.Max.x < outer.Max.x); + const bool fill_U = (inner.Min.y > outer.Min.y); + const bool fill_D = (inner.Max.y < outer.Max.y); + if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft)); + if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight)); + if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight)); + if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight)); + if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopLeft); + if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopRight); + if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomLeft); + if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight); +} + +ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold) +{ + bool round_l = r_in.Min.x <= r_outer.Min.x + threshold; + bool round_r = r_in.Max.x >= r_outer.Max.x - threshold; + bool round_t = r_in.Min.y <= r_outer.Min.y + threshold; + bool round_b = r_in.Max.y >= r_outer.Max.y - threshold; + return ImDrawFlags_RoundCornersNone + | ((round_t && round_l) ? ImDrawFlags_RoundCornersTopLeft : 0) | ((round_t && round_r) ? ImDrawFlags_RoundCornersTopRight : 0) + | ((round_b && round_l) ? ImDrawFlags_RoundCornersBottomLeft : 0) | ((round_b && round_r) ? ImDrawFlags_RoundCornersBottomRight : 0); +} + +// Helper for ColorPicker4() +// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that. +// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether. +// FIXME: uses ImGui::GetColorU32 +void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags) +{ + if ((flags & ImDrawFlags_RoundCornersMask_) == 0) + flags = ImDrawFlags_RoundCornersDefault_; + if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) + { + ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col)); + ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col)); + draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags); + + int yi = 0; + for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++) + { + float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); + if (y2 <= y1) + continue; + for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) + { + float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); + if (x2 <= x1) + continue; + ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; + if (y1 <= p_min.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersTopLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersTopRight; } + if (y2 >= p_max.y) { if (x1 <= p_min.x) cell_flags |= ImDrawFlags_RoundCornersBottomLeft; if (x2 >= p_max.x) cell_flags |= ImDrawFlags_RoundCornersBottomRight; } + + // Combine flags + cell_flags = (flags == ImDrawFlags_RoundCornersNone || cell_flags == ImDrawFlags_RoundCornersNone) ? ImDrawFlags_RoundCornersNone : (cell_flags & flags); + draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding, cell_flags); + } + } + } + else + { + draw_list->AddRectFilled(p_min, p_max, col, rounding, flags); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] Decompression code +//----------------------------------------------------------------------------- +// Compressed with stb_compress() then converted to a C array and encoded as base85. +// Use the program in misc/fonts/binary_to_compressed_c.cpp to create the array from a TTF file. +// The purpose of encoding as base85 instead of "0x00,0x01,..." style is only save on _source code_ size. +// Decompression from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h +//----------------------------------------------------------------------------- + +static unsigned int stb_decompress_length(const unsigned char *input) +{ + return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; +} + +static unsigned char *stb__barrier_out_e, *stb__barrier_out_b; +static const unsigned char *stb__barrier_in_b; +static unsigned char *stb__dout; +static void stb__match(const unsigned char *data, unsigned int length) +{ + // INVERSE of memmove... write each byte before copying the next... + IM_ASSERT(stb__dout + length <= stb__barrier_out_e); + if (stb__dout + length > stb__barrier_out_e) { stb__dout += length; return; } + if (data < stb__barrier_out_b) { stb__dout = stb__barrier_out_e+1; return; } + while (length--) *stb__dout++ = *data++; +} + +static void stb__lit(const unsigned char *data, unsigned int length) +{ + IM_ASSERT(stb__dout + length <= stb__barrier_out_e); + if (stb__dout + length > stb__barrier_out_e) { stb__dout += length; return; } + if (data < stb__barrier_in_b) { stb__dout = stb__barrier_out_e+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 const unsigned char *stb_decompress_token(const 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 = buflen % 5552; + + unsigned long i; + 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, const unsigned char *i, unsigned int /*length*/) +{ + if (stb__in4(0) != 0x57bC0000) return 0; + if (stb__in4(4) != 0) return 0; // error! stream is > 4GB + const unsigned int olen = stb_decompress_length(i); + stb__barrier_in_b = i; + stb__barrier_out_e = output + olen; + stb__barrier_out_b = output; + i += 16; + + stb__dout = output; + for (;;) { + const 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; + } +} + +//----------------------------------------------------------------------------- +// [SECTION] Default font data (ProggyClean.ttf) +//----------------------------------------------------------------------------- +// 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 +//----------------------------------------------------------------------------- +// File: 'ProggyClean.ttf' (41208 bytes) +// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding). +// The purpose of encoding as base85 instead of "0x00,0x01,..." style is only save on _source code_ size. +//----------------------------------------------------------------------------- +static const char proggy_clean_ttf_compressed_data_base85[11980 + 1] = + "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" + "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" + "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc." + "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" + "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" + "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#" + "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM" + "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" + "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/" + "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO" + "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" + "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" + "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" + "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" + "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M" + "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" + "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" + "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" + "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" + "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" + "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" + ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" + "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" + "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" + "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" + "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" + "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8" + "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" + "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" + "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%" + "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" + "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:" + "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$U4O]GKx'm9)b@p7YsvK3w^YR-" + "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" + "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IXSsDiWP,##P`%/L-" + "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj" + "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" + ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" + "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" + "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)" + "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" + "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P" + "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" + "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#" + ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T" + "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4" + "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#" + "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" + "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp" + "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; + +static const char* GetDefaultCompressedFontDataTTFBase85() +{ + return proggy_clean_ttf_compressed_data_base85; +} + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui_internal.h b/libultraship/libultraship/Lib/ImGui/imgui_internal.h new file mode 100644 index 000000000..b8212198b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui_internal.h @@ -0,0 +1,3220 @@ +// dear imgui, v1.87 +// (internal structures/api) + +// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! +// Set: +// #define IMGUI_DEFINE_MATH_OPERATORS +// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) + +/* + +Index of this file: + +// [SECTION] Header mess +// [SECTION] Forward declarations +// [SECTION] Context pointer +// [SECTION] STB libraries includes +// [SECTION] Macros +// [SECTION] Generic helpers +// [SECTION] ImDrawList support +// [SECTION] Widgets support: flags, enums, data structures +// [SECTION] Inputs support +// [SECTION] Clipper support +// [SECTION] Navigation support +// [SECTION] Columns support +// [SECTION] Multi-select support +// [SECTION] Docking support +// [SECTION] Viewport support +// [SECTION] Settings support +// [SECTION] Metrics, Debug tools +// [SECTION] Generic context hooks +// [SECTION] ImGuiContext (main imgui context) +// [SECTION] ImGuiWindowTempData, ImGuiWindow +// [SECTION] Tab bar, Tab item support +// [SECTION] Table support +// [SECTION] ImGui internal API +// [SECTION] ImFontAtlas internal API +// [SECTION] Test Engine specific hooks (imgui_test_engine) + +*/ + +#pragma once +#ifndef IMGUI_DISABLE + +//----------------------------------------------------------------------------- +// [SECTION] Header mess +//----------------------------------------------------------------------------- + +#ifndef IMGUI_VERSION +#include "imgui.h" +#endif + +#include // FILE*, sscanf +#include // NULL, malloc, free, qsort, atoi, atof +#include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf +#include // INT_MIN, INT_MAX + +// Enable SSE intrinsics if available +#if (defined __SSE__ || defined __x86_64__ || defined _M_X64) && !defined(IMGUI_DISABLE_SSE) +#define IMGUI_ENABLE_SSE +#include +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) +#pragma warning (disable: 26812) // The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer) +#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6). +#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later +#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types +#endif +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloorSigned() +#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wold-style-cast" +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#pragma clang diagnostic ignored "-Wdouble-promotion" +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn' +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +// Legacy defines +#ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Renamed in 1.74 +#error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS +#endif +#ifdef IMGUI_DISABLE_MATH_FUNCTIONS // Renamed in 1.74 +#error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS +#endif + +// Enable stb_truetype by default unless FreeType is enabled. +// You can compile with both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE together. +#ifndef IMGUI_ENABLE_FREETYPE +#define IMGUI_ENABLE_STB_TRUETYPE +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Forward declarations +//----------------------------------------------------------------------------- + +struct ImBitVector; // Store 1-bit per value +struct ImRect; // An axis-aligned rectangle (2 points) +struct ImDrawDataBuilder; // Helper to build a ImDrawData instance +struct ImDrawListSharedData; // Data shared between all ImDrawList instances +struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it +struct ImGuiContext; // Main Dear ImGui context +struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine +struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum +struct ImGuiDockContext; // Docking system context +struct ImGuiDockRequest; // Docking system dock/undock queued request +struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes) +struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session) +struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() +struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box +struct ImGuiLastItemData; // Status storage for last submitted items +struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only +struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result +struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions +struct ImGuiNextWindowData; // Storage for SetNextWindow** functions +struct ImGuiNextItemData; // Storage for SetNextItem** functions +struct ImGuiOldColumnData; // Storage data for a single column for legacy Columns() api +struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api +struct ImGuiPopupData; // Storage for current popup stack +struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file +struct ImGuiStackSizes; // Storage of stack sizes for debugging/asserting +struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it +struct ImGuiTabBar; // Storage for a tab bar +struct ImGuiTabItem; // Storage for a tab item (within a tab bar) +struct ImGuiTable; // Storage for a table +struct ImGuiTableColumn; // Storage for one column of a table +struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables. +struct ImGuiTableSettings; // Storage for a table .ini settings +struct ImGuiTableColumnsSettings; // Storage for a column .ini settings +struct ImGuiWindow; // Storage for one window +struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) +struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) + +// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. +typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field +typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical +typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) +typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() +typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags +typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() +typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() +typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: for GetNavInputAmount2d() +typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests +typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions +typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions +typedef int ImGuiScrollFlags; // -> enum ImGuiScrollFlags_ // Flags: for ScrollToItem() and navigation requests +typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx() +typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx() +typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx() + +typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...); + +//----------------------------------------------------------------------------- +// [SECTION] Context pointer +// See implementation of this variable in imgui.cpp for comments and details. +//----------------------------------------------------------------------------- + +#ifndef GImGui +extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer +#endif + +//------------------------------------------------------------------------- +// [SECTION] STB libraries includes +//------------------------------------------------------------------------- + +namespace ImStb +{ + +#undef STB_TEXTEDIT_STRING +#undef STB_TEXTEDIT_CHARTYPE +#define STB_TEXTEDIT_STRING ImGuiInputTextState +#define STB_TEXTEDIT_CHARTYPE ImWchar +#define STB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f) +#define STB_TEXTEDIT_UNDOSTATECOUNT 99 +#define STB_TEXTEDIT_UNDOCHARCOUNT 999 +#include "imstb_textedit.h" + +} // namespace ImStb + +//----------------------------------------------------------------------------- +// [SECTION] Macros +//----------------------------------------------------------------------------- + +// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui. +#define IMGUI_PAYLOAD_TYPE_WINDOW "_IMWINDOW" // Payload == ImGuiWindow* + +// Debug Logging +#ifndef IMGUI_DEBUG_LOG +#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__) +#endif + +// Debug Logging for selected systems. Remove the '((void)0) //' to enable. +//#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log +//#define IMGUI_DEBUG_LOG_NAV IMGUI_DEBUG_LOG // Enable log +//#define IMGUI_DEBUG_LOG_IO IMGUI_DEBUG_LOG // Enable log +//#define IMGUI_DEBUG_LOG_VIEWPORT IMGUI_DEBUG_LOG // Enable log +//#define IMGUI_DEBUG_LOG_DOCKING IMGUI_DEBUG_LOG // Enable log +#define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log +#define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log +#define IMGUI_DEBUG_LOG_IO(...) ((void)0) // Disable log +#define IMGUI_DEBUG_LOG_VIEWPORT(...) ((void)0) // Disable log +#define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log + +// Static Asserts +#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "") + +// "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much. +// We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code. +//#define IMGUI_DEBUG_PARANOID +#ifdef IMGUI_DEBUG_PARANOID +#define IM_ASSERT_PARANOID(_EXPR) IM_ASSERT(_EXPR) +#else +#define IM_ASSERT_PARANOID(_EXPR) +#endif + +// Error handling +// Down the line in some frameworks/languages we would like to have a way to redirect those to the programmer and recover from more faults. +#ifndef IM_ASSERT_USER_ERROR +#define IM_ASSERT_USER_ERROR(_EXP,_MSG) IM_ASSERT((_EXP) && _MSG) // Recoverable User Error +#endif + +// Misc Macros +#define IM_PI 3.14159265358979323846f +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" // Play it nice with Windows users (Update: since 2018-05, Notepad finally appears to support Unix-style carriage returns!) +#else +#define IM_NEWLINE "\n" +#endif +#define IM_TABSIZE (4) +#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + (_ALIGN - 1)) & ~(_ALIGN - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8 +#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose +#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 +#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds +#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // + +// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall +#ifdef _MSC_VER +#define IMGUI_CDECL __cdecl +#else +#define IMGUI_CDECL +#endif + +// Warnings +#if defined(_MSC_VER) && !defined(__clang__) +#define IM_MSVC_WARNING_SUPPRESS(XXXX) __pragma(warning(suppress: XXXX)) +#else +#define IM_MSVC_WARNING_SUPPRESS(XXXX) +#endif + +// Debug Tools +// Use 'Metrics/Debugger->Tools->Item Picker' to break into the call-stack of a specific item. +// This will call IM_DEBUG_BREAK() which you may redefine yourself. See https://github.com/scottt/debugbreak for more reference. +#ifndef IM_DEBUG_BREAK +#if defined (_MSC_VER) +#define IM_DEBUG_BREAK() __debugbreak() +#elif defined(__clang__) +#define IM_DEBUG_BREAK() __builtin_debugtrap() +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define IM_DEBUG_BREAK() __asm__ volatile("int $0x03") +#elif defined(__GNUC__) && defined(__thumb__) +#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01") +#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) +#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0"); +#else +#define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger! +#endif +#endif // #ifndef IM_DEBUG_BREAK + +//----------------------------------------------------------------------------- +// [SECTION] Generic helpers +// Note that the ImXXX helpers functions are lower-level than ImGui functions. +// ImGui functions or the ImGui context are never called/used from other ImXXX functions. +//----------------------------------------------------------------------------- +// - Helpers: Hashing +// - Helpers: Sorting +// - Helpers: Bit manipulation +// - Helpers: String, Formatting +// - Helpers: UTF-8 <> wchar conversions +// - Helpers: ImVec2/ImVec4 operators +// - Helpers: Maths +// - Helpers: Geometry +// - Helper: ImVec1 +// - Helper: ImVec2ih +// - Helper: ImRect +// - Helper: ImBitArray +// - Helper: ImBitVector +// - Helper: ImSpan<>, ImSpanAllocator<> +// - Helper: ImPool<> +// - Helper: ImChunkStream<> +//----------------------------------------------------------------------------- + +// Helpers: Hashing +IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0); +IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0); +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68] +#endif + +// Helpers: Sorting +#ifndef ImQsort +static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); } +#endif + +// Helpers: Color Blending +IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b); + +// Helpers: Bit manipulation +static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } +static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 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; } + +// Helpers: String, Formatting +IMGUI_API int ImStricmp(const char* str1, const char* str2); +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); +IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); +IMGUI_API char* ImStrdup(const char* str); +IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); +IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); +IMGUI_API int ImStrlenW(const ImWchar* str); +IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line +IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line +IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); +IMGUI_API void ImStrTrimBlanks(char* str); +IMGUI_API const char* ImStrSkipBlank(const char* str); +IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API const char* ImParseFormatFindStart(const char* format); +IMGUI_API const char* ImParseFormatFindEnd(const char* format); +IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size); +IMGUI_API int ImParseFormatPrecision(const char* format, int default_value); +static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } +static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } + +// Helpers: UTF-8 <> wchar conversions +IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf +IMGUI_API int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count +IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // read one character. return input UTF-8 bytes count +IMGUI_API int ImTextStrFromUtf8(ImWchar* out_buf, int out_buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count +IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) +IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end); // return number of bytes to express one char in UTF-8 +IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8 + +// Helpers: ImVec2/ImVec4 operators +// We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.) +// We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself. +#ifdef IMGUI_DEFINE_MATH_OPERATORS +IM_MSVC_RUNTIME_CHECKS_OFF +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 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 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 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 ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } +static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } +static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } +IM_MSVC_RUNTIME_CHECKS_RESTORE +#endif + +// Helpers: File System +#ifdef IMGUI_DISABLE_FILE_FUNCTIONS +#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS +typedef void* ImFileHandle; +static inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; } +static inline bool ImFileClose(ImFileHandle) { return false; } +static inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; } +static inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; } +static inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; } +#endif +#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS +typedef FILE* ImFileHandle; +IMGUI_API ImFileHandle ImFileOpen(const char* filename, const char* mode); +IMGUI_API bool ImFileClose(ImFileHandle file); +IMGUI_API ImU64 ImFileGetSize(ImFileHandle file); +IMGUI_API ImU64 ImFileRead(void* data, ImU64 size, ImU64 count, ImFileHandle file); +IMGUI_API ImU64 ImFileWrite(const void* data, ImU64 size, ImU64 count, ImFileHandle file); +#else +#define IMGUI_DISABLE_TTY_FUNCTIONS // Can't use stdout, fflush if we are not using default file functions +#endif +IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size = NULL, int padding_bytes = 0); + +// Helpers: Maths +IM_MSVC_RUNTIME_CHECKS_OFF +// - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy) +#ifndef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS +#define ImFabs(X) fabsf(X) +#define ImSqrt(X) sqrtf(X) +#define ImFmod(X, Y) fmodf((X), (Y)) +#define ImCos(X) cosf(X) +#define ImSin(X) sinf(X) +#define ImAcos(X) acosf(X) +#define ImAtan2(Y, X) atan2f((Y), (X)) +#define ImAtof(STR) atof(STR) +//#define ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned() +#define ImCeil(X) ceilf(X) +static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision +static inline double ImPow(double x, double y) { return pow(x, y); } +static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision +static inline double ImLog(double x) { return log(x); } +static inline int ImAbs(int x) { return x < 0 ? -x : x; } +static inline float ImAbs(float x) { return fabsf(x); } +static inline double ImAbs(double x) { return fabs(x); } +static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument +static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; } +#ifdef IMGUI_ENABLE_SSE +static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); } +#else +static inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); } +#endif +static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); } +#endif +// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double +// (Exceptionally using templates here but we could also redefine them for those types) +template static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } +template static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } +template static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +template static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } +template static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } +template static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; } +template static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; } +// - Misc maths helpers +static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } +static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } +static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * 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 ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } +static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); } +static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } +static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } +static inline float ImFloor(float f) { return (float)(int)(f); } +static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() +static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } +static inline ImVec2 ImFloorSigned(const ImVec2& v) { return ImVec2(ImFloorSigned(v.x), ImFloorSigned(v.y)); } +static inline int ImModPositive(int a, int b) { return (a + b) % b; } +static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } +static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } +static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } +static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; } +IM_MSVC_RUNTIME_CHECKS_RESTORE + +// Helpers: Geometry +IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); +IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments +IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol +IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t); +IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); +IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); +inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } +IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy); + +// Helper: ImVec1 (1D vector) +// (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches) +IM_MSVC_RUNTIME_CHECKS_OFF +struct ImVec1 +{ + float x; + ImVec1() { x = 0.0f; } + ImVec1(float _x) { x = _x; } +}; + +// Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) +struct ImVec2ih +{ + short x, y; + ImVec2ih() { x = y = 0; } + ImVec2ih(short _x, short _y) { x = _x; y = _y; } + explicit ImVec2ih(const ImVec2& rhs) { x = (short)rhs.x; y = (short)rhs.y; } +}; + +// Helper: ImRect (2D axis aligned bounding-box) +// NB: we can't rely on ImVec2 math operators being available here! +struct IMGUI_API ImRect +{ + ImVec2 Min; // Upper-left + ImVec2 Max; // Lower-right + + ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} + ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} + ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} + ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} + + ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } + ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } + float GetWidth() const { return Max.x - Min.x; } + float GetHeight() const { return Max.y - Min.y; } + float GetArea() const { return (Max.x - Min.x) * (Max.y - Min.y); } + ImVec2 GetTL() const { return Min; } // Top-left + ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right + ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left + ImVec2 GetBR() const { return Max; } // Bottom-right + 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& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } + void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.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.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } + void Translate(const ImVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; } + void TranslateX(float dx) { Min.x += dx; Max.x += dx; } + void TranslateY(float dy) { Min.y += dy; Max.y += dy; } + void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. + void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. + void Floor() { Min.x = IM_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(Max.y); } + bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } + ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); } +}; +IM_MSVC_RUNTIME_CHECKS_RESTORE + +// Helper: ImBitArray +inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; } +inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; } +inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; } +inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on range [n..n2) +{ + n2--; + while (n <= n2) + { + int a_mod = (n & 31); + int b_mod = (n2 > (n | 31) ? 31 : (n2 & 31)) + 1; + ImU32 mask = (ImU32)(((ImU64)1 << b_mod) - 1) & ~(ImU32)(((ImU64)1 << a_mod) - 1); + arr[n >> 5] |= mask; + n = (n + 32) & ~31; + } +} + +// Helper: ImBitArray class (wrapper over ImBitArray functions) +// Store 1-bit per value. +template +struct ImBitArray +{ + ImU32 Storage[(BITCOUNT + 31) >> 5]; + ImBitArray() { ClearAllBits(); } + void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } + void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } + bool TestBit(int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); } + void SetBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArraySetBit(Storage, n + OFFSET); } + void ClearBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArrayClearBit(Storage, n + OFFSET); } + void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n + OFFSET, n2 + OFFSET); } // Works on range [n..n2) + bool operator[](int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); } +}; + +// Helper: ImBitVector +// Store 1-bit per value. +struct IMGUI_API ImBitVector +{ + ImVector Storage; + void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); } + void Clear() { Storage.clear(); } + bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return ImBitArrayTestBit(Storage.Data, n); } + void SetBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArraySetBit(Storage.Data, n); } + void ClearBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArrayClearBit(Storage.Data, n); } +}; + +// Helper: ImSpan<> +// Pointing to a span of data we don't own. +template +struct ImSpan +{ + T* Data; + T* DataEnd; + + // Constructors, destructor + inline ImSpan() { Data = DataEnd = NULL; } + inline ImSpan(T* data, int size) { Data = data; DataEnd = data + size; } + inline ImSpan(T* data, T* data_end) { Data = data; DataEnd = data_end; } + + inline void set(T* data, int size) { Data = data; DataEnd = data + size; } + inline void set(T* data, T* data_end) { Data = data; DataEnd = data_end; } + inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); } + inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); } + inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } + inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } + + inline T* begin() { return Data; } + inline const T* begin() const { return Data; } + inline T* end() { return DataEnd; } + inline const T* end() const { return DataEnd; } + + // Utilities + inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < DataEnd); const ptrdiff_t off = it - Data; return (int)off; } +}; + +// Helper: ImSpanAllocator<> +// Facilitate storing multiple chunks into a single large block (the "arena") +// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges. +template +struct ImSpanAllocator +{ + char* BasePtr; + int CurrOff; + int CurrIdx; + int Offsets[CHUNKS]; + int Sizes[CHUNKS]; + + ImSpanAllocator() { memset(this, 0, sizeof(*this)); } + inline void Reserve(int n, size_t sz, int a=4) { IM_ASSERT(n == CurrIdx && n < CHUNKS); CurrOff = IM_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; } + inline int GetArenaSizeInBytes() { return CurrOff; } + inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; } + inline void* GetSpanPtrBegin(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n]); } + inline void* GetSpanPtrEnd(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n] + Sizes[n]); } + template + inline void GetSpan(int n, ImSpan* span) { span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n)); } +}; + +// Helper: ImPool<> +// Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a dense/hot buffer, +// Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object. +typedef int ImPoolIdx; +template +struct ImPool +{ + ImVector Buf; // Contiguous data + ImGuiStorage Map; // ID->Index + ImPoolIdx FreeIdx; // Next free idx to use + ImPoolIdx AliveCount; // Number of active/alive items (for display purpose) + + ImPool() { FreeIdx = AliveCount = 0; } + ~ImPool() { Clear(); } + T* GetByKey(ImGuiID key) { int idx = Map.GetInt(key, -1); return (idx != -1) ? &Buf[idx] : NULL; } + T* GetByIndex(ImPoolIdx n) { return &Buf[n]; } + ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Buf.Data && p < Buf.Data + Buf.Size); return (ImPoolIdx)(p - Buf.Data); } + T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Buf[*p_idx]; *p_idx = FreeIdx; return Add(); } + bool Contains(const T* p) const { return (p >= Buf.Data && p < Buf.Data + Buf.Size); } + void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Buf[idx].~T(); } Map.Clear(); Buf.clear(); FreeIdx = AliveCount = 0; } + T* Add() { int idx = FreeIdx; if (idx == Buf.Size) { Buf.resize(Buf.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Buf[idx]; } IM_PLACEMENT_NEW(&Buf[idx]) T(); AliveCount++; return &Buf[idx]; } + void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); } + void Remove(ImGuiID key, ImPoolIdx idx) { Buf[idx].~T(); *(int*)&Buf[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); AliveCount--; } + void Reserve(int capacity) { Buf.reserve(capacity); Map.Data.reserve(capacity); } + + // To iterate a ImPool: for (int n = 0; n < pool.GetMapSize(); n++) if (T* t = pool.TryGetMapData(n)) { ... } + // Can be avoided if you know .Remove() has never been called on the pool, or AliveCount == GetMapSize() + int GetAliveCount() const { return AliveCount; } // Number of active/alive items in the pool (for display purpose) + int GetBufSize() const { return Buf.Size; } + int GetMapSize() const { return Map.Data.Size; } // It is the map we need iterate to find valid items, since we don't have "alive" storage anywhere + T* TryGetMapData(ImPoolIdx n) { int idx = Map.Data[n].val_i; if (idx == -1) return NULL; return GetByIndex(idx); } +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304) +#endif +}; + +// Helper: ImChunkStream<> +// Build and iterate a contiguous stream of variable-sized structures. +// This is used by Settings to store persistent data while reducing allocation count. +// We store the chunk size first, and align the final size on 4 bytes boundaries. +// The tedious/zealous amount of casting is to avoid -Wcast-align warnings. +template +struct ImChunkStream +{ + ImVector Buf; + + void clear() { Buf.clear(); } + bool empty() const { return Buf.Size == 0; } + int size() const { return Buf.Size; } + T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = IM_MEMALIGN(HDR_SZ + sz, 4u); int off = Buf.Size; Buf.resize(off + (int)sz); ((int*)(void*)(Buf.Data + off))[0] = (int)sz; return (T*)(void*)(Buf.Data + off + (int)HDR_SZ); } + T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); } + T* next_chunk(T* p) { size_t HDR_SZ = 4; IM_ASSERT(p >= begin() && p < end()); p = (T*)(void*)((char*)(void*)p + chunk_size(p)); if (p == (T*)(void*)((char*)end() + HDR_SZ)) return (T*)0; IM_ASSERT(p < end()); return p; } + int chunk_size(const T* p) { return ((const int*)p)[-1]; } + T* end() { return (T*)(void*)(Buf.Data + Buf.Size); } + int offset_from_ptr(const T* p) { IM_ASSERT(p >= begin() && p < end()); const ptrdiff_t off = (const char*)p - Buf.Data; return (int)off; } + T* ptr_from_offset(int off) { IM_ASSERT(off >= 4 && off < Buf.Size); return (T*)(void*)(Buf.Data + off); } + void swap(ImChunkStream& rhs) { rhs.Buf.swap(Buf); } + +}; + +//----------------------------------------------------------------------------- +// [SECTION] ImDrawList support +//----------------------------------------------------------------------------- + +// ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value. +// Estimation of number of circle segment based on error is derived using method described in https://stackoverflow.com/a/2244088/15194693 +// Number of segments (N) is calculated using equation: +// N = ceil ( pi / acos(1 - error / r) ) where r > 0, error <= r +// Our equation is significantly simpler that one in the post thanks for choosing segment that is +// perpendicular to X axis. Follow steps in the article from this starting condition and you will +// will get this result. +// +// Rendering circles with an odd number of segments, while mathematically correct will produce +// asymmetrical results on the raster grid. Therefore we're rounding N to next even number (7->8, 8->8, 9->10 etc.) +// +#define IM_ROUNDUP_TO_EVEN(_V) ((((_V) + 1) / 2) * 2) +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4 +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp(IM_ROUNDUP_TO_EVEN((int)ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD)))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) + +// Raw equation from IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC rewritten for 'r' and 'error'. +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(_N,_MAXERROR) ((_MAXERROR) / (1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI)))) +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_ERROR(_N,_RAD) ((1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI))) / (_RAD)) + +// ImDrawList: Lookup table size for adaptive arc drawing, cover full circle. +#ifndef IM_DRAWLIST_ARCFAST_TABLE_SIZE +#define IM_DRAWLIST_ARCFAST_TABLE_SIZE 48 // Number of samples in lookup table. +#endif +#define IM_DRAWLIST_ARCFAST_SAMPLE_MAX IM_DRAWLIST_ARCFAST_TABLE_SIZE // Sample index _PathArcToFastEx() for 360 angle. + +// Data shared between all ImDrawList instances +// You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure. +struct IMGUI_API ImDrawListSharedData +{ + ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas + ImFont* Font; // Current/default font (optional, for simplified AddText overload) + float FontSize; // Current/default font size (optional, for simplified AddText overload) + float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() + float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) + + // [Internal] Lookup tables + ImVec2 ArcFastVtx[IM_DRAWLIST_ARCFAST_TABLE_SIZE]; // Sample points on the quarter of the circle. + float ArcFastRadiusCutoff; // Cutoff radius after which arc drawing will fallback to slower PathArcTo() + ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) + const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas + + ImDrawListSharedData(); + void SetCircleTessellationMaxError(float max_error); +}; + +struct ImDrawDataBuilder +{ + ImVector Layers[2]; // Global layers for: regular, tooltip + + void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } + void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } + int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; } + IMGUI_API void FlattenIntoSingleLayer(); +}; + +//----------------------------------------------------------------------------- +// [SECTION] Widgets support: flags, enums, data structures +//----------------------------------------------------------------------------- + +// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). +// This is going to be exposed in imgui.h when stabilized enough. +enum ImGuiItemFlags_ +{ + ImGuiItemFlags_None = 0, + ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav) + ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. + ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211 + ImGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop) + ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items) + ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window + ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) + ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. + ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. +}; + +// Storage for LastItem data +enum ImGuiItemStatusFlags_ +{ + ImGuiItemStatusFlags_None = 0, + ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test) + ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid + ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets) + ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues. + ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state. + ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag. + ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. + ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. + ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8 // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon) + +#ifdef IMGUI_ENABLE_TEST_ENGINE + , // [imgui_tests only] + ImGuiItemStatusFlags_Openable = 1 << 20, // + ImGuiItemStatusFlags_Opened = 1 << 21, // + ImGuiItemStatusFlags_Checkable = 1 << 22, // + ImGuiItemStatusFlags_Checked = 1 << 23 // +#endif +}; + +// Extend ImGuiInputTextFlags_ +enum ImGuiInputTextFlagsPrivate_ +{ + // [Internal] + ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline() + ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data + ImGuiInputTextFlags_MergedItem = 1 << 28 // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. +}; + +// Extend ImGuiButtonFlags_ +enum ImGuiButtonFlagsPrivate_ +{ + ImGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event) + ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using + ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item + ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release) + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release) + ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) + ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat + ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping + ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() + ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED] + //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled + ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine + ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held + ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) + ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated + ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item + ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold, + ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease +}; + +// Extend ImGuiComboFlags_ +enum ImGuiComboFlagsPrivate_ +{ + ImGuiComboFlags_CustomPreview = 1 << 20 // enable BeginComboPreview() +}; + +// Extend ImGuiSliderFlags_ +enum ImGuiSliderFlagsPrivate_ +{ + ImGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically? + ImGuiSliderFlags_ReadOnly = 1 << 21 +}; + +// Extend ImGuiSelectableFlags_ +enum ImGuiSelectableFlagsPrivate_ +{ + // NB: need to be in sync with last value of ImGuiSelectableFlags_ + ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20, + ImGuiSelectableFlags_SelectOnNav = 1 << 21, // (WIP) Auto-select when moved into. This is not exposed in public API as to handle multi-select and modifiers we will need user to explicitly control focus scope. May be replaced with a BeginSelection() API. + ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release) + ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release) + ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) + ImGuiSelectableFlags_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. + ImGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem) + ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27 // Disable padding each side with ItemSpacing * 0.5f +}; + +// Extend ImGuiTreeNodeFlags_ +enum ImGuiTreeNodeFlagsPrivate_ +{ + ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20 +}; + +enum ImGuiSeparatorFlags_ +{ + ImGuiSeparatorFlags_None = 0, + ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar + ImGuiSeparatorFlags_Vertical = 1 << 1, + ImGuiSeparatorFlags_SpanAllColumns = 1 << 2 +}; + +enum ImGuiTextFlags_ +{ + ImGuiTextFlags_None = 0, + ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0 +}; + +enum ImGuiTooltipFlags_ +{ + ImGuiTooltipFlags_None = 0, + ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0 // Override will clear/ignore previously submitted tooltip (defaults to append) +}; + +// FIXME: this is in development, not exposed/functional as a generic feature yet. +// Horizontal/Vertical enums are fixed to 0/1 so they may be used to index ImVec2 +enum ImGuiLayoutType_ +{ + ImGuiLayoutType_Horizontal = 0, + ImGuiLayoutType_Vertical = 1 +}; + +enum ImGuiLogType +{ + ImGuiLogType_None = 0, + ImGuiLogType_TTY, + ImGuiLogType_File, + ImGuiLogType_Buffer, + ImGuiLogType_Clipboard +}; + +// X/Y enums are fixed to 0/1 so they may be used to index ImVec2 +enum ImGuiAxis +{ + ImGuiAxis_None = -1, + ImGuiAxis_X = 0, + ImGuiAxis_Y = 1 +}; + +enum ImGuiPlotType +{ + ImGuiPlotType_Lines, + ImGuiPlotType_Histogram +}; + +enum ImGuiPopupPositionPolicy +{ + ImGuiPopupPositionPolicy_Default, + ImGuiPopupPositionPolicy_ComboBox, + ImGuiPopupPositionPolicy_Tooltip +}; + +struct ImGuiDataTypeTempStorage +{ + ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT +}; + +// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). +struct ImGuiDataTypeInfo +{ + size_t Size; // Size in bytes + const char* Name; // Short descriptive name for the type, for debugging + const char* PrintFmt; // Default printf format for the type + const char* ScanFmt; // Default scanf format for the type +}; + +// Extend ImGuiDataType_ +enum ImGuiDataTypePrivate_ +{ + ImGuiDataType_String = ImGuiDataType_COUNT + 1, + ImGuiDataType_Pointer, + ImGuiDataType_ID +}; + +// Stacked color modifier, backup of modified data so we can restore it +struct ImGuiColorMod +{ + ImGuiCol Col; + ImVec4 BackupValue; +}; + +// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. +struct ImGuiStyleMod +{ + ImGuiStyleVar VarIdx; + union { int BackupInt[2]; float BackupFloat[2]; }; + ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; } + ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; } + ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } +}; + +// Storage data for BeginComboPreview()/EndComboPreview() +struct IMGUI_API ImGuiComboPreviewData +{ + ImRect PreviewRect; + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + ImVec2 BackupCursorPosPrevLine; + float BackupPrevLineTextBaseOffset; + ImGuiLayoutType BackupLayout; + + ImGuiComboPreviewData() { memset(this, 0, sizeof(*this)); } +}; + +// Stacked storage data for BeginGroup()/EndGroup() +struct IMGUI_API ImGuiGroupData +{ + ImGuiID WindowID; + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + ImVec1 BackupIndent; + ImVec1 BackupGroupOffset; + ImVec2 BackupCurrLineSize; + float BackupCurrLineTextBaseOffset; + ImGuiID BackupActiveIdIsAlive; + bool BackupActiveIdPreviousFrameIsAlive; + bool BackupHoveredIdIsAlive; + bool EmitItem; +}; + +// Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper. +struct IMGUI_API ImGuiMenuColumns +{ + ImU32 TotalWidth; + ImU32 NextTotalWidth; + ImU16 Spacing; + ImU16 OffsetIcon; // Always zero for now + ImU16 OffsetLabel; // Offsets are locked in Update() + ImU16 OffsetShortcut; + ImU16 OffsetMark; + ImU16 Widths[4]; // Width of: Icon, Label, Shortcut, Mark (accumulators for current frame) + + ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); } + void Update(float spacing, bool window_reappearing); + float DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark); + void CalcNextTotalWidth(bool update_offsets); +}; + +// Internal state of the currently focused/edited text input box +// For a given item ID, access with ImGui::GetInputTextState() +struct IMGUI_API ImGuiInputTextState +{ + ImGuiID ID; // widget id owning the text state + int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not. + ImVector TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. + ImVector TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity. + ImVector InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) + bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument) + int BufCapacityA; // end-user buffer capacity + float ScrollX; // horizontal scrolling/offset + ImStb::STB_TexteditState Stb; // state for stb_textedit.h + float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately + bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) + bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection + bool Edited; // edited this frame + ImGuiInputTextFlags Flags; // copy of InputText() flags + + ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } + void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } + void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); } + int GetUndoAvailCount() const { return Stb.undostate.undo_point; } + int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; } + void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation + + // Cursor & Selection + void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking + void CursorClamp() { Stb.cursor = ImMin(Stb.cursor, CurLenW); Stb.select_start = ImMin(Stb.select_start, CurLenW); Stb.select_end = ImMin(Stb.select_end, CurLenW); } + bool HasSelection() const { return Stb.select_start != Stb.select_end; } + void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; } + int GetCursorPos() const { return Stb.cursor; } + int GetSelectionStart() const { return Stb.select_start; } + int GetSelectionEnd() const { return Stb.select_end; } + void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; } +}; + +// Storage for current popup stack +struct ImGuiPopupData +{ + ImGuiID PopupId; // Set on OpenPopup() + ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() + ImGuiWindow* SourceWindow; // Set on OpenPopup() copy of NavWindow at the time of opening the popup + int OpenFrameCount; // Set on OpenPopup() + ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) + ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) + ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup + + ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; } +}; + +enum ImGuiNextWindowDataFlags_ +{ + ImGuiNextWindowDataFlags_None = 0, + ImGuiNextWindowDataFlags_HasPos = 1 << 0, + ImGuiNextWindowDataFlags_HasSize = 1 << 1, + ImGuiNextWindowDataFlags_HasContentSize = 1 << 2, + ImGuiNextWindowDataFlags_HasCollapsed = 1 << 3, + ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4, + ImGuiNextWindowDataFlags_HasFocus = 1 << 5, + ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, + ImGuiNextWindowDataFlags_HasScroll = 1 << 7, + ImGuiNextWindowDataFlags_HasViewport = 1 << 8, + ImGuiNextWindowDataFlags_HasDock = 1 << 9, + ImGuiNextWindowDataFlags_HasWindowClass = 1 << 10 +}; + +// Storage for SetNexWindow** functions +struct ImGuiNextWindowData +{ + ImGuiNextWindowDataFlags Flags; + ImGuiCond PosCond; + ImGuiCond SizeCond; + ImGuiCond CollapsedCond; + ImGuiCond DockCond; + ImVec2 PosVal; + ImVec2 PosPivotVal; + ImVec2 SizeVal; + ImVec2 ContentSizeVal; + ImVec2 ScrollVal; + bool PosUndock; + bool CollapsedVal; + ImRect SizeConstraintRect; + ImGuiSizeCallback SizeCallback; + void* SizeCallbackUserData; + float BgAlphaVal; // Override background alpha + ImGuiID ViewportId; + ImGuiID DockId; + ImGuiWindowClass WindowClass; + ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?) + + ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); } + inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } +}; + +enum ImGuiNextItemDataFlags_ +{ + ImGuiNextItemDataFlags_None = 0, + ImGuiNextItemDataFlags_HasWidth = 1 << 0, + ImGuiNextItemDataFlags_HasOpen = 1 << 1 +}; + +struct ImGuiNextItemData +{ + ImGuiNextItemDataFlags Flags; + float Width; // Set by SetNextItemWidth() + ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging) + ImGuiCond OpenCond; + bool OpenVal; // Set by SetNextItemOpen() + + ImGuiNextItemData() { memset(this, 0, sizeof(*this)); } + inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()! +}; + +// Status storage for the last submitted item +struct ImGuiLastItemData +{ + ImGuiID ID; + ImGuiItemFlags InFlags; // See ImGuiItemFlags_ + ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ + ImRect Rect; // Full rectangle + ImRect NavRect; // Navigation scoring rectangle (not displayed) + ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set) + + ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } +}; + +struct IMGUI_API ImGuiStackSizes +{ + short SizeOfIDStack; + short SizeOfColorStack; + short SizeOfStyleVarStack; + short SizeOfFontStack; + short SizeOfFocusScopeStack; + short SizeOfGroupStack; + short SizeOfItemFlagsStack; + short SizeOfBeginPopupStack; + short SizeOfDisabledStack; + + ImGuiStackSizes() { memset(this, 0, sizeof(*this)); } + void SetToCurrentState(); + void CompareWithCurrentState(); +}; + +// Data saved for each window pushed into the stack +struct ImGuiWindowStackData +{ + ImGuiWindow* Window; + ImGuiLastItemData ParentLastItemDataBackup; + ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting +}; + +struct ImGuiShrinkWidthItem +{ + int Index; + float Width; +}; + +struct ImGuiPtrOrIndex +{ + void* Ptr; // Either field can be set, not both. e.g. Dock node tab bars are loose while BeginTabBar() ones are in a pool. + int Index; // Usually index in a main pool. + + ImGuiPtrOrIndex(void* ptr) { Ptr = ptr; Index = -1; } + ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Inputs support +//----------------------------------------------------------------------------- + +typedef ImBitArray ImBitArrayForNamedKeys; + +enum ImGuiKeyPrivate_ +{ + ImGuiKey_LegacyNativeKey_BEGIN = 0, + ImGuiKey_LegacyNativeKey_END = 512, + ImGuiKey_Gamepad_BEGIN = ImGuiKey_GamepadStart, + ImGuiKey_Gamepad_END = ImGuiKey_GamepadRStickRight + 1 +}; + +enum ImGuiInputEventType +{ + ImGuiInputEventType_None = 0, + ImGuiInputEventType_MousePos, + ImGuiInputEventType_MouseWheel, + ImGuiInputEventType_MouseButton, + ImGuiInputEventType_MouseViewport, + ImGuiInputEventType_Key, + ImGuiInputEventType_Char, + ImGuiInputEventType_Focus, + ImGuiInputEventType_COUNT +}; + +enum ImGuiInputSource +{ + ImGuiInputSource_None = 0, + ImGuiInputSource_Mouse, + ImGuiInputSource_Keyboard, + ImGuiInputSource_Gamepad, + ImGuiInputSource_Clipboard, // Currently only used by InputText() + ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only + ImGuiInputSource_COUNT +}; + +// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension? +// Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor' +struct ImGuiInputEventMousePos { float PosX, PosY; }; +struct ImGuiInputEventMouseWheel { float WheelX, WheelY; }; +struct ImGuiInputEventMouseButton { int Button; bool Down; }; +struct ImGuiInputEventMouseViewport { ImGuiID HoveredViewportID; }; +struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; }; +struct ImGuiInputEventText { unsigned int Char; }; +struct ImGuiInputEventAppFocused { bool Focused; }; + +struct ImGuiInputEvent +{ + ImGuiInputEventType Type; + ImGuiInputSource Source; + union + { + ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos + ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel + ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton + ImGuiInputEventMouseViewport MouseViewport; // if Type == ImGuiInputEventType_MouseViewport + ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key + ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text + ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus + }; + bool AddedByTestEngine; + + ImGuiInputEvent() { memset(this, 0, sizeof(*this)); } +}; + +// FIXME-NAV: Clarify/expose various repeat delay/rate +enum ImGuiInputReadMode +{ + ImGuiInputReadMode_Down, + ImGuiInputReadMode_Pressed, + ImGuiInputReadMode_Released, + ImGuiInputReadMode_Repeat, + ImGuiInputReadMode_RepeatSlow, + ImGuiInputReadMode_RepeatFast +}; + +//----------------------------------------------------------------------------- +// [SECTION] Clipper support +//----------------------------------------------------------------------------- + +struct ImGuiListClipperRange +{ + int Min; + int Max; + bool PosToIndexConvert; // Begin/End are absolute position (will be converted to indices later) + ImS8 PosToIndexOffsetMin; // Add to Min after converting to indices + ImS8 PosToIndexOffsetMax; // Add to Min after converting to indices + + static ImGuiListClipperRange FromIndices(int min, int max) { ImGuiListClipperRange r = { min, max, false, 0, 0 }; return r; } + static ImGuiListClipperRange FromPositions(float y1, float y2, int off_min, int off_max) { ImGuiListClipperRange r = { (int)y1, (int)y2, true, (ImS8)off_min, (ImS8)off_max }; return r; } +}; + +// Temporary clipper data, buffers shared/reused between instances +struct ImGuiListClipperData +{ + ImGuiListClipper* ListClipper; + float LossynessOffset; + int StepNo; + int ItemsFrozen; + ImVector Ranges; + + ImGuiListClipperData() { memset(this, 0, sizeof(*this)); } + void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Navigation support +//----------------------------------------------------------------------------- + +enum ImGuiActivateFlags_ +{ + ImGuiActivateFlags_None = 0, + ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available. + ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available. + ImGuiActivateFlags_TryToPreserveState = 1 << 2 // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection) +}; + +// Early work-in-progress API for ScrollToItem() +enum ImGuiScrollFlags_ +{ + ImGuiScrollFlags_None = 0, + ImGuiScrollFlags_KeepVisibleEdgeX = 1 << 0, // If item is not visible: scroll as little as possible on X axis to bring item back into view [default for X axis] + ImGuiScrollFlags_KeepVisibleEdgeY = 1 << 1, // If item is not visible: scroll as little as possible on Y axis to bring item back into view [default for Y axis for windows that are already visible] + ImGuiScrollFlags_KeepVisibleCenterX = 1 << 2, // If item is not visible: scroll to make the item centered on X axis [rarely used] + ImGuiScrollFlags_KeepVisibleCenterY = 1 << 3, // If item is not visible: scroll to make the item centered on Y axis + ImGuiScrollFlags_AlwaysCenterX = 1 << 4, // Always center the result item on X axis [rarely used] + ImGuiScrollFlags_AlwaysCenterY = 1 << 5, // Always center the result item on Y axis [default for Y axis for appearing window) + ImGuiScrollFlags_NoScrollParent = 1 << 6, // Disable forwarding scrolling to parent window if required to keep item/rect visible (only scroll window the function was applied to). + ImGuiScrollFlags_MaskX_ = ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleCenterX | ImGuiScrollFlags_AlwaysCenterX, + ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY +}; + +enum ImGuiNavHighlightFlags_ +{ + ImGuiNavHighlightFlags_None = 0, + ImGuiNavHighlightFlags_TypeDefault = 1 << 0, + ImGuiNavHighlightFlags_TypeThin = 1 << 1, + ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. + ImGuiNavHighlightFlags_NoRounding = 1 << 3 +}; + +enum ImGuiNavDirSourceFlags_ +{ + ImGuiNavDirSourceFlags_None = 0, + ImGuiNavDirSourceFlags_RawKeyboard = 1 << 0, // Raw keyboard (not pulled from nav), faciliate use of some functions before we can unify nav and keys + ImGuiNavDirSourceFlags_Keyboard = 1 << 1, + ImGuiNavDirSourceFlags_PadDPad = 1 << 2, + ImGuiNavDirSourceFlags_PadLStick = 1 << 3 +}; + +enum ImGuiNavMoveFlags_ +{ + ImGuiNavMoveFlags_None = 0, + ImGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side + ImGuiNavMoveFlags_LoopY = 1 << 1, + ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) + ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness + ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) + ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown) + ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary + ImGuiNavMoveFlags_Forwarded = 1 << 7, + ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result + ImGuiNavMoveFlags_FocusApi = 1 << 9, + ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight + ImGuiNavMoveFlags_Activate = 1 << 11, + ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 12 // Do not alter the visible state of keyboard vs mouse nav highlight +}; + +enum ImGuiNavLayer +{ + ImGuiNavLayer_Main = 0, // Main scrolling layer + ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu) + ImGuiNavLayer_COUNT +}; + +struct ImGuiNavItemData +{ + ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) + ImGuiID ID; // Init,Move // Best candidate item ID + ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID + ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space + ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags + float DistBox; // Move // Best candidate box distance to current NavId + float DistCenter; // Move // Best candidate center distance to current NavId + float DistAxial; // Move // Best candidate axial distance to current NavId + + ImGuiNavItemData() { Clear(); } + void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Columns support +//----------------------------------------------------------------------------- + +// Flags for internal's BeginColumns(). Prefix using BeginTable() nowadays! +enum ImGuiOldColumnFlags_ +{ + ImGuiOldColumnFlags_None = 0, + ImGuiOldColumnFlags_NoBorder = 1 << 0, // Disable column dividers + ImGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers + ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns + ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window + ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None, + ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder, + ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize, + ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths, + ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow, + ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize +#endif +}; + +struct ImGuiOldColumnData +{ + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNormBeforeResize; + ImGuiOldColumnFlags Flags; // Not exposed + ImRect ClipRect; + + ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); } +}; + +struct ImGuiOldColumns +{ + ImGuiID ID; + ImGuiOldColumnFlags Flags; + bool IsFirstFrame; + bool IsBeingResized; + int Current; + int Count; + float OffMinX, OffMaxX; // Offsets from HostWorkRect.Min.x + float LineMinY, LineMaxY; + float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns() + float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() + ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns() + ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground() + ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns() + ImVector Columns; + ImDrawListSplitter Splitter; + + ImGuiOldColumns() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Multi-select support +//----------------------------------------------------------------------------- + +#ifdef IMGUI_HAS_MULTI_SELECT +// +#endif // #ifdef IMGUI_HAS_MULTI_SELECT + +//----------------------------------------------------------------------------- +// [SECTION] Docking support +//----------------------------------------------------------------------------- + +#ifdef IMGUI_HAS_DOCK + +// Extend ImGuiDockNodeFlags_ +enum ImGuiDockNodeFlagsPrivate_ +{ + // [Internal] + ImGuiDockNodeFlags_DockSpace = 1 << 10, // Local, Saved // A dockspace is a node that occupy space within an existing user window. Otherwise the node is floating and create its own window. + ImGuiDockNodeFlags_CentralNode = 1 << 11, // Local, Saved // The central node has 2 main properties: stay visible when empty, only use "remaining" spaces from its neighbor. + ImGuiDockNodeFlags_NoTabBar = 1 << 12, // Local, Saved // Tab bar is completely unavailable. No triangle in the corner to enable it back. + ImGuiDockNodeFlags_HiddenTabBar = 1 << 13, // Local, Saved // Tab bar is hidden, with a triangle in the corner to show it again (NB: actual tab-bar instance may be destroyed as this is only used for single-window tab bar) + ImGuiDockNodeFlags_NoWindowMenuButton = 1 << 14, // Local, Saved // Disable window/docking menu (that one that appears instead of the collapse button) + ImGuiDockNodeFlags_NoCloseButton = 1 << 15, // Local, Saved // + ImGuiDockNodeFlags_NoDocking = 1 << 16, // Local, Saved // Disable any form of docking in this dockspace or individual node. (On a whole dockspace, this pretty much defeat the purpose of using a dockspace at all). Note: when turned on, existing docked nodes will be preserved. + ImGuiDockNodeFlags_NoDockingSplitMe = 1 << 17, // [EXPERIMENTAL] Prevent another window/node from splitting this node. + ImGuiDockNodeFlags_NoDockingSplitOther = 1 << 18, // [EXPERIMENTAL] Prevent this node from splitting another window/node. + ImGuiDockNodeFlags_NoDockingOverMe = 1 << 19, // [EXPERIMENTAL] Prevent another window/node to be docked over this node. + ImGuiDockNodeFlags_NoDockingOverOther = 1 << 20, // [EXPERIMENTAL] Prevent this node to be docked over another window or non-empty node. + ImGuiDockNodeFlags_NoDockingOverEmpty = 1 << 21, // [EXPERIMENTAL] Prevent this node to be docked over an empty node (e.g. DockSpace with no other windows) + ImGuiDockNodeFlags_NoResizeX = 1 << 22, // [EXPERIMENTAL] + ImGuiDockNodeFlags_NoResizeY = 1 << 23, // [EXPERIMENTAL] + ImGuiDockNodeFlags_SharedFlagsInheritMask_ = ~0, + ImGuiDockNodeFlags_NoResizeFlagsMask_ = ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_NoResizeX | ImGuiDockNodeFlags_NoResizeY, + ImGuiDockNodeFlags_LocalFlagsMask_ = ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoDocking, + ImGuiDockNodeFlags_LocalFlagsTransferMask_ = ImGuiDockNodeFlags_LocalFlagsMask_ & ~ImGuiDockNodeFlags_DockSpace, // When splitting those flags are moved to the inheriting child, never duplicated + ImGuiDockNodeFlags_SavedFlagsMask_ = ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoDocking +}; + +// Store the source authority (dock node vs window) of a field +enum ImGuiDataAuthority_ +{ + ImGuiDataAuthority_Auto, + ImGuiDataAuthority_DockNode, + ImGuiDataAuthority_Window +}; + +enum ImGuiDockNodeState +{ + ImGuiDockNodeState_Unknown, + ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow, + ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing, + ImGuiDockNodeState_HostWindowVisible +}; + +// sizeof() 156~192 +struct IMGUI_API ImGuiDockNode +{ + ImGuiID ID; + ImGuiDockNodeFlags SharedFlags; // (Write) Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node) + ImGuiDockNodeFlags LocalFlags; // (Write) Flags specific to this node + ImGuiDockNodeFlags LocalFlagsInWindows; // (Write) Flags specific to this node, applied from windows + ImGuiDockNodeFlags MergedFlags; // (Read) Effective flags (== SharedFlags | LocalFlagsInNode | LocalFlagsInWindows) + ImGuiDockNodeState State; + ImGuiDockNode* ParentNode; + ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array. + ImVector Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order. + ImGuiTabBar* TabBar; + ImVec2 Pos; // Current position + ImVec2 Size; // Current size + ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size. + ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y) + ImGuiWindowClass WindowClass; // [Root node only] + ImU32 LastBgColor; + + ImGuiWindow* HostWindow; + ImGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window. + ImGuiDockNode* CentralNode; // [Root node only] Pointer to central node. + ImGuiDockNode* OnlyNodeWithWindows; // [Root node only] Set when there is a single visible node within the hierarchy. + int CountNodeWithWindows; // [Root node only] + int LastFrameAlive; // Last frame number the node was updated or kept alive explicitly with DockSpace() + ImGuiDockNodeFlags_KeepAliveOnly + int LastFrameActive; // Last frame number the node was updated. + int LastFrameFocused; // Last frame number the node was focused. + ImGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused. + ImGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected. + ImGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window. + ImGuiDataAuthority AuthorityForPos :3; + ImGuiDataAuthority AuthorityForSize :3; + ImGuiDataAuthority AuthorityForViewport :3; + bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window) + bool IsFocused :1; + bool IsBgDrawnThisFrame :1; + bool HasCloseButton :1; // Provide space for a close button (if any of the docked window has one). Note that button may be hidden on window without one. + bool HasWindowMenuButton :1; + bool HasCentralNodeChild :1; + bool WantCloseAll :1; // Set when closing all tabs at once. + bool WantLockSizeOnce :1; + bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created host window + bool WantHiddenTabBarUpdate :1; + bool WantHiddenTabBarToggle :1; + + ImGuiDockNode(ImGuiID id); + ~ImGuiDockNode(); + bool IsRootNode() const { return ParentNode == NULL; } + bool IsDockSpace() const { return (MergedFlags & ImGuiDockNodeFlags_DockSpace) != 0; } + bool IsFloatingNode() const { return ParentNode == NULL && (MergedFlags & ImGuiDockNodeFlags_DockSpace) == 0; } + bool IsCentralNode() const { return (MergedFlags & ImGuiDockNodeFlags_CentralNode) != 0; } + bool IsHiddenTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_HiddenTabBar) != 0; } // Hidden tab bar can be shown back by clicking the small triangle + bool IsNoTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_NoTabBar) != 0; } // Never show a tab bar + bool IsSplitNode() const { return ChildNodes[0] != NULL; } + bool IsLeafNode() const { return ChildNodes[0] == NULL; } + bool IsEmpty() const { return ChildNodes[0] == NULL && Windows.Size == 0; } + ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } + + void SetLocalFlags(ImGuiDockNodeFlags flags) { LocalFlags = flags; UpdateMergedFlags(); } + void UpdateMergedFlags() { MergedFlags = SharedFlags | LocalFlags | LocalFlagsInWindows; } +}; + +// List of colors that are stored at the time of Begin() into Docked Windows. +// We currently store the packed colors in a simple array window->DockStyle.Colors[]. +// A better solution may involve appending into a log of colors in ImGuiContext + store offsets into those arrays in ImGuiWindow, +// but it would be more complex as we'd need to double-buffer both as e.g. drop target may refer to window from last frame. +enum ImGuiWindowDockStyleCol +{ + ImGuiWindowDockStyleCol_Text, + ImGuiWindowDockStyleCol_Tab, + ImGuiWindowDockStyleCol_TabHovered, + ImGuiWindowDockStyleCol_TabActive, + ImGuiWindowDockStyleCol_TabUnfocused, + ImGuiWindowDockStyleCol_TabUnfocusedActive, + ImGuiWindowDockStyleCol_COUNT +}; + +struct ImGuiWindowDockStyle +{ + ImU32 Colors[ImGuiWindowDockStyleCol_COUNT]; +}; + +struct ImGuiDockContext +{ + ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes + ImVector Requests; + ImVector NodesSettings; + bool WantFullRebuild; + ImGuiDockContext() { memset(this, 0, sizeof(*this)); } +}; + +#endif // #ifdef IMGUI_HAS_DOCK + +//----------------------------------------------------------------------------- +// [SECTION] Viewport support +//----------------------------------------------------------------------------- + +// ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!) +// Every instance of ImGuiViewport is in fact a ImGuiViewportP. +struct ImGuiViewportP : public ImGuiViewport +{ + int Idx; + int LastFrameActive; // Last frame number this viewport was activated by a window + int LastFrontMostStampCount;// Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order + ImGuiID LastNameHash; + ImVec2 LastPos; + float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) + float LastAlpha; + short PlatformMonitor; + bool PlatformWindowCreated; + ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set) + int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used + ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays. + ImDrawData DrawDataP; + ImDrawDataBuilder DrawDataBuilder; + ImVec2 LastPlatformPos; + ImVec2 LastPlatformSize; + ImVec2 LastRendererSize; + ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!) + ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height). + ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f. + ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f. + + ImGuiViewportP() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } + ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); } + void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } + + // Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect) + ImVec2 CalcWorkRectPos(const ImVec2& off_min) const { return ImVec2(Pos.x + off_min.x, Pos.y + off_min.y); } + ImVec2 CalcWorkRectSize(const ImVec2& off_min, const ImVec2& off_max) const { return ImVec2(ImMax(0.0f, Size.x - off_min.x + off_max.x), ImMax(0.0f, Size.y - off_min.y + off_max.y)); } + void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkOffsetMin); WorkSize = CalcWorkRectSize(WorkOffsetMin, WorkOffsetMax); } // Update public fields + + // Helpers to retrieve ImRect (we don't need to store BuildWorkRect as every access tend to change it, hence the code asymmetry) + ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } + ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); } + ImRect GetBuildWorkRect() const { ImVec2 pos = CalcWorkRectPos(BuildWorkOffsetMin); ImVec2 size = CalcWorkRectSize(BuildWorkOffsetMin, BuildWorkOffsetMax); return ImRect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Settings support +//----------------------------------------------------------------------------- + +// Windows data saved in imgui.ini file +// Because we never destroy or rename ImGuiWindowSettings, we can store the names in a separate buffer easily. +// (this is designed to be stored in a ImChunkStream buffer, with the variable-length Name following our structure) +struct ImGuiWindowSettings +{ + ImGuiID ID; + ImVec2ih Pos; // NB: Settings position are stored RELATIVE to the viewport! Whereas runtime ones are absolute positions. + ImVec2ih Size; + ImVec2ih ViewportPos; + ImGuiID ViewportId; + ImGuiID DockId; // ID of last known DockNode (even if the DockNode is invisible because it has only 1 active window), or 0 if none. + ImGuiID ClassId; // ID of window class if specified + short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible. + bool Collapsed; + bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context) + + ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); DockOrder = -1; } + char* GetName() { return (char*)(this + 1); } +}; + +struct ImGuiSettingsHandler +{ + const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' + ImGuiID TypeHash; // == ImHashStr(TypeName) + void (*ClearAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Clear all settings data + void (*ReadInitFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Read: Called before reading (in registration order) + void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); // Read: Called when entering into a new ini entry e.g. "[Window][Name]" + void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry + void (*ApplyAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Read: Called after reading (in registration order) + void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf' + void* UserData; + + ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Metrics, Debug Tools +//----------------------------------------------------------------------------- + +struct ImGuiMetricsConfig +{ + bool ShowStackTool; + bool ShowWindowsRects; + bool ShowWindowsBeginOrder; + bool ShowTablesRects; + bool ShowDrawCmdMesh; + bool ShowDrawCmdBoundingBoxes; + bool ShowDockingNodes; + int ShowWindowsRectsType; + int ShowTablesRectsType; + + ImGuiMetricsConfig() + { + ShowStackTool = false; + ShowWindowsRects = false; + ShowWindowsBeginOrder = false; + ShowTablesRects = false; + ShowDrawCmdMesh = true; + ShowDrawCmdBoundingBoxes = true; + ShowDockingNodes = false; + ShowWindowsRectsType = -1; + ShowTablesRectsType = -1; + } +}; + +struct ImGuiStackLevelInfo +{ + ImGuiID ID; + ImS8 QueryFrameCount; // >= 1: Query in progress + bool QuerySuccess; // Obtained result from DebugHookIdInfo() + char Desc[58]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) + + ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); } +}; + +// State for Stack tool queries +struct ImGuiStackTool +{ + int LastActiveFrame; + int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level + ImGuiID QueryId; // ID to query details for + ImVector Results; + + ImGuiStackTool() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Generic context hooks +//----------------------------------------------------------------------------- + +typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook); +enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ }; + +struct ImGuiContextHook +{ + ImGuiID HookId; // A unique ID assigned by AddContextHook() + ImGuiContextHookType Type; + ImGuiID Owner; + ImGuiContextHookCallback Callback; + void* UserData; + + ImGuiContextHook() { memset(this, 0, sizeof(*this)); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiContext (main imgui context) +//----------------------------------------------------------------------------- + +struct ImGuiContext +{ + bool Initialized; + bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it. + ImGuiIO IO; + ImGuiPlatformIO PlatformIO; + ImVector InputEventsQueue; // Input events which will be tricked/written into IO structure. + ImVector InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail. + ImGuiStyle Style; + ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame() + ImGuiConfigFlags ConfigFlagsLastFrame; + ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() + float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. + float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. + ImDrawListSharedData DrawListSharedData; + double Time; + int FrameCount; + int FrameCountEnded; + int FrameCountPlatformEnded; + int FrameCountRendered; + bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame() + bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed + bool WithinEndChild; // Set within EndChild() + bool GcCompactAll; // Request full GC + bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() + void* TestEngine; // Test engine user data + + // Windows state + ImVector Windows; // Windows, sorted in display order, back to front + ImVector WindowsFocusOrder; // Root windows, sorted in focus order, back to front. + ImVector WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child + ImVector CurrentWindowStack; + ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* + int WindowsActiveCount; // Number of unique windows submitted by frame + ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING) + ImGuiWindow* CurrentWindow; // Window being drawn into + ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. + ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set. + ImGuiDockNode* HoveredDockNode; // [Debug] Hovered dock node. + ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree. + ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window. + ImVec2 WheelingWindowRefMousePos; + float WheelingWindowTimer; + + // Item/widgets state and tracking information + ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] + ImGuiID HoveredId; // Hovered widget, filled during the frame + ImGuiID HoveredIdPreviousFrame; + bool HoveredIdAllowOverlap; + bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window. + bool HoveredIdPreviousFrameUsingMouseWheel; + bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. + float HoveredIdTimer; // Measure contiguous hovering time + float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active + ImGuiID ActiveId; // Active widget + ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame) + float ActiveIdTimer; + bool ActiveIdIsJustActivated; // Set at the time of activation for one frame + bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) + bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused. + bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch. + bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state. + bool ActiveIdHasBeenEditedThisFrame; + bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window. + ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) + ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs. + ImBitArrayForNamedKeys ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array. + ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) + ImGuiWindow* ActiveIdWindow; + ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) + int ActiveIdMouseButton; + ImGuiID ActiveIdPreviousFrame; + bool ActiveIdPreviousFrameIsAlive; + bool ActiveIdPreviousFrameHasBeenEditedBefore; + ImGuiWindow* ActiveIdPreviousFrameWindow; + ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. + float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. + + // Next window/item data + ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() + ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions + ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd) + ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions + + // Shared stacks + ImVector ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() + ImVector StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() + ImVector FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() + ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window + ImVectorItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() + ImVectorGroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() + ImVectorOpenPopupStack; // Which popups are open (persistent) + ImVectorBeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) + int BeginMenuCount; + + // Viewports + ImVector Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData. + float CurrentDpiScale; // == CurrentViewport->DpiScale + ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport() + ImGuiViewportP* MouseViewport; + ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag. + ImGuiID PlatformLastFocusedViewportId; + ImGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information. + int ViewportFrontMostStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter + + // Gamepad/keyboard Navigation + ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow' + ImGuiID NavId; // Focused item for navigation + ImGuiID NavFocusScopeId; // Identify a selection scope (selection code often wants to "clear other items" when landing on an item of the selection set) + ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem() + ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 + ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 + ImGuiID NavActivateInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0. + ImGuiActivateFlags NavActivateFlags; + ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). + ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). + ImGuiKeyModFlags NavJustMovedToKeyMods; + ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. + ImGuiActivateFlags NavNextActivateFlags; + ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. + ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. + bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid + bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) + bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) + bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. + + // Navigation: Init & Move Requests + bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() + bool NavInitRequest; // Init request for appearing window to select first item + bool NavInitRequestFromMove; + ImGuiID NavInitResultId; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) + ImRect NavInitResultRectRel; // Init request result rectangle (relative to parent window) + bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame() + bool NavMoveScoringItems; // Move request submitted, still scoring incoming items + bool NavMoveForwardToNextFrame; + ImGuiNavMoveFlags NavMoveFlags; + ImGuiScrollFlags NavMoveScrollFlags; + ImGuiKeyModFlags NavMoveKeyMods; + ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down) + ImGuiDir NavMoveDirForDebug; + ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? + ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring. + ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted + int NavScoringDebugCount; // Metrics for debugging + int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id + int NavTabbingCounter; // >0 when counting items for tabbing + ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow + ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) + ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) + ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy + + // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) + ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! + ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it. + ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents + float NavWindowingTimer; + float NavWindowingHighlightAlpha; + bool NavWindowingToggleLayer; + + // Render + float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) + ImGuiMouseCursor MouseCursor; + + // Drag and Drop + bool DragDropActive; + bool DragDropWithinSource; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag source. + bool DragDropWithinTarget; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag target. + ImGuiDragDropFlags DragDropSourceFlags; + int DragDropSourceFrameCount; + int DragDropMouseButton; + ImGuiPayload DragDropPayload; + ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping) + ImGuiID DragDropTargetId; + ImGuiDragDropFlags DragDropAcceptFlags; + float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface) + ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) + ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) + int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source + ImGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press. + ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size + unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads + + // Clipper + int ClipperTempDataStacked; + ImVector ClipperTempData; + + // Table + ImGuiTable* CurrentTable; + int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size) + ImVector TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting) + ImPool Tables; // Persistent table data + ImVector TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC) + ImVector DrawChannelsTempMergeBuffer; + + // Tab bars + ImGuiTabBar* CurrentTabBar; + ImPool TabBars; + ImVector CurrentTabBarStack; + ImVector ShrinkWidthBuffer; + + // Widget state + ImVec2 MouseLastValidPos; + ImGuiInputTextState InputTextState; + ImFont InputTextPasswordFont; + ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets + float ColorEditLastHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips + float ColorEditLastSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips + ImU32 ColorEditLastColor; // RGB value with alpha set to 0. + ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker. + ImGuiComboPreviewData ComboPreviewData; + float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. + bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? + bool DragCurrentAccumDirty; + float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings + float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio + float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? + float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled() + short DisabledStackSize; + short TooltipOverrideCount; + float TooltipSlowDelay; // Time before slow tooltips appears (FIXME: This is temporary until we merge in tooltip timer+priority work) + ImVector ClipboardHandlerData; // If no custom clipboard handler is defined + ImVector MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once + + // Platform support + ImGuiPlatformImeData PlatformImeData; // Data updated by current frame + ImGuiPlatformImeData PlatformImeDataPrev; // Previous frame data (when changing we will call io.SetPlatformImeDataFn + ImGuiID PlatformImeViewport; + char PlatformLocaleDecimalPoint; // '.' or *localeconv()->decimal_point + + // Extensions + // FIXME: We could provide an API to register one slot in an array held in ImGuiContext? + ImGuiDockContext DockContext; + + // Settings + bool SettingsLoaded; + float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero + ImGuiTextBuffer SettingsIniData; // In memory .ini settings + ImVector SettingsHandlers; // List of .ini settings handlers + ImChunkStream SettingsWindows; // ImGuiWindow .ini settings entries + ImChunkStream SettingsTables; // ImGuiTable .ini settings entries + ImVector Hooks; // Hooks for extensions (e.g. test engine) + ImGuiID HookIdNext; // Next available HookId + + // Capture/Logging + bool LogEnabled; // Currently capturing + ImGuiLogType LogType; // Capture target + ImFileHandle LogFile; // If != NULL log to stdout/ file + ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + const char* LogNextPrefix; + const char* LogNextSuffix; + float LogLinePosY; + bool LogLineFirstItem; + int LogDepthRef; + int LogDepthToExpand; + int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. + + // Debug Tools + bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker()) + ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID + ImGuiMetricsConfig DebugMetricsConfig; + ImGuiStackTool DebugStackTool; + + // Misc + float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. + int FramerateSecPerFrameIdx; + int FramerateSecPerFrameCount; + float FramerateSecPerFrameAccum; + int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those flags + int WantCaptureKeyboardNextFrame; + int WantTextInputNextFrame; + char TempBuffer[1024 * 3 + 1]; // Temporary text buffer + + ImGuiContext(ImFontAtlas* shared_font_atlas) + { + Initialized = false; + ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None; + FontAtlasOwnedByContext = shared_font_atlas ? false : true; + Font = NULL; + FontSize = FontBaseSize = 0.0f; + IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); + Time = 0.0f; + FrameCount = 0; + FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1; + WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false; + GcCompactAll = false; + TestEngineHookItems = false; + TestEngine = NULL; + + WindowsActiveCount = 0; + CurrentWindow = NULL; + HoveredWindow = NULL; + HoveredWindowUnderMovingWindow = NULL; + HoveredDockNode = NULL; + MovingWindow = NULL; + WheelingWindow = NULL; + WheelingWindowTimer = 0.0f; + + DebugHookIdInfo = 0; + HoveredId = HoveredIdPreviousFrame = 0; + HoveredIdAllowOverlap = false; + HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false; + HoveredIdDisabled = false; + HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; + ActiveId = 0; + ActiveIdIsAlive = 0; + ActiveIdTimer = 0.0f; + ActiveIdIsJustActivated = false; + ActiveIdAllowOverlap = false; + ActiveIdNoClearOnFocusLoss = false; + ActiveIdHasBeenPressedBefore = false; + ActiveIdHasBeenEditedBefore = false; + ActiveIdHasBeenEditedThisFrame = false; + ActiveIdUsingMouseWheel = false; + ActiveIdUsingNavDirMask = 0x00; + ActiveIdUsingNavInputMask = 0x00; + ActiveIdUsingKeyInputMask.ClearAllBits(); + ActiveIdClickOffset = ImVec2(-1, -1); + ActiveIdWindow = NULL; + ActiveIdSource = ImGuiInputSource_None; + ActiveIdMouseButton = -1; + ActiveIdPreviousFrame = 0; + ActiveIdPreviousFrameIsAlive = false; + ActiveIdPreviousFrameHasBeenEditedBefore = false; + ActiveIdPreviousFrameWindow = NULL; + LastActiveId = 0; + LastActiveIdTimer = 0.0f; + + CurrentItemFlags = ImGuiItemFlags_None; + BeginMenuCount = 0; + + CurrentDpiScale = 0.0f; + CurrentViewport = NULL; + MouseViewport = MouseLastHoveredViewport = NULL; + PlatformLastFocusedViewportId = 0; + ViewportFrontMostStampCount = 0; + + NavWindow = NULL; + NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0; + NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; + NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None; + NavJustMovedToKeyMods = ImGuiKeyModFlags_None; + NavInputSource = ImGuiInputSource_None; + NavLayer = ImGuiNavLayer_Main; + NavIdIsAlive = false; + NavMousePosDirty = false; + NavDisableHighlight = true; + NavDisableMouseHover = false; + NavAnyRequest = false; + NavInitRequest = false; + NavInitRequestFromMove = false; + NavInitResultId = 0; + NavMoveSubmitted = false; + NavMoveScoringItems = false; + NavMoveForwardToNextFrame = false; + NavMoveFlags = ImGuiNavMoveFlags_None; + NavMoveScrollFlags = ImGuiScrollFlags_None; + NavMoveKeyMods = ImGuiKeyModFlags_None; + NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None; + NavScoringDebugCount = 0; + NavTabbingDir = 0; + NavTabbingCounter = 0; + + NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; + NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; + NavWindowingToggleLayer = false; + + DimBgRatio = 0.0f; + MouseCursor = ImGuiMouseCursor_Arrow; + + DragDropActive = DragDropWithinSource = DragDropWithinTarget = false; + DragDropSourceFlags = ImGuiDragDropFlags_None; + DragDropSourceFrameCount = -1; + DragDropMouseButton = -1; + DragDropTargetId = 0; + DragDropAcceptFlags = ImGuiDragDropFlags_None; + DragDropAcceptIdCurrRectSurface = 0.0f; + DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; + DragDropAcceptFrameCount = -1; + DragDropHoldJustPressedId = 0; + memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); + + ClipperTempDataStacked = 0; + + CurrentTable = NULL; + TablesTempDataStacked = 0; + CurrentTabBar = NULL; + + TempInputId = 0; + ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; + ColorEditLastHue = ColorEditLastSat = 0.0f; + ColorEditLastColor = 0; + SliderCurrentAccum = 0.0f; + SliderCurrentAccumDirty = false; + DragCurrentAccumDirty = false; + DragCurrentAccum = 0.0f; + DragSpeedDefaultRatio = 1.0f / 100.0f; + DisabledAlphaBackup = 0.0f; + DisabledStackSize = 0; + ScrollbarClickDeltaToGrabCenter = 0.0f; + TooltipOverrideCount = 0; + TooltipSlowDelay = 0.50f; + + PlatformImeData.InputPos = ImVec2(0.0f, 0.0f); + PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission + PlatformImeViewport = 0; + PlatformLocaleDecimalPoint = '.'; + + SettingsLoaded = false; + SettingsDirtyTimer = 0.0f; + HookIdNext = 0; + + LogEnabled = false; + LogType = ImGuiLogType_None; + LogNextPrefix = LogNextSuffix = NULL; + LogFile = NULL; + LogLinePosY = FLT_MAX; + LogLineFirstItem = false; + LogDepthRef = 0; + LogDepthToExpand = LogDepthToExpandDefault = 2; + + DebugItemPickerActive = false; + DebugItemPickerBreakId = 0; + + memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); + FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0; + FramerateSecPerFrameAccum = 0.0f; + WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; + memset(TempBuffer, 0, sizeof(TempBuffer)); + } +}; + +//----------------------------------------------------------------------------- +// [SECTION] ImGuiWindowTempData, ImGuiWindow +//----------------------------------------------------------------------------- + +// Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC variable name in ImGuiWindow. +// (That's theory, in practice the delimitation between ImGuiWindow and ImGuiWindowTempData is quite tenuous and could be reconsidered..) +// (This doesn't need a constructor because we zero-clear it as part of ImGuiWindow and all frame-temporary data are setup on Begin) +struct IMGUI_API ImGuiWindowTempData +{ + // Layout + ImVec2 CursorPos; // Current emitting position, in absolute coordinates. + ImVec2 CursorPosPrevLine; + ImVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding. + ImVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling range and auto-resize. Always growing during the frame. + ImVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for auto-resize only. Always growing during the frame. + ImVec2 CurrLineSize; + ImVec2 PrevLineSize; + float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added). + float PrevLineTextBaseOffset; + ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + ImVec1 ColumnsOffset; // 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. + ImVec1 GroupOffset; + ImVec2 CursorStartPosLossyness;// Record the loss of precision of CursorStartPos due to really large scrolling amount. This is used by clipper to compensentate and fix the most common use case of large scroll area. + + // Keyboard/Gamepad navigation + ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) + short NavLayersActiveMask; // Which layers have been written to (result from previous frame) + short NavLayersActiveMaskNext;// Which layers have been written to (accumulator for current frame) + ImGuiID NavFocusScopeIdCurrent; // Current focus scope ID while appending + bool NavHideHighlightOneFrame; + bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) + + // Miscellaneous + bool MenuBarAppending; // FIXME: Remove this + ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs. + ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement + int TreeDepth; // Current tree depth. + ImU32 TreeJumpToParentOnPopMask; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31.. Could be turned into a ImU64 if necessary. + ImVector ChildWindows; + ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state) + ImGuiOldColumns* CurrentColumns; // Current columns set + int CurrentTableIdx; // Current table index (into g.Tables) + ImGuiLayoutType LayoutType; + ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() + + // Local parameters stacks + // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. + float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window). + float TextWrapPos; // Current text wrap pos. + ImVector ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth) + ImVector TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos) +}; + +// Storage for one window +struct IMGUI_API ImGuiWindow +{ + char* Name; // Window name, owned by the window. + ImGuiID ID; // == ImHashStr(Name) + ImGuiWindowFlags Flags, FlagsPreviousFrame; // See enum ImGuiWindowFlags_ + ImGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass() + ImGuiViewportP* Viewport; // Always set in Begin(), only inactive windows may have a NULL value here + ImGuiID ViewportId; // We backup the viewport id (since the viewport may disappear or never be created if the window is inactive) + ImVec2 ViewportPos; // We backup the viewport position (since the viewport may disappear or never be created if the window is inactive) + int ViewportAllowPlatformMonitorExtend; // Reset to -1 every frame (index is guaranteed to be valid between NewFrame..EndFrame), only used in the Appearing frame of a tooltip/popup to enforce clamping to a given monitor + ImVec2 Pos; // Position (always rounded-up to nearest pixel) + ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) + ImVec2 SizeFull; // Size when non collapsed + ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding. + ImVec2 ContentSizeIdeal; + ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize(). + ImVec2 WindowPadding; // Window padding at the time of Begin(). + float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc. + float WindowBorderSize; // Window border size at the time of Begin(). + int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! + ImGuiID MoveId; // == window->GetID("#MOVE") + ImGuiID TabId; // == window->GetID("#TAB") + ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) + ImVec2 Scroll; + ImVec2 ScrollMax; + ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) + ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered + ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold + ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar. + bool ScrollbarX, ScrollbarY; // Are scrollbars visible? + bool ViewportOwned; + bool Active; // Set to true on Begin(), unless Collapsed + bool WasActive; + bool WriteAccessed; // Set to true when any widget access the current window + bool Collapsed; // Set when collapsing window to become only title-bar + bool WantCollapseToggle; + bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) + bool Appearing; // Set during the frame where the window is appearing (or re-appearing) + bool Hidden; // Do not display (== HiddenFrames*** > 0) + bool IsFallbackWindow; // Set on the "Debug##Default" window. + bool IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked() + bool HasCloseButton; // Set when the window has a close button (p_open != NULL) + signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) + short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) + short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. + short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues. + short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused. + ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) + ImS8 AutoFitFramesX, AutoFitFramesY; + ImS8 AutoFitChildAxises; + bool AutoFitOnlyGrows; + ImGuiDir AutoPosLastDirection; + ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames + ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size + ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only + ImS8 DisableInputsFrames; // Disable window interactions for N frames + ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use. + ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use. + ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use. + ImGuiCond SetWindowDockAllowFlags : 8; // store acceptable condition flags for SetNextWindowDock() use. + ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) + ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right. + + ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack. (In theory this should be in the TempData structure) + ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name. + + // The best way to understand what those rectangles are is to use the 'Metrics->Tools->Show Windows Rectangles' viewer. + // The main 'OuterRect', omitted as a field, is window->Rect(). + ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window. + ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar) + ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect. + ImRect WorkRect; // Initially covers the whole scrolling region. Reduced by containers e.g columns/tables when active. Shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward). + ImRect ParentWorkRect; // Backup of WorkRect before entering a container such as columns/tables. Used by e.g. SpanAllColumns functions to easily access. Stacked containers are responsible for maintaining this. // FIXME-WORKRECT: Could be a stack? + ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back(). + ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on. + ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window. + ImVec2ih HitTestHoleOffset; + + int LastFrameActive; // Last frame number the window was Active. + int LastFrameJustFocused; // Last frame number the window was made Focused. + float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there) + float ItemWidthDefault; + ImGuiStorage StateStorage; + ImVector ColumnsStorage; + float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale() + float FontDpiScale; + int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back) + + ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer) + ImDrawList DrawListInst; + ImGuiWindow* ParentWindow; // If we are a child _or_ popup _or_ docked window, this is pointing to our parent. Otherwise NULL. + ImGuiWindow* ParentWindowInBeginStack; + ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes. + ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child. + ImGuiWindow* RootWindowDockTree; // Point to ourself or first ancestor that is not a child window. Cross through dock nodes. + ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. + ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag. + + ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.) + ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1) + ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space + + int MemoryDrawListIdxCapacity; // Backup of last idx/vtx count, so when waking up the window we can preallocate and avoid iterative alloc/copy + int MemoryDrawListVtxCapacity; + bool MemoryCompacted; // Set when window extraneous data have been garbage collected + + // Docking + bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1). + bool DockNodeIsVisible :1; + bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected? + bool DockTabWantClose :1; + short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible. + ImGuiWindowDockStyle DockStyle; + ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden. + ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows) + ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more + ImGuiItemStatusFlags DockTabItemStatusFlags; + ImRect DockTabItemRect; + +public: + ImGuiWindow(ImGuiContext* context, const char* name); + ~ImGuiWindow(); + + ImGuiID GetID(const char* str, const char* str_end = NULL); + ImGuiID GetID(const void* ptr); + ImGuiID GetID(int n); + ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); + ImGuiID GetIDNoKeepAlive(const void* ptr); + ImGuiID GetIDNoKeepAlive(int n); + ImGuiID GetIDFromRectangle(const ImRect& r_abs); + + // We don't use g.FontSize because the window may be != g.CurrentWidow. + ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } + float CalcFontSize() const { ImGuiContext& g = *GImGui; float scale = g.FontBaseSize * FontWindowScale * FontDpiScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; } + float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; } + ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } + float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; } + ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Tab bar, Tab item support +//----------------------------------------------------------------------------- + +// Extend ImGuiTabBarFlags_ +enum ImGuiTabBarFlagsPrivate_ +{ + ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node [we don't use this in the master branch but it facilitate branch syncing to keep this around] + ImGuiTabBarFlags_IsFocused = 1 << 21, + ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs +}; + +// Extend ImGuiTabItemFlags_ +enum ImGuiTabItemFlagsPrivate_ +{ + ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing, + ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout) + ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button + ImGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window. + ImGuiTabItemFlags_Preview = 1 << 23 // [Docking] Display tab shape for docking preview (height is adjusted slightly to compensate for the yet missing tab bar) +}; + +// Storage for one active tab item (sizeof() 48 bytes) +struct ImGuiTabItem +{ + ImGuiID ID; + ImGuiTabItemFlags Flags; + ImGuiWindow* Window; // When TabItem is part of a DockNode's TabBar, we hold on to a window. + int LastFrameVisible; + int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance + float Offset; // Position relative to beginning of tab + float Width; // Width currently displayed + float ContentWidth; // Width of label, stored during BeginTabItem() call + ImS32 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames + ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable + ImS16 IndexDuringLayout; // Index only used during TabBarLayout() + bool WantClose; // Marked as closed by SetTabItemClosed() + + ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; } +}; + +// Storage for a tab bar (sizeof() 152 bytes) +struct IMGUI_API ImGuiTabBar +{ + ImVector Tabs; + ImGuiTabBarFlags Flags; + ImGuiID ID; // Zero for tab-bars used by docking + ImGuiID SelectedTabId; // Selected tab/window + ImGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation + ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for CTRL+TAB preview) + int CurrFrameVisible; + int PrevFrameVisible; + ImRect BarRect; + float CurrTabsContentsHeight; + float PrevTabsContentsHeight; // Record the height of contents submitted below the tab bar + float WidthAllTabs; // Actual width of all tabs (locked during layout) + float WidthAllTabsIdeal; // Ideal width if all tabs were visible and not clipped + float ScrollingAnim; + float ScrollingTarget; + float ScrollingTargetDistToVisibility; + float ScrollingSpeed; + float ScrollingRectMinX; + float ScrollingRectMaxX; + ImGuiID ReorderRequestTabId; + ImS16 ReorderRequestOffset; + ImS8 BeginCount; + bool WantLayout; + bool VisibleTabWasSubmitted; + bool TabsAddedNew; // Set to true when a new tab item or button has been added to the tab bar during last frame + ImS16 TabsActiveCount; // Number of tabs submitted this frame. + ImS16 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem() + float ItemSpacingY; + ImVec2 FramePadding; // style.FramePadding locked at the time of BeginTabBar() + ImVec2 BackupCursorPos; + ImGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer. + + ImGuiTabBar(); + int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); } + const char* GetTabName(const ImGuiTabItem* tab) const + { + if (tab->Window) + return tab->Window->Name; + IM_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size); + return TabsNames.Buf.Data + tab->NameOffset; + } +}; + +//----------------------------------------------------------------------------- +// [SECTION] Table support +//----------------------------------------------------------------------------- + +#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. +#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. +#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels() + +// Our current column maximum is 64 but we may raise that in the future. +typedef ImS8 ImGuiTableColumnIdx; +typedef ImU8 ImGuiTableDrawChannelIdx; + +// [Internal] sizeof() ~ 104 +// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. +// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping. +// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped". +struct ImGuiTableColumn +{ + ImGuiTableColumnFlags Flags; // Flags after some patching (not directly same as provided by user). See ImGuiTableColumnFlags_ + float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in tight space. + float MinX; // Absolute positions + float MaxX; + float WidthRequest; // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from StretchWeight in TableUpdateLayout() + float WidthAuto; // Automatic width + float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially. + float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_). + ImRect ClipRect; // Clipping rectangle for the column + ImGuiID UserID; // Optional, value passed to TableSetupColumn() + float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when entering column + float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2) + float ItemWidth; // Current item width for the column, preserved across rows + float ContentMaxXFrozen; // Contents maximum position for frozen rows (apart from headers), from which we can infer content width. + float ContentMaxXUnfrozen; + float ContentMaxXHeadersUsed; // Contents maximum position for headers rows (regardless of freezing). TableHeader() automatically softclip itself + report ideal desired size, to avoid creating extraneous draw calls + float ContentMaxXHeadersIdeal; + ImS16 NameOffset; // Offset into parent ColumnsNames[] + ImGuiTableColumnIdx DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users) + ImGuiTableColumnIdx IndexWithinEnabledSet; // Index within enabled/visible set (<= IndexToDisplayOrder) + ImGuiTableColumnIdx PrevEnabledColumn; // Index of prev enabled/visible column within Columns[], -1 if first enabled/visible column + ImGuiTableColumnIdx NextEnabledColumn; // Index of next enabled/visible column within Columns[], -1 if last enabled/visible column + ImGuiTableColumnIdx SortOrder; // Index of this column within sort specs, -1 if not sorting on this column, 0 for single-sort, may be >0 on multi-sort + ImGuiTableDrawChannelIdx DrawChannelCurrent; // Index within DrawSplitter.Channels[] + ImGuiTableDrawChannelIdx DrawChannelFrozen; // Draw channels for frozen rows (often headers) + ImGuiTableDrawChannelIdx DrawChannelUnfrozen; // Draw channels for unfrozen rows + bool IsEnabled; // IsUserEnabled && (Flags & ImGuiTableColumnFlags_Disabled) == 0 + bool IsUserEnabled; // Is the column not marked Hidden by the user? (unrelated to being off view, e.g. clipped by scrolling). + bool IsUserEnabledNextFrame; + bool IsVisibleX; // Is actually in view (e.g. overlapping the host window clipping rectangle, not scrolled). + bool IsVisibleY; + bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to output contents or not. + bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen). + bool IsPreserveWidthAuto; + ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte + ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit + ImU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem + ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending + ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3) + ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each) + ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each) + + ImGuiTableColumn() + { + memset(this, 0, sizeof(*this)); + StretchWeight = WidthRequest = -1.0f; + NameOffset = -1; + DisplayOrder = IndexWithinEnabledSet = -1; + PrevEnabledColumn = NextEnabledColumn = -1; + SortOrder = -1; + SortDirection = ImGuiSortDirection_None; + DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU8)-1; + } +}; + +// Transient cell data stored per row. +// sizeof() ~ 6 +struct ImGuiTableCellData +{ + ImU32 BgColor; // Actual color + ImGuiTableColumnIdx Column; // Column number +}; + +// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData +struct IMGUI_API ImGuiTable +{ + ImGuiID ID; + ImGuiTableFlags Flags; + void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[] + ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[] + ImSpan Columns; // Point within RawData[] + ImSpan DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1) + ImSpan RowCellData; // Point within RawData[]. Store cells background requests for current row. + ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map + ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data + ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect) + ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items) + ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order) + int SettingsOffset; // Offset in g.SettingsTables + int LastFrameActive; + int ColumnsCount; // Number of columns declared in BeginTable() + int CurrentRow; + int CurrentColumn; + ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched. + ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with + float RowPosY1; + float RowPosY2; + float RowMinHeight; // Height submitted to TableNextRow() + float RowTextBaseline; + float RowIndentOffsetX; + ImGuiTableRowFlags RowFlags : 16; // Current row flags, see ImGuiTableRowFlags_ + ImGuiTableRowFlags LastRowFlags : 16; + int RowBgColorCounter; // Counter for alternating background colors (can be fast-forwarded by e.g clipper), not same as CurrentRow because header rows typically don't increase this. + ImU32 RowBgColor[2]; // Background color override for current row. + ImU32 BorderColorStrong; + ImU32 BorderColorLight; + float BorderX1; + float BorderX2; + float HostIndentX; + float MinColumnWidth; + float OuterPaddingX; + float CellPaddingX; // Padding from each borders + float CellPaddingY; + float CellSpacingX1; // Spacing between non-bordered cells + float CellSpacingX2; + float LastOuterHeight; // Outer height from last frame + float LastFirstRowHeight; // Height of first row from last frame + float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details. + float ColumnsGivenWidth; // Sum of current column width + float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window + float ResizedColumnNextWidth; + float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table. + float RefScale; // Reference scale to be able to rescale columns on font/dpi changes. + ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable(). + ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is + ImRect WorkRect; + ImRect InnerClipRect; + ImRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries + ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped + ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect. + ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window. + ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground() + ImGuiWindow* OuterWindow; // Parent window for the table + ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) + ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names + ImDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per columns to avoid switching clip rect constantly + ImGuiTableColumnSortSpecs SortSpecsSingle; + ImVector SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good. + ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs() + ImGuiTableColumnIdx SortSpecsCount; + ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount) + ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns (<= ColumnsCount) + ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn() + ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column! + ImGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing). + ImGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit. + ImGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0. + ImGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame. + ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held. + ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared) + ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1 + ImGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column. + ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column. + ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column. + ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column. + ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot + ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count + ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset) + ImGuiTableColumnIdx FreezeColumnsRequest; // Requested frozen columns count + ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset) + ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row + ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here. + ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[] + ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen; + bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row. + bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow(). + bool IsInitializing; + bool IsSortSpecsDirty; + bool IsUsingHeaders; // Set when the first row had the ImGuiTableRowFlags_Headers flag. + bool IsContextPopupOpen; // Set when default context menu is open (also see: ContextPopupColumn, InstanceInteracted). + bool IsSettingsRequestLoad; + bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data. + bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1) + bool IsResetAllRequest; + bool IsResetDisplayOrderRequest; + bool IsUnfrozenRows; // Set when we got past the frozen row. + bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable() + bool MemoryCompacted; + bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis + + ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; } + ~ImGuiTable() { IM_FREE(RawData); } +}; + +// Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table). +// - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table structure. +// - We also leave out of this structure data that tend to be particularly useful for debugging/metrics. +struct IMGUI_API ImGuiTableTempData +{ + int TableIndex; // Index in g.Tables.Buf[] pool + float LastTimeActive; // Last timestamp this structure was used + + ImVec2 UserOuterSize; // outer_size.x passed to BeginTable() + ImDrawListSplitter DrawSplitter; + + ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable() + ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable() + ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable() + ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable() + ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable() + ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable() + float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable() + int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable() + + ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; } +}; + +// sizeof() ~ 12 +struct ImGuiTableColumnSettings +{ + float WidthOrWeight; + ImGuiID UserID; + ImGuiTableColumnIdx Index; + ImGuiTableColumnIdx DisplayOrder; + ImGuiTableColumnIdx SortOrder; + ImU8 SortDirection : 2; + ImU8 IsEnabled : 1; // "Visible" in ini file + ImU8 IsStretch : 1; + + ImGuiTableColumnSettings() + { + WidthOrWeight = 0.0f; + UserID = 0; + Index = -1; + DisplayOrder = SortOrder = -1; + SortDirection = ImGuiSortDirection_None; + IsEnabled = 1; + IsStretch = 0; + } +}; + +// This is designed to be stored in a single ImChunkStream (1 header followed by N ImGuiTableColumnSettings, etc.) +struct ImGuiTableSettings +{ + ImGuiID ID; // Set to 0 to invalidate/delete the setting + ImGuiTableFlags SaveFlags; // Indicate data we want to save using the Resizable/Reorderable/Sortable/Hideable flags (could be using its own flags..) + float RefScale; // Reference scale to be able to rescale columns on font/dpi changes. + ImGuiTableColumnIdx ColumnsCount; + ImGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher + bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context) + + ImGuiTableSettings() { memset(this, 0, sizeof(*this)); } + ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); } +}; + +//----------------------------------------------------------------------------- +// [SECTION] ImGui internal API +// No guarantee of forward compatibility here! +//----------------------------------------------------------------------------- + +namespace ImGui +{ + // Windows + // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) + // If this ever crash because g.CurrentWindow is NULL it means that either + // - ImGui::NewFrame() has never been called, which is illegal. + // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. + inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } + inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } + IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); + IMGUI_API ImGuiWindow* FindWindowByName(const char* name); + IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); + IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window); + IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy, bool dock_hierarchy); + IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent); + IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below); + IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); + IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); + IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); + IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0); + IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size); + inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); } + inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); } + + // Windows: Display Order and Focus Order + IMGUI_API void FocusWindow(ImGuiWindow* window); + IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window); + IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* above_window); + IMGUI_API int FindWindowDisplayIndex(ImGuiWindow* window); + IMGUI_API ImGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window); + + // Fonts, drawing + IMGUI_API void SetCurrentFont(ImFont* font); + inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } + inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); } + + // Init + IMGUI_API void Initialize(ImGuiContext* context); + IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). + + // NewFrame + IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs); + IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); + IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); + IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock_floating_node); + IMGUI_API void UpdateMouseMovingWindowNewFrame(); + IMGUI_API void UpdateMouseMovingWindowEndFrame(); + + // Generic context hooks + IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook); + IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove); + IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type); + + // Viewports + IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos); + IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale); + IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport); + IMGUI_API void SetCurrentViewport(ImGuiWindow* window, ImGuiViewportP* viewport); + IMGUI_API const ImGuiPlatformMonitor* GetViewportPlatformMonitor(ImGuiViewport* viewport); + IMGUI_API ImGuiViewportP* FindHoveredViewportFromPlatformWindowStack(const ImVec2& mouse_platform_pos); + + // Settings + IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window); + IMGUI_API void ClearIniSettings(); + IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name); + IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); + IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name); + IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); + + // Scrolling + IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // Use -1.0f on one axis to leave as-is + IMGUI_API void SetScrollX(ImGuiWindow* window, float scroll_x); + IMGUI_API void SetScrollY(ImGuiWindow* window, float scroll_y); + IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio); + IMGUI_API void SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio); + + // Early work-in-progress API (ScrollToItem() will become public) + IMGUI_API void ScrollToItem(ImGuiScrollFlags flags = 0); + IMGUI_API void ScrollToRect(ImGuiWindow* window, const ImRect& rect, ImGuiScrollFlags flags = 0); + IMGUI_API ImVec2 ScrollToRectEx(ImGuiWindow* window, const ImRect& rect, ImGuiScrollFlags flags = 0); +//#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + inline void ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& rect) { ScrollToRect(window, rect, ImGuiScrollFlags_KeepVisibleEdgeY); } +//#endif + + // Basic Accessors + inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.LastItemData.ID; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand) + inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } + inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } + inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } + inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } + IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); + IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window); + IMGUI_API void ClearActiveID(); + IMGUI_API ImGuiID GetHoveredID(); + IMGUI_API void SetHoveredID(ImGuiID id); + IMGUI_API void KeepAliveID(ImGuiID id); + IMGUI_API void MarkItemEdited(ImGuiID id); // Mark data associated to given item as "edited", used by IsItemDeactivatedAfterEdit() function. + IMGUI_API void PushOverrideID(ImGuiID id); // Push given value as-is at the top of the ID stack (whereas PushID combines old and new hashes) + IMGUI_API ImGuiID GetIDWithSeed(const char* str_id_begin, const char* str_id_end, ImGuiID seed); + + // Basic Helpers for widget code + IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f); + IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f); + IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0); + IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); + IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id); + IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); + IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); + IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); + IMGUI_API void PushMultiItemsWidths(int components, float width_full); + IMGUI_API bool IsItemToggledSelection(); // Was the last item selection toggled? (after Selectable(), TreeNode() etc. We only returns toggle _event_ in order to handle clipping correctly) + IMGUI_API ImVec2 GetContentRegionMaxAbs(); + IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); + + // Parameter stacks + IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); + IMGUI_API void PopItemFlag(); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // Currently refactoring focus/nav/tabbing system + // If you have old/custom copy-and-pasted widgets that used FocusableItemRegister(): + // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)' + // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' + // (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || g.NavActivateInputId == id' (WIP) + // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() + inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd() + inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem +#endif + + // Logging/Capture + IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. + IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer + IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); + IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); + + // Popups, Modals, Tooltips + IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); + IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None); + IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); + IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); + IMGUI_API void ClosePopupsExceptModals(); + IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags); + IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); + IMGUI_API void BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); + IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); + IMGUI_API ImGuiWindow* GetTopMostPopupModal(); + IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal(); + IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); + IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); + + // Menus + IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); + IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true); + IMGUI_API bool MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true); + + // Combos + IMGUI_API bool BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags); + IMGUI_API bool BeginComboPreview(); + IMGUI_API void EndComboPreview(); + + // Gamepad/Keyboard Navigation + IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); + IMGUI_API void NavInitRequestApplyResult(); + IMGUI_API bool NavMoveRequestButNoResultYet(); + IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); + IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); + IMGUI_API void NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result); + IMGUI_API void NavMoveRequestCancel(); + IMGUI_API void NavMoveRequestApplyResult(); + IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); + IMGUI_API const char* GetNavInputName(ImGuiNavInput n); + IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); + IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); + IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); + IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. + IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); + + // Focus Scope (WIP) + // This is generally used to identify a selection set (multiple of which may be in the same window), as selection + // patterns generally need to react (e.g. clear selection) when landing on an item of the set. + IMGUI_API void PushFocusScope(ImGuiID id); + IMGUI_API void PopFocusScope(); + inline ImGuiID GetFocusedFocusScope() { ImGuiContext& g = *GImGui; return g.NavFocusScopeId; } // Focus scope which is actually active + inline ImGuiID GetFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.NavFocusScopeIdCurrent; } // Focus scope we are outputting into, set by PushFocusScope() + + // Inputs + // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. + inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; } + inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; } + inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } + IMGUI_API ImGuiKeyData* GetKeyData(ImGuiKey key); + IMGUI_API void SetItemUsingMouseWheel(); + IMGUI_API void SetActiveIdUsingNavAndKeys(); + inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } + inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; } + inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; return g.ActiveIdUsingKeyInputMask[key]; } + inline void SetActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; g.ActiveIdUsingKeyInputMask.SetBit(key); } + IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f); + inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; } + inline bool IsNavInputTest(ImGuiNavInput n, ImGuiInputReadMode rm) { return (GetNavInputAmount(n, rm) > 0.0f); } + IMGUI_API ImGuiKeyModFlags GetMergedKeyModFlags(); +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } +#endif + + // Docking + // (some functions are only declared in imgui.cpp, see Docking section) + IMGUI_API void DockContextInitialize(ImGuiContext* ctx); + IMGUI_API void DockContextShutdown(ImGuiContext* ctx); + IMGUI_API void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all + IMGUI_API void DockContextRebuildNodes(ImGuiContext* ctx); + IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx); + IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx); + IMGUI_API void DockContextEndFrame(ImGuiContext* ctx); + IMGUI_API ImGuiID DockContextGenNodeID(ImGuiContext* ctx); + IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer); + IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window); + IMGUI_API void DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node); + IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos); + IMGUI_API bool DockNodeBeginAmendTabBar(ImGuiDockNode* node); + IMGUI_API void DockNodeEndAmendTabBar(); + inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; } + inline bool DockNodeIsInHierarchyOf(ImGuiDockNode* node, ImGuiDockNode* parent) { while (node) { if (node == parent) return true; node = node->ParentNode; } return false; } + inline int DockNodeGetDepth(const ImGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; } + inline ImGuiID DockNodeGetWindowMenuButtonId(const ImGuiDockNode* node) { return ImHashStr("#COLLAPSE", 0, node->ID); } + inline ImGuiDockNode* GetWindowDockNode() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DockNode; } + IMGUI_API bool GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window); + IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open); + IMGUI_API void BeginDockableDragDropSource(ImGuiWindow* window); + IMGUI_API void BeginDockableDragDropTarget(ImGuiWindow* window); + IMGUI_API void SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond); + + // Docking - Builder function needs to be generally called before the node is used/submitted. + // - The DockBuilderXXX functions are designed to _eventually_ become a public API, but it is too early to expose it and guarantee stability. + // - Do not hold on ImGuiDockNode* pointers! They may be invalidated by any split/merge/remove operation and every frame. + // - To create a DockSpace() node, make sure to set the ImGuiDockNodeFlags_DockSpace flag when calling DockBuilderAddNode(). + // You can create dockspace nodes (attached to a window) _or_ floating nodes (carry its own window) with this API. + // - DockBuilderSplitNode() create 2 child nodes within 1 node. The initial node becomes a parent node. + // - If you intend to split the node immediately after creation using DockBuilderSplitNode(), make sure + // to call DockBuilderSetNodeSize() beforehand. If you don't, the resulting split sizes may not be reliable. + // - Call DockBuilderFinish() after you are done. + IMGUI_API void DockBuilderDockWindow(const char* window_name, ImGuiID node_id); + IMGUI_API ImGuiDockNode*DockBuilderGetNode(ImGuiID node_id); + inline ImGuiDockNode* DockBuilderGetCentralNode(ImGuiID node_id) { ImGuiDockNode* node = DockBuilderGetNode(node_id); if (!node) return NULL; return DockNodeGetRootNode(node)->CentralNode; } + IMGUI_API ImGuiID DockBuilderAddNode(ImGuiID node_id = 0, ImGuiDockNodeFlags flags = 0); + IMGUI_API void DockBuilderRemoveNode(ImGuiID node_id); // Remove node and all its child, undock all windows + IMGUI_API void DockBuilderRemoveNodeDockedWindows(ImGuiID node_id, bool clear_settings_refs = true); + IMGUI_API void DockBuilderRemoveNodeChildNodes(ImGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the remaining root node (node_id). + IMGUI_API void DockBuilderSetNodePos(ImGuiID node_id, ImVec2 pos); + IMGUI_API void DockBuilderSetNodeSize(ImGuiID node_id, ImVec2 size); + IMGUI_API ImGuiID DockBuilderSplitNode(ImGuiID node_id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir); // Create 2 child nodes in this parent node. + IMGUI_API void DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_dockspace_id, ImVector* in_window_remap_pairs); + IMGUI_API void DockBuilderCopyNode(ImGuiID src_node_id, ImGuiID dst_node_id, ImVector* out_node_remap_pairs); + IMGUI_API void DockBuilderCopyWindowSettings(const char* src_name, const char* dst_name); + IMGUI_API void DockBuilderFinish(ImGuiID node_id); + + // Drag and Drop + IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); + IMGUI_API void ClearDragDrop(); + IMGUI_API bool IsDragDropPayloadBeingAccepted(); + + // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) + IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); + IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). + IMGUI_API void EndColumns(); // close columns + IMGUI_API void PushColumnClipRect(int column_index); + IMGUI_API void PushColumnsBackground(); + IMGUI_API void PopColumnsBackground(); + IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); + IMGUI_API ImGuiOldColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); + IMGUI_API float GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm); + IMGUI_API float GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset); + + // Tables: Candidates for public API + IMGUI_API void TableOpenContextMenu(int column_n = -1); + IMGUI_API void TableSetColumnWidth(int column_n, float width); + IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); + IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. + IMGUI_API float TableGetHeaderRowHeight(); + IMGUI_API void TablePushBackgroundChannel(); + IMGUI_API void TablePopBackgroundChannel(); + + // Tables: Internals + inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } + IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); + IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); + IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); + IMGUI_API void TableBeginApplyRequests(ImGuiTable* table); + IMGUI_API void TableSetupDrawChannels(ImGuiTable* table); + IMGUI_API void TableUpdateLayout(ImGuiTable* table); + IMGUI_API void TableUpdateBorders(ImGuiTable* table); + IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); + IMGUI_API void TableDrawBorders(ImGuiTable* table); + IMGUI_API void TableDrawContextMenu(ImGuiTable* table); + IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); + IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); + IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); + IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column); + IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column); + IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column); + IMGUI_API void TableBeginRow(ImGuiTable* table); + IMGUI_API void TableEndRow(ImGuiTable* table); + IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n); + IMGUI_API void TableEndCell(ImGuiTable* table); + IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n); + IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n); + IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); + IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n); + IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); + IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); + IMGUI_API void TableRemove(ImGuiTable* table); + IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table); + IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table); + IMGUI_API void TableGcCompactSettings(); + + // Tables: Settings + IMGUI_API void TableLoadSettings(ImGuiTable* table); + IMGUI_API void TableSaveSettings(ImGuiTable* table); + IMGUI_API void TableResetSettings(ImGuiTable* table); + IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); + IMGUI_API void TableSettingsInstallHandler(ImGuiContext* context); + IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count); + IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id); + + // Tab Bars + IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); + IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); + IMGUI_API ImGuiTabItem* TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar); + IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window); + IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); + IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); + IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset); + IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos); + IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); + IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window); + IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button); + IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col); + IMGUI_API void TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped); + + // Render helpers + // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. + // NB: All position are in absolute pixels coordinates (we are never using window coordinates internally) + IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); + IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); + IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); + IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); + IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known); + IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); + IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); + IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); + IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight + IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. + IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow); + + // Render helpers (those functions don't access any ImGui state!) + IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f); + IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col); + IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz); + IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col); + IMGUI_API void RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col); + IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); + IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding); + IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // [1.71: 2019/06/07: Updating prototypes of some of the internal functions. Leaving those for reference for a short while] + inline void RenderArrow(ImVec2 pos, ImGuiDir dir, float scale=1.0f) { ImGuiWindow* window = GetCurrentWindow(); RenderArrow(window->DrawList, pos, GetColorU32(ImGuiCol_Text), dir, scale); } + inline void RenderBullet(ImVec2 pos) { ImGuiWindow* window = GetCurrentWindow(); RenderBullet(window->DrawList, pos, GetColorU32(ImGuiCol_Text)); } +#endif + + // Widgets + IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); + IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); + IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos); + IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node); + IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); + IMGUI_API void Scrollbar(ImGuiAxis axis); + IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags); + IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col); + IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); + IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); + IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners + IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir); + IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags); + IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value); + IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value); + + // Widgets low-level behaviors + IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); + IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); + IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, ImU32 bg_col = 0); + IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); + IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging + IMGUI_API void TreePushOverrideID(ImGuiID id); + + // Template functions are instantiated in imgui_widgets.cpp for a finite number of types. + // To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036). + // e.g. " extern template IMGUI_API float RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, float v); " + template IMGUI_API float ScaleRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size); + template IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size); + template IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags); + template IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); + template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); + template IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value); + + // Data type helpers + IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); + IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); + IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); + IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format); + IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); + IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); + + // InputText + IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags); + IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); + inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } + inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active + + // Color + IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); + IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); + IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags); + + // Plot + IMGUI_API int PlotEx(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 frame_size); + + // Shade functions (write over already created vertices) + IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); + IMGUI_API void ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); + + // Garbage collection + IMGUI_API void GcCompactTransientMiscBuffers(); + IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); + IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); + + // Debug Tools + IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL); + IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL); + inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); } + inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; } + + IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); + IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end); + IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns); + IMGUI_API void DebugNodeDockNode(ImGuiDockNode* node, const char* label); + IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label); + IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb); + IMGUI_API void DebugNodeFont(ImFont* font); + IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label); + IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label); + IMGUI_API void DebugNodeTable(ImGuiTable* table); + IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings); + IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label); + IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings); + IMGUI_API void DebugNodeWindowsList(ImVector* windows, const char* label); + IMGUI_API void DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack); + IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport); + IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb); + +} // namespace ImGui + + +//----------------------------------------------------------------------------- +// [SECTION] ImFontAtlas internal API +//----------------------------------------------------------------------------- + +// This structure is likely to evolve as we add support for incremental atlas updates +struct ImFontBuilderIO +{ + bool (*FontBuilder_Build)(ImFontAtlas* atlas); +}; + +// Helper for font builder +#ifdef IMGUI_ENABLE_STB_TRUETYPE +IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype(); +#endif +IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); +IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); +IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value); +IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value); +IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); +IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); + +//----------------------------------------------------------------------------- +// [SECTION] Test Engine specific hooks (imgui_test_engine) +//----------------------------------------------------------------------------- + +#ifdef IMGUI_ENABLE_TEST_ENGINE +extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id); +extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags); +extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...); +extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id); + +#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box +#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) +#define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log +#else +#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0) +#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g) +#endif + +//----------------------------------------------------------------------------- + +#if defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui_tables.cpp b/libultraship/libultraship/Lib/ImGui/imgui_tables.cpp new file mode 100644 index 000000000..27f1d5386 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui_tables.cpp @@ -0,0 +1,4054 @@ +// dear imgui, v1.87 +// (tables and columns code) + +/* + +Index of this file: + +// [SECTION] Commentary +// [SECTION] Header mess +// [SECTION] Tables: Main code +// [SECTION] Tables: Simple accessors +// [SECTION] Tables: Row changes +// [SECTION] Tables: Columns changes +// [SECTION] Tables: Columns width management +// [SECTION] Tables: Drawing +// [SECTION] Tables: Sorting +// [SECTION] Tables: Headers +// [SECTION] Tables: Context Menu +// [SECTION] Tables: Settings (.ini data) +// [SECTION] Tables: Garbage Collection +// [SECTION] Tables: Debugging +// [SECTION] Columns, BeginColumns, EndColumns, etc. + +*/ + +// Navigating this file: +// - In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. + +//----------------------------------------------------------------------------- +// [SECTION] Commentary +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Typical tables call flow: (root level is generally public API): +//----------------------------------------------------------------------------- +// - BeginTable() user begin into a table +// | BeginChild() - (if ScrollX/ScrollY is set) +// | TableBeginInitMemory() - first time table is used +// | TableResetSettings() - on settings reset +// | TableLoadSettings() - on settings load +// | TableBeginApplyRequests() - apply queued resizing/reordering/hiding requests +// | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame) +// | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width +// - TableSetupColumn() user submit columns details (optional) +// - TableSetupScrollFreeze() user submit scroll freeze information (optional) +//----------------------------------------------------------------------------- +// - TableUpdateLayout() [Internal] followup to BeginTable(): setup everything: widths, columns positions, clipping rectangles. Automatically called by the FIRST call to TableNextRow() or TableHeadersRow(). +// | TableSetupDrawChannels() - setup ImDrawList channels +// | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission +// | TableDrawContextMenu() - draw right-click context menu +//----------------------------------------------------------------------------- +// - TableHeadersRow() or TableHeader() user submit a headers row (optional) +// | TableSortSpecsClickColumn() - when left-clicked: alter sort order and sort direction +// | TableOpenContextMenu() - when right-clicked: trigger opening of the default context menu +// - TableGetSortSpecs() user queries updated sort specs (optional, generally after submitting headers) +// - TableNextRow() user begin into a new row (also automatically called by TableHeadersRow()) +// | TableEndRow() - finish existing row +// | TableBeginRow() - add a new row +// - TableSetColumnIndex() / TableNextColumn() user begin into a cell +// | TableEndCell() - close existing column/cell +// | TableBeginCell() - enter into current column/cell +// - [...] user emit contents +//----------------------------------------------------------------------------- +// - EndTable() user ends the table +// | TableDrawBorders() - draw outer borders, inner vertical borders +// | TableMergeDrawChannels() - merge draw channels if clipping isn't required +// | EndChild() - (if ScrollX/ScrollY is set) +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// TABLE SIZING +//----------------------------------------------------------------------------- +// (Read carefully because this is subtle but it does make sense!) +//----------------------------------------------------------------------------- +// About 'outer_size': +// Its meaning needs to differ slightly depending on if we are using ScrollX/ScrollY flags. +// Default value is ImVec2(0.0f, 0.0f). +// X +// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge. +// - outer_size.x > 0.0f -> Set Fixed width. +// Y with ScrollX/ScrollY disabled: we output table directly in current window +// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll. +// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set) +// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set) +// Y with ScrollX/ScrollY enabled: using a child window for scrolling +// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll. +// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window. +// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis. +//----------------------------------------------------------------------------- +// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags. +// Important to that note how the two flags have slightly different behaviors! +// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. +// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY is disabled. Data below the limit will be clipped and not visible. +// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height. +// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable) +//----------------------------------------------------------------------------- +// About 'inner_width': +// With ScrollX disabled: +// - inner_width -> *ignored* +// With ScrollX enabled: +// - inner_width < 0.0f -> *illegal* fit in known width (right align from outer_size.x) <-- weird +// - inner_width = 0.0f -> fit in outer_width: Fixed size columns will take space they need (if avail, otherwise shrink down), Stretch columns becomes Fixed columns. +// - inner_width > 0.0f -> override scrolling width, generally to be larger than outer_size.x. Fixed column take space they need (if avail, otherwise shrink down), Stretch columns share remaining space! +//----------------------------------------------------------------------------- +// Details: +// - If you want to use Stretch columns with ScrollX, you generally need to specify 'inner_width' otherwise the concept +// of "available space" doesn't make sense. +// - Even if not really useful, we allow 'inner_width < outer_size.x' for consistency and to facilitate understanding +// of what the value does. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// COLUMNS SIZING POLICIES +//----------------------------------------------------------------------------- +// About overriding column sizing policy and width/weight with TableSetupColumn(): +// We use a default parameter of 'init_width_or_weight == -1'. +// - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic +// - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom +// - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f +// - with ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom +// Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f) +// and you can fit a 100.0f wide item in it without clipping and with full padding. +//----------------------------------------------------------------------------- +// About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag) +// - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width +// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is max of all contents width +// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f +// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents +// Default Width and default Weight can be overridden when calling TableSetupColumn(). +//----------------------------------------------------------------------------- +// About mixing Fixed/Auto and Stretch columns together: +// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns. +// - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place! +// that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in. +// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the width of the maximum contents. +// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths. +//----------------------------------------------------------------------------- +// About using column width: +// If a column is manual resizable or has a width specified with TableSetupColumn(): +// - you may use GetContentRegionAvail().x to query the width available in a given column. +// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width. +// If the column is not resizable and has no width specified with TableSetupColumn(): +// - its width will be automatic and be set to the max of items submitted. +// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN). +// - but if the column has one or more items of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN). +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// TABLES CLIPPING/CULLING +//----------------------------------------------------------------------------- +// About clipping/culling of Rows in Tables: +// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows. +// ImGuiListClipper is reliant on the fact that rows are of equal height. +// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper. +// - Note that auto-resizing columns don't play well with using the clipper. +// By default a table with _ScrollX but without _Resizable will have column auto-resize. +// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns width explicitly with _WidthFixed. +//----------------------------------------------------------------------------- +// About clipping/culling of Columns in Tables: +// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing +// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know +// it is not going to contribute to row height. +// In many situations, you may skip submitting contents for every column but one (e.g. the first one). +// - Case A: column is not hidden by user, and at least partially in sight (most common case). +// - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output. +// - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.). +// +// [A] [B] [C] +// TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() return false, user can skip submitting items but only if the column doesn't contribute to row height. +// SkipItems: false false true -> [internal] when SkipItems is true, most widgets will early out if submitted, resulting is no layout output. +// ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way. +// ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway). +// +// - We need to distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row. +// However, in the majority of cases, the contribution to row height is the same for all columns, or the tallest cells are known by the programmer. +//----------------------------------------------------------------------------- +// About clipping/culling of whole Tables: +// - Scrolling tables with a known outer size can be clipped earlier as BeginTable() will return false. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// [SECTION] Header mess +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui_internal.h" + +// System includes +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later +#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types +#endif +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#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 (typically 0.0f) is 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 "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') +#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Tables: Main code +//----------------------------------------------------------------------------- +// - TableFixFlags() [Internal] +// - TableFindByID() [Internal] +// - BeginTable() +// - BeginTableEx() [Internal] +// - TableBeginInitMemory() [Internal] +// - TableBeginApplyRequests() [Internal] +// - TableSetupColumnFlags() [Internal] +// - TableUpdateLayout() [Internal] +// - TableUpdateBorders() [Internal] +// - EndTable() +// - TableSetupColumn() +// - TableSetupScrollFreeze() +//----------------------------------------------------------------------------- + +// Configuration +static const int TABLE_DRAW_CHANNEL_BG0 = 0; +static const int TABLE_DRAW_CHANNEL_BG2_FROZEN = 1; +static const int TABLE_DRAW_CHANNEL_NOCLIP = 2; // When using ImGuiTableFlags_NoClip (this becomes the last visible channel) +static const float TABLE_BORDER_SIZE = 1.0f; // FIXME-TABLE: Currently hard-coded because of clipping assumptions with outer borders rendering. +static const float TABLE_RESIZE_SEPARATOR_HALF_THICKNESS = 4.0f; // Extend outside inner borders. +static const float TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER = 0.06f; // Delay/timer before making the hover feedback (color+cursor) visible because tables/columns tends to be more cramped. + +// Helper +inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_window) +{ + // Adjust flags: set default sizing policy + if ((flags & ImGuiTableFlags_SizingMask_) == 0) + flags |= ((flags & ImGuiTableFlags_ScrollX) || (outer_window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) ? ImGuiTableFlags_SizingFixedFit : ImGuiTableFlags_SizingStretchSame; + + // Adjust flags: enable NoKeepColumnsVisible when using ImGuiTableFlags_SizingFixedSame + if ((flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame) + flags |= ImGuiTableFlags_NoKeepColumnsVisible; + + // Adjust flags: enforce borders when resizable + if (flags & ImGuiTableFlags_Resizable) + flags |= ImGuiTableFlags_BordersInnerV; + + // Adjust flags: disable NoHostExtendX/NoHostExtendY if we have any scrolling going on + if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) + flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY); + + // Adjust flags: NoBordersInBodyUntilResize takes priority over NoBordersInBody + if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize) + flags &= ~ImGuiTableFlags_NoBordersInBody; + + // Adjust flags: disable saved settings if there's nothing to save + if ((flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Sortable)) == 0) + flags |= ImGuiTableFlags_NoSavedSettings; + + // Inherit _NoSavedSettings from top-level window (child windows always have _NoSavedSettings set) + if (outer_window->RootWindow->Flags & ImGuiWindowFlags_NoSavedSettings) + flags |= ImGuiTableFlags_NoSavedSettings; + + return flags; +} + +ImGuiTable* ImGui::TableFindByID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + return g.Tables.GetByKey(id); +} + +// Read about "TABLE SIZING" at the top of this file. +bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width) +{ + ImGuiID id = GetID(str_id); + return BeginTableEx(str_id, id, columns_count, flags, outer_size, inner_width); +} + +bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* outer_window = GetCurrentWindow(); + if (outer_window->SkipItems) // Consistent with other tables + beneficial side effect that assert on miscalling EndTable() will be more visible. + return false; + + // Sanity checks + IM_ASSERT(columns_count > 0 && columns_count <= IMGUI_TABLE_MAX_COLUMNS && "Only 1..64 columns allowed!"); + if (flags & ImGuiTableFlags_ScrollX) + IM_ASSERT(inner_width >= 0.0f); + + // If an outer size is specified ahead we will be able to early out when not visible. Exact clipping rules may evolve. + const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0; + const ImVec2 avail_size = GetContentRegionAvail(); + ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f); + ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size); + if (use_child_window && IsClippedEx(outer_rect, 0)) + { + ItemSize(outer_rect); + return false; + } + + // Acquire storage for the table + ImGuiTable* table = g.Tables.GetOrAddByKey(id); + const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1; + const ImGuiID instance_id = id + instance_no; + const ImGuiTableFlags table_last_flags = table->Flags; + if (instance_no > 0) + IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID"); + + // Acquire temporary buffers + const int table_idx = g.Tables.GetIndex(table); + if (++g.TablesTempDataStacked > g.TablesTempData.Size) + g.TablesTempData.resize(g.TablesTempDataStacked, ImGuiTableTempData()); + ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempData[g.TablesTempDataStacked - 1]; + temp_data->TableIndex = table_idx; + table->DrawSplitter = &table->TempData->DrawSplitter; + table->DrawSplitter->Clear(); + + // Fix flags + table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0; + flags = TableFixFlags(flags, outer_window); + + // Initialize + table->ID = id; + table->Flags = flags; + table->InstanceCurrent = (ImS16)instance_no; + table->LastFrameActive = g.FrameCount; + table->OuterWindow = table->InnerWindow = outer_window; + table->ColumnsCount = columns_count; + table->IsLayoutLocked = false; + table->InnerWidth = inner_width; + temp_data->UserOuterSize = outer_size; + + // When not using a child window, WorkRect.Max will grow as we append contents. + if (use_child_window) + { + // Ensure no vertical scrollbar appears if we only want horizontal one, to make flag consistent + // (we have no other way to disable vertical scrollbar of a window while keeping the horizontal one showing) + ImVec2 override_content_size(FLT_MAX, FLT_MAX); + if ((flags & ImGuiTableFlags_ScrollX) && !(flags & ImGuiTableFlags_ScrollY)) + override_content_size.y = FLT_MIN; + + // Ensure specified width (when not specified, Stretched columns will act as if the width == OuterWidth and + // never lead to any scrolling). We don't handle inner_width < 0.0f, we could potentially use it to right-align + // based on the right side of the child window work rect, which would require knowing ahead if we are going to + // have decoration taking horizontal spaces (typically a vertical scrollbar). + if ((flags & ImGuiTableFlags_ScrollX) && inner_width > 0.0f) + override_content_size.x = inner_width; + + if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX) + SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f)); + + // Reset scroll if we are reactivating it + if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0) + SetNextWindowScroll(ImVec2(0.0f, 0.0f)); + + // Create scrolling region (without border and zero window padding) + ImGuiWindowFlags child_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None; + BeginChildEx(name, instance_id, outer_rect.GetSize(), false, child_flags); + table->InnerWindow = g.CurrentWindow; + table->WorkRect = table->InnerWindow->WorkRect; + table->OuterRect = table->InnerWindow->Rect(); + table->InnerRect = table->InnerWindow->InnerRect; + IM_ASSERT(table->InnerWindow->WindowPadding.x == 0.0f && table->InnerWindow->WindowPadding.y == 0.0f && table->InnerWindow->WindowBorderSize == 0.0f); + } + else + { + // For non-scrolling tables, WorkRect == OuterRect == InnerRect. + // But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable(). + table->WorkRect = table->OuterRect = table->InnerRect = outer_rect; + } + + // Push a standardized ID for both child-using and not-child-using tables + PushOverrideID(instance_id); + + // Backup a copy of host window members we will modify + ImGuiWindow* inner_window = table->InnerWindow; + table->HostIndentX = inner_window->DC.Indent.x; + table->HostClipRect = inner_window->ClipRect; + table->HostSkipItems = inner_window->SkipItems; + temp_data->HostBackupWorkRect = inner_window->WorkRect; + temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect; + temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset; + temp_data->HostBackupPrevLineSize = inner_window->DC.PrevLineSize; + temp_data->HostBackupCurrLineSize = inner_window->DC.CurrLineSize; + temp_data->HostBackupCursorMaxPos = inner_window->DC.CursorMaxPos; + temp_data->HostBackupItemWidth = outer_window->DC.ItemWidth; + temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size; + inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + + // Padding and Spacing + // - None ........Content..... Pad .....Content........ + // - PadOuter | Pad ..Content..... Pad .....Content.. Pad | + // - PadInner ........Content.. Pad | Pad ..Content........ + // - PadOuter+PadInner | Pad ..Content.. Pad | Pad ..Content.. Pad | + const bool pad_outer_x = (flags & ImGuiTableFlags_NoPadOuterX) ? false : (flags & ImGuiTableFlags_PadOuterX) ? true : (flags & ImGuiTableFlags_BordersOuterV) != 0; + const bool pad_inner_x = (flags & ImGuiTableFlags_NoPadInnerX) ? false : true; + const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f; + const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f; + const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f; + table->CellSpacingX1 = inner_spacing_explicit + inner_spacing_for_border; + table->CellSpacingX2 = inner_spacing_explicit; + table->CellPaddingX = inner_padding_explicit; + table->CellPaddingY = g.Style.CellPadding.y; + + const float outer_padding_for_border = (flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f; + const float outer_padding_explicit = pad_outer_x ? g.Style.CellPadding.x : 0.0f; + table->OuterPaddingX = (outer_padding_for_border + outer_padding_explicit) - table->CellPaddingX; + + table->CurrentColumn = -1; + table->CurrentRow = -1; + table->RowBgColorCounter = 0; + table->LastRowFlags = ImGuiTableRowFlags_None; + table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect; + table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width + table->InnerClipRect.ClipWithFull(table->HostClipRect); + table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y; + + table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow + table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow() + table->FreezeRowsRequest = table->FreezeRowsCount = 0; // This will be setup by TableSetupScrollFreeze(), if any + table->FreezeColumnsRequest = table->FreezeColumnsCount = 0; + table->IsUnfrozenRows = true; + table->DeclColumnsCount = 0; + + // Using opaque colors facilitate overlapping elements of the grid + table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong); + table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight); + + // Make table current + g.CurrentTable = table; + outer_window->DC.CurrentTableIdx = table_idx; + if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. + inner_window->DC.CurrentTableIdx = table_idx; + + if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) + table->IsResetDisplayOrderRequest = true; + + // Mark as used + if (table_idx >= g.TablesLastTimeActive.Size) + g.TablesLastTimeActive.resize(table_idx + 1, -1.0f); + g.TablesLastTimeActive[table_idx] = (float)g.Time; + temp_data->LastTimeActive = (float)g.Time; + table->MemoryCompacted = false; + + // Setup memory buffer (clear data if columns count changed) + ImGuiTableColumn* old_columns_to_preserve = NULL; + void* old_columns_raw_data = NULL; + const int old_columns_count = table->Columns.size(); + if (old_columns_count != 0 && old_columns_count != columns_count) + { + // Attempt to preserve width on column count change (#4046) + old_columns_to_preserve = table->Columns.Data; + old_columns_raw_data = table->RawData; + table->RawData = NULL; + } + if (table->RawData == NULL) + { + TableBeginInitMemory(table, columns_count); + table->IsInitializing = table->IsSettingsRequestLoad = true; + } + if (table->IsResetAllRequest) + TableResetSettings(table); + if (table->IsInitializing) + { + // Initialize + table->SettingsOffset = -1; + table->IsSortSpecsDirty = true; + table->InstanceInteracted = -1; + table->ContextPopupColumn = -1; + table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1; + table->AutoFitSingleColumn = -1; + table->HoveredColumnBody = table->HoveredColumnBorder = -1; + for (int n = 0; n < columns_count; n++) + { + ImGuiTableColumn* column = &table->Columns[n]; + if (old_columns_to_preserve && n < old_columns_count) + { + // FIXME: We don't attempt to preserve column order in this path. + *column = old_columns_to_preserve[n]; + } + else + { + float width_auto = column->WidthAuto; + *column = ImGuiTableColumn(); + column->WidthAuto = width_auto; + column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker + column->IsEnabled = column->IsUserEnabled = column->IsUserEnabledNextFrame = true; + } + column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n; + } + } + if (old_columns_raw_data) + IM_FREE(old_columns_raw_data); + + // Load settings + if (table->IsSettingsRequestLoad) + TableLoadSettings(table); + + // Handle DPI/font resize + // This is designed to facilitate DPI changes with the assumption that e.g. style.CellPadding has been scaled as well. + // It will also react to changing fonts with mixed results. It doesn't need to be perfect but merely provide a decent transition. + // FIXME-DPI: Provide consistent standards for reference size. Perhaps using g.CurrentDpiScale would be more self explanatory. + // This is will lead us to non-rounded WidthRequest in columns, which should work but is a poorly tested path. + const float new_ref_scale_unit = g.FontSize; // g.Font->GetCharAdvance('A') ? + if (table->RefScale != 0.0f && table->RefScale != new_ref_scale_unit) + { + const float scale_factor = new_ref_scale_unit / table->RefScale; + //IMGUI_DEBUG_LOG("[table] %08X RefScaleUnit %.3f -> %.3f, scaling width by %.3f\n", table->ID, table->RefScaleUnit, new_ref_scale_unit, scale_factor); + for (int n = 0; n < columns_count; n++) + table->Columns[n].WidthRequest = table->Columns[n].WidthRequest * scale_factor; + } + table->RefScale = new_ref_scale_unit; + + // Disable output until user calls TableNextRow() or TableNextColumn() leading to the TableUpdateLayout() call.. + // This is not strictly necessary but will reduce cases were "out of table" output will be misleading to the user. + // Because we cannot safely assert in EndTable() when no rows have been created, this seems like our best option. + inner_window->SkipItems = true; + + // Clear names + // At this point the ->NameOffset field of each column will be invalid until TableUpdateLayout() or the first call to TableSetupColumn() + if (table->ColumnsNames.Buf.Size > 0) + table->ColumnsNames.Buf.resize(0); + + // Apply queued resizing/reordering/hiding requests + TableBeginApplyRequests(table); + + return true; +} + +// For reference, the average total _allocation count_ for a table is: +// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables) +// + 1 (for table->RawData allocated below) +// + 1 (for table->ColumnsNames, if names are used) +// Shared allocations per number of nested tables +// + 1 (for table->Splitter._Channels) +// + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels) +// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableSetupDrawChannels() for details. +// Unused channels don't perform their +2 allocations. +void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count) +{ + // Allocate single buffer for our arrays + ImSpanAllocator<3> span_allocator; + span_allocator.Reserve(0, columns_count * sizeof(ImGuiTableColumn)); + span_allocator.Reserve(1, columns_count * sizeof(ImGuiTableColumnIdx)); + span_allocator.Reserve(2, columns_count * sizeof(ImGuiTableCellData), 4); + table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes()); + memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes()); + span_allocator.SetArenaBasePtr(table->RawData); + span_allocator.GetSpan(0, &table->Columns); + span_allocator.GetSpan(1, &table->DisplayOrderToIndex); + span_allocator.GetSpan(2, &table->RowCellData); +} + +// Apply queued resizing/reordering/hiding requests +void ImGui::TableBeginApplyRequests(ImGuiTable* table) +{ + // Handle resizing request + // (We process this at the first TableBegin of the frame) + // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling? + if (table->InstanceCurrent == 0) + { + if (table->ResizedColumn != -1 && table->ResizedColumnNextWidth != FLT_MAX) + TableSetColumnWidth(table->ResizedColumn, table->ResizedColumnNextWidth); + table->LastResizedColumn = table->ResizedColumn; + table->ResizedColumnNextWidth = FLT_MAX; + table->ResizedColumn = -1; + + // Process auto-fit for single column, which is a special case for stretch columns and fixed columns with FixedSame policy. + // FIXME-TABLE: Would be nice to redistribute available stretch space accordingly to other weights, instead of giving it all to siblings. + if (table->AutoFitSingleColumn != -1) + { + TableSetColumnWidth(table->AutoFitSingleColumn, table->Columns[table->AutoFitSingleColumn].WidthAuto); + table->AutoFitSingleColumn = -1; + } + } + + // Handle reordering request + // Note: we don't clear ReorderColumn after handling the request. + if (table->InstanceCurrent == 0) + { + if (table->HeldHeaderColumn == -1 && table->ReorderColumn != -1) + table->ReorderColumn = -1; + table->HeldHeaderColumn = -1; + if (table->ReorderColumn != -1 && table->ReorderColumnDir != 0) + { + // We need to handle reordering across hidden columns. + // In the configuration below, moving C to the right of E will lead to: + // ... C [D] E ---> ... [D] E C (Column name/index) + // ... 2 3 4 ... 2 3 4 (Display order) + const int reorder_dir = table->ReorderColumnDir; + IM_ASSERT(reorder_dir == -1 || reorder_dir == +1); + IM_ASSERT(table->Flags & ImGuiTableFlags_Reorderable); + ImGuiTableColumn* src_column = &table->Columns[table->ReorderColumn]; + ImGuiTableColumn* dst_column = &table->Columns[(reorder_dir == -1) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn]; + IM_UNUSED(dst_column); + const int src_order = src_column->DisplayOrder; + const int dst_order = dst_column->DisplayOrder; + src_column->DisplayOrder = (ImGuiTableColumnIdx)dst_order; + for (int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir) + table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir; + IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir); + + // Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[], + // rebuild the later from the former. + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n; + table->ReorderColumnDir = 0; + table->IsSettingsDirty = true; + } + } + + // Handle display order reset request + if (table->IsResetDisplayOrderRequest) + { + for (int n = 0; n < table->ColumnsCount; n++) + table->DisplayOrderToIndex[n] = table->Columns[n].DisplayOrder = (ImGuiTableColumnIdx)n; + table->IsResetDisplayOrderRequest = false; + table->IsSettingsDirty = true; + } +} + +// Adjust flags: default width mode + stretch columns are not allowed when auto extending +static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags flags_in) +{ + ImGuiTableColumnFlags flags = flags_in; + + // Sizing Policy + if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) + { + const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_); + if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame) + flags |= ImGuiTableColumnFlags_WidthFixed; + else + flags |= ImGuiTableColumnFlags_WidthStretch; + } + else + { + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_)); // Check that only 1 of each set is used. + } + + // Resize + if ((table->Flags & ImGuiTableFlags_Resizable) == 0) + flags |= ImGuiTableColumnFlags_NoResize; + + // Sorting + if ((flags & ImGuiTableColumnFlags_NoSortAscending) && (flags & ImGuiTableColumnFlags_NoSortDescending)) + flags |= ImGuiTableColumnFlags_NoSort; + + // Indentation + if ((flags & ImGuiTableColumnFlags_IndentMask_) == 0) + flags |= (table->Columns.index_from_ptr(column) == 0) ? ImGuiTableColumnFlags_IndentEnable : ImGuiTableColumnFlags_IndentDisable; + + // Alignment + //if ((flags & ImGuiTableColumnFlags_AlignMask_) == 0) + // flags |= ImGuiTableColumnFlags_AlignCenter; + //IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_AlignMask_)); // Check that only 1 of each set is used. + + // Preserve status flags + column->Flags = flags | (column->Flags & ImGuiTableColumnFlags_StatusMask_); + + // Build an ordered list of available sort directions + column->SortDirectionsAvailCount = column->SortDirectionsAvailMask = column->SortDirectionsAvailList = 0; + if (table->Flags & ImGuiTableFlags_Sortable) + { + int count = 0, mask = 0, list = 0; + if ((flags & ImGuiTableColumnFlags_PreferSortAscending) != 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) { mask |= 1 << ImGuiSortDirection_Ascending; list |= ImGuiSortDirection_Ascending << (count << 1); count++; } + if ((flags & ImGuiTableColumnFlags_PreferSortDescending) != 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) { mask |= 1 << ImGuiSortDirection_Descending; list |= ImGuiSortDirection_Descending << (count << 1); count++; } + if ((flags & ImGuiTableColumnFlags_PreferSortAscending) == 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) { mask |= 1 << ImGuiSortDirection_Ascending; list |= ImGuiSortDirection_Ascending << (count << 1); count++; } + if ((flags & ImGuiTableColumnFlags_PreferSortDescending) == 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) { mask |= 1 << ImGuiSortDirection_Descending; list |= ImGuiSortDirection_Descending << (count << 1); count++; } + if ((table->Flags & ImGuiTableFlags_SortTristate) || count == 0) { mask |= 1 << ImGuiSortDirection_None; count++; } + column->SortDirectionsAvailList = (ImU8)list; + column->SortDirectionsAvailMask = (ImU8)mask; + column->SortDirectionsAvailCount = (ImU8)count; + ImGui::TableFixColumnSortDirection(table, column); + } +} + +// Layout columns for the frame. This is in essence the followup to BeginTable(). +// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() to be called first. +// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns. +// Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns? +void ImGui::TableUpdateLayout(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(table->IsLayoutLocked == false); + + const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_); + table->IsDefaultDisplayOrder = true; + table->ColumnsEnabledCount = 0; + table->EnabledMaskByIndex = 0x00; + table->EnabledMaskByDisplayOrder = 0x00; + table->LeftMostEnabledColumn = -1; + table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE + + // [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns. + // Process columns in their visible orders as we are building the Prev/Next indices. + int count_fixed = 0; // Number of columns that have fixed sizing policies + int count_stretch = 0; // Number of columns that have stretch sizing policies + int prev_visible_column_idx = -1; + bool has_auto_fit_request = false; + bool has_resizable = false; + float stretch_sum_width_auto = 0.0f; + float fixed_max_width_auto = 0.0f; + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + { + const int column_n = table->DisplayOrderToIndex[order_n]; + if (column_n != order_n) + table->IsDefaultDisplayOrder = false; + ImGuiTableColumn* column = &table->Columns[column_n]; + + // Clear column setup if not submitted by user. Currently we make it mandatory to call TableSetupColumn() every frame. + // It would easily work without but we're not ready to guarantee it since e.g. names need resubmission anyway. + // We take a slight shortcut but in theory we could be calling TableSetupColumn() here with dummy values, it should yield the same effect. + if (table->DeclColumnsCount <= column_n) + { + TableSetupColumnFlags(table, column, ImGuiTableColumnFlags_None); + column->NameOffset = -1; + column->UserID = 0; + column->InitStretchWeightOrWidth = -1.0f; + } + + // Update Enabled state, mark settings and sort specs dirty + if (!(table->Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide)) + column->IsUserEnabledNextFrame = true; + if (column->IsUserEnabled != column->IsUserEnabledNextFrame) + { + column->IsUserEnabled = column->IsUserEnabledNextFrame; + table->IsSettingsDirty = true; + } + column->IsEnabled = column->IsUserEnabled && (column->Flags & ImGuiTableColumnFlags_Disabled) == 0; + + if (column->SortOrder != -1 && !column->IsEnabled) + table->IsSortSpecsDirty = true; + if (column->SortOrder > 0 && !(table->Flags & ImGuiTableFlags_SortMulti)) + table->IsSortSpecsDirty = true; + + // Auto-fit unsized columns + const bool start_auto_fit = (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f); + if (start_auto_fit) + column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames + + if (!column->IsEnabled) + { + column->IndexWithinEnabledSet = -1; + continue; + } + + // Mark as enabled and link to previous/next enabled column + column->PrevEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx; + column->NextEnabledColumn = -1; + if (prev_visible_column_idx != -1) + table->Columns[prev_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n; + else + table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n; + column->IndexWithinEnabledSet = table->ColumnsEnabledCount++; + table->EnabledMaskByIndex |= (ImU64)1 << column_n; + table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder; + prev_visible_column_idx = column_n; + IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); + + // Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping) + // Combine width from regular rows + width from headers unless requested not to. + if (!column->IsPreserveWidthAuto) + column->WidthAuto = TableGetColumnWidthAuto(table, column); + + // Non-resizable columns keep their requested width (apply user value regardless of IsPreserveWidthAuto) + const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0; + if (column_is_resizable) + has_resizable = true; + if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f && !column_is_resizable) + column->WidthAuto = column->InitStretchWeightOrWidth; + + if (column->AutoFitQueue != 0x00) + has_auto_fit_request = true; + if (column->Flags & ImGuiTableColumnFlags_WidthStretch) + { + stretch_sum_width_auto += column->WidthAuto; + count_stretch++; + } + else + { + fixed_max_width_auto = ImMax(fixed_max_width_auto, column->WidthAuto); + count_fixed++; + } + } + if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) + table->IsSortSpecsDirty = true; + table->RightMostEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx; + IM_ASSERT(table->LeftMostEnabledColumn >= 0 && table->RightMostEnabledColumn >= 0); + + // [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible + // to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing). + // FIXME-TABLE: for always auto-resizing columns may not want to do that all the time. + if (has_auto_fit_request && table->OuterWindow != table->InnerWindow) + table->InnerWindow->SkipItems = false; + if (has_auto_fit_request) + table->IsSettingsDirty = true; + + // [Part 3] Fix column flags and record a few extra information. + float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding. + float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns. + table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) + continue; + ImGuiTableColumn* column = &table->Columns[column_n]; + + const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0; + if (column->Flags & ImGuiTableColumnFlags_WidthFixed) + { + // Apply same widths policy + float width_auto = column->WidthAuto; + if (table_sizing_policy == ImGuiTableFlags_SizingFixedSame && (column->AutoFitQueue != 0x00 || !column_is_resizable)) + width_auto = fixed_max_width_auto; + + // Apply automatic width + // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) + if (column->AutoFitQueue != 0x00) + column->WidthRequest = width_auto; + else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n))) + column->WidthRequest = width_auto; + + // FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets + // (e.g. TextWrapped) too much. Otherwise what tends to happen is that TextWrapped would output a very + // large height (= first frame scrollbar display very off + clipper would skip lots of items). + // This is merely making the side-effect less extreme, but doesn't properly fixes it. + // FIXME: Move this to ->WidthGiven to avoid temporary lossyless? + // FIXME: This break IsPreserveWidthAuto from not flickering if the stored WidthAuto was smaller. + if (column->AutoFitQueue > 0x01 && table->IsInitializing && !column->IsPreserveWidthAuto) + column->WidthRequest = ImMax(column->WidthRequest, table->MinColumnWidth * 4.0f); // FIXME-TABLE: Another constant/scale? + sum_width_requests += column->WidthRequest; + } + else + { + // Initialize stretch weight + if (column->AutoFitQueue != 0x00 || column->StretchWeight < 0.0f || !column_is_resizable) + { + if (column->InitStretchWeightOrWidth > 0.0f) + column->StretchWeight = column->InitStretchWeightOrWidth; + else if (table_sizing_policy == ImGuiTableFlags_SizingStretchProp) + column->StretchWeight = (column->WidthAuto / stretch_sum_width_auto) * count_stretch; + else + column->StretchWeight = 1.0f; + } + + stretch_sum_weights += column->StretchWeight; + if (table->LeftMostStretchedColumn == -1 || table->Columns[table->LeftMostStretchedColumn].DisplayOrder > column->DisplayOrder) + table->LeftMostStretchedColumn = (ImGuiTableColumnIdx)column_n; + if (table->RightMostStretchedColumn == -1 || table->Columns[table->RightMostStretchedColumn].DisplayOrder < column->DisplayOrder) + table->RightMostStretchedColumn = (ImGuiTableColumnIdx)column_n; + } + column->IsPreserveWidthAuto = false; + sum_width_requests += table->CellPaddingX * 2.0f; + } + table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed; + + // [Part 4] Apply final widths based on requested widths + const ImRect work_rect = table->WorkRect; + const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); + const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth(); + const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; + float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; + table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) + continue; + ImGuiTableColumn* column = &table->Columns[column_n]; + + // Allocate width for stretched/weighted columns (StretchWeight gets converted into WidthRequest) + if (column->Flags & ImGuiTableColumnFlags_WidthStretch) + { + float weight_ratio = column->StretchWeight / stretch_sum_weights; + column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, table->MinColumnWidth) + 0.01f); + width_remaining_for_stretched_columns -= column->WidthRequest; + } + + // [Resize Rule 1] The right-most Visible column is not resizable if there is at least one Stretch column + // See additional comments in TableSetColumnWidth(). + if (column->NextEnabledColumn == -1 && table->LeftMostStretchedColumn != -1) + column->Flags |= ImGuiTableColumnFlags_NoDirectResize_; + + // Assign final width, record width in case we will need to shrink + column->WidthGiven = ImFloor(ImMax(column->WidthRequest, table->MinColumnWidth)); + table->ColumnsGivenWidth += column->WidthGiven; + } + + // [Part 5] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column). + // Using right-to-left distribution (more likely to match resizing cursor). + if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths)) + for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) + { + if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + continue; + ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]]; + if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch)) + continue; + column->WidthRequest += 1.0f; + column->WidthGiven += 1.0f; + width_remaining_for_stretched_columns -= 1.0f; + } + + table->HoveredColumnBody = -1; + table->HoveredColumnBorder = -1; + const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table->LastOuterHeight)); + const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0); + + // [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column + // Process columns in their visible orders as we are comparing the visible order and adjusting host_clip_rect while looping. + int visible_n = 0; + bool offset_x_frozen = (table->FreezeColumnsCount > 0); + float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1; + ImRect host_clip_rect = table->InnerClipRect; + //host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2; + table->VisibleMaskByIndex = 0x00; + table->RequestOutputMaskByIndex = 0x00; + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + { + const int column_n = table->DisplayOrderToIndex[order_n]; + ImGuiTableColumn* column = &table->Columns[column_n]; + + column->NavLayerCurrent = (ImS8)((table->FreezeRowsCount > 0 || column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); + + if (offset_x_frozen && table->FreezeColumnsCount == visible_n) + { + offset_x += work_rect.Min.x - table->OuterRect.Min.x; + offset_x_frozen = false; + } + + // Clear status flags + column->Flags &= ~ImGuiTableColumnFlags_StatusMask_; + + if ((table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)) == 0) + { + // Hidden column: clear a few fields and we are done with it for the remainder of the function. + // We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper. + column->MinX = column->MaxX = column->WorkMinX = column->ClipRect.Min.x = column->ClipRect.Max.x = offset_x; + column->WidthGiven = 0.0f; + column->ClipRect.Min.y = work_rect.Min.y; + column->ClipRect.Max.y = FLT_MAX; + column->ClipRect.ClipWithFull(host_clip_rect); + column->IsVisibleX = column->IsVisibleY = column->IsRequestOutput = false; + column->IsSkipItems = true; + column->ItemWidth = 1.0f; + continue; + } + + // Detect hovered column + if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x) + table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n; + + // Lock start position + column->MinX = offset_x; + + // Lock width based on start position and minimum/maximum width for this position + float max_width = TableGetMaxColumnWidth(table, column_n); + column->WidthGiven = ImMin(column->WidthGiven, max_width); + column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, table->MinColumnWidth)); + column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; + + // Lock other positions + // - ClipRect.Min.x: Because merging draw commands doesn't compare min boundaries, we make ClipRect.Min.x match left bounds to be consistent regardless of merging. + // - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column. + // - ClipRect.Max.x: using MaxX makes it easier for header to receive hover highlight with no discontinuity and display sorting arrow. + // - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter. + column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1; + column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max + column->ItemWidth = ImFloor(column->WidthGiven * 0.65f); + column->ClipRect.Min.x = column->MinX; + column->ClipRect.Min.y = work_rect.Min.y; + column->ClipRect.Max.x = column->MaxX; //column->WorkMaxX; + column->ClipRect.Max.y = FLT_MAX; + column->ClipRect.ClipWithFull(host_clip_rect); + + // Mark column as Clipped (not in sight) + // Note that scrolling tables (where inner_window != outer_window) handle Y clipped earlier in BeginTable() so IsVisibleY really only applies to non-scrolling tables. + // FIXME-TABLE: Because InnerClipRect.Max.y is conservatively ==outer_window->ClipRect.Max.y, we never can mark columns _Above_ the scroll line as not IsVisibleY. + // Taking advantage of LastOuterHeight would yield good results there... + // FIXME-TABLE: Y clipping is disabled because it effectively means not submitting will reduce contents width which is fed to outer_window->DC.CursorMaxPos.x, + // and this may be used (e.g. typically by outer_window using AlwaysAutoResize or outer_window's horizontal scrollbar, but could be something else). + // Possible solution to preserve last known content width for clipped column. Test 'table_reported_size' fails when enabling Y clipping and window is resized small. + column->IsVisibleX = (column->ClipRect.Max.x > column->ClipRect.Min.x); + column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y); + const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY; + if (is_visible) + table->VisibleMaskByIndex |= ((ImU64)1 << column_n); + + // Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output. + column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0; + if (column->IsRequestOutput) + table->RequestOutputMaskByIndex |= ((ImU64)1 << column_n); + + // Mark column as SkipItems (ignoring all items/layout) + column->IsSkipItems = !column->IsEnabled || table->HostSkipItems; + if (column->IsSkipItems) + IM_ASSERT(!is_visible); + + // Update status flags + column->Flags |= ImGuiTableColumnFlags_IsEnabled; + if (is_visible) + column->Flags |= ImGuiTableColumnFlags_IsVisible; + if (column->SortOrder != -1) + column->Flags |= ImGuiTableColumnFlags_IsSorted; + if (table->HoveredColumnBody == column_n) + column->Flags |= ImGuiTableColumnFlags_IsHovered; + + // Alignment + // FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in + // many cases (to be able to honor this we might be able to store a log of cells width, per row, for + // visible rows, but nav/programmatic scroll would have visible artifacts.) + //if (column->Flags & ImGuiTableColumnFlags_AlignRight) + // column->WorkMinX = ImMax(column->WorkMinX, column->MaxX - column->ContentWidthRowsUnfrozen); + //else if (column->Flags & ImGuiTableColumnFlags_AlignCenter) + // column->WorkMinX = ImLerp(column->WorkMinX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f); + + // Reset content width variables + column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX; + column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX; + + // Don't decrement auto-fit counters until container window got a chance to submit its items + if (table->HostSkipItems == false) + { + column->AutoFitQueue >>= 1; + column->CannotSkipItemsQueue >>= 1; + } + + if (visible_n < table->FreezeColumnsCount) + host_clip_rect.Min.x = ImClamp(column->MaxX + TABLE_BORDER_SIZE, host_clip_rect.Min.x, host_clip_rect.Max.x); + + offset_x += column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; + visible_n++; + } + + // [Part 7] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it) + // Clear Resizable flag if none of our column are actually resizable (either via an explicit _NoResize flag, either + // because of using _WidthAuto/_WidthStretch). This will hide the resizing option from the context menu. + const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x); + if (is_hovering_table && table->HoveredColumnBody == -1) + { + if (g.IO.MousePos.x >= unused_x1) + table->HoveredColumnBody = (ImGuiTableColumnIdx)table->ColumnsCount; + } + if (has_resizable == false && (table->Flags & ImGuiTableFlags_Resizable)) + table->Flags &= ~ImGuiTableFlags_Resizable; + + // [Part 8] Lock actual OuterRect/WorkRect right-most position. + // This is done late to handle the case of fixed-columns tables not claiming more widths that they need. + // Because of this we are careful with uses of WorkRect and InnerClipRect before this point. + if (table->RightMostStretchedColumn != -1) + table->Flags &= ~ImGuiTableFlags_NoHostExtendX; + if (table->Flags & ImGuiTableFlags_NoHostExtendX) + { + table->OuterRect.Max.x = table->WorkRect.Max.x = unused_x1; + table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1); + } + table->InnerWindow->ParentWorkRect = table->WorkRect; + table->BorderX1 = table->InnerClipRect.Min.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : -1.0f); + table->BorderX2 = table->InnerClipRect.Max.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : +1.0f); + + // [Part 9] Allocate draw channels and setup background cliprect + TableSetupDrawChannels(table); + + // [Part 10] Hit testing on borders + if (table->Flags & ImGuiTableFlags_Resizable) + TableUpdateBorders(table); + table->LastFirstRowHeight = 0.0f; + table->IsLayoutLocked = true; + table->IsUsingHeaders = false; + + // [Part 11] Context menu + if (table->IsContextPopupOpen && table->InstanceCurrent == table->InstanceInteracted) + { + const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID); + if (BeginPopupEx(context_menu_id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings)) + { + TableDrawContextMenu(table); + EndPopup(); + } + else + { + table->IsContextPopupOpen = false; + } + } + + // [Part 13] Sanitize and build sort specs before we have a change to use them for display. + // This path will only be exercised when sort specs are modified before header rows (e.g. init or visibility change) + if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable)) + TableSortSpecsBuild(table); + + // Initial state + ImGuiWindow* inner_window = table->InnerWindow; + if (table->Flags & ImGuiTableFlags_NoClip) + table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP); + else + inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false); +} + +// Process hit-testing on resizing borders. Actual size change will be applied in EndTable() +// - Set table->HoveredColumnBorder with a short delay/timer to reduce feedback noise +// - Submit ahead of table contents and header, use ImGuiButtonFlags_AllowItemOverlap to prioritize widgets +// overlapping the same area. +void ImGui::TableUpdateBorders(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(table->Flags & ImGuiTableFlags_Resizable); + + // At this point OuterRect height may be zero or under actual final height, so we rely on temporal coherency and + // use the final height from last frame. Because this is only affecting _interaction_ with columns, it is not + // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). + // Actual columns highlight/render will be performed in EndTable() and not be affected. + const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS; + const float hit_y1 = table->OuterRect.Min.y; + const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table->LastOuterHeight); + const float hit_y2_head = hit_y1 + table->LastFirstRowHeight; + + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + { + if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + continue; + + const int column_n = table->DisplayOrderToIndex[order_n]; + ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) + continue; + + // ImGuiTableFlags_NoBordersInBodyUntilResize will be honored in TableDrawBorders() + const float border_y2_hit = (table->Flags & ImGuiTableFlags_NoBordersInBody) ? hit_y2_head : hit_y2_body; + if ((table->Flags & ImGuiTableFlags_NoBordersInBody) && table->IsUsingHeaders == false) + continue; + + if (!column->IsVisibleX && table->LastResizedColumn != column_n) + continue; + + ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent); + ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit); + //GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100)); + KeepAliveID(column_id); + + bool hovered = false, held = false; + bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus); + if (pressed && IsMouseDoubleClicked(0)) + { + TableSetColumnWidthAutoSingle(table, column_n); + ClearActiveID(); + held = hovered = false; + } + if (held) + { + if (table->LastResizedColumn == -1) + table->ResizeLockMinContentsX2 = table->RightMostEnabledColumn != -1 ? table->Columns[table->RightMostEnabledColumn].MaxX : -FLT_MAX; + table->ResizedColumn = (ImGuiTableColumnIdx)column_n; + table->InstanceInteracted = table->InstanceCurrent; + } + if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held) + { + table->HoveredColumnBorder = (ImGuiTableColumnIdx)column_n; + SetMouseCursor(ImGuiMouseCursor_ResizeEW); + } + } +} + +void ImGui::EndTable() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!"); + + // This assert would be very useful to catch a common error... unfortunately it would probably trigger in some + // cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border) + //IM_ASSERT(table->IsLayoutLocked && "Table unused: never called TableNextRow(), is that the intent?"); + + // If the user never got to call TableNextRow() or TableNextColumn(), we call layout ourselves to ensure all our + // code paths are consistent (instead of just hoping that TableBegin/TableEnd will work), get borders drawn, etc. + if (!table->IsLayoutLocked) + TableUpdateLayout(table); + + const ImGuiTableFlags flags = table->Flags; + ImGuiWindow* inner_window = table->InnerWindow; + ImGuiWindow* outer_window = table->OuterWindow; + ImGuiTableTempData* temp_data = table->TempData; + IM_ASSERT(inner_window == g.CurrentWindow); + IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow); + + if (table->IsInsideRow) + TableEndRow(table); + + // Context menu in columns body + if (flags & ImGuiTableFlags_ContextMenuInBody) + if (table->HoveredColumnBody != -1 && !IsAnyItemHovered() && IsMouseReleased(ImGuiMouseButton_Right)) + TableOpenContextMenu((int)table->HoveredColumnBody); + + // Finalize table height + inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize; + inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize; + inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos; + const float inner_content_max_y = table->RowPosY2; + IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y); + if (inner_window != outer_window) + inner_window->DC.CursorMaxPos.y = inner_content_max_y; + else if (!(flags & ImGuiTableFlags_NoHostExtendY)) + table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_content_max_y); // Patch OuterRect/InnerRect height + table->WorkRect.Max.y = ImMax(table->WorkRect.Max.y, table->OuterRect.Max.y); + table->LastOuterHeight = table->OuterRect.GetHeight(); + + // Setup inner scrolling range + // FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y, + // but since the later is likely to be impossible to do we'd rather update both axises together. + if (table->Flags & ImGuiTableFlags_ScrollX) + { + const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f; + float max_pos_x = table->InnerWindow->DC.CursorMaxPos.x; + if (table->RightMostEnabledColumn != -1) + max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border); + if (table->ResizedColumn != -1) + max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2); + table->InnerWindow->DC.CursorMaxPos.x = max_pos_x; + } + + // Pop clipping rect + if (!(flags & ImGuiTableFlags_NoClip)) + inner_window->DrawList->PopClipRect(); + inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back(); + + // Draw borders + if ((flags & ImGuiTableFlags_Borders) != 0) + TableDrawBorders(table); + +#if 0 + // Strip out dummy channel draw calls + // We have no way to prevent user submitting direct ImDrawList calls into a hidden column (but ImGui:: calls will be clipped out) + // Pros: remove draw calls which will have no effect. since they'll have zero-size cliprect they may be early out anyway. + // Cons: making it harder for users watching metrics/debugger to spot the wasted vertices. + if (table->DummyDrawChannel != (ImGuiTableColumnIdx)-1) + { + ImDrawChannel* dummy_channel = &table->DrawSplitter._Channels[table->DummyDrawChannel]; + dummy_channel->_CmdBuffer.resize(0); + dummy_channel->_IdxBuffer.resize(0); + } +#endif + + // Flatten channels and merge draw calls + ImDrawListSplitter* splitter = table->DrawSplitter; + splitter->SetCurrentChannel(inner_window->DrawList, 0); + if ((table->Flags & ImGuiTableFlags_NoClip) == 0) + TableMergeDrawChannels(table); + splitter->Merge(inner_window->DrawList); + + // Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable() + const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); + table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + if (table->EnabledMaskByIndex & ((ImU64)1 << column_n)) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) + table->ColumnsAutoFitWidth += column->WidthRequest; + else + table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, column); + } + + // Update scroll + if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window) + { + inner_window->Scroll.x = 0.0f; + } + else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceCurrent) + { + // When releasing a column being resized, scroll to keep the resulting column in sight + const float neighbor_width_to_keep_visible = table->MinColumnWidth + table->CellPaddingX * 2.0f; + ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn]; + if (column->MaxX < table->InnerClipRect.Min.x) + SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x - neighbor_width_to_keep_visible, 1.0f); + else if (column->MaxX > table->InnerClipRect.Max.x) + SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x + neighbor_width_to_keep_visible, 1.0f); + } + + // Apply resizing/dragging at the end of the frame + if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted) + { + ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; + const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); + const float new_width = ImFloor(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); + table->ResizedColumnNextWidth = new_width; + } + + // Pop from id stack + IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!"); + IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= temp_data->HostBackupItemWidthStackSize, "Too many PopItemWidth!"); + PopID(); + + // Restore window data that we modified + const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos; + inner_window->WorkRect = temp_data->HostBackupWorkRect; + inner_window->ParentWorkRect = temp_data->HostBackupParentWorkRect; + inner_window->SkipItems = table->HostSkipItems; + outer_window->DC.CursorPos = table->OuterRect.Min; + outer_window->DC.ItemWidth = temp_data->HostBackupItemWidth; + outer_window->DC.ItemWidthStack.Size = temp_data->HostBackupItemWidthStackSize; + outer_window->DC.ColumnsOffset = temp_data->HostBackupColumnsOffset; + + // Layout in outer window + // (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding + // CursorPosPrevLine and CursorMaxPos manually. That should be a more general layout feature, see same problem e.g. #3414) + if (inner_window != outer_window) + { + EndChild(); + } + else + { + ItemSize(table->OuterRect.GetSize()); + ItemAdd(table->OuterRect, 0); + } + + // Override declared contents width/height to enable auto-resize while not needlessly adding a scrollbar + if (table->Flags & ImGuiTableFlags_NoHostExtendX) + { + // FIXME-TABLE: Could we remove this section? + // ColumnsAutoFitWidth may be one frame ahead here since for Fixed+NoResize is calculated from latest contents + IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0); + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth); + } + else if (temp_data->UserOuterSize.x <= 0.0f) + { + const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f; + outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x); + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth)); + } + else + { + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x); + } + if (temp_data->UserOuterSize.y <= 0.0f) + { + const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f; + outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y); + outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y)); + } + else + { + // OuterRect.Max.y may already have been pushed downward from the initial value (unless ImGuiTableFlags_NoHostExtendY is set) + outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, table->OuterRect.Max.y); + } + + // Save settings + if (table->IsSettingsDirty) + TableSaveSettings(table); + table->IsInitializing = false; + + // Clear or restore current table, if any + IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table); + IM_ASSERT(g.TablesTempDataStacked > 0); + temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL; + g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL; + if (g.CurrentTable) + { + g.CurrentTable->TempData = temp_data; + g.CurrentTable->DrawSplitter = &temp_data->DrawSplitter; + } + outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1; +} + +// See "COLUMN SIZING POLICIES" comments at the top of this file +// If (init_width_or_weight <= 0.0f) it is ignored +void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!"); + IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!"); + IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()"); + if (table->DeclColumnsCount >= table->ColumnsCount) + { + IM_ASSERT_USER_ERROR(table->DeclColumnsCount < table->ColumnsCount, "Called TableSetupColumn() too many times!"); + return; + } + + ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount]; + table->DeclColumnsCount++; + + // Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa. + // Give a grace to users of ImGuiTableFlags_ScrollX. + if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0) + IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column."); + + // When passing a width automatically enforce WidthFixed policy + // (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable) + if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f) + if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame) + flags |= ImGuiTableColumnFlags_WidthFixed; + + TableSetupColumnFlags(table, column, flags); + column->UserID = user_id; + flags = column->Flags; + + // Initialize defaults + column->InitStretchWeightOrWidth = init_width_or_weight; + if (table->IsInitializing) + { + // Init width or weight + if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f) + { + if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) + column->WidthRequest = init_width_or_weight; + if (flags & ImGuiTableColumnFlags_WidthStretch) + column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f; + + // Disable auto-fit if an explicit width/weight has been specified + if (init_width_or_weight > 0.0f) + column->AutoFitQueue = 0x00; + } + + // Init default visibility/sort state + if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0) + column->IsUserEnabled = column->IsUserEnabledNextFrame = false; + if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0) + { + column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs. + column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending); + } + } + + // Store name (append with zero-terminator in contiguous buffer) + column->NameOffset = -1; + if (label != NULL && label[0] != 0) + { + column->NameOffset = (ImS16)table->ColumnsNames.size(); + table->ColumnsNames.append(label, label + strlen(label) + 1); + } +} + +// [Public] +void ImGui::TableSetupScrollFreeze(int columns, int rows) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!"); + IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!"); + IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS); + IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit + + table->FreezeColumnsRequest = (table->Flags & ImGuiTableFlags_ScrollX) ? (ImGuiTableColumnIdx)ImMin(columns, table->ColumnsCount) : 0; + table->FreezeColumnsCount = (table->InnerWindow->Scroll.x != 0.0f) ? table->FreezeColumnsRequest : 0; + table->FreezeRowsRequest = (table->Flags & ImGuiTableFlags_ScrollY) ? (ImGuiTableColumnIdx)rows : 0; + table->FreezeRowsCount = (table->InnerWindow->Scroll.y != 0.0f) ? table->FreezeRowsRequest : 0; + table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b + + // Ensure frozen columns are ordered in their section. We still allow multiple frozen columns to be reordered. + // FIXME-TABLE: This work for preserving 2143 into 21|43. How about 4321 turning into 21|43? (preserve relative order in each section) + for (int column_n = 0; column_n < table->FreezeColumnsRequest; column_n++) + { + int order_n = table->DisplayOrderToIndex[column_n]; + if (order_n != column_n && order_n >= table->FreezeColumnsRequest) + { + ImSwap(table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder, table->Columns[table->DisplayOrderToIndex[column_n]].DisplayOrder); + ImSwap(table->DisplayOrderToIndex[order_n], table->DisplayOrderToIndex[column_n]); + } + } +} + +//----------------------------------------------------------------------------- +// [SECTION] Tables: Simple accessors +//----------------------------------------------------------------------------- +// - TableGetColumnCount() +// - TableGetColumnName() +// - TableGetColumnName() [Internal] +// - TableSetColumnEnabled() +// - TableGetColumnFlags() +// - TableGetCellBgRect() [Internal] +// - TableGetColumnResizeID() [Internal] +// - TableGetHoveredColumn() [Internal] +// - TableSetBgColor() +//----------------------------------------------------------------------------- + +int ImGui::TableGetColumnCount() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + return table ? table->ColumnsCount : 0; +} + +const char* ImGui::TableGetColumnName(int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return NULL; + if (column_n < 0) + column_n = table->CurrentColumn; + return TableGetColumnName(table, column_n); +} + +const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n) +{ + if (table->IsLayoutLocked == false && column_n >= table->DeclColumnsCount) + return ""; // NameOffset is invalid at this point + const ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->NameOffset == -1) + return ""; + return &table->ColumnsNames.Buf[column->NameOffset]; +} + +// Change user accessible enabled/disabled state of a column (often perceived as "showing/hiding" from users point of view) +// Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody) +// - Require table to have the ImGuiTableFlags_Hideable flag because we are manipulating user accessible state. +// - Request will be applied during next layout, which happens on the first call to TableNextRow() after BeginTable(). +// - For the getter you can test (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled) != 0. +// - Alternative: the ImGuiTableColumnFlags_Disabled is an overriding/master disable flag which will also hide the column from context menu. +void ImGui::TableSetColumnEnabled(int column_n, bool enabled) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL); + if (!table) + return; + IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above + if (column_n < 0) + column_n = table->CurrentColumn; + IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount); + ImGuiTableColumn* column = &table->Columns[column_n]; + column->IsUserEnabledNextFrame = enabled; +} + +// We allow querying for an extra column in order to poll the IsHovered state of the right-most section +ImGuiTableColumnFlags ImGui::TableGetColumnFlags(int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return ImGuiTableColumnFlags_None; + if (column_n < 0) + column_n = table->CurrentColumn; + if (column_n == table->ColumnsCount) + return (table->HoveredColumnBody == column_n) ? ImGuiTableColumnFlags_IsHovered : ImGuiTableColumnFlags_None; + return table->Columns[column_n].Flags; +} + +// Return the cell rectangle based on currently known height. +// - Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations. +// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it, or in TableEndRow() when we locked that height. +// - Important: if ImGuiTableFlags_PadOuterX is set but ImGuiTableFlags_PadInnerX is not set, the outer-most left and right +// columns report a small offset so their CellBgRect can extend up to the outer border. +// FIXME: But the rendering code in TableEndRow() nullifies that with clamping required for scrolling. +ImRect ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n) +{ + const ImGuiTableColumn* column = &table->Columns[column_n]; + float x1 = column->MinX; + float x2 = column->MaxX; + //if (column->PrevEnabledColumn == -1) + // x1 -= table->OuterPaddingX; + //if (column->NextEnabledColumn == -1) + // x2 += table->OuterPaddingX; + x1 = ImMax(x1, table->WorkRect.Min.x); + x2 = ImMin(x2, table->WorkRect.Max.x); + return ImRect(x1, table->RowPosY1, x2, table->RowPosY2); +} + +// Return the resizing ID for the right-side of the given column. +ImGuiID ImGui::TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no) +{ + IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount); + ImGuiID id = table->ID + 1 + (instance_no * table->ColumnsCount) + column_n; + return id; +} + +// Return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. +int ImGui::TableGetHoveredColumn() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return -1; + return (int)table->HoveredColumnBody; +} + +void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(target != ImGuiTableBgTarget_None); + + if (color == IM_COL32_DISABLE) + color = 0; + + // We cannot draw neither the cell or row background immediately as we don't know the row height at this point in time. + switch (target) + { + case ImGuiTableBgTarget_CellBg: + { + if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard + return; + if (column_n == -1) + column_n = table->CurrentColumn; + if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) + return; + if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n) + table->RowCellDataCurrent++; + ImGuiTableCellData* cell_data = &table->RowCellData[table->RowCellDataCurrent]; + cell_data->BgColor = color; + cell_data->Column = (ImGuiTableColumnIdx)column_n; + break; + } + case ImGuiTableBgTarget_RowBg0: + case ImGuiTableBgTarget_RowBg1: + { + if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard + return; + IM_ASSERT(column_n == -1); + int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0; + table->RowBgColor[bg_idx] = color; + break; + } + default: + IM_ASSERT(0); + } +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Row changes +//------------------------------------------------------------------------- +// - TableGetRowIndex() +// - TableNextRow() +// - TableBeginRow() [Internal] +// - TableEndRow() [Internal] +//------------------------------------------------------------------------- + +// [Public] Note: for row coloring we use ->RowBgColorCounter which is the same value without counting header rows +int ImGui::TableGetRowIndex() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return 0; + return table->CurrentRow; +} + +// [Public] Starts into the first cell of a new row +void ImGui::TableNextRow(ImGuiTableRowFlags row_flags, float row_min_height) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + + if (!table->IsLayoutLocked) + TableUpdateLayout(table); + if (table->IsInsideRow) + TableEndRow(table); + + table->LastRowFlags = table->RowFlags; + table->RowFlags = row_flags; + table->RowMinHeight = row_min_height; + TableBeginRow(table); + + // We honor min_row_height requested by user, but cannot guarantee per-row maximum height, + // because that would essentially require a unique clipping rectangle per-cell. + table->RowPosY2 += table->CellPaddingY * 2.0f; + table->RowPosY2 = ImMax(table->RowPosY2, table->RowPosY1 + row_min_height); + + // Disable output until user calls TableNextColumn() + table->InnerWindow->SkipItems = true; +} + +// [Internal] Called by TableNextRow() +void ImGui::TableBeginRow(ImGuiTable* table) +{ + ImGuiWindow* window = table->InnerWindow; + IM_ASSERT(!table->IsInsideRow); + + // New row + table->CurrentRow++; + table->CurrentColumn = -1; + table->RowBgColor[0] = table->RowBgColor[1] = IM_COL32_DISABLE; + table->RowCellDataCurrent = -1; + table->IsInsideRow = true; + + // Begin frozen rows + float next_y1 = table->RowPosY2; + if (table->CurrentRow == 0 && table->FreezeRowsCount > 0) + next_y1 = window->DC.CursorPos.y = table->OuterRect.Min.y; + + table->RowPosY1 = table->RowPosY2 = next_y1; + table->RowTextBaseline = 0.0f; + table->RowIndentOffsetX = window->DC.Indent.x - table->HostIndentX; // Lock indent + window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.CursorMaxPos.y = next_y1; + + // Making the header BG color non-transparent will allow us to overlay it multiple times when handling smooth dragging. + if (table->RowFlags & ImGuiTableRowFlags_Headers) + { + TableSetBgColor(ImGuiTableBgTarget_RowBg0, GetColorU32(ImGuiCol_TableHeaderBg)); + if (table->CurrentRow == 0) + table->IsUsingHeaders = true; + } +} + +// [Internal] Called by TableNextRow() +void ImGui::TableEndRow(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(window == table->InnerWindow); + IM_ASSERT(table->IsInsideRow); + + if (table->CurrentColumn != -1) + TableEndCell(table); + + // Logging + if (g.LogEnabled) + LogRenderedText(NULL, "|"); + + // Position cursor at the bottom of our row so it can be used for e.g. clipping calculation. However it is + // likely that the next call to TableBeginCell() will reposition the cursor to take account of vertical padding. + window->DC.CursorPos.y = table->RowPosY2; + + // Row background fill + const float bg_y1 = table->RowPosY1; + const float bg_y2 = table->RowPosY2; + const bool unfreeze_rows_actual = (table->CurrentRow + 1 == table->FreezeRowsCount); + const bool unfreeze_rows_request = (table->CurrentRow + 1 == table->FreezeRowsRequest); + if (table->CurrentRow == 0) + table->LastFirstRowHeight = bg_y2 - bg_y1; + + const bool is_visible = (bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y); + if (is_visible) + { + // Decide of background color for the row + ImU32 bg_col0 = 0; + ImU32 bg_col1 = 0; + if (table->RowBgColor[0] != IM_COL32_DISABLE) + bg_col0 = table->RowBgColor[0]; + else if (table->Flags & ImGuiTableFlags_RowBg) + bg_col0 = GetColorU32((table->RowBgColorCounter & 1) ? ImGuiCol_TableRowBgAlt : ImGuiCol_TableRowBg); + if (table->RowBgColor[1] != IM_COL32_DISABLE) + bg_col1 = table->RowBgColor[1]; + + // Decide of top border color + ImU32 border_col = 0; + const float border_size = TABLE_BORDER_SIZE; + if (table->CurrentRow > 0 || table->InnerWindow == table->OuterWindow) + if (table->Flags & ImGuiTableFlags_BordersInnerH) + border_col = (table->LastRowFlags & ImGuiTableRowFlags_Headers) ? table->BorderColorStrong : table->BorderColorLight; + + const bool draw_cell_bg_color = table->RowCellDataCurrent >= 0; + const bool draw_strong_bottom_border = unfreeze_rows_actual; + if ((bg_col0 | bg_col1 | border_col) != 0 || draw_strong_bottom_border || draw_cell_bg_color) + { + // In theory we could call SetWindowClipRectBeforeSetChannel() but since we know TableEndRow() is + // always followed by a change of clipping rectangle we perform the smallest overwrite possible here. + if ((table->Flags & ImGuiTableFlags_NoClip) == 0) + window->DrawList->_CmdHeader.ClipRect = table->Bg0ClipRectForDrawCmd.ToVec4(); + table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0); + } + + // Draw row background + // We soft/cpu clip this so all backgrounds and borders can share the same clipping rectangle + if (bg_col0 || bg_col1) + { + ImRect row_rect(table->WorkRect.Min.x, bg_y1, table->WorkRect.Max.x, bg_y2); + row_rect.ClipWith(table->BgClipRect); + if (bg_col0 != 0 && row_rect.Min.y < row_rect.Max.y) + window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col0); + if (bg_col1 != 0 && row_rect.Min.y < row_rect.Max.y) + window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col1); + } + + // Draw cell background color + if (draw_cell_bg_color) + { + ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCurrent]; + for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++) + { + // As we render the BG here we need to clip things (for layout we would not) + // FIXME: This cancels the OuterPadding addition done by TableGetCellBgRect(), need to keep it while rendering correctly while scrolling. + const ImGuiTableColumn* column = &table->Columns[cell_data->Column]; + ImRect cell_bg_rect = TableGetCellBgRect(table, cell_data->Column); + cell_bg_rect.ClipWith(table->BgClipRect); + cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling + cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX); + window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); + } + } + + // Draw top border + if (border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y) + window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y1), ImVec2(table->BorderX2, bg_y1), border_col, border_size); + + // Draw bottom border at the row unfreezing mark (always strong) + if (draw_strong_bottom_border && bg_y2 >= table->BgClipRect.Min.y && bg_y2 < table->BgClipRect.Max.y) + window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size); + } + + // End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle) + // We need to do that in TableEndRow() instead of TableBeginRow() so the list clipper can mark end of row and + // get the new cursor position. + if (unfreeze_rows_request) + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + column->NavLayerCurrent = (ImS8)((column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); + } + if (unfreeze_rows_actual) + { + IM_ASSERT(table->IsUnfrozenRows == false); + table->IsUnfrozenRows = true; + + // BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect + float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y); + table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y); + table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y; + table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen; + IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y); + + float row_height = table->RowPosY2 - table->RowPosY1; + table->RowPosY2 = window->DC.CursorPos.y = table->WorkRect.Min.y + table->RowPosY2 - table->OuterRect.Min.y; + table->RowPosY1 = table->RowPosY2 - row_height; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + column->DrawChannelCurrent = column->DrawChannelUnfrozen; + column->ClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y; + } + + // Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y + SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect); + table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent); + } + + if (!(table->RowFlags & ImGuiTableRowFlags_Headers)) + table->RowBgColorCounter++; + table->IsInsideRow = false; +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Columns changes +//------------------------------------------------------------------------- +// - TableGetColumnIndex() +// - TableSetColumnIndex() +// - TableNextColumn() +// - TableBeginCell() [Internal] +// - TableEndCell() [Internal] +//------------------------------------------------------------------------- + +int ImGui::TableGetColumnIndex() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return 0; + return table->CurrentColumn; +} + +// [Public] Append into a specific column +bool ImGui::TableSetColumnIndex(int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return false; + + if (table->CurrentColumn != column_n) + { + if (table->CurrentColumn != -1) + TableEndCell(table); + IM_ASSERT(column_n >= 0 && table->ColumnsCount); + TableBeginCell(table, column_n); + } + + // Return whether the column is visible. User may choose to skip submitting items based on this return value, + // however they shouldn't skip submitting for columns that may have the tallest contribution to row height. + return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; +} + +// [Public] Append into the next column, wrap and create a new row when already on last column +bool ImGui::TableNextColumn() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (!table) + return false; + + if (table->IsInsideRow && table->CurrentColumn + 1 < table->ColumnsCount) + { + if (table->CurrentColumn != -1) + TableEndCell(table); + TableBeginCell(table, table->CurrentColumn + 1); + } + else + { + TableNextRow(); + TableBeginCell(table, 0); + } + + // Return whether the column is visible. User may choose to skip submitting items based on this return value, + // however they shouldn't skip submitting for columns that may have the tallest contribution to row height. + int column_n = table->CurrentColumn; + return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; +} + + +// [Internal] Called by TableSetColumnIndex()/TableNextColumn() +// This is called very frequently, so we need to be mindful of unnecessary overhead. +// FIXME-TABLE FIXME-OPT: Could probably shortcut some things for non-active or clipped columns. +void ImGui::TableBeginCell(ImGuiTable* table, int column_n) +{ + ImGuiTableColumn* column = &table->Columns[column_n]; + ImGuiWindow* window = table->InnerWindow; + table->CurrentColumn = column_n; + + // Start position is roughly ~~ CellRect.Min + CellPadding + Indent + float start_x = column->WorkMinX; + if (column->Flags & ImGuiTableColumnFlags_IndentEnable) + start_x += table->RowIndentOffsetX; // ~~ += window.DC.Indent.x - table->HostIndentX, except we locked it for the row. + + window->DC.CursorPos.x = start_x; + window->DC.CursorPos.y = table->RowPosY1 + table->CellPaddingY; + window->DC.CursorMaxPos.x = window->DC.CursorPos.x; + window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x; // FIXME-WORKRECT + window->DC.CurrLineTextBaseOffset = table->RowTextBaseline; + window->DC.NavLayerCurrent = (ImGuiNavLayer)column->NavLayerCurrent; + + window->WorkRect.Min.y = window->DC.CursorPos.y; + window->WorkRect.Min.x = column->WorkMinX; + window->WorkRect.Max.x = column->WorkMaxX; + window->DC.ItemWidth = column->ItemWidth; + + // To allow ImGuiListClipper to function we propagate our row height + if (!column->IsEnabled) + window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, table->RowPosY2); + + window->SkipItems = column->IsSkipItems; + if (column->IsSkipItems) + { + ImGuiContext& g = *GImGui; + g.LastItemData.ID = 0; + g.LastItemData.StatusFlags = 0; + } + + if (table->Flags & ImGuiTableFlags_NoClip) + { + // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed. + table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP); + //IM_ASSERT(table->DrawSplitter._Current == TABLE_DRAW_CHANNEL_NOCLIP); + } + else + { + // FIXME-TABLE: Could avoid this if draw channel is dummy channel? + SetWindowClipRectBeforeSetChannel(window, column->ClipRect); + table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); + } + + // Logging + ImGuiContext& g = *GImGui; + if (g.LogEnabled && !column->IsSkipItems) + { + LogRenderedText(&window->DC.CursorPos, "|"); + g.LogLinePosY = FLT_MAX; + } +} + +// [Internal] Called by TableNextRow()/TableSetColumnIndex()/TableNextColumn() +void ImGui::TableEndCell(ImGuiTable* table) +{ + ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; + ImGuiWindow* window = table->InnerWindow; + + // Report maximum position so we can infer content size per column. + float* p_max_pos_x; + if (table->RowFlags & ImGuiTableRowFlags_Headers) + p_max_pos_x = &column->ContentMaxXHeadersUsed; // Useful in case user submit contents in header row that is not a TableHeader() call + else + p_max_pos_x = table->IsUnfrozenRows ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen; + *p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x); + table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY); + column->ItemWidth = window->DC.ItemWidth; + + // Propagate text baseline for the entire row + // FIXME-TABLE: Here we propagate text baseline from the last line of the cell.. instead of the first one. + table->RowTextBaseline = ImMax(table->RowTextBaseline, window->DC.PrevLineTextBaseOffset); +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Columns width management +//------------------------------------------------------------------------- +// - TableGetMaxColumnWidth() [Internal] +// - TableGetColumnWidthAuto() [Internal] +// - TableSetColumnWidth() +// - TableSetColumnWidthAutoSingle() [Internal] +// - TableSetColumnWidthAutoAll() [Internal] +// - TableUpdateColumnsWeightFromWidth() [Internal] +//------------------------------------------------------------------------- + +// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis. +float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n) +{ + const ImGuiTableColumn* column = &table->Columns[column_n]; + float max_width = FLT_MAX; + const float min_column_distance = table->MinColumnWidth + table->CellPaddingX * 2.0f + table->CellSpacingX1 + table->CellSpacingX2; + if (table->Flags & ImGuiTableFlags_ScrollX) + { + // Frozen columns can't reach beyond visible width else scrolling will naturally break. + // (we use DisplayOrder as within a set of multiple frozen column reordering is possible) + if (column->DisplayOrder < table->FreezeColumnsRequest) + { + max_width = (table->InnerClipRect.Max.x - (table->FreezeColumnsRequest - column->DisplayOrder) * min_column_distance) - column->MinX; + max_width = max_width - table->OuterPaddingX - table->CellPaddingX - table->CellSpacingX2; + } + } + else if ((table->Flags & ImGuiTableFlags_NoKeepColumnsVisible) == 0) + { + // If horizontal scrolling if disabled, we apply a final lossless shrinking of columns in order to make + // sure they are all visible. Because of this we also know that all of the columns will always fit in + // table->WorkRect and therefore in table->InnerRect (because ScrollX is off) + // FIXME-TABLE: This is solved incorrectly but also quite a difficult problem to fix as we also want ClipRect width to match. + // See "table_width_distrib" and "table_width_keep_visible" tests + max_width = table->WorkRect.Max.x - (table->ColumnsEnabledCount - column->IndexWithinEnabledSet - 1) * min_column_distance - column->MinX; + //max_width -= table->CellSpacingX1; + max_width -= table->CellSpacingX2; + max_width -= table->CellPaddingX * 2.0f; + max_width -= table->OuterPaddingX; + } + return max_width; +} + +// Note this is meant to be stored in column->WidthAuto, please generally use the WidthAuto field +float ImGui::TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column) +{ + const float content_width_body = ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX; + const float content_width_headers = column->ContentMaxXHeadersIdeal - column->WorkMinX; + float width_auto = content_width_body; + if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth)) + width_auto = ImMax(width_auto, content_width_headers); + + // Non-resizable fixed columns preserve their requested width + if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f) + if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize)) + width_auto = column->InitStretchWeightOrWidth; + + return ImMax(width_auto, table->MinColumnWidth); +} + +// 'width' = inner column width, without padding +void ImGui::TableSetColumnWidth(int column_n, float width) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && table->IsLayoutLocked == false); + IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount); + ImGuiTableColumn* column_0 = &table->Columns[column_n]; + float column_0_width = width; + + // Apply constraints early + // Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded) + IM_ASSERT(table->MinColumnWidth > 0.0f); + const float min_width = table->MinColumnWidth; + const float max_width = ImMax(min_width, TableGetMaxColumnWidth(table, column_n)); + column_0_width = ImClamp(column_0_width, min_width, max_width); + if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width) + return; + + //IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthGiven, column_0_width); + ImGuiTableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &table->Columns[column_0->NextEnabledColumn] : NULL; + + // In this surprisingly not simple because of how we support mixing Fixed and multiple Stretch columns. + // - All fixed: easy. + // - All stretch: easy. + // - One or more fixed + one stretch: easy. + // - One or more fixed + more than one stretch: tricky. + // Qt when manual resize is enabled only support a single _trailing_ stretch column. + + // When forwarding resize from Wn| to Fn+1| we need to be considerate of the _NoResize flag on Fn+1. + // FIXME-TABLE: Find a way to rewrite all of this so interactions feel more consistent for the user. + // Scenarios: + // - F1 F2 F3 resize from F1| or F2| --> ok: alter ->WidthRequested of Fixed column. Subsequent columns will be offset. + // - F1 F2 F3 resize from F3| --> ok: alter ->WidthRequested of Fixed column. If active, ScrollX extent can be altered. + // - F1 F2 W3 resize from F1| or F2| --> ok: alter ->WidthRequested of Fixed column. If active, ScrollX extent can be altered, but it doesn't make much sense as the Stretch column will always be minimal size. + // - F1 F2 W3 resize from W3| --> ok: no-op (disabled by Resize Rule 1) + // - W1 W2 W3 resize from W1| or W2| --> ok + // - W1 W2 W3 resize from W3| --> ok: no-op (disabled by Resize Rule 1) + // - W1 F2 F3 resize from F3| --> ok: no-op (disabled by Resize Rule 1) + // - W1 F2 resize from F2| --> ok: no-op (disabled by Resize Rule 1) + // - W1 W2 F3 resize from W1| or W2| --> ok + // - W1 F2 W3 resize from W1| or F2| --> ok + // - F1 W2 F3 resize from W2| --> ok + // - F1 W3 F2 resize from W3| --> ok + // - W1 F2 F3 resize from W1| --> ok: equivalent to resizing |F2. F3 will not move. + // - W1 F2 F3 resize from F2| --> ok + // All resizes from a Wx columns are locking other columns. + + // Possible improvements: + // - W1 W2 W3 resize W1| --> to not be stuck, both W2 and W3 would stretch down. Seems possible to fix. Would be most beneficial to simplify resize of all-weighted columns. + // - W3 F1 F2 resize W3| --> to not be stuck past F1|, both F1 and F2 would need to stretch down, which would be lossy or ambiguous. Seems hard to fix. + + // [Resize Rule 1] Can't resize from right of right-most visible column if there is any Stretch column. Implemented in TableUpdateLayout(). + + // If we have all Fixed columns OR resizing a Fixed column that doesn't come after a Stretch one, we can do an offsetting resize. + // This is the preferred resize path + if (column_0->Flags & ImGuiTableColumnFlags_WidthFixed) + if (!column_1 || table->LeftMostStretchedColumn == -1 || table->Columns[table->LeftMostStretchedColumn].DisplayOrder >= column_0->DisplayOrder) + { + column_0->WidthRequest = column_0_width; + table->IsSettingsDirty = true; + return; + } + + // We can also use previous column if there's no next one (this is used when doing an auto-fit on the right-most stretch column) + if (column_1 == NULL) + column_1 = (column_0->PrevEnabledColumn != -1) ? &table->Columns[column_0->PrevEnabledColumn] : NULL; + if (column_1 == NULL) + return; + + // Resizing from right-side of a Stretch column before a Fixed column forward sizing to left-side of fixed column. + // (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b) + float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width); + column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width; + IM_ASSERT(column_0_width > 0.0f && column_1_width > 0.0f); + column_0->WidthRequest = column_0_width; + column_1->WidthRequest = column_1_width; + if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch) + TableUpdateColumnsWeightFromWidth(table); + table->IsSettingsDirty = true; +} + +// Disable clipping then auto-fit, will take 2 frames +// (we don't take a shortcut for unclipped columns to reduce inconsistencies when e.g. resizing multiple columns) +void ImGui::TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n) +{ + // Single auto width uses auto-fit + ImGuiTableColumn* column = &table->Columns[column_n]; + if (!column->IsEnabled) + return; + column->CannotSkipItemsQueue = (1 << 0); + table->AutoFitSingleColumn = (ImGuiTableColumnIdx)column_n; +} + +void ImGui::TableSetColumnWidthAutoAll(ImGuiTable* table) +{ + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (!column->IsEnabled && !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) // Cannot reset weight of hidden stretch column + continue; + column->CannotSkipItemsQueue = (1 << 0); + column->AutoFitQueue = (1 << 1); + } +} + +void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table) +{ + IM_ASSERT(table->LeftMostStretchedColumn != -1 && table->RightMostStretchedColumn != -1); + + // Measure existing quantity + float visible_weight = 0.0f; + float visible_width = 0.0f; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) + continue; + IM_ASSERT(column->StretchWeight > 0.0f); + visible_weight += column->StretchWeight; + visible_width += column->WidthRequest; + } + IM_ASSERT(visible_weight > 0.0f && visible_width > 0.0f); + + // Apply new weights + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch)) + continue; + column->StretchWeight = (column->WidthRequest / visible_width) * visible_weight; + IM_ASSERT(column->StretchWeight > 0.0f); + } +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Drawing +//------------------------------------------------------------------------- +// - TablePushBackgroundChannel() [Internal] +// - TablePopBackgroundChannel() [Internal] +// - TableSetupDrawChannels() [Internal] +// - TableMergeDrawChannels() [Internal] +// - TableDrawBorders() [Internal] +//------------------------------------------------------------------------- + +// Bg2 is used by Selectable (and possibly other widgets) to render to the background. +// Unlike our Bg0/1 channel which we uses for RowBg/CellBg/Borders and where we guarantee all shapes to be CPU-clipped, the Bg2 channel being widgets-facing will rely on regular ClipRect. +void ImGui::TablePushBackgroundChannel() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiTable* table = g.CurrentTable; + + // Optimization: avoid SetCurrentChannel() + PushClipRect() + table->HostBackupInnerClipRect = window->ClipRect; + SetWindowClipRectBeforeSetChannel(window, table->Bg2ClipRectForDrawCmd); + table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Bg2DrawChannelCurrent); +} + +void ImGui::TablePopBackgroundChannel() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiTable* table = g.CurrentTable; + ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; + + // Optimization: avoid PopClipRect() + SetCurrentChannel() + SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect); + table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); +} + +// Allocate draw channels. Called by TableUpdateLayout() +// - We allocate them following storage order instead of display order so reordering columns won't needlessly +// increase overall dormant memory cost. +// - We isolate headers draw commands in their own channels instead of just altering clip rects. +// This is in order to facilitate merging of draw commands. +// - After crossing FreezeRowsCount, all columns see their current draw channel changed to a second set of channels. +// - We only use the dummy draw channel so we can push a null clipping rectangle into it without affecting other +// channels, while simplifying per-row/per-cell overhead. It will be empty and discarded when merged. +// - We allocate 1 or 2 background draw channels. This is because we know TablePushBackgroundChannel() is only used for +// horizontal spanning. If we allowed vertical spanning we'd need one background draw channel per merge group (1-4). +// Draw channel allocation (before merging): +// - NoClip --> 2+D+1 channels: bg0/1 + bg2 + foreground (same clip rect == always 1 draw call) +// - Clip --> 2+D+N channels +// - FreezeRows --> 2+D+N*2 (unless scrolling value is zero) +// - FreezeRows || FreezeColunns --> 3+D+N*2 (unless scrolling value is zero) +// Where D is 1 if any column is clipped or hidden (dummy channel) otherwise 0. +void ImGui::TableSetupDrawChannels(ImGuiTable* table) +{ + const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1; + const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount; + const int channels_for_bg = 1 + 1 * freeze_row_multiplier; + const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0; + const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy; + table->DrawSplitter->Split(table->InnerWindow->DrawList, channels_total); + table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1); + table->Bg2DrawChannelCurrent = TABLE_DRAW_CHANNEL_BG2_FROZEN; + table->Bg2DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)((table->FreezeRowsCount > 0) ? 2 + channels_for_row : TABLE_DRAW_CHANNEL_BG2_FROZEN); + + int draw_channel_current = 2; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->IsVisibleX && column->IsVisibleY) + { + column->DrawChannelFrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current); + column->DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current + (table->FreezeRowsCount > 0 ? channels_for_row + 1 : 0)); + if (!(table->Flags & ImGuiTableFlags_NoClip)) + draw_channel_current++; + } + else + { + column->DrawChannelFrozen = column->DrawChannelUnfrozen = table->DummyDrawChannel; + } + column->DrawChannelCurrent = column->DrawChannelFrozen; + } + + // Initial draw cmd starts with a BgClipRect that matches the one of its host, to facilitate merge draw commands by default. + // All our cell highlight are manually clipped with BgClipRect. When unfreezing it will be made smaller to fit scrolling rect. + // (This technically isn't part of setting up draw channels, but is reasonably related to be done here) + table->BgClipRect = table->InnerClipRect; + table->Bg0ClipRectForDrawCmd = table->OuterWindow->ClipRect; + table->Bg2ClipRectForDrawCmd = table->HostClipRect; + IM_ASSERT(table->BgClipRect.Min.y <= table->BgClipRect.Max.y); +} + +// This function reorder draw channels based on matching clip rectangle, to facilitate merging them. Called by EndTable(). +// For simplicity we call it TableMergeDrawChannels() but in fact it only reorder channels + overwrite ClipRect, +// actual merging is done by table->DrawSplitter.Merge() which is called right after TableMergeDrawChannels(). +// +// Columns where the contents didn't stray off their local clip rectangle can be merged. To achieve +// this we merge their clip rect and make them contiguous in the channel list, so they can be merged +// by the call to DrawSplitter.Merge() following to the call to this function. +// We reorder draw commands by arranging them into a maximum of 4 distinct groups: +// +// 1 group: 2 groups: 2 groups: 4 groups: +// [ 0. ] no freeze [ 0. ] row freeze [ 01 ] col freeze [ 01 ] row+col freeze +// [ .. ] or no scroll [ 2. ] and v-scroll [ .. ] and h-scroll [ 23 ] and v+h-scroll +// +// Each column itself can use 1 channel (row freeze disabled) or 2 channels (row freeze enabled). +// When the contents of a column didn't stray off its limit, we move its channels into the corresponding group +// based on its position (within frozen rows/columns groups or not). +// At the end of the operation our 1-4 groups will each have a ImDrawCmd using the same ClipRect. +// This function assume that each column are pointing to a distinct draw channel, +// otherwise merge_group->ChannelsCount will not match set bit count of merge_group->ChannelsMask. +// +// Column channels will not be merged into one of the 1-4 groups in the following cases: +// - The contents stray off its clipping rectangle (we only compare the MaxX value, not the MinX value). +// Direct ImDrawList calls won't be taken into account by default, if you use them make sure the ImGui:: bounds +// matches, by e.g. calling SetCursorScreenPos(). +// - The channel uses more than one draw command itself. We drop all our attempt at merging stuff here.. +// we could do better but it's going to be rare and probably not worth the hassle. +// Columns for which the draw channel(s) haven't been merged with other will use their own ImDrawCmd. +// +// This function is particularly tricky to understand.. take a breath. +void ImGui::TableMergeDrawChannels(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + ImDrawListSplitter* splitter = table->DrawSplitter; + const bool has_freeze_v = (table->FreezeRowsCount > 0); + const bool has_freeze_h = (table->FreezeColumnsCount > 0); + IM_ASSERT(splitter->_Current == 0); + + // Track which groups we are going to attempt to merge, and which channels goes into each group. + struct MergeGroup + { + ImRect ClipRect; + int ChannelsCount; + ImBitArray ChannelsMask; + + MergeGroup() { ChannelsCount = 0; } + }; + int merge_group_mask = 0x00; + MergeGroup merge_groups[4]; + + // 1. Scan channels and take note of those which can be merged + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) + continue; + ImGuiTableColumn* column = &table->Columns[column_n]; + + const int merge_group_sub_count = has_freeze_v ? 2 : 1; + for (int merge_group_sub_n = 0; merge_group_sub_n < merge_group_sub_count; merge_group_sub_n++) + { + const int channel_no = (merge_group_sub_n == 0) ? column->DrawChannelFrozen : column->DrawChannelUnfrozen; + + // Don't attempt to merge if there are multiple draw calls within the column + ImDrawChannel* src_channel = &splitter->_Channels[channel_no]; + if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0 && src_channel->_CmdBuffer.back().UserCallback != NULL) // Equivalent of PopUnusedDrawCmd() + src_channel->_CmdBuffer.pop_back(); + if (src_channel->_CmdBuffer.Size != 1) + continue; + + // Find out the width of this merge group and check if it will fit in our column + // (note that we assume that rendering didn't stray on the left direction. we should need a CursorMinPos to detect it) + if (!(column->Flags & ImGuiTableColumnFlags_NoClip)) + { + float content_max_x; + if (!has_freeze_v) + content_max_x = ImMax(column->ContentMaxXUnfrozen, column->ContentMaxXHeadersUsed); // No row freeze + else if (merge_group_sub_n == 0) + content_max_x = ImMax(column->ContentMaxXFrozen, column->ContentMaxXHeadersUsed); // Row freeze: use width before freeze + else + content_max_x = column->ContentMaxXUnfrozen; // Row freeze: use width after freeze + if (content_max_x > column->ClipRect.Max.x) + continue; + } + + const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2); + IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS); + MergeGroup* merge_group = &merge_groups[merge_group_n]; + if (merge_group->ChannelsCount == 0) + merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); + merge_group->ChannelsMask.SetBit(channel_no); + merge_group->ChannelsCount++; + merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect); + merge_group_mask |= (1 << merge_group_n); + } + + // Invalidate current draw channel + // (we don't clear DrawChannelFrozen/DrawChannelUnfrozen solely to facilitate debugging/later inspection of data) + column->DrawChannelCurrent = (ImGuiTableDrawChannelIdx)-1; + } + + // [DEBUG] Display merge groups +#if 0 + if (g.IO.KeyShift) + for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++) + { + MergeGroup* merge_group = &merge_groups[merge_group_n]; + if (merge_group->ChannelsCount == 0) + continue; + char buf[32]; + ImFormatString(buf, 32, "MG%d:%d", merge_group_n, merge_group->ChannelsCount); + ImVec2 text_pos = merge_group->ClipRect.Min + ImVec2(4, 4); + ImVec2 text_size = CalcTextSize(buf, NULL); + GetForegroundDrawList()->AddRectFilled(text_pos, text_pos + text_size, IM_COL32(0, 0, 0, 255)); + GetForegroundDrawList()->AddText(text_pos, IM_COL32(255, 255, 0, 255), buf, NULL); + GetForegroundDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 255, 0, 255)); + } +#endif + + // 2. Rewrite channel list in our preferred order + if (merge_group_mask != 0) + { + // We skip channel 0 (Bg0/Bg1) and 1 (Bg2 frozen) from the shuffling since they won't move - see channels allocation in TableSetupDrawChannels(). + const int LEADING_DRAW_CHANNELS = 2; + g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized + ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data; + ImBitArray remaining_mask; // We need 132-bit of storage + remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count); + remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen); + IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN); + int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS); + //ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect; + ImRect host_rect = table->HostClipRect; + for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++) + { + if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount) + { + MergeGroup* merge_group = &merge_groups[merge_group_n]; + ImRect merge_clip_rect = merge_group->ClipRect; + + // Extend outer-most clip limits to match those of host, so draw calls can be merged even if + // outer-most columns have some outer padding offsetting them from their parent ClipRect. + // The principal cases this is dealing with are: + // - On a same-window table (not scrolling = single group), all fitting columns ClipRect -> will extend and match host ClipRect -> will merge + // - Columns can use padding and have left-most ClipRect.Min.x and right-most ClipRect.Max.x != from host ClipRect -> will extend and match host ClipRect -> will merge + // FIXME-TABLE FIXME-WORKRECT: We are wasting a merge opportunity on tables without scrolling if column doesn't fit + // within host clip rect, solely because of the half-padding difference between window->WorkRect and window->InnerClipRect. + if ((merge_group_n & 1) == 0 || !has_freeze_h) + merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, host_rect.Min.x); + if ((merge_group_n & 2) == 0 || !has_freeze_v) + merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, host_rect.Min.y); + if ((merge_group_n & 1) != 0) + merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x); + if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0) + merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y); +#if 0 + GetOverlayDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, 0, 1.0f); + GetOverlayDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200)); + GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200)); +#endif + remaining_count -= merge_group->ChannelsCount; + for (int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++) + remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n]; + for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++) + { + // Copy + overwrite new clip rect + if (!merge_group->ChannelsMask.TestBit(n)) + continue; + merge_group->ChannelsMask.ClearBit(n); + merge_channels_count--; + + ImDrawChannel* channel = &splitter->_Channels[n]; + IM_ASSERT(channel->_CmdBuffer.Size == 1 && merge_clip_rect.Contains(ImRect(channel->_CmdBuffer[0].ClipRect))); + channel->_CmdBuffer[0].ClipRect = merge_clip_rect.ToVec4(); + memcpy(dst_tmp++, channel, sizeof(ImDrawChannel)); + } + } + + // Make sure Bg2DrawChannelUnfrozen appears in the middle of our groups (whereas Bg0/Bg1 and Bg2 frozen are fixed to 0 and 1) + if (merge_group_n == 1 && has_freeze_v) + memcpy(dst_tmp++, &splitter->_Channels[table->Bg2DrawChannelUnfrozen], sizeof(ImDrawChannel)); + } + + // Append unmergeable channels that we didn't reorder at the end of the list + for (int n = 0; n < splitter->_Count && remaining_count != 0; n++) + { + if (!remaining_mask.TestBit(n)) + continue; + ImDrawChannel* channel = &splitter->_Channels[n]; + memcpy(dst_tmp++, channel, sizeof(ImDrawChannel)); + remaining_count--; + } + IM_ASSERT(dst_tmp == g.DrawChannelsTempMergeBuffer.Data + g.DrawChannelsTempMergeBuffer.Size); + memcpy(splitter->_Channels.Data + LEADING_DRAW_CHANNELS, g.DrawChannelsTempMergeBuffer.Data, (splitter->_Count - LEADING_DRAW_CHANNELS) * sizeof(ImDrawChannel)); + } +} + +// FIXME-TABLE: This is a mess, need to redesign how we render borders (as some are also done in TableEndRow) +void ImGui::TableDrawBorders(ImGuiTable* table) +{ + ImGuiWindow* inner_window = table->InnerWindow; + if (!table->OuterWindow->ClipRect.Overlaps(table->OuterRect)) + return; + + ImDrawList* inner_drawlist = inner_window->DrawList; + table->DrawSplitter->SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0); + inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false); + + // Draw inner border and resizing feedback + const float border_size = TABLE_BORDER_SIZE; + const float draw_y1 = table->InnerRect.Min.y; + const float draw_y2_body = table->InnerRect.Max.y; + const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1; + if (table->Flags & ImGuiTableFlags_BordersInnerV) + { + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + { + if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + continue; + + const int column_n = table->DisplayOrderToIndex[order_n]; + ImGuiTableColumn* column = &table->Columns[column_n]; + const bool is_hovered = (table->HoveredColumnBorder == column_n); + const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent); + const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0; + const bool is_frozen_separator = (table->FreezeColumnsCount == order_n + 1); + if (column->MaxX > table->InnerClipRect.Max.x && !is_resized) + continue; + + // Decide whether right-most column is visible + if (column->NextEnabledColumn == -1 && !is_resizable) + if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (table->Flags & ImGuiTableFlags_NoHostExtendX)) + continue; + if (column->MaxX <= column->ClipRect.Min.x) // FIXME-TABLE FIXME-STYLE: Assume BorderSize==1, this is problematic if we want to increase the border size.. + continue; + + // Draw in outer window so right-most column won't be clipped + // Always draw full height border when being resized/hovered, or on the delimitation of frozen column scrolling. + ImU32 col; + float draw_y2; + if (is_hovered || is_resized || is_frozen_separator) + { + draw_y2 = draw_y2_body; + col = is_resized ? GetColorU32(ImGuiCol_SeparatorActive) : is_hovered ? GetColorU32(ImGuiCol_SeparatorHovered) : table->BorderColorStrong; + } + else + { + draw_y2 = (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? draw_y2_head : draw_y2_body; + col = (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? table->BorderColorStrong : table->BorderColorLight; + } + + if (draw_y2 > draw_y1) + inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), col, border_size); + } + } + + // Draw outer border + // FIXME: could use AddRect or explicit VLine/HLine helper? + if (table->Flags & ImGuiTableFlags_BordersOuter) + { + // Display outer border offset by 1 which is a simple way to display it without adding an extra draw call + // (Without the offset, in outer_window it would be rendered behind cells, because child windows are above their + // parent. In inner_window, it won't reach out over scrollbars. Another weird solution would be to display part + // of it in inner window, and the part that's over scrollbars in the outer window..) + // Either solution currently won't allow us to use a larger border size: the border would clipped. + const ImRect outer_border = table->OuterRect; + const ImU32 outer_col = table->BorderColorStrong; + if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter) + { + inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size); + } + else if (table->Flags & ImGuiTableFlags_BordersOuterV) + { + inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size); + inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size); + } + else if (table->Flags & ImGuiTableFlags_BordersOuterH) + { + inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size); + inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size); + } + } + if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y) + { + // Draw bottom-most row border + const float border_y = table->RowPosY2; + if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y) + inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size); + } + + inner_drawlist->PopClipRect(); +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Sorting +//------------------------------------------------------------------------- +// - TableGetSortSpecs() +// - TableFixColumnSortDirection() [Internal] +// - TableGetColumnNextSortDirection() [Internal] +// - TableSetColumnSortDirection() [Internal] +// - TableSortSpecsSanitize() [Internal] +// - TableSortSpecsBuild() [Internal] +//------------------------------------------------------------------------- + +// Return NULL if no sort specs (most often when ImGuiTableFlags_Sortable is not set) +// You can sort your data again when 'SpecsChanged == true'. It will be true with sorting specs have changed since +// last call, or the first time. +// Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable()! +ImGuiTableSortSpecs* ImGui::TableGetSortSpecs() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL); + + if (!(table->Flags & ImGuiTableFlags_Sortable)) + return NULL; + + // Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths. + if (!table->IsLayoutLocked) + TableUpdateLayout(table); + + TableSortSpecsBuild(table); + + return &table->SortSpecs; +} + +static inline ImGuiSortDirection TableGetColumnAvailSortDirection(ImGuiTableColumn* column, int n) +{ + IM_ASSERT(n < column->SortDirectionsAvailCount); + return (column->SortDirectionsAvailList >> (n << 1)) & 0x03; +} + +// Fix sort direction if currently set on a value which is unavailable (e.g. activating NoSortAscending/NoSortDescending) +void ImGui::TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column) +{ + if (column->SortOrder == -1 || (column->SortDirectionsAvailMask & (1 << column->SortDirection)) != 0) + return; + column->SortDirection = (ImU8)TableGetColumnAvailSortDirection(column, 0); + table->IsSortSpecsDirty = true; +} + +// Calculate next sort direction that would be set after clicking the column +// - If the PreferSortDescending flag is set, we will default to a Descending direction on the first click. +// - Note that the PreferSortAscending flag is never checked, it is essentially the default and therefore a no-op. +IM_STATIC_ASSERT(ImGuiSortDirection_None == 0 && ImGuiSortDirection_Ascending == 1 && ImGuiSortDirection_Descending == 2); +ImGuiSortDirection ImGui::TableGetColumnNextSortDirection(ImGuiTableColumn* column) +{ + IM_ASSERT(column->SortDirectionsAvailCount > 0); + if (column->SortOrder == -1) + return TableGetColumnAvailSortDirection(column, 0); + for (int n = 0; n < 3; n++) + if (column->SortDirection == TableGetColumnAvailSortDirection(column, n)) + return TableGetColumnAvailSortDirection(column, (n + 1) % column->SortDirectionsAvailCount); + IM_ASSERT(0); + return ImGuiSortDirection_None; +} + +// Note that the NoSortAscending/NoSortDescending flags are processed in TableSortSpecsSanitize(), and they may change/revert +// the value of SortDirection. We could technically also do it here but it would be unnecessary and duplicate code. +void ImGui::TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + + if (!(table->Flags & ImGuiTableFlags_SortMulti)) + append_to_sort_specs = false; + if (!(table->Flags & ImGuiTableFlags_SortTristate)) + IM_ASSERT(sort_direction != ImGuiSortDirection_None); + + ImGuiTableColumnIdx sort_order_max = 0; + if (append_to_sort_specs) + for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++) + sort_order_max = ImMax(sort_order_max, table->Columns[other_column_n].SortOrder); + + ImGuiTableColumn* column = &table->Columns[column_n]; + column->SortDirection = (ImU8)sort_direction; + if (column->SortDirection == ImGuiSortDirection_None) + column->SortOrder = -1; + else if (column->SortOrder == -1 || !append_to_sort_specs) + column->SortOrder = append_to_sort_specs ? sort_order_max + 1 : 0; + + for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++) + { + ImGuiTableColumn* other_column = &table->Columns[other_column_n]; + if (other_column != column && !append_to_sort_specs) + other_column->SortOrder = -1; + TableFixColumnSortDirection(table, other_column); + } + table->IsSettingsDirty = true; + table->IsSortSpecsDirty = true; +} + +void ImGui::TableSortSpecsSanitize(ImGuiTable* table) +{ + IM_ASSERT(table->Flags & ImGuiTableFlags_Sortable); + + // Clear SortOrder from hidden column and verify that there's no gap or duplicate. + int sort_order_count = 0; + ImU64 sort_order_mask = 0x00; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->SortOrder != -1 && !column->IsEnabled) + column->SortOrder = -1; + if (column->SortOrder == -1) + continue; + sort_order_count++; + sort_order_mask |= ((ImU64)1 << column->SortOrder); + IM_ASSERT(sort_order_count < (int)sizeof(sort_order_mask) * 8); + } + + const bool need_fix_linearize = ((ImU64)1 << sort_order_count) != (sort_order_mask + 1); + const bool need_fix_single_sort_order = (sort_order_count > 1) && !(table->Flags & ImGuiTableFlags_SortMulti); + if (need_fix_linearize || need_fix_single_sort_order) + { + ImU64 fixed_mask = 0x00; + for (int sort_n = 0; sort_n < sort_order_count; sort_n++) + { + // Fix: Rewrite sort order fields if needed so they have no gap or duplicate. + // (e.g. SortOrder 0 disappeared, SortOrder 1..2 exists --> rewrite then as SortOrder 0..1) + int column_with_smallest_sort_order = -1; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + if ((fixed_mask & ((ImU64)1 << (ImU64)column_n)) == 0 && table->Columns[column_n].SortOrder != -1) + if (column_with_smallest_sort_order == -1 || table->Columns[column_n].SortOrder < table->Columns[column_with_smallest_sort_order].SortOrder) + column_with_smallest_sort_order = column_n; + IM_ASSERT(column_with_smallest_sort_order != -1); + fixed_mask |= ((ImU64)1 << column_with_smallest_sort_order); + table->Columns[column_with_smallest_sort_order].SortOrder = (ImGuiTableColumnIdx)sort_n; + + // Fix: Make sure only one column has a SortOrder if ImGuiTableFlags_MultiSortable is not set. + if (need_fix_single_sort_order) + { + sort_order_count = 1; + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + if (column_n != column_with_smallest_sort_order) + table->Columns[column_n].SortOrder = -1; + break; + } + } + } + + // Fallback default sort order (if no column had the ImGuiTableColumnFlags_DefaultSort flag) + if (sort_order_count == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->IsEnabled && !(column->Flags & ImGuiTableColumnFlags_NoSort)) + { + sort_order_count = 1; + column->SortOrder = 0; + column->SortDirection = (ImU8)TableGetColumnAvailSortDirection(column, 0); + break; + } + } + + table->SortSpecsCount = (ImGuiTableColumnIdx)sort_order_count; +} + +void ImGui::TableSortSpecsBuild(ImGuiTable* table) +{ + bool dirty = table->IsSortSpecsDirty; + if (dirty) + { + TableSortSpecsSanitize(table); + table->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount); + table->SortSpecs.SpecsDirty = true; // Mark as dirty for user + table->IsSortSpecsDirty = false; // Mark as not dirty for us + } + + // Write output + ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data; + if (dirty && sort_specs != NULL) + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + { + ImGuiTableColumn* column = &table->Columns[column_n]; + if (column->SortOrder == -1) + continue; + IM_ASSERT(column->SortOrder < table->SortSpecsCount); + ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder]; + sort_spec->ColumnUserID = column->UserID; + sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n; + sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder; + sort_spec->SortDirection = column->SortDirection; + } + + table->SortSpecs.Specs = sort_specs; + table->SortSpecs.SpecsCount = table->SortSpecsCount; +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Headers +//------------------------------------------------------------------------- +// - TableGetHeaderRowHeight() [Internal] +// - TableHeadersRow() +// - TableHeader() +//------------------------------------------------------------------------- + +float ImGui::TableGetHeaderRowHeight() +{ + // Caring for a minor edge case: + // Calculate row height, for the unlikely case that some labels may be taller than others. + // If we didn't do that, uneven header height would highlight but smaller one before the tallest wouldn't catch input for all height. + // In your custom header row you may omit this all together and just call TableNextRow() without a height... + float row_height = GetTextLineHeight(); + int columns_count = TableGetColumnCount(); + for (int column_n = 0; column_n < columns_count; column_n++) + { + ImGuiTableColumnFlags flags = TableGetColumnFlags(column_n); + if ((flags & ImGuiTableColumnFlags_IsEnabled) && !(flags & ImGuiTableColumnFlags_NoHeaderLabel)) + row_height = ImMax(row_height, CalcTextSize(TableGetColumnName(column_n)).y); + } + row_height += GetStyle().CellPadding.y * 2.0f; + return row_height; +} + +// [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn(). +// The intent is that advanced users willing to create customized headers would not need to use this helper +// and can create their own! For example: TableHeader() may be preceeded by Checkbox() or other custom widgets. +// See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this. +// This code is constructed to not make much use of internal functions, as it is intended to be a template to copy. +// FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public. +void ImGui::TableHeadersRow() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!"); + + // Layout if not already done (this is automatically done by TableNextRow, we do it here solely to facilitate stepping in debugger as it is frequent to step in TableUpdateLayout) + if (!table->IsLayoutLocked) + TableUpdateLayout(table); + + // Open row + const float row_y1 = GetCursorScreenPos().y; + const float row_height = TableGetHeaderRowHeight(); + TableNextRow(ImGuiTableRowFlags_Headers, row_height); + if (table->HostSkipItems) // Merely an optimization, you may skip in your own code. + return; + + const int columns_count = TableGetColumnCount(); + for (int column_n = 0; column_n < columns_count; column_n++) + { + if (!TableSetColumnIndex(column_n)) + continue; + + // Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them) + // - in your own code you may omit the PushID/PopID all-together, provided you know they won't collide + // - table->InstanceCurrent is only >0 when we use multiple BeginTable/EndTable calls with same identifier. + const char* name = (TableGetColumnFlags(column_n) & ImGuiTableColumnFlags_NoHeaderLabel) ? "" : TableGetColumnName(column_n); + PushID(table->InstanceCurrent * table->ColumnsCount + column_n); + TableHeader(name); + PopID(); + } + + // Allow opening popup from the right-most section after the last column. + ImVec2 mouse_pos = ImGui::GetMousePos(); + if (IsMouseReleased(1) && TableGetHoveredColumn() == columns_count) + if (mouse_pos.y >= row_y1 && mouse_pos.y < row_y1 + row_height) + TableOpenContextMenu(-1); // Will open a non-column-specific popup. +} + +// Emit a column header (text + optional sort order) +// We cpu-clip text here so that all columns headers can be merged into a same draw call. +// Note that because of how we cpu-clip and display sorting indicators, you _cannot_ use SameLine() after a TableHeader() +void ImGui::TableHeader(const char* label) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + ImGuiTable* table = g.CurrentTable; + IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!"); + IM_ASSERT(table->CurrentColumn != -1); + const int column_n = table->CurrentColumn; + ImGuiTableColumn* column = &table->Columns[column_n]; + + // Label + if (label == NULL) + label = ""; + const char* label_end = FindRenderedTextEnd(label); + ImVec2 label_size = CalcTextSize(label, label_end, true); + ImVec2 label_pos = window->DC.CursorPos; + + // If we already got a row height, there's use that. + // FIXME-TABLE: Padding problem if the correct outer-padding CellBgRect strays off our ClipRect? + ImRect cell_r = TableGetCellBgRect(table, column_n); + float label_height = ImMax(label_size.y, table->RowMinHeight - table->CellPaddingY * 2.0f); + + // Calculate ideal size for sort order arrow + float w_arrow = 0.0f; + float w_sort_text = 0.0f; + char sort_order_suf[4] = ""; + const float ARROW_SCALE = 0.65f; + if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) + { + w_arrow = ImFloor(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x); + if (column->SortOrder > 0) + { + ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1); + w_sort_text = g.Style.ItemInnerSpacing.x + CalcTextSize(sort_order_suf).x; + } + } + + // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging. + float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow; + column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, column->WorkMaxX); + column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x); + + // Keep header highlighted when context menu is open. + const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent); + ImGuiID id = window->GetID(label); + ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f)); + ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal + if (!ItemAdd(bb, id)) + return; + + //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] + //GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] + + // Using AllowItemOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items. + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap); + if (g.ActiveId != id) + SetItemAllowOverlap(); + if (held || hovered || selected) + { + const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + //RenderFrame(bb.Min, bb.Max, col, false, 0.0f); + TableSetBgColor(ImGuiTableBgTarget_CellBg, col, table->CurrentColumn); + } + else + { + // Submit single cell bg color in the case we didn't submit a full header row + if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0) + TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn); + } + RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); + if (held) + table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n; + window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f; + + // Drag and drop to re-order columns. + // FIXME-TABLE: Scroll request while reordering a column and it lands out of the scrolling zone. + if (held && (table->Flags & ImGuiTableFlags_Reorderable) && IsMouseDragging(0) && !g.DragDropActive) + { + // While moving a column it will jump on the other side of the mouse, so we also test for MouseDelta.x + table->ReorderColumn = (ImGuiTableColumnIdx)column_n; + table->InstanceInteracted = table->InstanceCurrent; + + // We don't reorder: through the frozen<>unfrozen line, or through a column that is marked with ImGuiTableColumnFlags_NoReorder. + if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < cell_r.Min.x) + if (ImGuiTableColumn* prev_column = (column->PrevEnabledColumn != -1) ? &table->Columns[column->PrevEnabledColumn] : NULL) + if (!((column->Flags | prev_column->Flags) & ImGuiTableColumnFlags_NoReorder)) + if ((column->IndexWithinEnabledSet < table->FreezeColumnsRequest) == (prev_column->IndexWithinEnabledSet < table->FreezeColumnsRequest)) + table->ReorderColumnDir = -1; + if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > cell_r.Max.x) + if (ImGuiTableColumn* next_column = (column->NextEnabledColumn != -1) ? &table->Columns[column->NextEnabledColumn] : NULL) + if (!((column->Flags | next_column->Flags) & ImGuiTableColumnFlags_NoReorder)) + if ((column->IndexWithinEnabledSet < table->FreezeColumnsRequest) == (next_column->IndexWithinEnabledSet < table->FreezeColumnsRequest)) + table->ReorderColumnDir = +1; + } + + // Sort order arrow + const float ellipsis_max = cell_r.Max.x - w_arrow - w_sort_text; + if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) + { + if (column->SortOrder != -1) + { + float x = ImMax(cell_r.Min.x, cell_r.Max.x - w_arrow - w_sort_text); + float y = label_pos.y; + if (column->SortOrder > 0) + { + PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_Text, 0.70f)); + RenderText(ImVec2(x + g.Style.ItemInnerSpacing.x, y), sort_order_suf); + PopStyleColor(); + x += w_sort_text; + } + RenderArrow(window->DrawList, ImVec2(x, y), GetColorU32(ImGuiCol_Text), column->SortDirection == ImGuiSortDirection_Ascending ? ImGuiDir_Up : ImGuiDir_Down, ARROW_SCALE); + } + + // Handle clicking on column header to adjust Sort Order + if (pressed && table->ReorderColumn != column_n) + { + ImGuiSortDirection sort_direction = TableGetColumnNextSortDirection(column); + TableSetColumnSortDirection(column_n, sort_direction, g.IO.KeyShift); + } + } + + // Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will + // be merged into a single draw call. + //window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE); + RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size); + + const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x); + if (text_clipped && hovered && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay) + SetTooltip("%.*s", (int)(label_end - label), label); + + // We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden + if (IsMouseReleased(1) && IsItemHovered()) + TableOpenContextMenu(column_n); +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Context Menu +//------------------------------------------------------------------------- +// - TableOpenContextMenu() [Internal] +// - TableDrawContextMenu() [Internal] +//------------------------------------------------------------------------- + +// Use -1 to open menu not specific to a given column. +void ImGui::TableOpenContextMenu(int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + if (column_n == -1 && table->CurrentColumn != -1) // When called within a column automatically use this one (for consistency) + column_n = table->CurrentColumn; + if (column_n == table->ColumnsCount) // To facilitate using with TableGetHoveredColumn() + column_n = -1; + IM_ASSERT(column_n >= -1 && column_n < table->ColumnsCount); + if (table->Flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + table->IsContextPopupOpen = true; + table->ContextPopupColumn = (ImGuiTableColumnIdx)column_n; + table->InstanceInteracted = table->InstanceCurrent; + const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID); + OpenPopupEx(context_menu_id, ImGuiPopupFlags_None); + } +} + +// Output context menu into current window (generally a popup) +// FIXME-TABLE: Ideally this should be writable by the user. Full programmatic access to that data? +void ImGui::TableDrawContextMenu(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + bool want_separator = false; + const int column_n = (table->ContextPopupColumn >= 0 && table->ContextPopupColumn < table->ColumnsCount) ? table->ContextPopupColumn : -1; + ImGuiTableColumn* column = (column_n != -1) ? &table->Columns[column_n] : NULL; + + // Sizing + if (table->Flags & ImGuiTableFlags_Resizable) + { + if (column != NULL) + { + const bool can_resize = !(column->Flags & ImGuiTableColumnFlags_NoResize) && column->IsEnabled; + if (MenuItem("Size column to fit###SizeOne", NULL, false, can_resize)) + TableSetColumnWidthAutoSingle(table, column_n); + } + + const char* size_all_desc; + if (table->ColumnsEnabledFixedCount == table->ColumnsEnabledCount && (table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame) + size_all_desc = "Size all columns to fit###SizeAll"; // All fixed + else + size_all_desc = "Size all columns to default###SizeAll"; // All stretch or mixed + if (MenuItem(size_all_desc, NULL)) + TableSetColumnWidthAutoAll(table); + want_separator = true; + } + + // Ordering + if (table->Flags & ImGuiTableFlags_Reorderable) + { + if (MenuItem("Reset order", NULL, false, !table->IsDefaultDisplayOrder)) + table->IsResetDisplayOrderRequest = true; + want_separator = true; + } + + // Reset all (should work but seems unnecessary/noisy to expose?) + //if (MenuItem("Reset all")) + // table->IsResetAllRequest = true; + + // Sorting + // (modify TableOpenContextMenu() to add _Sortable flag if enabling this) +#if 0 + if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0) + { + if (want_separator) + Separator(); + want_separator = true; + + bool append_to_sort_specs = g.IO.KeyShift; + if (MenuItem("Sort in Ascending Order", NULL, column->SortOrder != -1 && column->SortDirection == ImGuiSortDirection_Ascending, (column->Flags & ImGuiTableColumnFlags_NoSortAscending) == 0)) + TableSetColumnSortDirection(table, column_n, ImGuiSortDirection_Ascending, append_to_sort_specs); + if (MenuItem("Sort in Descending Order", NULL, column->SortOrder != -1 && column->SortDirection == ImGuiSortDirection_Descending, (column->Flags & ImGuiTableColumnFlags_NoSortDescending) == 0)) + TableSetColumnSortDirection(table, column_n, ImGuiSortDirection_Descending, append_to_sort_specs); + } +#endif + + // Hiding / Visibility + if (table->Flags & ImGuiTableFlags_Hideable) + { + if (want_separator) + Separator(); + want_separator = true; + + PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true); + for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++) + { + ImGuiTableColumn* other_column = &table->Columns[other_column_n]; + if (other_column->Flags & ImGuiTableColumnFlags_Disabled) + continue; + + const char* name = TableGetColumnName(table, other_column_n); + if (name == NULL || name[0] == 0) + name = ""; + + // Make sure we can't hide the last active column + bool menu_item_active = (other_column->Flags & ImGuiTableColumnFlags_NoHide) ? false : true; + if (other_column->IsUserEnabled && table->ColumnsEnabledCount <= 1) + menu_item_active = false; + if (MenuItem(name, NULL, other_column->IsUserEnabled, menu_item_active)) + other_column->IsUserEnabledNextFrame = !other_column->IsUserEnabled; + } + PopItemFlag(); + } +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Settings (.ini data) +//------------------------------------------------------------------------- +// FIXME: The binding/finding/creating flow are too confusing. +//------------------------------------------------------------------------- +// - TableSettingsInit() [Internal] +// - TableSettingsCalcChunkSize() [Internal] +// - TableSettingsCreate() [Internal] +// - TableSettingsFindByID() [Internal] +// - TableGetBoundSettings() [Internal] +// - TableResetSettings() +// - TableSaveSettings() [Internal] +// - TableLoadSettings() [Internal] +// - TableSettingsHandler_ClearAll() [Internal] +// - TableSettingsHandler_ApplyAll() [Internal] +// - TableSettingsHandler_ReadOpen() [Internal] +// - TableSettingsHandler_ReadLine() [Internal] +// - TableSettingsHandler_WriteAll() [Internal] +// - TableSettingsInstallHandler() [Internal] +//------------------------------------------------------------------------- +// [Init] 1: TableSettingsHandler_ReadXXXX() Load and parse .ini file into TableSettings. +// [Main] 2: TableLoadSettings() When table is created, bind Table to TableSettings, serialize TableSettings data into Table. +// [Main] 3: TableSaveSettings() When table properties are modified, serialize Table data into bound or new TableSettings, mark .ini as dirty. +// [Main] 4: TableSettingsHandler_WriteAll() When .ini file is dirty (which can come from other source), save TableSettings into .ini file. +//------------------------------------------------------------------------- + +// Clear and initialize empty settings instance +static void TableSettingsInit(ImGuiTableSettings* settings, ImGuiID id, int columns_count, int columns_count_max) +{ + IM_PLACEMENT_NEW(settings) ImGuiTableSettings(); + ImGuiTableColumnSettings* settings_column = settings->GetColumnSettings(); + for (int n = 0; n < columns_count_max; n++, settings_column++) + IM_PLACEMENT_NEW(settings_column) ImGuiTableColumnSettings(); + settings->ID = id; + settings->ColumnsCount = (ImGuiTableColumnIdx)columns_count; + settings->ColumnsCountMax = (ImGuiTableColumnIdx)columns_count_max; + settings->WantApply = true; +} + +static size_t TableSettingsCalcChunkSize(int columns_count) +{ + return sizeof(ImGuiTableSettings) + (size_t)columns_count * sizeof(ImGuiTableColumnSettings); +} + +ImGuiTableSettings* ImGui::TableSettingsCreate(ImGuiID id, int columns_count) +{ + ImGuiContext& g = *GImGui; + ImGuiTableSettings* settings = g.SettingsTables.alloc_chunk(TableSettingsCalcChunkSize(columns_count)); + TableSettingsInit(settings, id, columns_count, columns_count); + return settings; +} + +// Find existing settings +ImGuiTableSettings* ImGui::TableSettingsFindByID(ImGuiID id) +{ + // FIXME-OPT: Might want to store a lookup map for this? + ImGuiContext& g = *GImGui; + for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) + if (settings->ID == id) + return settings; + return NULL; +} + +// Get settings for a given table, NULL if none +ImGuiTableSettings* ImGui::TableGetBoundSettings(ImGuiTable* table) +{ + if (table->SettingsOffset != -1) + { + ImGuiContext& g = *GImGui; + ImGuiTableSettings* settings = g.SettingsTables.ptr_from_offset(table->SettingsOffset); + IM_ASSERT(settings->ID == table->ID); + if (settings->ColumnsCountMax >= table->ColumnsCount) + return settings; // OK + settings->ID = 0; // Invalidate storage, we won't fit because of a count change + } + return NULL; +} + +// Restore initial state of table (with or without saved settings) +void ImGui::TableResetSettings(ImGuiTable* table) +{ + table->IsInitializing = table->IsSettingsDirty = true; + table->IsResetAllRequest = false; + table->IsSettingsRequestLoad = false; // Don't reload from ini + table->SettingsLoadedFlags = ImGuiTableFlags_None; // Mark as nothing loaded so our initialized data becomes authoritative +} + +void ImGui::TableSaveSettings(ImGuiTable* table) +{ + table->IsSettingsDirty = false; + if (table->Flags & ImGuiTableFlags_NoSavedSettings) + return; + + // Bind or create settings data + ImGuiContext& g = *GImGui; + ImGuiTableSettings* settings = TableGetBoundSettings(table); + if (settings == NULL) + { + settings = TableSettingsCreate(table->ID, table->ColumnsCount); + table->SettingsOffset = g.SettingsTables.offset_from_ptr(settings); + } + settings->ColumnsCount = (ImGuiTableColumnIdx)table->ColumnsCount; + + // Serialize ImGuiTable/ImGuiTableColumn into ImGuiTableSettings/ImGuiTableColumnSettings + IM_ASSERT(settings->ID == table->ID); + IM_ASSERT(settings->ColumnsCount == table->ColumnsCount && settings->ColumnsCountMax >= settings->ColumnsCount); + ImGuiTableColumn* column = table->Columns.Data; + ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); + + bool save_ref_scale = false; + settings->SaveFlags = ImGuiTableFlags_None; + for (int n = 0; n < table->ColumnsCount; n++, column++, column_settings++) + { + const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->StretchWeight : column->WidthRequest; + column_settings->WidthOrWeight = width_or_weight; + column_settings->Index = (ImGuiTableColumnIdx)n; + column_settings->DisplayOrder = column->DisplayOrder; + column_settings->SortOrder = column->SortOrder; + column_settings->SortDirection = column->SortDirection; + column_settings->IsEnabled = column->IsUserEnabled; + column_settings->IsStretch = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? 1 : 0; + if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) == 0) + save_ref_scale = true; + + // We skip saving some data in the .ini file when they are unnecessary to restore our state. + // Note that fixed width where initial width was derived from auto-fit will always be saved as InitStretchWeightOrWidth will be 0.0f. + // FIXME-TABLE: We don't have logic to easily compare SortOrder to DefaultSortOrder yet so it's always saved when present. + if (width_or_weight != column->InitStretchWeightOrWidth) + settings->SaveFlags |= ImGuiTableFlags_Resizable; + if (column->DisplayOrder != n) + settings->SaveFlags |= ImGuiTableFlags_Reorderable; + if (column->SortOrder != -1) + settings->SaveFlags |= ImGuiTableFlags_Sortable; + if (column->IsUserEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) == 0)) + settings->SaveFlags |= ImGuiTableFlags_Hideable; + } + settings->SaveFlags &= table->Flags; + settings->RefScale = save_ref_scale ? table->RefScale : 0.0f; + + MarkIniSettingsDirty(); +} + +void ImGui::TableLoadSettings(ImGuiTable* table) +{ + ImGuiContext& g = *GImGui; + table->IsSettingsRequestLoad = false; + if (table->Flags & ImGuiTableFlags_NoSavedSettings) + return; + + // Bind settings + ImGuiTableSettings* settings; + if (table->SettingsOffset == -1) + { + settings = TableSettingsFindByID(table->ID); + if (settings == NULL) + return; + if (settings->ColumnsCount != table->ColumnsCount) // Allow settings if columns count changed. We could otherwise decide to return... + table->IsSettingsDirty = true; + table->SettingsOffset = g.SettingsTables.offset_from_ptr(settings); + } + else + { + settings = TableGetBoundSettings(table); + } + + table->SettingsLoadedFlags = settings->SaveFlags; + table->RefScale = settings->RefScale; + + // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn + ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); + ImU64 display_order_mask = 0; + for (int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++) + { + int column_n = column_settings->Index; + if (column_n < 0 || column_n >= table->ColumnsCount) + continue; + + ImGuiTableColumn* column = &table->Columns[column_n]; + if (settings->SaveFlags & ImGuiTableFlags_Resizable) + { + if (column_settings->IsStretch) + column->StretchWeight = column_settings->WidthOrWeight; + else + column->WidthRequest = column_settings->WidthOrWeight; + column->AutoFitQueue = 0x00; + } + if (settings->SaveFlags & ImGuiTableFlags_Reorderable) + column->DisplayOrder = column_settings->DisplayOrder; + else + column->DisplayOrder = (ImGuiTableColumnIdx)column_n; + display_order_mask |= (ImU64)1 << column->DisplayOrder; + column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled; + column->SortOrder = column_settings->SortOrder; + column->SortDirection = column_settings->SortDirection; + } + + // Validate and fix invalid display order data + const ImU64 expected_display_order_mask = (settings->ColumnsCount == 64) ? ~0 : ((ImU64)1 << settings->ColumnsCount) - 1; + if (display_order_mask != expected_display_order_mask) + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + table->Columns[column_n].DisplayOrder = (ImGuiTableColumnIdx)column_n; + + // Rebuild index + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) + table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n; +} + +static void TableSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + ImGuiContext& g = *ctx; + for (int i = 0; i != g.Tables.GetMapSize(); i++) + if (ImGuiTable* table = g.Tables.TryGetMapData(i)) + table->SettingsOffset = -1; + g.SettingsTables.clear(); +} + +// Apply to existing windows (if any) +static void TableSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + ImGuiContext& g = *ctx; + for (int i = 0; i != g.Tables.GetMapSize(); i++) + if (ImGuiTable* table = g.Tables.TryGetMapData(i)) + { + table->IsSettingsRequestLoad = true; + table->SettingsOffset = -1; + } +} + +static void* TableSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) +{ + ImGuiID id = 0; + int columns_count = 0; + if (sscanf(name, "0x%08X,%d", &id, &columns_count) < 2) + return NULL; + + if (ImGuiTableSettings* settings = ImGui::TableSettingsFindByID(id)) + { + if (settings->ColumnsCountMax >= columns_count) + { + TableSettingsInit(settings, id, columns_count, settings->ColumnsCountMax); // Recycle + return settings; + } + settings->ID = 0; // Invalidate storage, we won't fit because of a count change + } + return ImGui::TableSettingsCreate(id, columns_count); +} + +static void TableSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line) +{ + // "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v" + ImGuiTableSettings* settings = (ImGuiTableSettings*)entry; + float f = 0.0f; + int column_n = 0, r = 0, n = 0; + + if (sscanf(line, "RefScale=%f", &f) == 1) { settings->RefScale = f; return; } + + if (sscanf(line, "Column %d%n", &column_n, &r) == 1) + { + if (column_n < 0 || column_n >= settings->ColumnsCount) + return; + line = ImStrSkipBlank(line + r); + char c = 0; + ImGuiTableColumnSettings* column = settings->GetColumnSettings() + column_n; + column->Index = (ImGuiTableColumnIdx)column_n; + if (sscanf(line, "UserID=0x%08X%n", (ImU32*)&n, &r)==1) { line = ImStrSkipBlank(line + r); column->UserID = (ImGuiID)n; } + if (sscanf(line, "Width=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->WidthOrWeight = (float)n; column->IsStretch = 0; settings->SaveFlags |= ImGuiTableFlags_Resizable; } + if (sscanf(line, "Weight=%f%n", &f, &r) == 1) { line = ImStrSkipBlank(line + r); column->WidthOrWeight = f; column->IsStretch = 1; settings->SaveFlags |= ImGuiTableFlags_Resizable; } + if (sscanf(line, "Visible=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->IsEnabled = (ImU8)n; settings->SaveFlags |= ImGuiTableFlags_Hideable; } + if (sscanf(line, "Order=%d%n", &n, &r) == 1) { line = ImStrSkipBlank(line + r); column->DisplayOrder = (ImGuiTableColumnIdx)n; settings->SaveFlags |= ImGuiTableFlags_Reorderable; } + if (sscanf(line, "Sort=%d%c%n", &n, &c, &r) == 2) { line = ImStrSkipBlank(line + r); column->SortOrder = (ImGuiTableColumnIdx)n; column->SortDirection = (c == '^') ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending; settings->SaveFlags |= ImGuiTableFlags_Sortable; } + } +} + +static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) +{ + ImGuiContext& g = *ctx; + for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) + { + if (settings->ID == 0) // Skip ditched settings + continue; + + // TableSaveSettings() may clear some of those flags when we establish that the data can be stripped + // (e.g. Order was unchanged) + const bool save_size = (settings->SaveFlags & ImGuiTableFlags_Resizable) != 0; + const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0; + const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0; + const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0; + if (!save_size && !save_visible && !save_order && !save_sort) + continue; + + buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve + buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount); + if (settings->RefScale != 0.0f) + buf->appendf("RefScale=%g\n", settings->RefScale); + ImGuiTableColumnSettings* column = settings->GetColumnSettings(); + for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++) + { + // "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v" + bool save_column = column->UserID != 0 || save_size || save_visible || save_order || (save_sort && column->SortOrder != -1); + if (!save_column) + continue; + buf->appendf("Column %-2d", column_n); + if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID); + if (save_size && column->IsStretch) buf->appendf(" Weight=%.4f", column->WidthOrWeight); + if (save_size && !column->IsStretch) buf->appendf(" Width=%d", (int)column->WidthOrWeight); + if (save_visible) buf->appendf(" Visible=%d", column->IsEnabled); + if (save_order) buf->appendf(" Order=%d", column->DisplayOrder); + if (save_sort && column->SortOrder != -1) buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); + buf->append("\n"); + } + buf->append("\n"); + } +} + +void ImGui::TableSettingsInstallHandler(ImGuiContext* context) +{ + ImGuiContext& g = *context; + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Table"; + ini_handler.TypeHash = ImHashStr("Table"); + ini_handler.ClearAllFn = TableSettingsHandler_ClearAll; + ini_handler.ReadOpenFn = TableSettingsHandler_ReadOpen; + ini_handler.ReadLineFn = TableSettingsHandler_ReadLine; + ini_handler.ApplyAllFn = TableSettingsHandler_ApplyAll; + ini_handler.WriteAllFn = TableSettingsHandler_WriteAll; + g.SettingsHandlers.push_back(ini_handler); +} + +//------------------------------------------------------------------------- +// [SECTION] Tables: Garbage Collection +//------------------------------------------------------------------------- +// - TableRemove() [Internal] +// - TableGcCompactTransientBuffers() [Internal] +// - TableGcCompactSettings() [Internal] +//------------------------------------------------------------------------- + +// Remove Table (currently only used by TestEngine) +void ImGui::TableRemove(ImGuiTable* table) +{ + //IMGUI_DEBUG_LOG("TableRemove() id=0x%08X\n", table->ID); + ImGuiContext& g = *GImGui; + int table_idx = g.Tables.GetIndex(table); + //memset(table->RawData.Data, 0, table->RawData.size_in_bytes()); + //memset(table, 0, sizeof(ImGuiTable)); + g.Tables.Remove(table->ID, table); + g.TablesLastTimeActive[table_idx] = -1.0f; +} + +// Free up/compact internal Table buffers for when it gets unused +void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table) +{ + //IMGUI_DEBUG_LOG("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID); + ImGuiContext& g = *GImGui; + IM_ASSERT(table->MemoryCompacted == false); + table->SortSpecs.Specs = NULL; + table->SortSpecsMulti.clear(); + table->IsSortSpecsDirty = true; // FIXME: shouldn't have to leak into user performing a sort + table->ColumnsNames.clear(); + table->MemoryCompacted = true; + for (int n = 0; n < table->ColumnsCount; n++) + table->Columns[n].NameOffset = -1; + g.TablesLastTimeActive[g.Tables.GetIndex(table)] = -1.0f; +} + +void ImGui::TableGcCompactTransientBuffers(ImGuiTableTempData* temp_data) +{ + temp_data->DrawSplitter.ClearFreeMemory(); + temp_data->LastTimeActive = -1.0f; +} + +// Compact and remove unused settings data (currently only used by TestEngine) +void ImGui::TableGcCompactSettings() +{ + ImGuiContext& g = *GImGui; + int required_memory = 0; + for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) + if (settings->ID != 0) + required_memory += (int)TableSettingsCalcChunkSize(settings->ColumnsCount); + if (required_memory == g.SettingsTables.Buf.Size) + return; + ImChunkStream new_chunk_stream; + new_chunk_stream.Buf.reserve(required_memory); + for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) + if (settings->ID != 0) + memcpy(new_chunk_stream.alloc_chunk(TableSettingsCalcChunkSize(settings->ColumnsCount)), settings, TableSettingsCalcChunkSize(settings->ColumnsCount)); + g.SettingsTables.swap(new_chunk_stream); +} + + +//------------------------------------------------------------------------- +// [SECTION] Tables: Debugging +//------------------------------------------------------------------------- +// - DebugNodeTable() [Internal] +//------------------------------------------------------------------------- + +#ifndef IMGUI_DISABLE_METRICS_WINDOW + +static const char* DebugNodeTableGetSizingPolicyDesc(ImGuiTableFlags sizing_policy) +{ + sizing_policy &= ImGuiTableFlags_SizingMask_; + if (sizing_policy == ImGuiTableFlags_SizingFixedFit) { return "FixedFit"; } + if (sizing_policy == ImGuiTableFlags_SizingFixedSame) { return "FixedSame"; } + if (sizing_policy == ImGuiTableFlags_SizingStretchProp) { return "StretchProp"; } + if (sizing_policy == ImGuiTableFlags_SizingStretchSame) { return "StretchSame"; } + return "N/A"; +} + +void ImGui::DebugNodeTable(ImGuiTable* table) +{ + char buf[512]; + char* p = buf; + const char* buf_end = buf + IM_ARRAYSIZE(buf); + const bool is_active = (table->LastFrameActive >= ImGui::GetFrameCount() - 2); // Note that fully clipped early out scrolling tables will appear as inactive here. + ImFormatString(p, buf_end - p, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*"); + if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } + bool open = TreeNode(table, "%s", buf); + if (!is_active) { PopStyleColor(); } + if (IsItemHovered()) + GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255)); + if (IsItemVisible() && table->HoveredColumnBody != -1) + GetForegroundDrawList()->AddRect(GetItemRectMin(), GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + if (!open) + return; + bool clear_settings = SmallButton("Clear settings"); + BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f) Sizing: '%s'", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight(), DebugNodeTableGetSizingPolicyDesc(table->Flags)); + BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsGivenWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); + BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", table->CellPaddingX, table->CellSpacingX1, table->CellSpacingX2, table->OuterPaddingX); + BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder); + BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn); + //BulletText("BgDrawChannels: %d/%d", 0, table->BgDrawChannelUnfrozen); + float sum_weights = 0.0f; + for (int n = 0; n < table->ColumnsCount; n++) + if (table->Columns[n].Flags & ImGuiTableColumnFlags_WidthStretch) + sum_weights += table->Columns[n].StretchWeight; + for (int n = 0; n < table->ColumnsCount; n++) + { + ImGuiTableColumn* column = &table->Columns[n]; + const char* name = TableGetColumnName(table, n); + ImFormatString(buf, IM_ARRAYSIZE(buf), + "Column %d order %d '%s': offset %+.2f to %+.2f%s\n" + "Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n" + "WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n" + "MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n" + "ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n" + "Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s..", + n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, (n < table->FreezeColumnsRequest) ? " (Frozen)" : "", + column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen, + column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, column->StretchWeight > 0.0f ? (column->StretchWeight / sum_weights) * 100.0f : 0.0f, + column->MinX, column->MaxX, column->MaxX - column->MinX, column->ClipRect.Min.x, column->ClipRect.Max.x, column->ClipRect.Max.x - column->ClipRect.Min.x, + column->ContentMaxXFrozen - column->WorkMinX, column->ContentMaxXUnfrozen - column->WorkMinX, column->ContentMaxXHeadersUsed - column->WorkMinX, column->ContentMaxXHeadersIdeal - column->WorkMinX, + column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags, + (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "", + (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "", + (column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : ""); + Bullet(); + Selectable(buf); + if (IsItemHovered()) + { + ImRect r(column->MinX, table->OuterRect.Min.y, column->MaxX, table->OuterRect.Max.y); + GetForegroundDrawList()->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255)); + } + } + if (ImGuiTableSettings* settings = TableGetBoundSettings(table)) + DebugNodeTableSettings(settings); + if (clear_settings) + table->IsResetAllRequest = true; + TreePop(); +} + +void ImGui::DebugNodeTableSettings(ImGuiTableSettings* settings) +{ + if (!TreeNode((void*)(intptr_t)settings->ID, "Settings 0x%08X (%d columns)", settings->ID, settings->ColumnsCount)) + return; + BulletText("SaveFlags: 0x%08X", settings->SaveFlags); + BulletText("ColumnsCount: %d (max %d)", settings->ColumnsCount, settings->ColumnsCountMax); + for (int n = 0; n < settings->ColumnsCount; n++) + { + ImGuiTableColumnSettings* column_settings = &settings->GetColumnSettings()[n]; + ImGuiSortDirection sort_dir = (column_settings->SortOrder != -1) ? (ImGuiSortDirection)column_settings->SortDirection : ImGuiSortDirection_None; + BulletText("Column %d Order %d SortOrder %d %s Vis %d %s %7.3f UserID 0x%08X", + n, column_settings->DisplayOrder, column_settings->SortOrder, + (sort_dir == ImGuiSortDirection_Ascending) ? "Asc" : (sort_dir == ImGuiSortDirection_Descending) ? "Des" : "---", + column_settings->IsEnabled, column_settings->IsStretch ? "Weight" : "Width ", column_settings->WidthOrWeight, column_settings->UserID); + } + TreePop(); +} + +#else // #ifndef IMGUI_DISABLE_METRICS_WINDOW + +void ImGui::DebugNodeTable(ImGuiTable*) {} +void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {} + +#endif + + +//------------------------------------------------------------------------- +// [SECTION] Columns, BeginColumns, EndColumns, etc. +// (This is a legacy API, prefer using BeginTable/EndTable!) +//------------------------------------------------------------------------- +// FIXME: sizing is lossy when columns width is very small (default width may turn negative etc.) +//------------------------------------------------------------------------- +// - SetWindowClipRectBeforeSetChannel() [Internal] +// - GetColumnIndex() +// - GetColumnsCount() +// - GetColumnOffset() +// - GetColumnWidth() +// - SetColumnOffset() +// - SetColumnWidth() +// - PushColumnClipRect() [Internal] +// - PushColumnsBackground() [Internal] +// - PopColumnsBackground() [Internal] +// - FindOrCreateColumns() [Internal] +// - GetColumnsID() [Internal] +// - BeginColumns() +// - NextColumn() +// - EndColumns() +// - Columns() +//------------------------------------------------------------------------- + +// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences, +// they would meddle many times with the underlying ImDrawCmd. +// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let +// the subsequent single call to SetCurrentChannel() does it things once. +void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect) +{ + ImVec4 clip_rect_vec4 = clip_rect.ToVec4(); + window->ClipRect = clip_rect; + window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4; + window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4; +} + +int ImGui::GetColumnIndex() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0; +} + +int ImGui::GetColumnsCount() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1; +} + +float ImGui::GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm) +{ + return offset_norm * (columns->OffMaxX - columns->OffMinX); +} + +float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset) +{ + return offset / (columns->OffMaxX - columns->OffMinX); +} + +static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f; + +static float GetDraggedColumnOffset(ImGuiOldColumns* columns, 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. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. + IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); + + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x; + x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); + if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths)) + x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); + + return x; +} + +float ImGui::GetColumnOffset(int column_index) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (columns == NULL) + return 0.0f; + + if (column_index < 0) + column_index = columns->Current; + IM_ASSERT(column_index < columns->Columns.Size); + + const float t = columns->Columns[column_index].OffsetNorm; + const float x_offset = ImLerp(columns->OffMinX, columns->OffMaxX, t); + return x_offset; +} + +static float GetColumnWidthEx(ImGuiOldColumns* columns, int column_index, bool before_resize = false) +{ + if (column_index < 0) + column_index = columns->Current; + + float offset_norm; + if (before_resize) + offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize; + else + offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm; + return ImGui::GetColumnOffsetFromNorm(columns, offset_norm); +} + +float ImGui::GetColumnWidth(int column_index) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (columns == NULL) + return GetContentRegionAvail().x; + + if (column_index < 0) + column_index = columns->Current; + return GetColumnOffsetFromNorm(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm); +} + +void ImGui::SetColumnOffset(int column_index, float offset) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiOldColumns* columns = window->DC.CurrentColumns; + IM_ASSERT(columns != NULL); + + if (column_index < 0) + column_index = columns->Current; + IM_ASSERT(column_index < columns->Columns.Size); + + const bool preserve_width = !(columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths) && (column_index < columns->Count - 1); + const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f; + + if (!(columns->Flags & ImGuiOldColumnFlags_NoForceWithinWindow)) + offset = ImMin(offset, columns->OffMaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); + columns->Columns[column_index].OffsetNorm = GetColumnNormFromOffset(columns, offset - columns->OffMinX); + + if (preserve_width) + SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); +} + +void ImGui::SetColumnWidth(int column_index, float width) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + IM_ASSERT(columns != NULL); + + if (column_index < 0) + column_index = columns->Current; + SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width); +} + +void ImGui::PushColumnClipRect(int column_index) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (column_index < 0) + column_index = columns->Current; + + ImGuiOldColumnData* column = &columns->Columns[column_index]; + PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false); +} + +// Get into the columns background draw command (which is generally the same draw command as before we called BeginColumns) +void ImGui::PushColumnsBackground() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (columns->Count == 1) + return; + + // Optimization: avoid SetCurrentChannel() + PushClipRect() + columns->HostBackupClipRect = window->ClipRect; + SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect); + columns->Splitter.SetCurrentChannel(window->DrawList, 0); +} + +void ImGui::PopColumnsBackground() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (columns->Count == 1) + return; + + // Optimization: avoid PopClipRect() + SetCurrentChannel() + SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect); + columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1); +} + +ImGuiOldColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id) +{ + // We have few columns per window so for now we don't need bother much with turning this into a faster lookup. + for (int n = 0; n < window->ColumnsStorage.Size; n++) + if (window->ColumnsStorage[n].ID == id) + return &window->ColumnsStorage[n]; + + window->ColumnsStorage.push_back(ImGuiOldColumns()); + ImGuiOldColumns* columns = &window->ColumnsStorage.back(); + columns->ID = id; + return columns; +} + +ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count) +{ + ImGuiWindow* window = GetCurrentWindow(); + + // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. + // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. + PushID(0x11223347 + (str_id ? 0 : columns_count)); + ImGuiID id = window->GetID(str_id ? str_id : "columns"); + PopID(); + + return id; +} + +void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + IM_ASSERT(columns_count >= 1); + IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported + + // Acquire storage for the columns set + ImGuiID id = GetColumnsID(str_id, columns_count); + ImGuiOldColumns* columns = FindOrCreateColumns(window, id); + IM_ASSERT(columns->ID == id); + columns->Current = 0; + columns->Count = columns_count; + columns->Flags = flags; + window->DC.CurrentColumns = columns; + + columns->HostCursorPosY = window->DC.CursorPos.y; + columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; + columns->HostInitialClipRect = window->ClipRect; + columns->HostBackupParentWorkRect = window->ParentWorkRect; + window->ParentWorkRect = window->WorkRect; + + // Set state for first column + // We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect + const float column_padding = g.Style.ItemSpacing.x; + const float half_clip_extend_x = ImFloor(ImMax(window->WindowPadding.x * 0.5f, window->WindowBorderSize)); + const float max_1 = window->WorkRect.Max.x + column_padding - ImMax(column_padding - window->WindowPadding.x, 0.0f); + const float max_2 = window->WorkRect.Max.x + half_clip_extend_x; + columns->OffMinX = window->DC.Indent.x - column_padding + ImMax(column_padding - window->WindowPadding.x, 0.0f); + columns->OffMaxX = ImMax(ImMin(max_1, max_2) - window->Pos.x, columns->OffMinX + 1.0f); + columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y; + + // Clear data if columns count changed + if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1) + columns->Columns.resize(0); + + // Initialize default widths + columns->IsFirstFrame = (columns->Columns.Size == 0); + if (columns->Columns.Size == 0) + { + columns->Columns.reserve(columns_count + 1); + for (int n = 0; n < columns_count + 1; n++) + { + ImGuiOldColumnData column; + column.OffsetNorm = n / (float)columns_count; + columns->Columns.push_back(column); + } + } + + for (int n = 0; n < columns_count; n++) + { + // Compute clipping rectangle + ImGuiOldColumnData* column = &columns->Columns[n]; + float clip_x1 = IM_ROUND(window->Pos.x + GetColumnOffset(n)); + float clip_x2 = IM_ROUND(window->Pos.x + GetColumnOffset(n + 1) - 1.0f); + column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + column->ClipRect.ClipWithFull(window->ClipRect); + } + + if (columns->Count > 1) + { + columns->Splitter.Split(window->DrawList, 1 + columns->Count); + columns->Splitter.SetCurrentChannel(window->DrawList, 1); + PushColumnClipRect(0); + } + + // We don't generally store Indent.x inside ColumnsOffset because it may be manipulated by the user. + float offset_0 = GetColumnOffset(columns->Current); + float offset_1 = GetColumnOffset(columns->Current + 1); + float width = offset_1 - offset_0; + PushItemWidth(width * 0.65f); + window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); + window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); + window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding; +} + +void ImGui::NextColumn() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems || window->DC.CurrentColumns == NULL) + return; + + ImGuiContext& g = *GImGui; + ImGuiOldColumns* columns = window->DC.CurrentColumns; + + if (columns->Count == 1) + { + window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); + IM_ASSERT(columns->Current == 0); + return; + } + + // Next column + if (++columns->Current == columns->Count) + columns->Current = 0; + + PopItemWidth(); + + // Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect() + // (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them), + ImGuiOldColumnData* column = &columns->Columns[columns->Current]; + SetWindowClipRectBeforeSetChannel(window, column->ClipRect); + columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1); + + const float column_padding = g.Style.ItemSpacing.x; + columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); + if (columns->Current > 0) + { + // Columns 1+ ignore IndentX (by canceling it out) + // FIXME-COLUMNS: Unnecessary, could be locked? + window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding; + } + else + { + // New row/line: column 0 honor IndentX. + window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); + columns->LineMinY = columns->LineMaxY; + } + window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); + window->DC.CursorPos.y = columns->LineMinY; + window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + window->DC.CurrLineTextBaseOffset = 0.0f; + + // FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup. + float offset_0 = GetColumnOffset(columns->Current); + float offset_1 = GetColumnOffset(columns->Current + 1); + float width = offset_1 - offset_0; + PushItemWidth(width * 0.65f); + window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding; +} + +void ImGui::EndColumns() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + ImGuiOldColumns* columns = window->DC.CurrentColumns; + IM_ASSERT(columns != NULL); + + PopItemWidth(); + if (columns->Count > 1) + { + PopClipRect(); + columns->Splitter.Merge(window->DrawList); + } + + const ImGuiOldColumnFlags flags = columns->Flags; + columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = columns->LineMaxY; + if (!(flags & ImGuiOldColumnFlags_GrowParentContentsSize)) + window->DC.CursorMaxPos.x = columns->HostCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent + + // Draw columns borders and handle resize + // The IsBeingResized flag ensure we preserve pre-resize columns width so back-and-forth are not lossy + bool is_being_resized = false; + if (!(flags & ImGuiOldColumnFlags_NoBorder) && !window->SkipItems) + { + // We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers. + const float y1 = ImMax(columns->HostCursorPosY, window->ClipRect.Min.y); + const float y2 = ImMin(window->DC.CursorPos.y, window->ClipRect.Max.y); + int dragging_column = -1; + for (int n = 1; n < columns->Count; n++) + { + ImGuiOldColumnData* column = &columns->Columns[n]; + float x = window->Pos.x + GetColumnOffset(n); + const ImGuiID column_id = columns->ID + ImGuiID(n); + const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; + const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); + KeepAliveID(column_id); + if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test + continue; + + bool hovered = false, held = false; + if (!(flags & ImGuiOldColumnFlags_NoResize)) + { + ButtonBehavior(column_hit_rect, column_id, &hovered, &held); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + if (held && !(column->Flags & ImGuiOldColumnFlags_NoResize)) + dragging_column = n; + } + + // Draw column + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + const float xi = IM_FLOOR(x); + window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + } + + // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. + if (dragging_column != -1) + { + if (!columns->IsBeingResized) + for (int n = 0; n < columns->Count + 1; n++) + columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm; + columns->IsBeingResized = is_being_resized = true; + float x = GetDraggedColumnOffset(columns, dragging_column); + SetColumnOffset(dragging_column, x); + } + } + columns->IsBeingResized = is_being_resized; + + window->WorkRect = window->ParentWorkRect; + window->ParentWorkRect = columns->HostBackupParentWorkRect; + window->DC.CurrentColumns = NULL; + window->DC.ColumnsOffset.x = 0.0f; + window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); +} + +void ImGui::Columns(int columns_count, const char* id, bool border) +{ + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(columns_count >= 1); + + ImGuiOldColumnFlags flags = (border ? 0 : ImGuiOldColumnFlags_NoBorder); + //flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior + ImGuiOldColumns* columns = window->DC.CurrentColumns; + if (columns != NULL && columns->Count == columns_count && columns->Flags == flags) + return; + + if (columns != NULL) + EndColumns(); + + if (columns_count != 1) + BeginColumns(id, columns_count, flags); +} + +//------------------------------------------------------------------------- + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp b/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp new file mode 100644 index 000000000..3d165580b --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp @@ -0,0 +1,8428 @@ +// dear imgui, v1.87 +// (widgets code) + +/* + +Index of this file: + +// [SECTION] Forward Declarations +// [SECTION] Widgets: Text, etc. +// [SECTION] Widgets: Main (Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc.) +// [SECTION] Widgets: Low-level Layout helpers (Spacing, Dummy, NewLine, Separator, etc.) +// [SECTION] Widgets: ComboBox +// [SECTION] Data Type and Data Formatting Helpers +// [SECTION] Widgets: DragScalar, DragFloat, DragInt, etc. +// [SECTION] Widgets: SliderScalar, SliderFloat, SliderInt, etc. +// [SECTION] Widgets: InputScalar, InputFloat, InputInt, etc. +// [SECTION] Widgets: InputText, InputTextMultiline +// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc. +// [SECTION] Widgets: TreeNode, CollapsingHeader, etc. +// [SECTION] Widgets: Selectable +// [SECTION] Widgets: ListBox +// [SECTION] Widgets: PlotLines, PlotHistogram +// [SECTION] Widgets: Value helpers +// [SECTION] Widgets: MenuItem, BeginMenu, EndMenu, etc. +// [SECTION] Widgets: BeginTabBar, EndTabBar, etc. +// [SECTION] Widgets: BeginTabItem, EndTabItem, etc. +// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc. + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui_internal.h" + +// System includes +#include // toupper +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +//------------------------------------------------------------------------- +// Warnings +//------------------------------------------------------------------------- + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later +#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types +#endif +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#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 (typically 0.0f) is 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 "-Wsign-conversion" // warning: implicit conversion changes signedness +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') +#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#endif + +//------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------- + +// Widgets +static const float DRAGDROP_HOLD_TO_OPEN_TIMER = 0.70f; // Time for drag-hold to activate items accepting the ImGuiButtonFlags_PressedOnDragDropHold button behavior. +static const float DRAG_MOUSE_THRESHOLD_FACTOR = 0.50f; // Multiplier for the default value of io.MouseDragThreshold to make DragFloat/DragInt react faster to mouse drags. + +// Those MIN/MAX values are not define because we need to point to them +static const signed char IM_S8_MIN = -128; +static const signed char IM_S8_MAX = 127; +static const unsigned char IM_U8_MIN = 0; +static const unsigned char IM_U8_MAX = 0xFF; +static const signed short IM_S16_MIN = -32768; +static const signed short IM_S16_MAX = 32767; +static const unsigned short IM_U16_MIN = 0; +static const unsigned short IM_U16_MAX = 0xFFFF; +static const ImS32 IM_S32_MIN = INT_MIN; // (-2147483647 - 1), (0x80000000); +static const ImS32 IM_S32_MAX = INT_MAX; // (2147483647), (0x7FFFFFFF) +static const ImU32 IM_U32_MIN = 0; +static const ImU32 IM_U32_MAX = UINT_MAX; // (0xFFFFFFFF) +#ifdef LLONG_MIN +static const ImS64 IM_S64_MIN = LLONG_MIN; // (-9223372036854775807ll - 1ll); +static const ImS64 IM_S64_MAX = LLONG_MAX; // (9223372036854775807ll); +#else +static const ImS64 IM_S64_MIN = -9223372036854775807LL - 1; +static const ImS64 IM_S64_MAX = 9223372036854775807LL; +#endif +static const ImU64 IM_U64_MIN = 0; +#ifdef ULLONG_MAX +static const ImU64 IM_U64_MAX = ULLONG_MAX; // (0xFFFFFFFFFFFFFFFFull); +#else +static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1); +#endif + +//------------------------------------------------------------------------- +// [SECTION] Forward Declarations +//------------------------------------------------------------------------- + +// For InputTextEx() +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source); +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); +static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Text, etc. +//------------------------------------------------------------------------- +// - TextEx() [Internal] +// - TextUnformatted() +// - Text() +// - TextV() +// - TextColored() +// - TextColoredV() +// - TextDisabled() +// - TextDisabledV() +// - TextWrapped() +// - TextWrappedV() +// - LabelText() +// - LabelTextV() +// - BulletText() +// - BulletTextV() +//------------------------------------------------------------------------- + +void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; + + // Accept null ranges + if (text == text_end) + text = text_end = ""; + + // Calculate length + const char* text_begin = text; + if (text_end == NULL) + text_end = text + strlen(text); // FIXME-OPT + + const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); + const float wrap_pos_x = window->DC.TextWrapPos; + 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. + // - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop. + const char* line = text; + const float line_height = GetTextLineHeight(); + ImVec2 text_size(0, 0); + + // Lines to skip (can't skip when logging text) + ImVec2 pos = text_pos; + if (!g.LogEnabled) + { + int lines_skippable = (int)((window->ClipRect.Min.y - text_pos.y) / line_height); + if (lines_skippable > 0) + { + int lines_skipped = 0; + while (line < text_end && lines_skipped < lines_skippable) + { + const char* line_end = (const char*)memchr(line, '\n', text_end - line); + if (!line_end) + line_end = text_end; + if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) + text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x); + 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(FLT_MAX, line_height)); + while (line < text_end) + { + if (IsClippedEx(line_rect, 0)) + break; + + const char* line_end = (const char*)memchr(line, '\n', text_end - line); + if (!line_end) + line_end = text_end; + text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x); + RenderText(pos, line, line_end, false); + 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 = (const char*)memchr(line, '\n', text_end - line); + if (!line_end) + line_end = text_end; + if ((flags & ImGuiTextFlags_NoWidthForLargeClippedText) == 0) + text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x); + 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(text_size, 0.0f); + ItemAdd(bb, 0); + } + 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); + + ImRect bb(text_pos, text_pos + text_size); + ItemSize(text_size, 0.0f); + if (!ItemAdd(bb, 0)) + return; + + // Render (we don't hide text after ## in this end-user function) + RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); + } +} + +void ImGui::TextUnformatted(const char* text, const char* text_end) +{ + TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); +} + +void ImGui::Text(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextV(fmt, args); + va_end(args); +} + +void ImGui::TextV(const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // FIXME-OPT: Handle the %s shortcut? + ImGuiContext& g = *GImGui; + const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); +} + +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::TextColoredV(const ImVec4& col, const char* fmt, va_list args) +{ + PushStyleColor(ImGuiCol_Text, col); + if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) + TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting + else + TextV(fmt, args); + PopStyleColor(); +} + +void ImGui::TextDisabled(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextDisabledV(fmt, args); + va_end(args); +} + +void ImGui::TextDisabledV(const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) + TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting + else + TextV(fmt, args); + PopStyleColor(); +} + +void ImGui::TextWrapped(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + TextWrappedV(fmt, args); + va_end(args); +} + +void ImGui::TextWrappedV(const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set + if (need_backup) + PushTextWrapPos(0.0f); + if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) + TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting + else + TextV(fmt, args); + if (need_backup) + PopTextWrapPos(); +} + +void ImGui::LabelText(const char* label, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + LabelTextV(label, fmt, args); + va_end(args); +} + +// Add a label+text combo aligned to other label+value widgets +void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float w = 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 value_size = CalcTextSize(value_text_begin, value_text_end, false); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const ImVec2 pos = window->DC.CursorPos; + const ImRect value_bb(pos, pos + ImVec2(w, value_size.y + style.FramePadding.y * 2)); + const ImRect total_bb(pos, pos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, 0)) + return; + + // Render + RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text_begin, value_text_end, &value_size, ImVec2(0.0f, 0.0f)); + if (label_size.x > 0.0f) + RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); +} + +void ImGui::BulletText(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + BulletTextV(fmt, args); + va_end(args); +} + +// Text with a little bullet aligned to the typical tree node. +void ImGui::BulletTextV(const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + const char* text_begin = g.TempBuffer; + const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); + const ImVec2 total_size = ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding + ImVec2 pos = window->DC.CursorPos; + pos.y += window->DC.CurrLineTextBaseOffset; + ItemSize(total_size, 0.0f); + const ImRect bb(pos, pos + total_size); + if (!ItemAdd(bb, 0)) + return; + + // Render + ImU32 text_col = GetColorU32(ImGuiCol_Text); + RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col); + RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text_begin, text_end, false); +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Main +//------------------------------------------------------------------------- +// - ButtonBehavior() [Internal] +// - Button() +// - SmallButton() +// - InvisibleButton() +// - ArrowButton() +// - CloseButton() [Internal] +// - CollapseButton() [Internal] +// - GetWindowScrollbarID() [Internal] +// - GetWindowScrollbarRect() [Internal] +// - Scrollbar() [Internal] +// - ScrollbarEx() [Internal] +// - Image() +// - ImageButton() +// - Checkbox() +// - CheckboxFlagsT() [Internal] +// - CheckboxFlags() +// - RadioButton() +// - ProgressBar() +// - Bullet() +//------------------------------------------------------------------------- + +// The ButtonBehavior() function is key to many interactions and used by many/most widgets. +// Because we handle so many cases (keyboard/gamepad navigation, drag and drop) and many specific behavior (via ImGuiButtonFlags_), +// this code is a little complex. +// By far the most common path is interacting with the Mouse using the default ImGuiButtonFlags_PressedOnClickRelease button behavior. +// See the series of events below and the corresponding state reported by dear imgui: +//------------------------------------------------------------------------------------------------------------------------------------------------ +// with PressedOnClickRelease: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked() +// Frame N+0 (mouse is outside bb) - - - - - - +// Frame N+1 (mouse moves inside bb) - true - - - - +// Frame N+2 (mouse button is down) - true true true - true +// Frame N+3 (mouse button is down) - true true - - - +// Frame N+4 (mouse moves outside bb) - - true - - - +// Frame N+5 (mouse moves inside bb) - true true - - - +// Frame N+6 (mouse button is released) true true - - true - +// Frame N+7 (mouse button is released) - true - - - - +// Frame N+8 (mouse moves outside bb) - - - - - - +//------------------------------------------------------------------------------------------------------------------------------------------------ +// with PressedOnClick: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked() +// Frame N+2 (mouse button is down) true true true true - true +// Frame N+3 (mouse button is down) - true true - - - +// Frame N+6 (mouse button is released) - true - - true - +// Frame N+7 (mouse button is released) - true - - - - +//------------------------------------------------------------------------------------------------------------------------------------------------ +// with PressedOnRelease: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked() +// Frame N+2 (mouse button is down) - true - - - true +// Frame N+3 (mouse button is down) - true - - - - +// Frame N+6 (mouse button is released) true true - - - - +// Frame N+7 (mouse button is released) - true - - - - +//------------------------------------------------------------------------------------------------------------------------------------------------ +// with PressedOnDoubleClick: return-value IsItemHovered() IsItemActive() IsItemActivated() IsItemDeactivated() IsItemClicked() +// Frame N+0 (mouse button is down) - true - - - true +// Frame N+1 (mouse button is down) - true - - - - +// Frame N+2 (mouse button is released) - true - - - - +// Frame N+3 (mouse button is released) - true - - - - +// Frame N+4 (mouse button is down) true true true true - true +// Frame N+5 (mouse button is down) - true true - - - +// Frame N+6 (mouse button is released) - true - - true - +// Frame N+7 (mouse button is released) - true - - - - +//------------------------------------------------------------------------------------------------------------------------------------------------ +// Note that some combinations are supported, +// - PressedOnDragDropHold can generally be associated with any flag. +// - PressedOnDoubleClick can be associated by PressedOnClickRelease/PressedOnRelease, in which case the second release event won't be reported. +//------------------------------------------------------------------------------------------------------------------------------------------------ +// The behavior of the return-value changes when ImGuiButtonFlags_Repeat is set: +// Repeat+ Repeat+ Repeat+ Repeat+ +// PressedOnClickRelease PressedOnClick PressedOnRelease PressedOnDoubleClick +//------------------------------------------------------------------------------------------------------------------------------------------------- +// Frame N+0 (mouse button is down) - true - true +// ... - - - - +// Frame N + RepeatDelay true true - true +// ... - - - - +// Frame N + RepeatDelay + RepeatRate*N true true - true +//------------------------------------------------------------------------------------------------------------------------------------------------- + +bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + // Default only reacts to left mouse button + if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) + flags |= ImGuiButtonFlags_MouseButtonDefault_; + + // Default behavior requires click + release inside bounding box + if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) + flags |= ImGuiButtonFlags_PressedOnDefault_; + + ImGuiWindow* backup_hovered_window = g.HoveredWindow; + const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindowDockTree == window->RootWindowDockTree; + if (flatten_hovered_children) + g.HoveredWindow = window; + +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (id != 0 && g.LastItemData.ID != id) + IMGUI_TEST_ENGINE_ITEM_ADD(bb, id); +#endif + + bool pressed = false; + bool hovered = ItemHoverable(bb, id); + + // Drag source doesn't report as hovered + if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) + hovered = false; + + // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button + if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) + if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + { + hovered = true; + SetHoveredID(id); + if (g.HoveredIdTimer - g.IO.DeltaTime <= DRAGDROP_HOLD_TO_OPEN_TIMER && g.HoveredIdTimer >= DRAGDROP_HOLD_TO_OPEN_TIMER) + { + pressed = true; + g.DragDropHoldJustPressedId = id; + FocusWindow(window); + } + } + + if (flatten_hovered_children) + g.HoveredWindow = backup_hovered_window; + + // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. + if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) + hovered = false; + + // Mouse handling + if (hovered) + { + if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) + { + // Poll buttons + int mouse_button_clicked = -1; + int mouse_button_released = -1; + if ((flags & ImGuiButtonFlags_MouseButtonLeft) && g.IO.MouseClicked[0]) { mouse_button_clicked = 0; } + else if ((flags & ImGuiButtonFlags_MouseButtonRight) && g.IO.MouseClicked[1]) { mouse_button_clicked = 1; } + else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && g.IO.MouseClicked[2]) { mouse_button_clicked = 2; } + if ((flags & ImGuiButtonFlags_MouseButtonLeft) && g.IO.MouseReleased[0]) { mouse_button_released = 0; } + else if ((flags & ImGuiButtonFlags_MouseButtonRight) && g.IO.MouseReleased[1]) { mouse_button_released = 1; } + else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && g.IO.MouseReleased[2]) { mouse_button_released = 2; } + + if (mouse_button_clicked != -1 && g.ActiveId != id) + { + if (flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere)) + { + SetActiveID(id, window); + g.ActiveIdMouseButton = mouse_button_clicked; + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + FocusWindow(window); + } + if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseClickedCount[mouse_button_clicked] == 2)) + { + pressed = true; + if (flags & ImGuiButtonFlags_NoHoldingActiveId) + ClearActiveID(); + else + SetActiveID(id, window); // Hold on ID + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + g.ActiveIdMouseButton = mouse_button_clicked; + FocusWindow(window); + } + } + if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1) + { + // Repeat mode trumps on release behavior + const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; + if (!has_repeated_at_least_once) + pressed = true; + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + ClearActiveID(); + } + + // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). + // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. + if (g.ActiveId == id && (flags & ImGuiButtonFlags_Repeat)) + if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, true)) + pressed = true; + } + + if (pressed) + g.NavDisableHighlight = true; + } + + // Gamepad/Keyboard navigation + // We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse. + if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover && (g.ActiveId == 0 || g.ActiveId == id || g.ActiveId == window->MoveId)) + if (!(flags & ImGuiButtonFlags_NoHoveredOnFocus)) + hovered = true; + if (g.NavActivateDownId == id) + { + bool nav_activated_by_code = (g.NavActivateId == id); + bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed); + if (nav_activated_by_code || nav_activated_by_inputs) + { + // Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button. + pressed = true; + SetActiveID(id, window); + g.ActiveIdSource = ImGuiInputSource_Nav; + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + } + } + + // Process while held + bool held = false; + if (g.ActiveId == id) + { + if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + if (g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; + + const int mouse_button = g.ActiveIdMouseButton; + IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT); + if (g.IO.MouseDown[mouse_button]) + { + held = true; + } + else + { + bool release_in = hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease) != 0; + bool release_anywhere = (flags & ImGuiButtonFlags_PressedOnClickReleaseAnywhere) != 0; + if ((release_in || release_anywhere) && !g.DragDropActive) + { + // Report as pressed when releasing the mouse (this is the most common path) + bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2; + bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps + if (!is_double_click_release && !is_repeating_already) + pressed = true; + } + ClearActiveID(); + } + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + g.NavDisableHighlight = true; + } + else if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + // When activated using Nav, we hold on the ActiveID until activation button is released + if (g.NavActivateDownId != id) + ClearActiveID(); + } + if (pressed) + g.ActiveIdHasBeenPressedBefore = true; + } + + if (out_hovered) *out_hovered = hovered; + if (out_held) *out_held = held; + + return pressed; +} + +bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + ImVec2 pos = window->DC.CursorPos; + if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag) + pos.y += window->DC.CurrLineTextBaseOffset - style.FramePadding.y; + ImVec2 size = CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); + + const ImRect bb(pos, pos + size); + ItemSize(size, style.FramePadding.y); + if (!ItemAdd(bb, id)) + return false; + + if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) + flags |= ImGuiButtonFlags_Repeat; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + + if (g.LogEnabled) + LogSetNextTextDecoration("[", "]"); + RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb); + + // Automatically close popups + //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + // CloseCurrentPopup(); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + return pressed; +} + +bool ImGui::Button(const char* label, const ImVec2& size_arg) +{ + return ButtonEx(label, size_arg, ImGuiButtonFlags_None); +} + +// Small buttons fits within text without additional vertical spacing. +bool ImGui::SmallButton(const char* label) +{ + ImGuiContext& g = *GImGui; + float backup_padding_y = g.Style.FramePadding.y; + g.Style.FramePadding.y = 0.0f; + bool pressed = ButtonEx(label, ImVec2(0, 0), ImGuiButtonFlags_AlignTextBaseLine); + g.Style.FramePadding.y = backup_padding_y; + 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_arg, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + // Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size. + IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f); + + const ImGuiID id = window->GetID(str_id); + ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(size); + if (!ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags); + return pressed; +} + +bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + 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); + const float default_size = GetFrameHeight(); + ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f); + if (!ItemAdd(bb, id)) + return false; + + if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) + flags |= ImGuiButtonFlags_Repeat; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + // Render + const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + const ImU32 text_col = GetColorU32(ImGuiCol_Text); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding); + RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags); + return pressed; +} + +bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir) +{ + float sz = GetFrameHeight(); + return ArrowButtonEx(str_id, dir, ImVec2(sz, sz), ImGuiButtonFlags_None); +} + +// Button to close a window +bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // Tweak 1: Shrink hit-testing area if button covers an abnormally large proportion of the visible region. That's in order to facilitate moving the window away. (#3825) + // This may better be applied as a general hit-rect reduction mechanism for all widgets to ensure the area to move window is always accessible? + const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f); + ImRect bb_interact = bb; + const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea(); + if (area_to_visible_ratio < 1.5f) + bb_interact.Expand(ImFloor(bb_interact.GetSize() * -0.25f)); + + // Tweak 2: We intentionally allow interaction when clipped so that a mechanical Alt,Right,Activate sequence can always close a window. + // (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible). + bool is_clipped = !ItemAdd(bb_interact, id); + + bool hovered, held; + bool pressed = ButtonBehavior(bb_interact, id, &hovered, &held); + if (is_clipped) + return pressed; + + // Render + // FIXME: Clarify this mess + ImU32 col = GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered); + ImVec2 center = bb.GetCenter(); + if (hovered) + window->DrawList->AddCircleFilled(center, ImMax(2.0f, g.FontSize * 0.5f + 1.0f), col, 12); + + float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f; + ImU32 cross_col = GetColorU32(ImGuiCol_Text); + center -= ImVec2(0.5f, 0.5f); + window->DrawList->AddLine(center + ImVec2(+cross_extent, +cross_extent), center + ImVec2(-cross_extent, -cross_extent), cross_col, 1.0f); + window->DrawList->AddLine(center + ImVec2(+cross_extent, -cross_extent), center + ImVec2(-cross_extent, +cross_extent), cross_col, 1.0f); + + return pressed; +} + +// The Collapse button also functions as a Dock Menu button. +bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f); + ItemAdd(bb, id); + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None); + + // Render + //bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed); + ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + ImU32 text_col = GetColorU32(ImGuiCol_Text); + ImVec2 center = bb.GetCenter(); + if (hovered || held) + window->DrawList->AddCircleFilled(center + ImVec2(0,-0.5f), g.FontSize * 0.5f + 1.0f, bg_col, 12); + + if (dock_node) + RenderArrowDockMenu(window->DrawList, bb.Min + g.Style.FramePadding, g.FontSize, text_col); + else + RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); + + // Switch to moving the window after mouse is moved beyond the initial drag threshold + if (IsItemActive() && IsMouseDragging(0)) + StartMouseMovingWindowOrNode(window, dock_node, true); + + return pressed; +} + +ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis) +{ + return window->GetIDNoKeepAlive(axis == ImGuiAxis_X ? "#SCROLLX" : "#SCROLLY"); +} + +// Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set. +ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis) +{ + const ImRect outer_rect = window->Rect(); + const ImRect inner_rect = window->InnerRect; + const float border_size = window->WindowBorderSize; + const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar) + IM_ASSERT(scrollbar_size > 0.0f); + if (axis == ImGuiAxis_X) + return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x, outer_rect.Max.y); + else + return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x, inner_rect.Max.y); +} + +void ImGui::Scrollbar(ImGuiAxis axis) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const ImGuiID id = GetWindowScrollbarID(window, axis); + KeepAliveID(id); + + // Calculate scrollbar bounding box + ImRect bb = GetWindowScrollbarRect(window, axis); + ImDrawFlags rounding_corners = ImDrawFlags_RoundCornersNone; + if (axis == ImGuiAxis_X) + { + rounding_corners |= ImDrawFlags_RoundCornersBottomLeft; + if (!window->ScrollbarY) + rounding_corners |= ImDrawFlags_RoundCornersBottomRight; + } + else + { + if ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) + rounding_corners |= ImDrawFlags_RoundCornersTopRight; + if (!window->ScrollbarX) + rounding_corners |= ImDrawFlags_RoundCornersBottomRight; + } + float size_avail = window->InnerRect.Max[axis] - window->InnerRect.Min[axis]; + float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f; + ImS64 scroll = (ImS64)window->Scroll[axis]; + ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_avail, (ImS64)size_contents, rounding_corners); + window->Scroll[axis] = (float)scroll; +} + +// Vertical/Horizontal 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 normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar +// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. +// Still, the code should probably be made simpler.. +bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_avail_v, ImS64 size_contents_v, ImDrawFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + const float bb_frame_width = bb_frame.GetWidth(); + const float bb_frame_height = bb_frame.GetHeight(); + if (bb_frame_width <= 0.0f || bb_frame_height <= 0.0f) + return false; + + // When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the window resize grab) + float alpha = 1.0f; + if ((axis == ImGuiAxis_Y) && bb_frame_height < g.FontSize + g.Style.FramePadding.y * 2.0f) + alpha = ImSaturate((bb_frame_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f)); + if (alpha <= 0.0f) + return false; + + const ImGuiStyle& style = g.Style; + const bool allow_interaction = (alpha >= 1.0f); + + ImRect bb = bb_frame; + bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f))); + + // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) + const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight(); + + // Calculate the height of our grabbable box. It 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. + IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. + const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), (ImS64)1); + const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_avail_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v); + const float grab_h_norm = grab_h_pixels / scrollbar_size_v; + + // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). + bool held = false; + bool hovered = false; + ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); + + const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v); + float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); + float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space + if (held && allow_interaction && grab_h_norm < 1.0f) + { + const float scrollbar_pos_v = bb.Min[axis]; + const float mouse_pos_v = g.IO.MousePos[axis]; + + // Click position in scrollbar normalized space (0.0f->1.0f) + const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); + SetHoveredID(id); + + bool seek_absolute = false; + if (g.ActiveIdIsJustActivated) + { + // On initial click calculate the distance between mouse and the center of the grab + seek_absolute = (clicked_v_norm < grab_v_norm || clicked_v_norm > grab_v_norm + grab_h_norm); + if (seek_absolute) + g.ScrollbarClickDeltaToGrabCenter = 0.0f; + else + g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + } + + // Apply scroll (p_scroll_v will generally point on one member of window->Scroll) + // It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position + const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); + *p_scroll_v = (ImS64)(scroll_v_norm * scroll_max); + + // Update values for rendering + scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); + grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; + + // Update distance to grab now that we have seeked and saturated + if (seek_absolute) + g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + } + + // Render + const ImU32 bg_col = GetColorU32(ImGuiCol_ScrollbarBg); + const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha); + window->DrawList->AddRectFilled(bb_frame.Min, bb_frame.Max, bg_col, window->WindowRounding, flags); + ImRect grab_rect; + if (axis == ImGuiAxis_X) + grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y); + else + grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels); + window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); + + return held; +} + +void ImGui::ImageRotated(ImTextureID tex_id, ImVec2 center, ImVec2 size, float angle) { + + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImRect bb(window->DC.CursorPos + ImVec2(size.x / 2, size.y / 2), window->DC.CursorPos + size); + + ImVec2 pos[4] = + { + center + bb.Min + ImVec2(-size.x * 0.5f, -size.y * 0.5f), + center + bb.Min + ImVec2(+size.x * 0.5f, -size.y * 0.5f), + center + bb.Min + ImVec2(+size.x * 0.5f, +size.y * 0.5f), + center + bb.Min + ImVec2(-size.x * 0.5f, +size.y * 0.5f) + }; + ImVec2 uvs[4] = + { + ImVec2(0.0f, 1.0f), + ImVec2(1.0f, 1.0f), + ImVec2(1.0f, 0.0f), + ImVec2(0.0f, 0.0f) + }; + + draw_list->AddImageQuad(tex_id, pos[0], pos[1], pos[2], pos[3], uvs[0], uvs[1], uvs[2], uvs[3], IM_COL32_WHITE); +} + +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, 0)) + return; + + if (border_col.w > 0.0f) + { + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f); + window->DrawList->AddImage(user_texture_id, bb.Min + ImVec2(1, 1), bb.Max - ImVec2(1, 1), uv0, uv1, GetColorU32(tint_col)); + } + else + { + window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, GetColorU32(tint_col)); + } +} + +// ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390) +// We provide this internal helper to write your own variant while we figure out how to redesign the public ImageButton() API. +bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2); + ItemSize(bb); + if (!ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding)); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col)); + window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col)); + + return pressed; +} + +// frame_padding < 0: uses FramePadding from style (default) +// frame_padding = 0: no framing +// frame_padding > 0: set framing size +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) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + // Default to using texture ID as ID. User can still push string/integer prefixes. + PushID((void*)(intptr_t)user_texture_id); + const ImGuiID id = window->GetID("#image"); + PopID(); + + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding; + return ImageButtonEx(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col); +} + +bool ImGui::Checkbox(const char* label, bool* v) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const float square_sz = GetFrameHeight(); + const ImVec2 pos = window->DC.CursorPos; + const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id)) + { + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); + return false; + } + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) + { + *v = !(*v); + MarkItemEdited(id); + } + + const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); + RenderNavHighlight(total_bb, id); + RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); + bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; + if (mixed_value) + { + // Undocumented tristate/mixed/indeterminate checkbox (#2644) + // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) + ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f))); + window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); + } + else if (*v) + { + const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); + RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); + } + + ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); + if (g.LogEnabled) + LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]"); + if (label_size.x > 0.0f) + RenderText(label_pos, label); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); + return pressed; +} + +template +bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value) +{ + bool all_on = (*flags & flags_value) == flags_value; + bool any_on = (*flags & flags_value) != 0; + bool pressed; + if (!all_on && any_on) + { + ImGuiContext& g = *GImGui; + ImGuiItemFlags backup_item_flags = g.CurrentItemFlags; + g.CurrentItemFlags |= ImGuiItemFlags_MixedValue; + pressed = Checkbox(label, &all_on); + g.CurrentItemFlags = backup_item_flags; + } + else + { + pressed = Checkbox(label, &all_on); + + } + if (pressed) + { + if (all_on) + *flags |= flags_value; + else + *flags &= ~flags_value; + } + return pressed; +} + +bool ImGui::CheckboxFlags(const char* label, int* flags, int flags_value) +{ + return CheckboxFlagsT(label, flags, flags_value); +} + +bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) +{ + return CheckboxFlagsT(label, flags, flags_value); +} + +bool ImGui::CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value) +{ + return CheckboxFlagsT(label, flags, flags_value); +} + +bool ImGui::CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value) +{ + return CheckboxFlagsT(label, flags, flags_value); +} + +bool ImGui::RadioButton(const char* label, bool active) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + const float square_sz = GetFrameHeight(); + const ImVec2 pos = window->DC.CursorPos; + const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); + const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id)) + return false; + + ImVec2 center = check_bb.GetCenter(); + center.x = IM_ROUND(center.x); + center.y = IM_ROUND(center.y); + const float radius = (square_sz - 1.0f) * 0.5f; + + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) + MarkItemEdited(id); + + RenderNavHighlight(total_bb, id); + window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); + if (active) + { + const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); + window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark), 16); + } + + if (style.FrameBorderSize > 0.0f) + { + window->DrawList->AddCircle(center + ImVec2(1, 1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); + } + + ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); + if (g.LogEnabled) + LogRenderedText(&label_pos, active ? "(x)" : "( )"); + if (label_size.x > 0.0f) + RenderText(label_pos, label); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + return pressed; +} + +// FIXME: This would work nicely if it was a public template, e.g. 'template RadioButton(const char* label, T* v, T v_button)', but I'm not sure how we would expose it.. +bool ImGui::RadioButton(const char* label, int* v, int v_button) +{ + const bool pressed = RadioButton(label, *v == v_button); + if (pressed) + *v = v_button; + return pressed; +} + +// size_arg (for each axis) < 0.0f: align to end, 0.0f: auto, > 0.0f: specified size +void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* overlay) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + ImVec2 pos = window->DC.CursorPos; + ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y * 2.0f); + ImRect bb(pos, pos + size); + ItemSize(size, style.FramePadding.y); + if (!ItemAdd(bb, 0)) + return; + + // Render + fraction = ImSaturate(fraction); + RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); + const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); + RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); + + // Default displaying the fraction as percentage string, but user can override it + char overlay_buf[32]; + if (!overlay) + { + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); + overlay = overlay_buf; + } + + ImVec2 overlay_size = CalcTextSize(overlay, NULL); + if (overlay_size.x > 0.0f) + RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); +} + +void ImGui::Bullet() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); + ItemSize(bb); + if (!ItemAdd(bb, 0)) + { + SameLine(0, style.FramePadding.x * 2); + return; + } + + // Render and stay on same line + ImU32 text_col = GetColorU32(ImGuiCol_Text); + RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, line_height * 0.5f), text_col); + SameLine(0, style.FramePadding.x * 2.0f); +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Low-level Layout helpers +//------------------------------------------------------------------------- +// - Spacing() +// - Dummy() +// - NewLine() +// - AlignTextToFramePadding() +// - SeparatorEx() [Internal] +// - Separator() +// - SplitterBehavior() [Internal] +// - ShrinkWidths() [Internal] +//------------------------------------------------------------------------- + +void ImGui::Spacing() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ItemSize(ImVec2(0, 0)); +} + +void ImGui::Dummy(const ImVec2& size) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(size); + ItemAdd(bb, 0); +} + +void ImGui::NewLine() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; + window->DC.LayoutType = ImGuiLayoutType_Vertical; + if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. + ItemSize(ImVec2(0, 0)); + else + ItemSize(ImVec2(0.0f, g.FontSize)); + window->DC.LayoutType = backup_layout_type; +} + +void ImGui::AlignTextToFramePadding() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + window->DC.CurrLineSize.y = ImMax(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2); + window->DC.CurrLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, g.Style.FramePadding.y); +} + +// Horizontal/vertical separating line +void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + ImGuiContext& g = *GImGui; + IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected + + float thickness_draw = 1.0f; + float thickness_layout = 0.0f; + if (flags & ImGuiSeparatorFlags_Vertical) + { + // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout. + float y1 = window->DC.CursorPos.y; + float y2 = window->DC.CursorPos.y + window->DC.CurrLineSize.y; + const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + thickness_draw, y2)); + ItemSize(ImVec2(thickness_layout, 0.0f)); + if (!ItemAdd(bb, 0)) + return; + + // Draw + window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); + if (g.LogEnabled) + LogText(" |"); + } + else if (flags & ImGuiSeparatorFlags_Horizontal) + { + // Horizontal Separator + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + + // FIXME-WORKRECT: old hack (#205) until we decide of consistent behavior with WorkRect/Indent and Separator + if (g.GroupStack.Size > 0 && g.GroupStack.back().WindowID == window->ID) + x1 += window->DC.Indent.x; + + // FIXME-WORKRECT: In theory we should simply be using WorkRect.Min.x/Max.x everywhere but it isn't aesthetically what we want, + // need to introduce a variant of WorkRect for that purpose. (#4787) + if (ImGuiTable* table = g.CurrentTable) + { + x1 = table->Columns[table->CurrentColumn].MinX; + x2 = table->Columns[table->CurrentColumn].MaxX; + } + + ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL; + if (columns) + PushColumnsBackground(); + + // We don't provide our width to the layout so that it doesn't get feed back into AutoFit + // FIXME: This prevents ->CursorMaxPos based bounding box evaluation from working (e.g. TableEndCell) + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw)); + ItemSize(ImVec2(0.0f, thickness_layout)); + const bool item_visible = ItemAdd(bb, 0); + if (item_visible) + { + // Draw + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); + if (g.LogEnabled) + LogRenderedText(&bb.Min, "--------------------------------\n"); + + } + if (columns) + { + PopColumnsBackground(); + columns->LineMinY = window->DC.CursorPos.y; + } + } +} + +void ImGui::Separator() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + // Those flags should eventually be overridable by the user + ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; + flags |= ImGuiSeparatorFlags_SpanAllColumns; // NB: this only applies to legacy Columns() api as they relied on Separator() a lot. + SeparatorEx(flags); +} + +// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise. +bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay, ImU32 bg_col) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags; + g.CurrentItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; + bool item_add = ItemAdd(bb, id); + g.CurrentItemFlags = item_flags_backup; + if (!item_add) + return false; + + bool hovered, held; + ImRect bb_interact = bb; + bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); + ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); + if (hovered) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb + if (g.ActiveId != id) + SetItemAllowOverlap(); + + if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay)) + SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); + + ImRect bb_render = bb; + if (held) + { + ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; + float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; + + // Minimum pane size + float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1); + float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2); + if (mouse_delta < -size_1_maximum_delta) + mouse_delta = -size_1_maximum_delta; + if (mouse_delta > size_2_maximum_delta) + mouse_delta = size_2_maximum_delta; + + // Apply resize + if (mouse_delta != 0.0f) + { + if (mouse_delta < 0.0f) + IM_ASSERT(*size1 + mouse_delta >= min_size1); + if (mouse_delta > 0.0f) + IM_ASSERT(*size2 - mouse_delta >= min_size2); + *size1 += mouse_delta; + *size2 -= mouse_delta; + bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); + MarkItemEdited(id); + } + } + + // Render at new position + if (bg_col & IM_COL32_A_MASK) + window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, bg_col, 0.0f); + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, 0.0f); + + return held; +} + +static int IMGUI_CDECL ShrinkWidthItemComparer(const void* lhs, const void* rhs) +{ + const ImGuiShrinkWidthItem* a = (const ImGuiShrinkWidthItem*)lhs; + const ImGuiShrinkWidthItem* b = (const ImGuiShrinkWidthItem*)rhs; + if (int d = (int)(b->Width - a->Width)) + return d; + return (b->Index - a->Index); +} + +// Shrink excess width from a set of item, by removing width from the larger items first. +// Set items Width to -1.0f to disable shrinking this item. +void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess) +{ + if (count == 1) + { + if (items[0].Width >= 0.0f) + items[0].Width = ImMax(items[0].Width - width_excess, 1.0f); + return; + } + ImQsort(items, (size_t)count, sizeof(ImGuiShrinkWidthItem), ShrinkWidthItemComparer); + int count_same_width = 1; + while (width_excess > 0.0f && count_same_width < count) + { + while (count_same_width < count && items[0].Width <= items[count_same_width].Width) + count_same_width++; + float max_width_to_remove_per_item = (count_same_width < count && items[count_same_width].Width >= 0.0f) ? (items[0].Width - items[count_same_width].Width) : (items[0].Width - 1.0f); + if (max_width_to_remove_per_item <= 0.0f) + break; + float width_to_remove_per_item = ImMin(width_excess / count_same_width, max_width_to_remove_per_item); + for (int item_n = 0; item_n < count_same_width; item_n++) + items[item_n].Width -= width_to_remove_per_item; + width_excess -= width_to_remove_per_item * count_same_width; + } + + // Round width and redistribute remainder left-to-right (could make it an option of the function?) + // Ensure that e.g. the right-most tab of a shrunk tab-bar always reaches exactly at the same distance from the right-most edge of the tab bar separator. + width_excess = 0.0f; + for (int n = 0; n < count; n++) + { + float width_rounded = ImFloor(items[n].Width); + width_excess += items[n].Width - width_rounded; + items[n].Width = width_rounded; + } + if (width_excess > 0.0f) + for (int n = 0; n < count; n++) + if (items[n].Index < (int)(width_excess + 0.01f)) + items[n].Width += 1.0f; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: ComboBox +//------------------------------------------------------------------------- +// - CalcMaxPopupHeightFromItemCount() [Internal] +// - BeginCombo() +// - BeginComboPopup() [Internal] +// - EndCombo() +// - BeginComboPreview() [Internal] +// - EndComboPreview() [Internal] +// - Combo() +//------------------------------------------------------------------------- + +static float CalcMaxPopupHeightFromItemCount(int items_count) +{ + ImGuiContext& g = *GImGui; + if (items_count <= 0) + return FLT_MAX; + return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2); +} + +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + + ImGuiNextWindowDataFlags backup_next_window_data_flags = g.NextWindowData.Flags; + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together + + const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight(); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : CalcItemWidth(); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); + const ImRect total_bb(bb.Min, 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, &bb)) + return false; + + // Open on click + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + const ImGuiID popup_id = ImHashStr("##ComboPopup", 0, id); + bool popup_open = IsPopupOpen(popup_id, ImGuiPopupFlags_None); + if (pressed && !popup_open) + { + OpenPopupEx(popup_id, ImGuiPopupFlags_None); + popup_open = true; + } + + // Render shape + const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + const float value_x2 = ImMax(bb.Min.x, bb.Max.x - arrow_size); + RenderNavHighlight(bb, id); + if (!(flags & ImGuiComboFlags_NoPreview)) + window->DrawList->AddRectFilled(bb.Min, ImVec2(value_x2, bb.Max.y), frame_col, style.FrameRounding, (flags & ImGuiComboFlags_NoArrowButton) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersLeft); + if (!(flags & ImGuiComboFlags_NoArrowButton)) + { + ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + ImU32 text_col = GetColorU32(ImGuiCol_Text); + window->DrawList->AddRectFilled(ImVec2(value_x2, bb.Min.y), bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersRight); + if (value_x2 + arrow_size - style.FramePadding.x <= bb.Max.x) + RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down, 1.0f); + } + RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); + + // Custom preview + if (flags & ImGuiComboFlags_CustomPreview) + { + g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y); + IM_ASSERT(preview_value == NULL || preview_value[0] == 0); + preview_value = NULL; + } + + // Render preview and label + if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) + { + if (g.LogEnabled) + LogSetNextTextDecoration("{", "}"); + RenderTextClipped(bb.Min + style.FramePadding, ImVec2(value_x2, bb.Max.y), preview_value, NULL, NULL); + } + if (label_size.x > 0) + RenderText(ImVec2(bb.Max.x + style.ItemInnerSpacing.x, bb.Min.y + style.FramePadding.y), label); + + if (!popup_open) + return false; + + g.NextWindowData.Flags = backup_next_window_data_flags; + return BeginComboPopup(popup_id, bb, flags); +} + +bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags) +{ + ImGuiContext& g = *GImGui; + if (!IsPopupOpen(popup_id, ImGuiPopupFlags_None)) + { + g.NextWindowData.ClearFlags(); + return false; + } + + // Set popup size + float w = bb.GetWidth(); + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) + { + g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); + } + else + { + if ((flags & ImGuiComboFlags_HeightMask_) == 0) + flags |= ImGuiComboFlags_HeightRegular; + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiComboFlags_HeightMask_)); // Only one + int popup_max_height_in_items = -1; + if (flags & ImGuiComboFlags_HeightRegular) popup_max_height_in_items = 8; + else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; + else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; + SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); + } + + // This is essentially a specialized version of BeginPopupEx() + char name[16]; + ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth + + // Set position given a custom constraint (peak into expected window size so we can position it) + // FIXME: This might be easier to express with an hypothetical SetNextWindowPosConstraints() function? + // FIXME: This might be moved to Begin() or at least around the same spot where Tooltips and other Popups are calling FindBestWindowPosForPopupEx()? + if (ImGuiWindow* popup_window = FindWindowByName(name)) + if (popup_window->WasActive) + { + // Always override 'AutoPosLastDirection' to not leave a chance for a past value to affect us. + ImVec2 size_expected = CalcWindowNextAutoFitSize(popup_window); + popup_window->AutoPosLastDirection = (flags & ImGuiComboFlags_PopupAlignLeft) ? ImGuiDir_Left : ImGuiDir_Down; // Left = "Below, Toward Left", Down = "Below, Toward Right (default)" + ImRect r_outer = GetPopupAllowedExtentRect(popup_window); + ImVec2 pos = FindBestWindowPosForPopupEx(bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, bb, ImGuiPopupPositionPolicy_ComboBox); + SetNextWindowPos(pos); + } + + // We don't use BeginPopupEx() solely because we have a custom name string, which we could make an argument to BeginPopupEx() + ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove; + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(g.Style.FramePadding.x, g.Style.WindowPadding.y)); // Horizontally align ourselves with the framed text + bool ret = Begin(name, NULL, window_flags); + PopStyleVar(); + if (!ret) + { + EndPopup(); + IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above + return false; + } + return true; +} + +void ImGui::EndCombo() +{ + EndPopup(); +} + +// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements +// (Experimental, see GitHub issues: #1658, #4168) +bool ImGui::BeginComboPreview() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiComboPreviewData* preview_data = &g.ComboPreviewData; + + if (window->SkipItems || !window->ClipRect.Overlaps(g.LastItemData.Rect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result + return false; + IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag? + if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional) + return false; + + // FIXME: This could be contained in a PushWorkRect() api + preview_data->BackupCursorPos = window->DC.CursorPos; + preview_data->BackupCursorMaxPos = window->DC.CursorMaxPos; + preview_data->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine; + preview_data->BackupPrevLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; + preview_data->BackupLayout = window->DC.LayoutType; + window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.LayoutType = ImGuiLayoutType_Horizontal; + PushClipRect(preview_data->PreviewRect.Min, preview_data->PreviewRect.Max, true); + + return true; +} + +void ImGui::EndComboPreview() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiComboPreviewData* preview_data = &g.ComboPreviewData; + + // FIXME: Using CursorMaxPos approximation instead of correct AABB which we will store in ImDrawCmd in the future + ImDrawList* draw_list = window->DrawList; + if (window->DC.CursorMaxPos.x < preview_data->PreviewRect.Max.x && window->DC.CursorMaxPos.y < preview_data->PreviewRect.Max.y) + if (draw_list->CmdBuffer.Size > 1) // Unlikely case that the PushClipRect() didn't create a command + { + draw_list->_CmdHeader.ClipRect = draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ClipRect = draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 2].ClipRect; + draw_list->_TryMergeDrawCmds(); + } + PopClipRect(); + window->DC.CursorPos = preview_data->BackupCursorPos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos); + window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine; + window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset; + window->DC.LayoutType = preview_data->BackupLayout; + preview_data->PreviewRect = ImRect(); +} + +// Getter for the old Combo() API: const char*[] +static bool Items_ArrayGetter(void* data, int idx, const char** out_text) +{ + const char* const* items = (const char* const*)data; + if (out_text) + *out_text = items[idx]; + return true; +} + +// Getter for the old Combo() API: "item1\0item2\0item3\0" +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; +} + +// Old API, prefer using BeginCombo() nowadays if you can. +bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_max_height_in_items) +{ + ImGuiContext& g = *GImGui; + + // Call the getter to obtain the preview string which is a parameter to BeginCombo() + const char* preview_value = NULL; + if (*current_item >= 0 && *current_item < items_count) + items_getter(data, *current_item, &preview_value); + + // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here. + if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)) + SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); + + if (!BeginCombo(label, preview_value, ImGuiComboFlags_None)) + return false; + + // Display items + // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) + bool value_changed = false; + for (int i = 0; i < items_count; i++) + { + PushID(i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (Selectable(item_text, item_selected)) + { + value_changed = true; + *current_item = i; + } + if (item_selected) + SetItemDefaultFocus(); + PopID(); + } + + EndCombo(); + + if (value_changed) + MarkItemEdited(g.LastItemData.ID); + + return value_changed; +} + +// Combo box helper allowing to pass an array of strings. +bool ImGui::Combo(const char* label, int* current_item, const char* const 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 literal holding multiple zero-terminated items "item1\0item2\0" +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, or at least only when combo is open + 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; +} + +//------------------------------------------------------------------------- +// [SECTION] Data Type and Data Formatting Helpers [Internal] +//------------------------------------------------------------------------- +// - PatchFormatStringFloatToInt() +// - DataTypeGetInfo() +// - DataTypeFormatString() +// - DataTypeApplyOp() +// - DataTypeApplyOpFromText() +// - DataTypeClamp() +// - GetMinimumStepAtDecimalPrecision +// - RoundScalarWithFormat<>() +//------------------------------------------------------------------------- + +static const ImGuiDataTypeInfo GDataTypeInfo[] = +{ + { sizeof(char), "S8", "%d", "%d" }, // ImGuiDataType_S8 + { sizeof(unsigned char), "U8", "%u", "%u" }, + { sizeof(short), "S16", "%d", "%d" }, // ImGuiDataType_S16 + { sizeof(unsigned short), "U16", "%u", "%u" }, + { sizeof(int), "S32", "%d", "%d" }, // ImGuiDataType_S32 + { sizeof(unsigned int), "U32", "%u", "%u" }, +#ifdef _MSC_VER + { sizeof(ImS64), "S64", "%I64d","%I64d" }, // ImGuiDataType_S64 + { sizeof(ImU64), "U64", "%I64u","%I64u" }, +#else + { sizeof(ImS64), "S64", "%lld", "%lld" }, // ImGuiDataType_S64 + { sizeof(ImU64), "U64", "%llu", "%llu" }, +#endif + { sizeof(float), "float", "%.3f","%f" }, // ImGuiDataType_Float (float are promoted to double in va_arg) + { sizeof(double), "double","%f", "%lf" }, // ImGuiDataType_Double +}; +IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT); + +// FIXME-LEGACY: Prior to 1.61 our DragInt() function internally used floats and because of this the compile-time default value for format was "%.0f". +// Even though we changed the compile-time default, we expect users to have carried %f around, which would break the display of DragInt() calls. +// To honor backward compatibility we are rewriting the format string, unless IMGUI_DISABLE_OBSOLETE_FUNCTIONS is enabled. What could possibly go wrong?! +static const char* PatchFormatStringFloatToInt(const char* fmt) +{ + if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '0' && fmt[3] == 'f' && fmt[4] == 0) // Fast legacy path for "%.0f" which is expected to be the most common case. + return "%d"; + const char* fmt_start = ImParseFormatFindStart(fmt); // Find % (if any, and ignore %%) + const char* fmt_end = ImParseFormatFindEnd(fmt_start); // Find end of format specifier, which itself is an exercise of confidence/recklessness (because snprintf is dependent on libc or user). + if (fmt_end > fmt_start && fmt_end[-1] == 'f') + { +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (fmt_start == fmt && fmt_end[0] == 0) + return "%d"; + ImGuiContext& g = *GImGui; + ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%.*s%%d%s", (int)(fmt_start - fmt), fmt, fmt_end); // Honor leading and trailing decorations, but lose alignment/precision. + return g.TempBuffer; +#else + IM_ASSERT(0 && "DragInt(): Invalid format string!"); // Old versions used a default parameter of "%.0f", please replace with e.g. "%d" +#endif + } + return fmt; +} + +const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type) +{ + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + return &GDataTypeInfo[data_type]; +} + +int ImGui::DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format) +{ + // Signedness doesn't matter when pushing integer arguments + if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) + return ImFormatString(buf, buf_size, format, *(const ImU32*)p_data); + if (data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64) + return ImFormatString(buf, buf_size, format, *(const ImU64*)p_data); + if (data_type == ImGuiDataType_Float) + return ImFormatString(buf, buf_size, format, *(const float*)p_data); + if (data_type == ImGuiDataType_Double) + return ImFormatString(buf, buf_size, format, *(const double*)p_data); + if (data_type == ImGuiDataType_S8) + return ImFormatString(buf, buf_size, format, *(const ImS8*)p_data); + if (data_type == ImGuiDataType_U8) + return ImFormatString(buf, buf_size, format, *(const ImU8*)p_data); + if (data_type == ImGuiDataType_S16) + return ImFormatString(buf, buf_size, format, *(const ImS16*)p_data); + if (data_type == ImGuiDataType_U16) + return ImFormatString(buf, buf_size, format, *(const ImU16*)p_data); + IM_ASSERT(0); + return 0; +} + +void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg1, const void* arg2) +{ + IM_ASSERT(op == '+' || op == '-'); + switch (data_type) + { + case ImGuiDataType_S8: + if (op == '+') { *(ImS8*)output = ImAddClampOverflow(*(const ImS8*)arg1, *(const ImS8*)arg2, IM_S8_MIN, IM_S8_MAX); } + if (op == '-') { *(ImS8*)output = ImSubClampOverflow(*(const ImS8*)arg1, *(const ImS8*)arg2, IM_S8_MIN, IM_S8_MAX); } + return; + case ImGuiDataType_U8: + if (op == '+') { *(ImU8*)output = ImAddClampOverflow(*(const ImU8*)arg1, *(const ImU8*)arg2, IM_U8_MIN, IM_U8_MAX); } + if (op == '-') { *(ImU8*)output = ImSubClampOverflow(*(const ImU8*)arg1, *(const ImU8*)arg2, IM_U8_MIN, IM_U8_MAX); } + return; + case ImGuiDataType_S16: + if (op == '+') { *(ImS16*)output = ImAddClampOverflow(*(const ImS16*)arg1, *(const ImS16*)arg2, IM_S16_MIN, IM_S16_MAX); } + if (op == '-') { *(ImS16*)output = ImSubClampOverflow(*(const ImS16*)arg1, *(const ImS16*)arg2, IM_S16_MIN, IM_S16_MAX); } + return; + case ImGuiDataType_U16: + if (op == '+') { *(ImU16*)output = ImAddClampOverflow(*(const ImU16*)arg1, *(const ImU16*)arg2, IM_U16_MIN, IM_U16_MAX); } + if (op == '-') { *(ImU16*)output = ImSubClampOverflow(*(const ImU16*)arg1, *(const ImU16*)arg2, IM_U16_MIN, IM_U16_MAX); } + return; + case ImGuiDataType_S32: + if (op == '+') { *(ImS32*)output = ImAddClampOverflow(*(const ImS32*)arg1, *(const ImS32*)arg2, IM_S32_MIN, IM_S32_MAX); } + if (op == '-') { *(ImS32*)output = ImSubClampOverflow(*(const ImS32*)arg1, *(const ImS32*)arg2, IM_S32_MIN, IM_S32_MAX); } + return; + case ImGuiDataType_U32: + if (op == '+') { *(ImU32*)output = ImAddClampOverflow(*(const ImU32*)arg1, *(const ImU32*)arg2, IM_U32_MIN, IM_U32_MAX); } + if (op == '-') { *(ImU32*)output = ImSubClampOverflow(*(const ImU32*)arg1, *(const ImU32*)arg2, IM_U32_MIN, IM_U32_MAX); } + return; + case ImGuiDataType_S64: + if (op == '+') { *(ImS64*)output = ImAddClampOverflow(*(const ImS64*)arg1, *(const ImS64*)arg2, IM_S64_MIN, IM_S64_MAX); } + if (op == '-') { *(ImS64*)output = ImSubClampOverflow(*(const ImS64*)arg1, *(const ImS64*)arg2, IM_S64_MIN, IM_S64_MAX); } + return; + case ImGuiDataType_U64: + if (op == '+') { *(ImU64*)output = ImAddClampOverflow(*(const ImU64*)arg1, *(const ImU64*)arg2, IM_U64_MIN, IM_U64_MAX); } + if (op == '-') { *(ImU64*)output = ImSubClampOverflow(*(const ImU64*)arg1, *(const ImU64*)arg2, IM_U64_MIN, IM_U64_MAX); } + return; + case ImGuiDataType_Float: + if (op == '+') { *(float*)output = *(const float*)arg1 + *(const float*)arg2; } + if (op == '-') { *(float*)output = *(const float*)arg1 - *(const float*)arg2; } + return; + case ImGuiDataType_Double: + if (op == '+') { *(double*)output = *(const double*)arg1 + *(const double*)arg2; } + if (op == '-') { *(double*)output = *(const double*)arg1 - *(const double*)arg2; } + return; + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); +} + +// User can input math operators (e.g. +100) to edit a numerical values. +// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. +bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) +{ + while (ImCharIsBlankA(*buf)) + buf++; + if (!buf[0]) + return false; + + // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. + const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); + ImGuiDataTypeTempStorage data_backup; + memcpy(&data_backup, p_data, type_info->Size); + + if (format == NULL) + format = type_info->ScanFmt; + + if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64 || data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + { + // For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf + if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + format = type_info->ScanFmt; + if (sscanf(buf, format, p_data) < 1) + return false; + } + else + { + // Small types need a 32-bit buffer to receive the result from scanf() + int v32; + if (sscanf(buf, format, &v32) < 1) + return false; + if (data_type == ImGuiDataType_S8) + *(ImS8*)p_data = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX); + else if (data_type == ImGuiDataType_U8) + *(ImU8*)p_data = (ImU8)ImClamp(v32, (int)IM_U8_MIN, (int)IM_U8_MAX); + else if (data_type == ImGuiDataType_S16) + *(ImS16*)p_data = (ImS16)ImClamp(v32, (int)IM_S16_MIN, (int)IM_S16_MAX); + else if (data_type == ImGuiDataType_U16) + *(ImU16*)p_data = (ImU16)ImClamp(v32, (int)IM_U16_MIN, (int)IM_U16_MAX); + else + IM_ASSERT(0); + } + + return memcmp(&data_backup, p_data, type_info->Size) != 0; +} + +template +static int DataTypeCompareT(const T* lhs, const T* rhs) +{ + if (*lhs < *rhs) return -1; + if (*lhs > *rhs) return +1; + return 0; +} + +int ImGui::DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2) +{ + switch (data_type) + { + case ImGuiDataType_S8: return DataTypeCompareT((const ImS8* )arg_1, (const ImS8* )arg_2); + case ImGuiDataType_U8: return DataTypeCompareT((const ImU8* )arg_1, (const ImU8* )arg_2); + case ImGuiDataType_S16: return DataTypeCompareT((const ImS16* )arg_1, (const ImS16* )arg_2); + case ImGuiDataType_U16: return DataTypeCompareT((const ImU16* )arg_1, (const ImU16* )arg_2); + case ImGuiDataType_S32: return DataTypeCompareT((const ImS32* )arg_1, (const ImS32* )arg_2); + case ImGuiDataType_U32: return DataTypeCompareT((const ImU32* )arg_1, (const ImU32* )arg_2); + case ImGuiDataType_S64: return DataTypeCompareT((const ImS64* )arg_1, (const ImS64* )arg_2); + case ImGuiDataType_U64: return DataTypeCompareT((const ImU64* )arg_1, (const ImU64* )arg_2); + case ImGuiDataType_Float: return DataTypeCompareT((const float* )arg_1, (const float* )arg_2); + case ImGuiDataType_Double: return DataTypeCompareT((const double*)arg_1, (const double*)arg_2); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return 0; +} + +template +static bool DataTypeClampT(T* v, const T* v_min, const T* v_max) +{ + // Clamp, both sides are optional, return true if modified + if (v_min && *v < *v_min) { *v = *v_min; return true; } + if (v_max && *v > *v_max) { *v = *v_max; return true; } + return false; +} + +bool ImGui::DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max) +{ + switch (data_type) + { + case ImGuiDataType_S8: return DataTypeClampT((ImS8* )p_data, (const ImS8* )p_min, (const ImS8* )p_max); + case ImGuiDataType_U8: return DataTypeClampT((ImU8* )p_data, (const ImU8* )p_min, (const ImU8* )p_max); + case ImGuiDataType_S16: return DataTypeClampT((ImS16* )p_data, (const ImS16* )p_min, (const ImS16* )p_max); + case ImGuiDataType_U16: return DataTypeClampT((ImU16* )p_data, (const ImU16* )p_min, (const ImU16* )p_max); + case ImGuiDataType_S32: return DataTypeClampT((ImS32* )p_data, (const ImS32* )p_min, (const ImS32* )p_max); + case ImGuiDataType_U32: return DataTypeClampT((ImU32* )p_data, (const ImU32* )p_min, (const ImU32* )p_max); + case ImGuiDataType_S64: return DataTypeClampT((ImS64* )p_data, (const ImS64* )p_min, (const ImS64* )p_max); + case ImGuiDataType_U64: return DataTypeClampT((ImU64* )p_data, (const ImU64* )p_min, (const ImU64* )p_max); + case ImGuiDataType_Float: return DataTypeClampT((float* )p_data, (const float* )p_min, (const float* )p_max); + case ImGuiDataType_Double: return DataTypeClampT((double*)p_data, (const double*)p_min, (const double*)p_max); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return false; +} + +static float GetMinimumStepAtDecimalPrecision(int decimal_precision) +{ + static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; + if (decimal_precision < 0) + return FLT_MIN; + return (decimal_precision < IM_ARRAYSIZE(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision); +} + +template +static const char* ImAtoi(const char* src, TYPE* output) +{ + int negative = 0; + if (*src == '-') { negative = 1; src++; } + if (*src == '+') { src++; } + TYPE v = 0; + while (*src >= '0' && *src <= '9') + v = (v * 10) + (*src++ - '0'); + *output = negative ? -v : v; + return src; +} + +// Sanitize format +// - Zero terminate so extra characters after format (e.g. "%f123") don't confuse atof/atoi +// - stb_sprintf.h supports several new modifiers which format numbers in a way that also makes them incompatible atof/atoi. +static void SanitizeFormatString(const char* fmt, char* fmt_out, size_t fmt_out_size) +{ + IM_UNUSED(fmt_out_size); + const char* fmt_end = ImParseFormatFindEnd(fmt); + IM_ASSERT((size_t)(fmt_end - fmt + 1) < fmt_out_size); // Format is too long, let us know if this happens to you! + while (fmt < fmt_end) + { + char c = *(fmt++); + if (c != '\'' && c != '$' && c != '_') // Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '. + *(fmt_out++) = c; + } + *fmt_out = 0; // Zero-terminate +} + +template +TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, TYPE v) +{ + const char* fmt_start = ImParseFormatFindStart(format); + if (fmt_start[0] != '%' || fmt_start[1] == '%') // Don't apply if the value is not visible in the format string + return v; + + // Sanitize format + char fmt_sanitized[32]; + SanitizeFormatString(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized)); + fmt_start = fmt_sanitized; + + // Format value with our rounding, and read back + char v_str[64]; + ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v); + const char* p = v_str; + while (*p == ' ') + p++; + if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + v = (TYPE)ImAtof(p); + else + ImAtoi(p, (SIGNEDTYPE*)&v); + return v; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: DragScalar, DragFloat, DragInt, etc. +//------------------------------------------------------------------------- +// - DragBehaviorT<>() [Internal] +// - DragBehavior() [Internal] +// - DragScalar() +// - DragScalarN() +// - DragFloat() +// - DragFloat2() +// - DragFloat3() +// - DragFloat4() +// - DragFloatRange2() +// - DragInt() +// - DragInt2() +// - DragInt3() +// - DragInt4() +// - DragIntRange2() +//------------------------------------------------------------------------- + +// This is called by DragBehavior() when the widget is active (held by mouse or being manipulated with Nav controls) +template +bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiContext& g = *GImGui; + const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; + const bool is_clamped = (v_min < v_max); + const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0; + const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + + // Default tweak speed + if (v_speed == 0.0f && is_clamped && (v_max - v_min < FLT_MAX)) + v_speed = (float)((v_max - v_min) * g.DragSpeedDefaultRatio); + + // Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings + float adjust_delta = 0.0f; + if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) + { + adjust_delta = g.IO.MouseDelta[axis]; + if (g.IO.KeyAlt) + adjust_delta *= 1.0f / 100.0f; + if (g.IO.KeyShift) + adjust_delta *= 10.0f; + } + else if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; + adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis]; + v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); + } + adjust_delta *= v_speed; + + // For vertical drag we currently assume that Up=higher value (like we do with vertical sliders). This may become a parameter. + if (axis == ImGuiAxis_Y) + adjust_delta = -adjust_delta; + + // For logarithmic use our range is effectively 0..1 so scale the delta into that range + if (is_logarithmic && (v_max - v_min < FLT_MAX) && ((v_max - v_min) > 0.000001f)) // Epsilon to avoid /0 + adjust_delta /= (float)(v_max - v_min); + + // Clear current value on activation + // Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300. + bool is_just_activated = g.ActiveIdIsJustActivated; + bool is_already_past_limits_and_pushing_outward = is_clamped && ((*v >= v_max && adjust_delta > 0.0f) || (*v <= v_min && adjust_delta < 0.0f)); + if (is_just_activated || is_already_past_limits_and_pushing_outward) + { + g.DragCurrentAccum = 0.0f; + g.DragCurrentAccumDirty = false; + } + else if (adjust_delta != 0.0f) + { + g.DragCurrentAccum += adjust_delta; + g.DragCurrentAccumDirty = true; + } + + if (!g.DragCurrentAccumDirty) + return false; + + TYPE v_cur = *v; + FLOATTYPE v_old_ref_for_accum_remainder = (FLOATTYPE)0.0f; + + float logarithmic_zero_epsilon = 0.0f; // Only valid when is_logarithmic is true + const float zero_deadzone_halfsize = 0.0f; // Drag widgets have no deadzone (as it doesn't make sense) + if (is_logarithmic) + { + // When using logarithmic sliders, we need to clamp to avoid hitting zero, but our choice of clamp value greatly affects slider precision. We attempt to use the specified precision to estimate a good lower bound. + const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 1; + logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision); + + // Convert to parametric space, apply delta, convert back + float v_old_parametric = ScaleRatioFromValueT(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + float v_new_parametric = v_old_parametric + g.DragCurrentAccum; + v_cur = ScaleValueFromRatioT(data_type, v_new_parametric, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + v_old_ref_for_accum_remainder = v_old_parametric; + } + else + { + v_cur += (SIGNEDTYPE)g.DragCurrentAccum; + } + + // Round to user desired precision based on format string + if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_cur = RoundScalarWithFormatT(format, data_type, v_cur); + + // Preserve remainder after rounding has been applied. This also allow slow tweaking of values. + g.DragCurrentAccumDirty = false; + if (is_logarithmic) + { + // Convert to parametric space, apply delta, convert back + float v_new_parametric = ScaleRatioFromValueT(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + g.DragCurrentAccum -= (float)(v_new_parametric - v_old_ref_for_accum_remainder); + } + else + { + g.DragCurrentAccum -= (float)((SIGNEDTYPE)v_cur - (SIGNEDTYPE)*v); + } + + // Lose zero sign for float/double + if (v_cur == (TYPE)-0) + v_cur = (TYPE)0; + + // Clamp values (+ handle overflow/wrap-around for integer types) + if (*v != v_cur && is_clamped) + { + if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_floating_point)) + v_cur = v_min; + if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_floating_point)) + v_cur = v_max; + } + + // Apply result + if (*v == v_cur) + return false; + *v = v_cur; + return true; +} + +bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) +{ + // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. + IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + + ImGuiContext& g = *GImGui; + if (g.ActiveId == id) + { + if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) + ClearActiveID(); + else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + ClearActiveID(); + } + if (g.ActiveId != id) + return false; + if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) + return false; + + switch (data_type) + { + case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = DragBehaviorT(ImGuiDataType_S32, &v32, v_speed, p_min ? *(const ImS8*) p_min : IM_S8_MIN, p_max ? *(const ImS8*)p_max : IM_S8_MAX, format, flags); if (r) *(ImS8*)p_v = (ImS8)v32; return r; } + case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)p_v; bool r = DragBehaviorT(ImGuiDataType_U32, &v32, v_speed, p_min ? *(const ImU8*) p_min : IM_U8_MIN, p_max ? *(const ImU8*)p_max : IM_U8_MAX, format, flags); if (r) *(ImU8*)p_v = (ImU8)v32; return r; } + case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)p_v; bool r = DragBehaviorT(ImGuiDataType_S32, &v32, v_speed, p_min ? *(const ImS16*)p_min : IM_S16_MIN, p_max ? *(const ImS16*)p_max : IM_S16_MAX, format, flags); if (r) *(ImS16*)p_v = (ImS16)v32; return r; } + case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)p_v; bool r = DragBehaviorT(ImGuiDataType_U32, &v32, v_speed, p_min ? *(const ImU16*)p_min : IM_U16_MIN, p_max ? *(const ImU16*)p_max : IM_U16_MAX, format, flags); if (r) *(ImU16*)p_v = (ImU16)v32; return r; } + case ImGuiDataType_S32: return DragBehaviorT(data_type, (ImS32*)p_v, v_speed, p_min ? *(const ImS32* )p_min : IM_S32_MIN, p_max ? *(const ImS32* )p_max : IM_S32_MAX, format, flags); + case ImGuiDataType_U32: return DragBehaviorT(data_type, (ImU32*)p_v, v_speed, p_min ? *(const ImU32* )p_min : IM_U32_MIN, p_max ? *(const ImU32* )p_max : IM_U32_MAX, format, flags); + case ImGuiDataType_S64: return DragBehaviorT(data_type, (ImS64*)p_v, v_speed, p_min ? *(const ImS64* )p_min : IM_S64_MIN, p_max ? *(const ImS64* )p_max : IM_S64_MAX, format, flags); + case ImGuiDataType_U64: return DragBehaviorT(data_type, (ImU64*)p_v, v_speed, p_min ? *(const ImU64* )p_min : IM_U64_MIN, p_max ? *(const ImU64* )p_max : IM_U64_MAX, format, flags); + case ImGuiDataType_Float: return DragBehaviorT(data_type, (float*)p_v, v_speed, p_min ? *(const float* )p_min : -FLT_MAX, p_max ? *(const float* )p_max : FLT_MAX, format, flags); + case ImGuiDataType_Double: return DragBehaviorT(data_type, (double*)p_v, v_speed, p_min ? *(const double*)p_min : -DBL_MAX, p_max ? *(const double*)p_max : DBL_MAX, format, flags); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return false; +} + +// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional. +// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. +bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = 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.y * 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)); + + const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0; + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0)) + return false; + + // Default format string when passing NULL + if (format == NULL) + format = DataTypeGetInfo(data_type)->PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) + format = PatchFormatStringFloatToInt(format); + + // Tabbing or CTRL-clicking on Drag turns it into an InputText + const bool hovered = ItemHoverable(frame_bb, id); + bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); + if (!temp_input_is_active) + { + const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; + const bool clicked = (hovered && g.IO.MouseClicked[0]); + const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2); + if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); + if (temp_input_allowed) + if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id) + temp_input_is_active = true; + } + + // Experimental: simple click (without moving) turns Drag into an InputText + if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) + if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) + { + g.NavActivateId = g.NavActivateInputId = id; + g.NavActivateFlags = ImGuiActivateFlags_PreferInput; + temp_input_is_active = true; + } + } + + if (temp_input_is_active) + { + // Only clamp CTRL+Click input when ImGuiSliderFlags_AlwaysClamp is set + const bool is_clamp_input = (flags & ImGuiSliderFlags_AlwaysClamp) != 0 && (p_min == NULL || p_max == NULL || DataTypeCompare(data_type, p_min, p_max) < 0); + return TempInputScalar(frame_bb, id, label, data_type, p_data, format, is_clamp_input ? p_min : NULL, is_clamp_input ? p_max : NULL); + } + + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + + // Drag behavior + const bool value_changed = DragBehavior(id, data_type, p_data, v_speed, p_min, p_max, format, flags); + if (value_changed) + MarkItemEdited(id); + + // 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 + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format); + if (g.LogEnabled) + LogSetNextTextDecoration("{", "}"); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + return value_changed; +} + +bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components, CalcItemWidth()); + size_t type_size = GDataTypeInfo[data_type].Size; + for (int i = 0; i < components; i++) + { + PushID(i); + if (i > 0) + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= DragScalar("", data_type, p_data, v_speed, p_min, p_max, format, flags); + PopID(); + PopItemWidth(); + p_data = (void*)((char*)p_data + type_size); + } + PopID(); + + const char* label_end = FindRenderedTextEnd(label); + if (label != label_end) + { + SameLine(0, g.Style.ItemInnerSpacing.x); + TextEx(label, label_end); + } + + EndGroup(); + return value_changed; +} + +bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, flags); +} + +// NB: You likely want to specify the ImGuiSliderFlags_AlwaysClamp when using this. +bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2, CalcItemWidth()); + + float min_min = (v_min >= v_max) ? -FLT_MAX : v_min; + float min_max = (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max); + ImGuiSliderFlags min_flags = flags | ((min_min == min_max) ? ImGuiSliderFlags_ReadOnly : 0); + bool value_changed = DragScalar("##min", ImGuiDataType_Float, v_current_min, v_speed, &min_min, &min_max, format, min_flags); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + float max_min = (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min); + float max_max = (v_min >= v_max) ? FLT_MAX : v_max; + ImGuiSliderFlags max_flags = flags | ((max_min == max_max) ? ImGuiSliderFlags_ReadOnly : 0); + value_changed |= DragScalar("##max", ImGuiDataType_Float, v_current_max, v_speed, &max_min, &max_max, format_max ? format_max : format, max_flags); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + TextEx(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); + + return value_changed; +} + +// 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* format, ImGuiSliderFlags flags) +{ + return DragScalar(label, ImGuiDataType_S32, v, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_S32, v, 2, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_S32, v, 3, v_speed, &v_min, &v_max, format, flags); +} + +bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return DragScalarN(label, ImGuiDataType_S32, v, 4, v_speed, &v_min, &v_max, format, flags); +} + +// NB: You likely want to specify the ImGuiSliderFlags_AlwaysClamp when using this. +bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2, CalcItemWidth()); + + int min_min = (v_min >= v_max) ? INT_MIN : v_min; + int min_max = (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max); + ImGuiSliderFlags min_flags = flags | ((min_min == min_max) ? ImGuiSliderFlags_ReadOnly : 0); + bool value_changed = DragInt("##min", v_current_min, v_speed, min_min, min_max, format, min_flags); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + int max_min = (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min); + int max_max = (v_min >= v_max) ? INT_MAX : v_max; + ImGuiSliderFlags max_flags = flags | ((max_min == max_max) ? ImGuiSliderFlags_ReadOnly : 0); + value_changed |= DragInt("##max", v_current_max, v_speed, max_min, max_max, format_max ? format_max : format, max_flags); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + + TextEx(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); + + return value_changed; +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +// Obsolete versions with power parameter. See https://github.com/ocornut/imgui/issues/3361 for details. +bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power) +{ + ImGuiSliderFlags drag_flags = ImGuiSliderFlags_None; + if (power != 1.0f) + { + IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); + IM_ASSERT(p_min != NULL && p_max != NULL); // When using a power curve the drag needs to have known bounds + drag_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths + } + return DragScalar(label, data_type, p_data, v_speed, p_min, p_max, format, drag_flags); +} + +bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power) +{ + ImGuiSliderFlags drag_flags = ImGuiSliderFlags_None; + if (power != 1.0f) + { + IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); + IM_ASSERT(p_min != NULL && p_max != NULL); // When using a power curve the drag needs to have known bounds + drag_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths + } + return DragScalarN(label, data_type, p_data, components, v_speed, p_min, p_max, format, drag_flags); +} + +#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +//------------------------------------------------------------------------- +// [SECTION] Widgets: SliderScalar, SliderFloat, SliderInt, etc. +//------------------------------------------------------------------------- +// - ScaleRatioFromValueT<> [Internal] +// - ScaleValueFromRatioT<> [Internal] +// - SliderBehaviorT<>() [Internal] +// - SliderBehavior() [Internal] +// - SliderScalar() +// - SliderScalarN() +// - SliderFloat() +// - SliderFloat2() +// - SliderFloat3() +// - SliderFloat4() +// - SliderAngle() +// - SliderInt() +// - SliderInt2() +// - SliderInt3() +// - SliderInt4() +// - VSliderScalar() +// - VSliderFloat() +// - VSliderInt() +//------------------------------------------------------------------------- + +// Convert a value v in the output space of a slider into a parametric position on the slider itself (the logical opposite of ScaleValueFromRatioT) +template +float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize) +{ + if (v_min == v_max) + return 0.0f; + IM_UNUSED(data_type); + + const TYPE v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min); + if (is_logarithmic) + { + bool flipped = v_max < v_min; + + if (flipped) // Handle the case where the range is backwards + ImSwap(v_min, v_max); + + // Fudge min/max to avoid getting close to log(0) + FLOATTYPE v_min_fudged = (ImAbs((FLOATTYPE)v_min) < logarithmic_zero_epsilon) ? ((v_min < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_min; + FLOATTYPE v_max_fudged = (ImAbs((FLOATTYPE)v_max) < logarithmic_zero_epsilon) ? ((v_max < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_max; + + // Awkward special cases - we need ranges of the form (-100 .. 0) to convert to (-100 .. -epsilon), not (-100 .. epsilon) + if ((v_min == 0.0f) && (v_max < 0.0f)) + v_min_fudged = -logarithmic_zero_epsilon; + else if ((v_max == 0.0f) && (v_min < 0.0f)) + v_max_fudged = -logarithmic_zero_epsilon; + + float result; + + if (v_clamped <= v_min_fudged) + result = 0.0f; // Workaround for values that are in-range but below our fudge + else if (v_clamped >= v_max_fudged) + result = 1.0f; // Workaround for values that are in-range but above our fudge + else if ((v_min * v_max) < 0.0f) // Range crosses zero, so split into two portions + { + float zero_point_center = (-(float)v_min) / ((float)v_max - (float)v_min); // The zero point in parametric space. There's an argument we should take the logarithmic nature into account when calculating this, but for now this should do (and the most common case of a symmetrical range works fine) + float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; + float zero_point_snap_R = zero_point_center + zero_deadzone_halfsize; + if (v == 0.0f) + result = zero_point_center; // Special case for exactly zero + else if (v < 0.0f) + result = (1.0f - (float)(ImLog(-(FLOATTYPE)v_clamped / logarithmic_zero_epsilon) / ImLog(-v_min_fudged / logarithmic_zero_epsilon))) * zero_point_snap_L; + else + result = zero_point_snap_R + ((float)(ImLog((FLOATTYPE)v_clamped / logarithmic_zero_epsilon) / ImLog(v_max_fudged / logarithmic_zero_epsilon)) * (1.0f - zero_point_snap_R)); + } + else if ((v_min < 0.0f) || (v_max < 0.0f)) // Entirely negative slider + result = 1.0f - (float)(ImLog(-(FLOATTYPE)v_clamped / -v_max_fudged) / ImLog(-v_min_fudged / -v_max_fudged)); + else + result = (float)(ImLog((FLOATTYPE)v_clamped / v_min_fudged) / ImLog(v_max_fudged / v_min_fudged)); + + return flipped ? (1.0f - result) : result; + } + + // Linear slider + return (float)((FLOATTYPE)(SIGNEDTYPE)(v_clamped - v_min) / (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min)); +} + +// Convert a parametric position on a slider into a value v in the output space (the logical opposite of ScaleRatioFromValueT) +template +TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize) +{ + if (v_min == v_max) + return v_min; + const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + + TYPE result; + if (is_logarithmic) + { + // We special-case the extents because otherwise our fudging can lead to "mathematically correct" but non-intuitive behaviors like a fully-left slider not actually reaching the minimum value + if (t <= 0.0f) + result = v_min; + else if (t >= 1.0f) + result = v_max; + else + { + bool flipped = v_max < v_min; // Check if range is "backwards" + + // Fudge min/max to avoid getting silly results close to zero + FLOATTYPE v_min_fudged = (ImAbs((FLOATTYPE)v_min) < logarithmic_zero_epsilon) ? ((v_min < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_min; + FLOATTYPE v_max_fudged = (ImAbs((FLOATTYPE)v_max) < logarithmic_zero_epsilon) ? ((v_max < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_max; + + if (flipped) + ImSwap(v_min_fudged, v_max_fudged); + + // Awkward special case - we need ranges of the form (-100 .. 0) to convert to (-100 .. -epsilon), not (-100 .. epsilon) + if ((v_max == 0.0f) && (v_min < 0.0f)) + v_max_fudged = -logarithmic_zero_epsilon; + + float t_with_flip = flipped ? (1.0f - t) : t; // t, but flipped if necessary to account for us flipping the range + + if ((v_min * v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts + { + float zero_point_center = (-(float)ImMin(v_min, v_max)) / ImAbs((float)v_max - (float)v_min); // The zero point in parametric space + float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; + float zero_point_snap_R = zero_point_center + zero_deadzone_halfsize; + if (t_with_flip >= zero_point_snap_L && t_with_flip <= zero_point_snap_R) + result = (TYPE)0.0f; // Special case to make getting exactly zero possible (the epsilon prevents it otherwise) + else if (t_with_flip < zero_point_center) + result = (TYPE)-(logarithmic_zero_epsilon * ImPow(-v_min_fudged / logarithmic_zero_epsilon, (FLOATTYPE)(1.0f - (t_with_flip / zero_point_snap_L)))); + else + result = (TYPE)(logarithmic_zero_epsilon * ImPow(v_max_fudged / logarithmic_zero_epsilon, (FLOATTYPE)((t_with_flip - zero_point_snap_R) / (1.0f - zero_point_snap_R)))); + } + else if ((v_min < 0.0f) || (v_max < 0.0f)) // Entirely negative slider + result = (TYPE)-(-v_max_fudged * ImPow(-v_min_fudged / -v_max_fudged, (FLOATTYPE)(1.0f - t_with_flip))); + else + result = (TYPE)(v_min_fudged * ImPow(v_max_fudged / v_min_fudged, (FLOATTYPE)t_with_flip)); + } + } + else + { + // Linear slider + if (is_floating_point) + { + result = ImLerp(v_min, v_max, t); + } + else + { + // - For integer values we want the clicking position to match the grab box so we round above + // This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property.. + // - Not doing a *1.0 multiply at the end of a range as it tends to be lossy. While absolute aiming at a large s64/u64 + // range is going to be imprecise anyway, with this check we at least make the edge values matches expected limits. + if (t < 1.0) + { + FLOATTYPE v_new_off_f = (SIGNEDTYPE)(v_max - v_min) * t; + result = (TYPE)((SIGNEDTYPE)v_min + (SIGNEDTYPE)(v_new_off_f + (FLOATTYPE)(v_min > v_max ? -0.5 : 0.5))); + } + else + { + result = v_max; + } + } + } + + return result; +} + +// FIXME: Move more of the code into SliderBehavior() +template +bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; + const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0; + const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + + const float grab_padding = 2.0f; + const float slider_sz = (bb.Max[axis] - bb.Min[axis]) - grab_padding * 2.0f; + float grab_sz = style.GrabMinSize; + SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max); + if (!is_floating_point && v_range >= 0) // v_range < 0 may happen on integer overflows + grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit + grab_sz = ImMin(grab_sz, slider_sz); + const float slider_usable_sz = slider_sz - grab_sz; + const float slider_usable_pos_min = bb.Min[axis] + grab_padding + grab_sz * 0.5f; + const float slider_usable_pos_max = bb.Max[axis] - grab_padding - grab_sz * 0.5f; + + float logarithmic_zero_epsilon = 0.0f; // Only valid when is_logarithmic is true + float zero_deadzone_halfsize = 0.0f; // Only valid when is_logarithmic is true + if (is_logarithmic) + { + // When using logarithmic sliders, we need to clamp to avoid hitting zero, but our choice of clamp value greatly affects slider precision. We attempt to use the specified precision to estimate a good lower bound. + const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 1; + logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision); + zero_deadzone_halfsize = (style.LogSliderDeadzone * 0.5f) / ImMax(slider_usable_sz, 1.0f); + } + + // Process interacting with the slider + bool value_changed = false; + if (g.ActiveId == id) + { + bool set_new_value = false; + float clicked_t = 0.0f; + if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + if (!g.IO.MouseDown[0]) + { + ClearActiveID(); + } + else + { + const float mouse_abs_pos = g.IO.MousePos[axis]; + clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; + if (axis == ImGuiAxis_Y) + clicked_t = 1.0f - clicked_t; + set_new_value = true; + } + } + else if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + if (g.ActiveIdIsJustActivated) + { + g.SliderCurrentAccum = 0.0f; // Reset any stored nav delta upon activation + g.SliderCurrentAccumDirty = false; + } + + const ImVec2 input_delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f); + float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y; + if (input_delta != 0.0f) + { + const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; + if (decimal_precision > 0) + { + input_delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds + if (IsNavInputDown(ImGuiNavInput_TweakSlow)) + input_delta /= 10.0f; + } + else + { + if ((v_range >= -100.0f && v_range <= 100.0f) || IsNavInputDown(ImGuiNavInput_TweakSlow)) + input_delta = ((input_delta < 0.0f) ? -1.0f : +1.0f) / (float)v_range; // Gamepad/keyboard tweak speeds in integer steps + else + input_delta /= 100.0f; + } + if (IsNavInputDown(ImGuiNavInput_TweakFast)) + input_delta *= 10.0f; + + g.SliderCurrentAccum += input_delta; + g.SliderCurrentAccumDirty = true; + } + + float delta = g.SliderCurrentAccum; + if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + { + ClearActiveID(); + } + else if (g.SliderCurrentAccumDirty) + { + clicked_t = ScaleRatioFromValueT(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + + if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f)) // This is to avoid applying the saturation when already past the limits + { + set_new_value = false; + g.SliderCurrentAccum = 0.0f; // If pushing up against the limits, don't continue to accumulate + } + else + { + set_new_value = true; + float old_clicked_t = clicked_t; + clicked_t = ImSaturate(clicked_t + delta); + + // Calculate what our "new" clicked_t will be, and thus how far we actually moved the slider, and subtract this from the accumulator + TYPE v_new = ScaleValueFromRatioT(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_new = RoundScalarWithFormatT(format, data_type, v_new); + float new_clicked_t = ScaleRatioFromValueT(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + + if (delta > 0) + g.SliderCurrentAccum -= ImMin(new_clicked_t - old_clicked_t, delta); + else + g.SliderCurrentAccum -= ImMax(new_clicked_t - old_clicked_t, delta); + } + + g.SliderCurrentAccumDirty = false; + } + } + + if (set_new_value) + { + TYPE v_new = ScaleValueFromRatioT(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + + // Round to user desired precision based on format string + if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_new = RoundScalarWithFormatT(format, data_type, v_new); + + // Apply result + if (*v != v_new) + { + *v = v_new; + value_changed = true; + } + } + } + + if (slider_sz < 1.0f) + { + *out_grab_bb = ImRect(bb.Min, bb.Min); + } + else + { + // Output grab position so it can be displayed by the caller + float grab_t = ScaleRatioFromValueT(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + if (axis == ImGuiAxis_Y) + grab_t = 1.0f - grab_t; + const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + if (axis == ImGuiAxis_X) + *out_grab_bb = ImRect(grab_pos - grab_sz * 0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz * 0.5f, bb.Max.y - grab_padding); + else + *out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz * 0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz * 0.5f); + } + + return value_changed; +} + +// For 32-bit and larger types, slider bounds are limited to half the natural type range. +// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok. +// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders. +bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb) +{ + // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. + IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + + ImGuiContext& g = *GImGui; + if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) + return false; + + switch (data_type) + { + case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = SliderBehaviorT(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; } + case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)p_v; bool r = SliderBehaviorT(bb, id, ImGuiDataType_U32, &v32, *(const ImU8*)p_min, *(const ImU8*)p_max, format, flags, out_grab_bb); if (r) *(ImU8*)p_v = (ImU8)v32; return r; } + case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)p_v; bool r = SliderBehaviorT(bb, id, ImGuiDataType_S32, &v32, *(const ImS16*)p_min, *(const ImS16*)p_max, format, flags, out_grab_bb); if (r) *(ImS16*)p_v = (ImS16)v32; return r; } + case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)p_v; bool r = SliderBehaviorT(bb, id, ImGuiDataType_U32, &v32, *(const ImU16*)p_min, *(const ImU16*)p_max, format, flags, out_grab_bb); if (r) *(ImU16*)p_v = (ImU16)v32; return r; } + case ImGuiDataType_S32: + IM_ASSERT(*(const ImS32*)p_min >= IM_S32_MIN / 2 && *(const ImS32*)p_max <= IM_S32_MAX / 2); + return SliderBehaviorT(bb, id, data_type, (ImS32*)p_v, *(const ImS32*)p_min, *(const ImS32*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_U32: + IM_ASSERT(*(const ImU32*)p_max <= IM_U32_MAX / 2); + return SliderBehaviorT(bb, id, data_type, (ImU32*)p_v, *(const ImU32*)p_min, *(const ImU32*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_S64: + IM_ASSERT(*(const ImS64*)p_min >= IM_S64_MIN / 2 && *(const ImS64*)p_max <= IM_S64_MAX / 2); + return SliderBehaviorT(bb, id, data_type, (ImS64*)p_v, *(const ImS64*)p_min, *(const ImS64*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_U64: + IM_ASSERT(*(const ImU64*)p_max <= IM_U64_MAX / 2); + return SliderBehaviorT(bb, id, data_type, (ImU64*)p_v, *(const ImU64*)p_min, *(const ImU64*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_Float: + IM_ASSERT(*(const float*)p_min >= -FLT_MAX / 2.0f && *(const float*)p_max <= FLT_MAX / 2.0f); + return SliderBehaviorT(bb, id, data_type, (float*)p_v, *(const float*)p_min, *(const float*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_Double: + IM_ASSERT(*(const double*)p_min >= -DBL_MAX / 2.0f && *(const double*)p_max <= DBL_MAX / 2.0f); + return SliderBehaviorT(bb, id, data_type, (double*)p_v, *(const double*)p_min, *(const double*)p_max, format, flags, out_grab_bb); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return false; +} + +// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required. +// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. +bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = 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.y * 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)); + + const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0; + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0)) + return false; + + // Default format string when passing NULL + if (format == NULL) + format = DataTypeGetInfo(data_type)->PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) + format = PatchFormatStringFloatToInt(format); + + // Tabbing or CTRL-clicking on Slider turns it into an input box + const bool hovered = ItemHoverable(frame_bb, id); + bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); + if (!temp_input_is_active) + { + const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; + const bool clicked = (hovered && g.IO.MouseClicked[0]); + if (input_requested_by_tabbing || clicked || g.NavActivateId == id || g.NavActivateInputId == id) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); + if (temp_input_allowed && (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id)) + temp_input_is_active = true; + } + } + + if (temp_input_is_active) + { + // Only clamp CTRL+Click input when ImGuiSliderFlags_AlwaysClamp is set + const bool is_clamp_input = (flags & ImGuiSliderFlags_AlwaysClamp) != 0; + return TempInputScalar(frame_bb, id, label, data_type, p_data, format, is_clamp_input ? p_min : NULL, is_clamp_input ? p_max : NULL); + } + + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding); + + // Slider behavior + ImRect grab_bb; + const bool value_changed = SliderBehavior(frame_bb, id, data_type, p_data, p_min, p_max, format, flags, &grab_bb); + if (value_changed) + MarkItemEdited(id); + + // Render grab + if (grab_bb.Max.x > grab_bb.Min.x) + window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); + + // 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 + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format); + if (g.LogEnabled) + LogSetNextTextDecoration("{", "}"); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + return value_changed; +} + +// Add multiple sliders on 1 line for compact edition of multiple components +bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components, CalcItemWidth()); + size_t type_size = GDataTypeInfo[data_type].Size; + for (int i = 0; i < components; i++) + { + PushID(i); + if (i > 0) + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= SliderScalar("", data_type, v, v_min, v_max, format, flags); + PopID(); + PopItemWidth(); + v = (void*)((char*)v + type_size); + } + PopID(); + + const char* label_end = FindRenderedTextEnd(label); + if (label != label_end) + { + SameLine(0, g.Style.ItemInnerSpacing.x); + TextEx(label, label_end); + } + + EndGroup(); + return value_changed; +} + +bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags) +{ + if (format == NULL) + format = "%.0f deg"; + float v_deg = (*v_rad) * 360.0f / (2 * IM_PI); + bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, flags); + *v_rad = v_deg * (2 * IM_PI) / 360.0f; + return value_changed; +} + +bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalar(label, ImGuiDataType_S32, v, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_S32, v, 2, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_S32, v, 3, &v_min, &v_max, format, flags); +} + +bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format, flags); +} + +bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + 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; + + // Default format string when passing NULL + if (format == NULL) + format = DataTypeGetInfo(data_type)->PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) + format = PatchFormatStringFloatToInt(format); + + const bool hovered = ItemHoverable(frame_bb, id); + if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + } + + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding); + + // Slider behavior + ImRect grab_bb; + const bool value_changed = SliderBehavior(frame_bb, id, data_type, p_data, p_min, p_max, format, flags | ImGuiSliderFlags_Vertical, &grab_bb); + if (value_changed) + MarkItemEdited(id); + + // Render grab + if (grab_bb.Max.y > grab_bb.Min.y) + window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); + + // 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]; + const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format); + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f)); + 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* format, ImGuiSliderFlags flags) +{ + return VSliderScalar(label, size, ImGuiDataType_Float, v, &v_min, &v_max, format, flags); +} + +bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) +{ + return VSliderScalar(label, size, ImGuiDataType_S32, v, &v_min, &v_max, format, flags); +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +// Obsolete versions with power parameter. See https://github.com/ocornut/imgui/issues/3361 for details. +bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power) +{ + ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None; + if (power != 1.0f) + { + IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); + slider_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths + } + return SliderScalar(label, data_type, p_data, p_min, p_max, format, slider_flags); +} + +bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format, float power) +{ + ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None; + if (power != 1.0f) + { + IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); + slider_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths + } + return SliderScalarN(label, data_type, v, components, v_min, v_max, format, slider_flags); +} + +#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS + +//------------------------------------------------------------------------- +// [SECTION] Widgets: InputScalar, InputFloat, InputInt, etc. +//------------------------------------------------------------------------- +// - ImParseFormatFindStart() [Internal] +// - ImParseFormatFindEnd() [Internal] +// - ImParseFormatTrimDecorations() [Internal] +// - ImParseFormatPrecision() [Internal] +// - TempInputTextScalar() [Internal] +// - InputScalar() +// - InputScalarN() +// - InputFloat() +// - InputFloat2() +// - InputFloat3() +// - InputFloat4() +// - InputInt() +// - InputInt2() +// - InputInt3() +// - InputInt4() +// - InputDouble() +//------------------------------------------------------------------------- + +// We don't use strchr() because our strings are usually very short and often start with '%' +const char* ImParseFormatFindStart(const char* fmt) +{ + while (char c = fmt[0]) + { + if (c == '%' && fmt[1] != '%') + return fmt; + else if (c == '%') + fmt++; + fmt++; + } + return fmt; +} + +const char* ImParseFormatFindEnd(const char* fmt) +{ + // Printf/scanf types modifiers: I/L/h/j/l/t/w/z. Other uppercase letters qualify as types aka end of the format. + if (fmt[0] != '%') + return fmt; + const unsigned int ignored_uppercase_mask = (1 << ('I'-'A')) | (1 << ('L'-'A')); + const unsigned int ignored_lowercase_mask = (1 << ('h'-'a')) | (1 << ('j'-'a')) | (1 << ('l'-'a')) | (1 << ('t'-'a')) | (1 << ('w'-'a')) | (1 << ('z'-'a')); + for (char c; (c = *fmt) != 0; fmt++) + { + if (c >= 'A' && c <= 'Z' && ((1 << (c - 'A')) & ignored_uppercase_mask) == 0) + return fmt + 1; + if (c >= 'a' && c <= 'z' && ((1 << (c - 'a')) & ignored_lowercase_mask) == 0) + return fmt + 1; + } + return fmt; +} + +// Extract the format out of a format string with leading or trailing decorations +// fmt = "blah blah" -> return fmt +// fmt = "%.3f" -> return fmt +// fmt = "hello %.3f" -> return fmt + 6 +// fmt = "%.3f hello" -> return buf written with "%.3f" +const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_size) +{ + const char* fmt_start = ImParseFormatFindStart(fmt); + if (fmt_start[0] != '%') + return fmt; + const char* fmt_end = ImParseFormatFindEnd(fmt_start); + if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data. + return fmt_start; + ImStrncpy(buf, fmt_start, ImMin((size_t)(fmt_end - fmt_start) + 1, buf_size)); + return buf; +} + +// Parse display precision back from the display format string +// FIXME: This is still used by some navigation code path to infer a minimum tweak step, but we should aim to rework widgets so it isn't needed. +int ImParseFormatPrecision(const char* fmt, int default_precision) +{ + fmt = ImParseFormatFindStart(fmt); + if (fmt[0] != '%') + return default_precision; + fmt++; + while (*fmt >= '0' && *fmt <= '9') + fmt++; + int precision = INT_MAX; + if (*fmt == '.') + { + fmt = ImAtoi(fmt + 1, &precision); + if (precision < 0 || precision > 99) + precision = default_precision; + } + if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation + precision = -1; + if ((*fmt == 'g' || *fmt == 'G') && precision == INT_MAX) + precision = -1; + return (precision == INT_MAX) ? default_precision : precision; +} + +// Create text input in place of another active widget (e.g. used when doing a CTRL+Click on drag/slider widgets) +// FIXME: Facilitate using this in variety of other situations. +bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags) +{ + // On the first frame, g.TempInputTextId == 0, then on subsequent frames it becomes == id. + // We clear ActiveID on the first frame to allow the InputText() taking it back. + ImGuiContext& g = *GImGui; + const bool init = (g.TempInputId != id); + if (init) + ClearActiveID(); + + g.CurrentWindow->DC.CursorPos = bb.Min; + bool value_changed = InputTextEx(label, NULL, buf, buf_size, bb.GetSize(), flags | ImGuiInputTextFlags_MergedItem); + if (init) + { + // First frame we started displaying the InputText widget, we expect it to take the active id. + IM_ASSERT(g.ActiveId == id); + g.TempInputId = g.ActiveId; + } + return value_changed; +} + +// Note that Drag/Slider functions are only forwarding the min/max values clamping values if the ImGuiSliderFlags_AlwaysClamp flag is set! +// This is intended: this way we allow CTRL+Click manual input to set a value out of bounds, for maximum flexibility. +// However this may not be ideal for all uses, as some user code may break on out of bound values. +bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max) +{ + char fmt_buf[32]; + char data_buf[32]; + format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf)); + DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format); + ImStrTrimBlanks(data_buf); + + ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited; + flags |= ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); + bool value_changed = false; + if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags)) + { + // Backup old value + size_t data_type_size = DataTypeGetInfo(data_type)->Size; + ImGuiDataTypeTempStorage data_backup; + memcpy(&data_backup, p_data, data_type_size); + + // Apply new value (or operations) then clamp + DataTypeApplyFromText(data_buf, data_type, p_data, NULL); + if (p_clamp_min || p_clamp_max) + { + if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0) + ImSwap(p_clamp_min, p_clamp_max); + DataTypeClamp(data_type, p_data, p_clamp_min, p_clamp_max); + } + + // Only mark as edited if new value is different + value_changed = memcmp(&data_backup, p_data, data_type_size) != 0; + if (value_changed) + MarkItemEdited(id); + } + return value_changed; +} + +// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional. +// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. +bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + + if (format == NULL) + format = DataTypeGetInfo(data_type)->PrintFmt; + + char buf[64]; + DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); + + bool value_changed = false; + if ((flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) + flags |= ImGuiInputTextFlags_CharsDecimal; + flags |= ImGuiInputTextFlags_AutoSelectAll; + flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. + + if (p_step != NULL) + { + const float button_size = GetFrameHeight(); + + BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive() + PushID(label); + SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); + if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + + // Step buttons + const ImVec2 backup_frame_padding = style.FramePadding; + style.FramePadding.x = style.FramePadding.y; + ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups; + if (flags & ImGuiInputTextFlags_ReadOnly) + BeginDisabled(); + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("-", ImVec2(button_size, button_size), button_flags)) + { + DataTypeApplyOp(data_type, '-', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step); + value_changed = true; + } + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("+", ImVec2(button_size, button_size), button_flags)) + { + DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step); + value_changed = true; + } + if (flags & ImGuiInputTextFlags_ReadOnly) + EndDisabled(); + + const char* label_end = FindRenderedTextEnd(label); + if (label != label_end) + { + SameLine(0, style.ItemInnerSpacing.x); + TextEx(label, label_end); + } + style.FramePadding = backup_frame_padding; + + PopID(); + EndGroup(); + } + else + { + if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + } + if (value_changed) + MarkItemEdited(g.LastItemData.ID); + + return value_changed; +} + +bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components, CalcItemWidth()); + size_t type_size = GDataTypeInfo[data_type].Size; + for (int i = 0; i < components; i++) + { + PushID(i); + if (i > 0) + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= InputScalar("", data_type, p_data, p_step, p_step_fast, format, flags); + PopID(); + PopItemWidth(); + p_data = (void*)((char*)p_data + type_size); + } + PopID(); + + const char* label_end = FindRenderedTextEnd(label); + if (label != label_end) + { + SameLine(0.0f, g.Style.ItemInnerSpacing.x); + TextEx(label, label_end); + } + + EndGroup(); + return value_changed; +} + +bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags) +{ + flags |= ImGuiInputTextFlags_CharsScientific; + return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step > 0.0f ? &step : NULL), (void*)(step_fast > 0.0f ? &step_fast : NULL), format, flags); +} + +bool ImGui::InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_Float, v, 2, NULL, NULL, format, flags); +} + +bool ImGui::InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_Float, v, 3, NULL, NULL, format, flags); +} + +bool ImGui::InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_Float, v, 4, NULL, NULL, format, flags); +} + +bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags) +{ + // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. + const char* format = (flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; + return InputScalar(label, ImGuiDataType_S32, (void*)v, (void*)(step > 0 ? &step : NULL), (void*)(step_fast > 0 ? &step_fast : NULL), format, flags); +} + +bool ImGui::InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_S32, v, 2, NULL, NULL, "%d", flags); +} + +bool ImGui::InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_S32, v, 3, NULL, NULL, "%d", flags); +} + +bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags) +{ + return InputScalarN(label, ImGuiDataType_S32, v, 4, NULL, NULL, "%d", flags); +} + +bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags) +{ + flags |= ImGuiInputTextFlags_CharsScientific; + return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step > 0.0 ? &step : NULL), (void*)(step_fast > 0.0 ? &step_fast : NULL), format, flags); +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: InputText, InputTextMultiline, InputTextWithHint +//------------------------------------------------------------------------- +// - InputText() +// - InputTextWithHint() +// - InputTextMultiline() +// - InputTextEx() [Internal] +//------------------------------------------------------------------------- + +bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); +} + +bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + return InputTextEx(label, NULL, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); +} + +bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); +} + +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) +{ + int line_count = 0; + const char* s = text_begin; + while (char c = *s++) // We are only matching for \n so we can ignore UTF-8 decoding + if (c == '\n') + line_count++; + s--; + if (s[0] != '\n' && s[0] != '\r') + line_count++; + *out_text_end = s; + return line_count; +} + +static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) +{ + ImGuiContext& g = *GImGui; + ImFont* font = g.Font; + const float line_height = g.FontSize; + const float scale = line_height / font->FontSize; + + ImVec2 text_size = ImVec2(0, 0); + float line_width = 0.0f; + + const ImWchar* s = text_begin; + while (s < text_end) + { + 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; + if (stop_on_new_line) + break; + continue; + } + if (c == '\r') + continue; + + const float char_width = font->GetCharAdvance((ImWchar)c) * scale; + line_width += char_width; + } + + if (text_size.x < line_width) + text_size.x = line_width; + + if (out_offset) + *out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n + + if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n + text_size.y += line_height; + + if (remaining) + *remaining = s; + + return text_size; +} + +// 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) +namespace ImStb +{ + +static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; } +static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { return obj->TextW[idx]; } +static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *GImGui; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); } +static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; } +static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; +static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx) +{ + const ImWchar* text = obj->TextW.Data; + const ImWchar* text_remaining = NULL; + const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); + 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 - (text + line_start_idx)); +} + +// When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators. +static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|' || c=='\n' || c=='\r'; } +static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (is_separator(obj->TextW[idx - 1]) && !is_separator(obj->TextW[idx]) ) : 1; } +static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (!is_separator(obj->TextW[idx - 1]) && is_separator(obj->TextW[idx])) : 1; } +static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } +static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } +#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h +#ifdef __APPLE__ // FIXME: Move setting to IO structure +#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_MAC +#else +static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } +#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_WIN +#endif + +static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n) +{ + ImWchar* dst = obj->TextW.Data + pos; + + // We maintain our buffer length in both UTF-8 and wchar formats + obj->Edited = true; + obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); + obj->CurLenW -= n; + + // Offset remaining text (FIXME-OPT: Use memmove) + const ImWchar* src = obj->TextW.Data + pos + n; + while (ImWchar c = *src++) + *dst++ = c; + *dst = '\0'; +} + +static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ImWchar* new_text, int new_text_len) +{ + const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0; + const int text_len = obj->CurLenW; + IM_ASSERT(pos <= text_len); + + const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); + if (!is_resizable && (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufCapacityA)) + return false; + + // Grow internal buffer if needed + if (new_text_len + text_len + 1 > obj->TextW.Size) + { + if (!is_resizable) + return false; + IM_ASSERT(text_len < obj->TextW.Size); + obj->TextW.resize(text_len + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1); + } + + ImWchar* text = obj->TextW.Data; + if (pos != text_len) + memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar)); + memcpy(text + pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); + + obj->Edited = true; + obj->CurLenW += new_text_len; + obj->CurLenA += new_text_len_utf8; + obj->TextW[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 0x200000 // keyboard input to move cursor left +#define STB_TEXTEDIT_K_RIGHT 0x200001 // keyboard input to move cursor right +#define STB_TEXTEDIT_K_UP 0x200002 // keyboard input to move cursor up +#define STB_TEXTEDIT_K_DOWN 0x200003 // keyboard input to move cursor down +#define STB_TEXTEDIT_K_LINESTART 0x200004 // keyboard input to move cursor to start of line +#define STB_TEXTEDIT_K_LINEEND 0x200005 // keyboard input to move cursor to end of line +#define STB_TEXTEDIT_K_TEXTSTART 0x200006 // keyboard input to move cursor to start of text +#define STB_TEXTEDIT_K_TEXTEND 0x200007 // keyboard input to move cursor to end of text +#define STB_TEXTEDIT_K_DELETE 0x200008 // keyboard input to delete selection or character under cursor +#define STB_TEXTEDIT_K_BACKSPACE 0x200009 // keyboard input to delete selection or character left of cursor +#define STB_TEXTEDIT_K_UNDO 0x20000A // keyboard input to perform undo +#define STB_TEXTEDIT_K_REDO 0x20000B // keyboard input to perform redo +#define STB_TEXTEDIT_K_WORDLEFT 0x20000C // keyboard input to move cursor left one word +#define STB_TEXTEDIT_K_WORDRIGHT 0x20000D // keyboard input to move cursor right one word +#define STB_TEXTEDIT_K_PGUP 0x20000E // keyboard input to move cursor up a page +#define STB_TEXTEDIT_K_PGDOWN 0x20000F // keyboard input to move cursor down a page +#define STB_TEXTEDIT_K_SHIFT 0x400000 + +#define STB_TEXTEDIT_IMPLEMENTATION +#include "imstb_textedit.h" + +// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling +// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?) +static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* state, const STB_TEXTEDIT_CHARTYPE* text, int text_len) +{ + stb_text_makeundo_replace(str, state, 0, str->CurLenW, text_len); + ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->CurLenW); + if (text_len <= 0) + return; + if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len)) + { + state->cursor = text_len; + state->has_preferred_x = 0; + return; + } + IM_ASSERT(0); // Failed to insert character, normally shouldn't happen because of how we currently use stb_textedit_replace() +} + +} // namespace ImStb + +void ImGuiInputTextState::OnKeyPressed(int key) +{ + stb_textedit_key(this, &Stb, key); + CursorFollow = true; + CursorAnimReset(); +} + +ImGuiInputTextCallbackData::ImGuiInputTextCallbackData() +{ + memset(this, 0, sizeof(*this)); +} + +// Public API to manipulate UTF-8 text +// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) +// FIXME: The existence of this rarely exercised code path is a bit of a nuisance. +void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count) +{ + IM_ASSERT(pos + bytes_count <= BufTextLen); + char* dst = Buf + pos; + const char* src = Buf + pos + bytes_count; + while (char c = *src++) + *dst++ = c; + *dst = '\0'; + + if (CursorPos >= pos + bytes_count) + CursorPos -= bytes_count; + else if (CursorPos >= pos) + CursorPos = pos; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen -= bytes_count; +} + +void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) +{ + const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0; + const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); + if (new_text_len + BufTextLen >= BufSize) + { + if (!is_resizable) + return; + + // Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!) + ImGuiContext& g = *GImGui; + ImGuiInputTextState* edit_state = &g.InputTextState; + IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID); + IM_ASSERT(Buf == edit_state->TextA.Data); + int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1; + edit_state->TextA.reserve(new_buf_size + 1); + Buf = edit_state->TextA.Data; + BufSize = edit_state->BufCapacityA = new_buf_size; + } + + if (BufTextLen != pos) + memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos)); + memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char)); + Buf[BufTextLen + new_text_len] = '\0'; + + if (CursorPos >= pos) + CursorPos += new_text_len; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen += new_text_len; +} + +// Return false to discard a character. +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source) +{ + IM_ASSERT(input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Clipboard); + unsigned int c = *p_char; + + // Filter non-printable (NB: isprint is unreliable! see #2467) + bool apply_named_filters = true; + if (c < 0x20) + { + bool pass = false; + pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); + pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput)); + if (!pass) + return false; + apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted. + } + + if (input_source != ImGuiInputSource_Clipboard) + { + // We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817) + if (c == 127) + return false; + + // Filter private Unicode range. GLFW on OSX seems to send private characters for special keys like arrow keys (FIXME) + if (c >= 0xE000 && c <= 0xF8FF) + return false; + } + + // Filter Unicode ranges we are not handling in this build + if (c > IM_UNICODE_CODEPOINT_MAX) + return false; + + // Generic named filters + if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))) + { + // The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.'. + // The standard mandate that programs starts in the "C" locale where the decimal point is '.'. + // We don't really intend to provide widespread support for it, but out of empathy for people stuck with using odd API, we support the bare minimum aka overriding the decimal point. + // Change the default decimal_point with: + // ImGui::GetCurrentContext()->PlatformLocaleDecimalPoint = *localeconv()->decimal_point; + // Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions. + ImGuiContext& g = *GImGui; + const unsigned c_decimal_point = (unsigned int)g.PlatformLocaleDecimalPoint; + + // Allow 0-9 . - + * / + if (flags & ImGuiInputTextFlags_CharsDecimal) + if (!(c >= '0' && c <= '9') && (c != c_decimal_point) && (c != '-') && (c != '+') && (c != '*') && (c != '/')) + return false; + + // Allow 0-9 . - + * / e E + if (flags & ImGuiInputTextFlags_CharsScientific) + if (!(c >= '0' && c <= '9') && (c != c_decimal_point) && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E')) + return false; + + // Allow 0-9 a-F A-F + if (flags & ImGuiInputTextFlags_CharsHexadecimal) + if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) + return false; + + // Turn a-z into A-Z + if (flags & ImGuiInputTextFlags_CharsUppercase) + if (c >= 'a' && c <= 'z') + *p_char = (c += (unsigned int)('A' - 'a')); + + if (flags & ImGuiInputTextFlags_CharsNoBlank) + if (ImCharIsBlankW(c)) + return false; + } + + // Custom callback filter + if (flags & ImGuiInputTextFlags_CallbackCharFilter) + { + ImGuiInputTextCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiInputTextCallbackData)); + 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 +// - buf_size account for the zero-terminator, so a buf_size of 6 can hold "Hello" but not "Hello!". +// This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match +// Note that in std::string world, capacity() would omit 1 byte used by the zero-terminator. +// - When active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while the InputText is active has no effect. +// - If you want to use ImGui::InputText() with std::string, see misc/cpp/imgui_stdlib.h +// (FIXME: Rather confusing and messy function, among the worse part of our codebase, expecting to rewrite a V2 at some point.. Partly because we are +// doing UTF8 > U16 > UTF8 conversions on the go to easily interface with stb_textedit. Ideally should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188) +bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + IM_ASSERT(buf != NULL && buf_size >= 0); + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) + + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + const ImGuiStyle& style = g.Style; + + const bool RENDER_SELECTION_WHEN_INACTIVE = false; + const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; + const bool is_readonly = (flags & ImGuiInputTextFlags_ReadOnly) != 0; + const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; + const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0; + const bool is_resizable = (flags & ImGuiInputTextFlags_CallbackResize) != 0; + if (is_resizable) + IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag! + + if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar) + BeginGroup(); + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line + const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + const ImRect total_bb(frame_bb.Min, frame_bb.Min + total_size); + + ImGuiWindow* draw_window = window; + ImVec2 inner_size = frame_size; + ImGuiItemStatusFlags item_status_flags = 0; + ImGuiLastItemData item_data_backup; + if (is_multiline) + { + ImVec2 backup_pos = window->DC.CursorPos; + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable)) + { + EndGroup(); + return false; + } + item_status_flags = g.LastItemData.StatusFlags; + item_data_backup = g.LastItemData; + window->DC.CursorPos = backup_pos; + + // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. + // FIXME-NAV: Pressing NavActivate will trigger general child activation right before triggering our own below. Harmless but bizarre. + PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Ensure no clip rect so mouse hover can reach FramePadding edges + bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove); + PopStyleVar(3); + PopStyleColor(); + if (!child_visible) + { + EndChild(); + EndGroup(); + return false; + } + draw_window = g.CurrentWindow; // Child window + draw_window->DC.NavLayersActiveMaskNext |= (1 << draw_window->DC.NavLayerCurrent); // This is to ensure that EndChild() will display a navigation highlight so we can "enter" into it. + draw_window->DC.CursorPos += style.FramePadding; + inner_size.x -= draw_window->ScrollbarSizes.x; + } + else + { + // Support for internal ImGuiInputTextFlags_MergedItem flag, which could be redesigned as an ItemFlags if needed (with test performed in ItemAdd) + ItemSize(total_bb, style.FramePadding.y); + if (!(flags & ImGuiInputTextFlags_MergedItem)) + if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable)) + return false; + item_status_flags = g.LastItemData.StatusFlags; + } + const bool hovered = ItemHoverable(frame_bb, id); + if (hovered) + g.MouseCursor = ImGuiMouseCursor_TextInput; + + // We are only allowed to access the state if we are already the active widget. + ImGuiInputTextState* state = GetInputTextState(id); + + const bool input_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; + const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard)); + + const bool user_clicked = hovered && io.MouseClicked[0]; + const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); + const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); + bool clear_active_id = false; + bool select_all = false; + + float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX; + + const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); + const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_tabbing); + const bool init_state = (init_make_active || user_scroll_active); + if ((init_state && g.ActiveId != id) || init_changed_specs) + { + // Access state even if we don't own it yet. + state = &g.InputTextState; + state->CursorAnimReset(); + + // 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' (unless we are in read-only mode) + const int buf_len = (int)strlen(buf); + state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. + memcpy(state->InitialTextA.Data, buf, buf_len + 1); + + // Start edition + const char* buf_end = NULL; + state->TextW.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data is always pointing to at least an empty string. + state->TextA.resize(0); + state->TextAIsValid = false; // TextA is not valid yet (we will display buf until then) + state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, buf_size, buf, NULL, &buf_end); + state->CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. + + // Preserve cursor position and undo/redo stack if we come back to same widget + // FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed. + const bool recycle_state = (state->ID == id && !init_changed_specs); + if (recycle_state) + { + // 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. + state->CursorClamp(); + } + else + { + state->ID = id; + state->ScrollX = 0.0f; + stb_textedit_initialize_state(&state->Stb, !is_multiline); + } + + if (!is_multiline) + { + if (flags & ImGuiInputTextFlags_AutoSelectAll) + select_all = true; + if (input_requested_by_nav && (!recycle_state || !(g.NavActivateFlags & ImGuiActivateFlags_TryToPreserveState))) + select_all = true; + if (input_requested_by_tabbing || (user_clicked && io.KeyCtrl)) + select_all = true; + } + + if (flags & ImGuiInputTextFlags_AlwaysOverwrite) + state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863) + } + + if (g.ActiveId != id && init_make_active) + { + IM_ASSERT(state && state->ID == id); + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + + // Declare our inputs + IM_ASSERT(ImGuiNavInput_COUNT < 32); + g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); + if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) + g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); + SetActiveIdUsingKey(ImGuiKey_Home); + SetActiveIdUsingKey(ImGuiKey_End); + if (is_multiline) + { + SetActiveIdUsingKey(ImGuiKey_PageUp); + SetActiveIdUsingKey(ImGuiKey_PageDown); + } + if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character. + { + SetActiveIdUsingKey(ImGuiKey_Tab); + } + } + + // We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function) + if (g.ActiveId == id && state == NULL) + ClearActiveID(); + + // Release focus when we click outside + if (g.ActiveId == id && io.MouseClicked[0] && !init_state && !init_make_active) //-V560 + clear_active_id = true; + + // Lock the decision of whether we are going to take the path displaying the cursor or selection + const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); + bool render_selection = state && (state->HasSelection() || select_all) && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); + bool value_changed = false; + bool enter_pressed = false; + + // When read-only we always use the live data passed to the function + // FIXME-OPT: Because our selection/cursor code currently needs the wide text we need to convert it when active, which is not ideal :( + if (is_readonly && state != NULL && (render_cursor || render_selection)) + { + const char* buf_end = NULL; + state->TextW.resize(buf_size + 1); + state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, buf, NULL, &buf_end); + state->CurLenA = (int)(buf_end - buf); + state->CursorClamp(); + render_selection &= state->HasSelection(); + } + + // Select the buffer to render. + const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state && state->TextAIsValid; + const bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0); + + // Password pushes a temporary font with only a fallback glyph + if (is_password && !is_displaying_hint) + { + const ImFontGlyph* glyph = g.Font->FindGlyph('*'); + ImFont* password_font = &g.InputTextPasswordFont; + password_font->FontSize = g.Font->FontSize; + password_font->Scale = g.Font->Scale; + password_font->Ascent = g.Font->Ascent; + password_font->Descent = g.Font->Descent; + password_font->ContainerAtlas = g.Font->ContainerAtlas; + password_font->FallbackGlyph = glyph; + password_font->FallbackAdvanceX = glyph->AdvanceX; + IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); + PushFont(password_font); + } + + // Process mouse inputs and character inputs + int backup_current_text_length = 0; + if (g.ActiveId == id) + { + IM_ASSERT(state != NULL); + backup_current_text_length = state->CurLenA; + state->Edited = false; + state->BufCapacityA = buf_size; + state->Flags = flags; + + // 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 library-wide concept of Selected vs Active. + g.ActiveIdAllowOverlap = !io.MouseDown[0]; + g.WantTextInputNextFrame = 1; + + // Edit in progress + const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX; + const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f)); + + const bool is_osx = io.ConfigMacOSXBehaviors; + if (select_all) + { + state->SelectAll(); + state->SelectedAllMouseLock = true; + } + else if (hovered && io.MouseClickedCount[0] >= 2 && !io.KeyShift) + { + stb_textedit_click(state, &state->Stb, mouse_x, mouse_y); + const int multiclick_count = (io.MouseClickedCount[0] - 2); + if ((multiclick_count % 2) == 0) + { + // Double-click: Select word + // We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant: + // FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS) + const bool is_bol = (state->Stb.cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor - 1) == '\n'; + if (STB_TEXT_HAS_SELECTION(&state->Stb) || !is_bol) + state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); + //state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + if (!STB_TEXT_HAS_SELECTION(&state->Stb)) + ImStb::stb_textedit_prep_selection_at_cursor(&state->Stb); + state->Stb.cursor = ImStb::STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state->Stb.cursor); + state->Stb.select_end = state->Stb.cursor; + ImStb::stb_textedit_clamp(state, &state->Stb); + } + else + { + // Triple-click: Select line + const bool is_eol = ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor) == '\n'; + state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART); + state->OnKeyPressed(STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT); + state->OnKeyPressed(STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT); + if (!is_eol && is_multiline) + { + ImSwap(state->Stb.select_start, state->Stb.select_end); + state->Stb.cursor = state->Stb.select_end; + } + state->CursorFollow = false; + } + state->CursorAnimReset(); + } + else if (io.MouseClicked[0] && !state->SelectedAllMouseLock) + { + // FIXME: unselect on late click could be done release? + if (hovered) + { + stb_textedit_click(state, &state->Stb, mouse_x, mouse_y); + state->CursorAnimReset(); + } + } + else if (io.MouseDown[0] && !state->SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) + { + stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y); + state->CursorAnimReset(); + state->CursorFollow = true; + } + if (state->SelectedAllMouseLock && !io.MouseDown[0]) + state->SelectedAllMouseLock = false; + + // It is ill-defined whether the backend needs to send a \t character when pressing the TAB keys. + // Win32 and GLFW naturally do it but not SDL. + const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); + if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressed(ImGuiKey_Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly) + if (!io.InputQueueCharacters.contains('\t')) + { + unsigned int c = '\t'; // Insert TAB + if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + state->OnKeyPressed((int)c); + } + + // Process regular text input (before we check for Return because using some IME will effectively send a Return?) + // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. + if (io.InputQueueCharacters.Size > 0) + { + if (!ignore_char_inputs && !is_readonly && !input_requested_by_nav) + for (int n = 0; n < io.InputQueueCharacters.Size; n++) + { + // Insert character if they pass filtering + unsigned int c = (unsigned int)io.InputQueueCharacters[n]; + if (c == '\t' && io.KeyShift) + continue; + if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + state->OnKeyPressed((int)c); + } + + // Consume characters + io.InputQueueCharacters.resize(0); + } + } + + // Process other shortcuts/key-presses + bool cancel_edit = false; + if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) + { + IM_ASSERT(state != NULL); + IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here. + + const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1); + state->Stb.row_count_per_page = row_count_per_page; + + const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); + const bool is_osx = io.ConfigMacOSXBehaviors; + const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyModFlags_Super | ImGuiKeyModFlags_Shift)); + const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_ctrl_key_only = (io.KeyMods == ImGuiKeyModFlags_Ctrl); + const bool is_shift_key_only = (io.KeyMods == ImGuiKeyModFlags_Shift); + const bool is_shortcut_key = g.IO.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl); + + const bool is_cut = ((is_shortcut_key && IsKeyPressed(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressed(ImGuiKey_Delete))) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); + const bool is_copy = ((is_shortcut_key && IsKeyPressed(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_password && (!is_multiline || state->HasSelection()); + const bool is_paste = ((is_shortcut_key && IsKeyPressed(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_readonly; + const bool is_undo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Z)) && !is_readonly && is_undoable); + const bool is_redo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressed(ImGuiKey_Z))) && !is_readonly && is_undoable; + + // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. + const bool is_validate_enter = IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_KeypadEnter); + const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed) && !IsKeyPressed(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed); + const bool is_cancel = IsKeyPressed(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed); + + if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } + else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } + else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressed(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressed(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; } + else if (IsKeyPressed(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; } + else if (IsKeyPressed(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressed(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressed(ImGuiKey_Delete) && !is_readonly && !is_cut) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } + else if (IsKeyPressed(ImGuiKey_Backspace) && !is_readonly) + { + if (!state->HasSelection()) + { + if (is_wordmove_key_down) + state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT); + else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) + state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT); + } + state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); + } + else if (is_validate_enter) + { + bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; + if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) + { + enter_pressed = clear_active_id = true; + } + else if (!is_readonly) + { + unsigned int c = '\n'; // Insert new line + if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + state->OnKeyPressed((int)c); + } + } + else if (is_validate_nav) + { + IM_ASSERT(!is_validate_enter); + enter_pressed = clear_active_id = true; + } + else if (is_cancel) + { + clear_active_id = cancel_edit = true; + } + else if (is_undo || is_redo) + { + state->OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_REDO); + state->ClearSelection(); + } + else if (is_shortcut_key && IsKeyPressed(ImGuiKey_A)) + { + state->SelectAll(); + state->CursorFollow = true; + } + else if (is_cut || is_copy) + { + // Cut, Copy + if (io.SetClipboardTextFn) + { + const int ib = state->HasSelection() ? ImMin(state->Stb.select_start, state->Stb.select_end) : 0; + const int ie = state->HasSelection() ? ImMax(state->Stb.select_start, state->Stb.select_end) : state->CurLenW; + const int clipboard_data_len = ImTextCountUtf8BytesFromStr(state->TextW.Data + ib, state->TextW.Data + ie) + 1; + char* clipboard_data = (char*)IM_ALLOC(clipboard_data_len * sizeof(char)); + ImTextStrToUtf8(clipboard_data, clipboard_data_len, state->TextW.Data + ib, state->TextW.Data + ie); + SetClipboardText(clipboard_data); + MemFree(clipboard_data); + } + if (is_cut) + { + if (!state->HasSelection()) + state->SelectAll(); + state->CursorFollow = true; + stb_textedit_cut(state, &state->Stb); + } + } + else if (is_paste) + { + if (const char* clipboard = GetClipboardText()) + { + // Filter pasted buffer + const int clipboard_len = (int)strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((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 (!InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard)) + 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(state, &state->Stb, clipboard_filtered, clipboard_filtered_len); + state->CursorFollow = true; + } + MemFree(clipboard_filtered); + } + } + + // Update render selection flag after events have been handled, so selection highlight can be displayed during the same frame. + render_selection |= state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); + } + + // Process callbacks and apply result back to user's buffer. + const char* apply_new_text = NULL; + int apply_new_text_length = 0; + if (g.ActiveId == id) + { + IM_ASSERT(state != NULL); + if (cancel_edit) + { + // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents. + if (!is_readonly && strcmp(buf, state->InitialTextA.Data) != 0) + { + // Push records into the undo stack so we can CTRL+Z the revert operation itself + apply_new_text = state->InitialTextA.Data; + apply_new_text_length = state->InitialTextA.Size - 1; + ImVector w_text; + if (apply_new_text_length > 0) + { + w_text.resize(ImTextCountCharsFromUtf8(apply_new_text, apply_new_text + apply_new_text_length) + 1); + ImTextStrFromUtf8(w_text.Data, w_text.Size, apply_new_text, apply_new_text + apply_new_text_length); + } + stb_textedit_replace(state, &state->Stb, w_text.Data, (apply_new_text_length > 0) ? (w_text.Size - 1) : 0); + } + } + + // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. + // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. + // This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize). + bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); + if (apply_edit_back_to_user_buffer) + { + // Apply new value immediately - copy modified buffer back + // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer + // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. + // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. + if (!is_readonly) + { + state->TextAIsValid = true; + state->TextA.resize(state->TextW.Size * 4 + 1); + ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->TextW.Data, NULL); + } + + // User callback + if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | 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_None; + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressed(ImGuiKey_Tab)) + { + event_flag = ImGuiInputTextFlags_CallbackCompletion; + event_key = ImGuiKey_Tab; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressed(ImGuiKey_UpArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_UpArrow; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressed(ImGuiKey_DownArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_DownArrow; + } + else if ((flags & ImGuiInputTextFlags_CallbackEdit) && state->Edited) + { + event_flag = ImGuiInputTextFlags_CallbackEdit; + } + else if (flags & ImGuiInputTextFlags_CallbackAlways) + { + event_flag = ImGuiInputTextFlags_CallbackAlways; + } + + if (event_flag) + { + ImGuiInputTextCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiInputTextCallbackData)); + callback_data.EventFlag = event_flag; + callback_data.Flags = flags; + callback_data.UserData = callback_user_data; + + char* callback_buf = is_readonly ? buf : state->TextA.Data; + callback_data.EventKey = event_key; + callback_data.Buf = callback_buf; + callback_data.BufTextLen = state->CurLenA; + callback_data.BufSize = state->BufCapacityA; + callback_data.BufDirty = false; + + // We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188) + ImWchar* text = state->TextW.Data; + const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + state->Stb.cursor); + const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + state->Stb.select_start); + const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + state->Stb.select_end); + + // Call user code + callback(&callback_data); + + // Read back what user may have modified + callback_buf = is_readonly ? buf : state->TextA.Data; // Pointer may have been invalidated by a resize callback + IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields + IM_ASSERT(callback_data.BufSize == state->BufCapacityA); + IM_ASSERT(callback_data.Flags == flags); + const bool buf_dirty = callback_data.BufDirty; + if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); state->CursorFollow = true; } + if (callback_data.SelectionStart != utf8_selection_start || buf_dirty) { state->Stb.select_start = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb.cursor : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); } + if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb.select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); } + if (buf_dirty) + { + IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + if (callback_data.BufTextLen > backup_current_text_length && is_resizable) + state->TextW.resize(state->TextW.Size + (callback_data.BufTextLen - backup_current_text_length)); + state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, callback_data.Buf, NULL); + state->CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() + state->CursorAnimReset(); + } + } + } + + // Will copy result string if modified + if (!is_readonly && strcmp(state->TextA.Data, buf) != 0) + { + apply_new_text = state->TextA.Data; + apply_new_text_length = state->CurLenA; + } + } + + // Clear temporary user storage + state->Flags = ImGuiInputTextFlags_None; + } + + // Copy result to user buffer. This can currently only happen when (g.ActiveId == id) + if (apply_new_text != NULL) + { + // We cannot test for 'backup_current_text_length != apply_new_text_length' here because we have no guarantee that the size + // of our owned buffer matches the size of the string object held by the user, and by design we allow InputText() to be used + // without any storage on user's side. + IM_ASSERT(apply_new_text_length >= 0); + if (is_resizable) + { + ImGuiInputTextCallbackData callback_data; + callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize; + callback_data.Flags = flags; + callback_data.Buf = buf; + callback_data.BufTextLen = apply_new_text_length; + callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1); + callback_data.UserData = callback_user_data; + callback(&callback_data); + buf = callback_data.Buf; + buf_size = callback_data.BufSize; + apply_new_text_length = ImMin(callback_data.BufTextLen, buf_size - 1); + IM_ASSERT(apply_new_text_length <= buf_size); + } + //IMGUI_DEBUG_LOG("InputText(\"%s\"): apply_new_text length %d\n", label, apply_new_text_length); + + // If the underlying buffer resize was denied or not carried to the next frame, apply_new_text_length+1 may be >= buf_size. + ImStrncpy(buf, apply_new_text, ImMin(apply_new_text_length + 1, buf_size)); + value_changed = true; + } + + // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) + if (clear_active_id && g.ActiveId == id) + ClearActiveID(); + + // Render frame + if (!is_multiline) + { + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + } + + const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + inner_size.x, frame_bb.Min.y + inner_size.y); // Not using frame_bb.Max because we have adjusted size + ImVec2 draw_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; + ImVec2 text_size(0.0f, 0.0f); + + // Set upper limit of single-line InputTextEx() at 2 million characters strings. The current pathological worst case is a long line + // without any carriage return, which would makes ImFont::RenderText() reserve too many vertices and probably crash. Avoid it altogether. + // Note that we only use this limit on single-line InputText(), so a pathologically large line on a InputTextMultiline() would still crash. + const int buf_display_max_length = 2 * 1024 * 1024; + const char* buf_display = buf_display_from_state ? state->TextA.Data : buf; //-V595 + const char* buf_display_end = NULL; // We have specialized paths below for setting the length + if (is_displaying_hint) + { + buf_display = hint; + buf_display_end = hint + strlen(hint); + } + + // Render text. We currently only render selection when the widget is active or while scrolling. + // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. + if (render_cursor || render_selection) + { + IM_ASSERT(state != NULL); + if (!is_displaying_hint) + buf_display_end = buf_display + state->CurLenA; + + // Render text (with cursor and selection) + // This is going to be messy. We need to: + // - Display the text (this alone can be more easily clipped) + // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) + // - Measure text height (for scrollbar) + // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) + // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. + const ImWchar* text_begin = state->TextW.Data; + ImVec2 cursor_offset, select_start_offset; + + { + // Find lines numbers straddling 'cursor' (slot 0) and 'select_start' (slot 1) positions. + const ImWchar* searches_input_ptr[2] = { NULL, NULL }; + int searches_result_line_no[2] = { -1000, -1000 }; + int searches_remaining = 0; + if (render_cursor) + { + searches_input_ptr[0] = text_begin + state->Stb.cursor; + searches_result_line_no[0] = -1; + searches_remaining++; + } + if (render_selection) + { + searches_input_ptr[1] = text_begin + ImMin(state->Stb.select_start, state->Stb.select_end); + searches_result_line_no[1] = -1; + searches_remaining++; + } + + // Iterate all lines to find our line numbers + // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. + searches_remaining += is_multiline ? 1 : 0; + int line_count = 0; + //for (const ImWchar* s = text_begin; (s = (const ImWchar*)wcschr((const wchar_t*)s, (wchar_t)'\n')) != NULL; s++) // FIXME-OPT: Could use this when wchar_t are 16-bit + for (const ImWchar* s = text_begin; *s != 0; s++) + if (*s == '\n') + { + line_count++; + if (searches_result_line_no[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_no[0] = line_count; if (--searches_remaining <= 0) break; } + if (searches_result_line_no[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_no[1] = line_count; if (--searches_remaining <= 0) break; } + } + line_count++; + if (searches_result_line_no[0] == -1) + searches_result_line_no[0] = line_count; + if (searches_result_line_no[1] == -1) + searches_result_line_no[1] = line_count; + + // Calculate 2d position by finding the beginning of the line and measuring distance + cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; + cursor_offset.y = searches_result_line_no[0] * g.FontSize; + if (searches_result_line_no[1] >= 0) + { + select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; + select_start_offset.y = searches_result_line_no[1] * g.FontSize; + } + + // Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224) + if (is_multiline) + text_size = ImVec2(inner_size.x, line_count * g.FontSize); + } + + // Scroll + if (render_cursor && state->CursorFollow) + { + // Horizontal scroll in chunks of quarter width + if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) + { + const float scroll_increment_x = inner_size.x * 0.25f; + const float visible_width = inner_size.x - style.FramePadding.x; + if (cursor_offset.x < state->ScrollX) + state->ScrollX = IM_FLOOR(ImMax(0.0f, cursor_offset.x - scroll_increment_x)); + else if (cursor_offset.x - visible_width >= state->ScrollX) + state->ScrollX = IM_FLOOR(cursor_offset.x - visible_width + scroll_increment_x); + } + else + { + state->ScrollX = 0.0f; + } + + // Vertical scroll + if (is_multiline) + { + // Test if cursor is vertically visible + if (cursor_offset.y - g.FontSize < scroll_y) + scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); + else if (cursor_offset.y - (inner_size.y - style.FramePadding.y * 2.0f) >= scroll_y) + scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f; + const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f); + scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y); + draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag + draw_window->Scroll.y = scroll_y; + } + + state->CursorFollow = false; + } + + // Draw selection + const ImVec2 draw_scroll = ImVec2(state->ScrollX, 0.0f); + if (render_selection) + { + const ImWchar* text_selected_begin = text_begin + ImMin(state->Stb.select_start, state->Stb.select_end); + const ImWchar* text_selected_end = text_begin + ImMax(state->Stb.select_start, state->Stb.select_end); + + ImU32 bg_color = GetColorU32(ImGuiCol_TextSelectedBg, render_cursor ? 1.0f : 0.6f); // FIXME: current code flow mandate that render_cursor is always true here, we are leaving the transparent one for tests. + float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. + float bg_offy_dn = is_multiline ? 0.0f : 2.0f; + ImVec2 rect_pos = draw_pos + select_start_offset - draw_scroll; + for (const ImWchar* p = text_selected_begin; p < text_selected_end; ) + { + if (rect_pos.y > clip_rect.w + g.FontSize) + break; + if (rect_pos.y < clip_rect.y) + { + //p = (const ImWchar*)wmemchr((const wchar_t*)p, '\n', text_selected_end - p); // FIXME-OPT: Could use this when wchar_t are 16-bit + //p = p ? p + 1 : text_selected_end; + while (p < text_selected_end) + if (*p++ == '\n') + break; + } + else + { + ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); + if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines + ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); + rect.ClipWith(clip_rect); + if (rect.Overlaps(clip_rect)) + draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color); + } + rect_pos.x = draw_pos.x - draw_scroll.x; + rect_pos.y += g.FontSize; + } + } + + // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash. + if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) + { + ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + } + + // Draw blinking cursor + if (render_cursor) + { + state->CursorAnim += io.DeltaTime; + bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f; + ImVec2 cursor_screen_pos = ImFloor(draw_pos + cursor_offset - draw_scroll); + ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); + if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) + draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); + + // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) + if (!is_readonly) + { + g.PlatformImeData.WantVisible = true; + g.PlatformImeData.InputPos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize); + g.PlatformImeData.InputLineHeight = g.FontSize; + g.PlatformImeViewport = window->Viewport->ID; + } + } + } + else + { + // Render text only (no selection, no cursor) + if (is_multiline) + text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width + else if (!is_displaying_hint && g.ActiveId == id) + buf_display_end = buf_display + state->CurLenA; + else if (!is_displaying_hint) + buf_display_end = buf_display + strlen(buf_display); + + if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) + { + ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + } + } + + if (is_password && !is_displaying_hint) + PopFont(); + + if (is_multiline) + { + // For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (ref issue #4761)... + Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y)); + ImGuiItemFlags backup_item_flags = g.CurrentItemFlags; + g.CurrentItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop; + EndChild(); + item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow); + g.CurrentItemFlags = backup_item_flags; + + // ...and then we need to undo the group overriding last item data, which gets a bit messy as EndGroup() tries to forward scrollbar being active... + // FIXME: This quite messy/tricky, should attempt to get rid of the child window. + EndGroup(); + if (g.LastItemData.ID == 0) + { + g.LastItemData.ID = id; + g.LastItemData.InFlags = item_data_backup.InFlags; + g.LastItemData.StatusFlags = item_data_backup.StatusFlags; + } + } + + // Log as text + if (g.LogEnabled && (!is_password || is_displaying_hint)) + { + LogSetNextTextDecoration("{", "}"); + LogRenderedText(&draw_pos, buf_display, buf_display_end); + } + + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + + if (value_changed && !(flags & ImGuiInputTextFlags_NoMarkEdited)) + MarkItemEdited(id); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) + return enter_pressed; + else + return value_changed; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc. +//------------------------------------------------------------------------- +// - ColorEdit3() +// - ColorEdit4() +// - ColorPicker3() +// - RenderColorRectWithAlphaCheckerboard() [Internal] +// - ColorPicker4() +// - ColorButton() +// - SetColorEditOptions() +// - ColorTooltip() [Internal] +// - ColorEditOptionsPopup() [Internal] +// - ColorPickerOptionsPopup() [Internal] +//------------------------------------------------------------------------- + +bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) +{ + return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); +} + +// ColorEdit supports RGB and HSV inputs. In case of RGB input resulting color may have undefined hue and/or saturation. +// Since widget displays both RGB and HSV values we must preserve hue and saturation to prevent these values resetting. +static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V) +{ + // This check is optional. Suppose we have two color widgets side by side, both widgets display different colors, but both colors have hue and/or saturation undefined. + // With color check: hue/saturation is preserved in one widget. Editing color in one widget would reset hue/saturation in another one. + // Without color check: common hue/saturation would be displayed in all widgets that have hue/saturation undefined. + // g.ColorEditLastColor is stored as ImU32 RGB value: this essentially gives us color equality check with reduced precision. + // Tiny external color changes would not be detected and this check would still pass. This is OK, since we only restore hue/saturation _only_ if they are undefined, + // therefore this change flipping hue/saturation from undefined to a very tiny value would still be represented in color picker. + ImGuiContext& g = *GImGui; + if (g.ColorEditLastColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) + return; + + // When S == 0, H is undefined. + // When H == 1 it wraps around to 0. + if (*S == 0.0f || (*H == 0.0f && g.ColorEditLastHue == 1)) + *H = g.ColorEditLastHue; + + // When V == 0, S is undefined. + if (*V == 0.0f) + *S = g.ColorEditLastSat; +} + +// Edit colors components (each component in 0.0f..1.0f range). +// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item. +bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float square_sz = GetFrameHeight(); + const float w_full = CalcItemWidth(); + const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); + const float w_inputs = w_full - w_button; + const char* label_display_end = FindRenderedTextEnd(label); + g.NextItemData.ClearFlags(); + + BeginGroup(); + PushID(label); + + // If we're not showing any slider there's no point in doing any HSV conversions + const ImGuiColorEditFlags flags_untouched = flags; + if (flags & ImGuiColorEditFlags_NoInputs) + flags = (flags & (~ImGuiColorEditFlags_DisplayMask_)) | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_NoOptions; + + // Context menu: display and modify options (before defaults are applied) + if (!(flags & ImGuiColorEditFlags_NoOptions)) + ColorEditOptionsPopup(col, flags); + + // Read stored options + if (!(flags & ImGuiColorEditFlags_DisplayMask_)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_DisplayMask_); + if (!(flags & ImGuiColorEditFlags_DataTypeMask_)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_DataTypeMask_); + if (!(flags & ImGuiColorEditFlags_PickerMask_)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_PickerMask_); + if (!(flags & ImGuiColorEditFlags_InputMask_)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_InputMask_); + flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_)); + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_DisplayMask_)); // Check that only 1 is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_InputMask_)); // Check that only 1 is selected + + const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; + const int components = alpha ? 4 : 3; + + // Convert to the formats we need + float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; + if ((flags & ImGuiColorEditFlags_InputHSV) && (flags & ImGuiColorEditFlags_DisplayRGB)) + ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV)) + { + // Hue is lost when converting from greyscale rgb (saturation=0). Restore it. + ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); + ColorEditRestoreHS(col, &f[0], &f[1], &f[2]); + } + int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; + + bool value_changed = false; + bool value_changed_as_float = false; + + const ImVec2 pos = window->DC.CursorPos; + const float inputs_offset_x = (style.ColorButtonPosition == ImGuiDir_Left) ? w_button : 0.0f; + window->DC.CursorPos.x = pos.x + inputs_offset_x; + + if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) + { + // RGB/HSV 0..255 Sliders + const float w_item_one = ImMax(1.0f, IM_FLOOR((w_inputs - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); + const float w_item_last = ImMax(1.0f, IM_FLOOR(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); + + const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); + static const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; + static const char* fmt_table_int[3][4] = + { + { "%3d", "%3d", "%3d", "%3d" }, // Short display + { "R:%3d", "G:%3d", "B:%3d", "A:%3d" }, // Long display for RGBA + { "H:%3d", "S:%3d", "V:%3d", "A:%3d" } // Long display for HSVA + }; + static const char* fmt_table_float[3][4] = + { + { "%0.3f", "%0.3f", "%0.3f", "%0.3f" }, // Short display + { "R:%0.3f", "G:%0.3f", "B:%0.3f", "A:%0.3f" }, // Long display for RGBA + { "H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f" } // Long display for HSVA + }; + const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_DisplayHSV) ? 2 : 1; + + for (int n = 0; n < components; n++) + { + if (n > 0) + SameLine(0, style.ItemInnerSpacing.x); + SetNextItemWidth((n + 1 < components) ? w_item_one : w_item_last); + + // FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0. + if (flags & ImGuiColorEditFlags_Float) + { + value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); + value_changed_as_float |= value_changed; + } + else + { + value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + } + } + else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) + { + // RGB Hexadecimal Input + char buf[64]; + if (alpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255)); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255)); + SetNextItemWidth(w_inputs); + if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) + { + value_changed = true; + char* p = buf; + while (*p == '#' || ImCharIsBlankA(*p)) + p++; + i[0] = i[1] = i[2] = 0; + i[3] = 0xFF; // alpha default to 255 is not parsed by scanf (e.g. inputting #FFFFFF omitting alpha) + int r; + if (alpha) + r = sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) + else + r = sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); + IM_UNUSED(r); // Fixes C6031: Return value ignored: 'sscanf'. + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + } + + ImGuiWindow* picker_active_window = NULL; + if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) + { + const float button_offset_x = ((flags & ImGuiColorEditFlags_NoInputs) || (style.ColorButtonPosition == ImGuiDir_Left)) ? 0.0f : w_inputs + style.ItemInnerSpacing.x; + window->DC.CursorPos = ImVec2(pos.x + button_offset_x, pos.y); + + const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); + if (ColorButton("##ColorButton", col_v4, flags)) + { + if (!(flags & ImGuiColorEditFlags_NoPicker)) + { + // Store current color and open a picker + g.ColorPickerRef = col_v4; + OpenPopup("picker"); + SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(0.0f, style.ItemSpacing.y)); + } + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + + if (BeginPopup("picker")) + { + picker_active_window = g.CurrentWindow; + if (label != label_display_end) + { + TextEx(label, label_display_end); + Spacing(); + } + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; + ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; + SetNextItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? + value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); + EndPopup(); + } + } + + if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) + { + const float text_offset_x = (flags & ImGuiColorEditFlags_NoInputs) ? w_button : w_full + style.ItemInnerSpacing.x; + window->DC.CursorPos = ImVec2(pos.x + text_offset_x, pos.y + style.FramePadding.y); + TextEx(label, label_display_end); + } + + // Convert back + if (value_changed && picker_active_window == NULL) + { + if (!value_changed_as_float) + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; + if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB)) + { + g.ColorEditLastHue = f[0]; + g.ColorEditLastSat = f[1]; + ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(f[0], f[1], f[2], 0)); + } + if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV)) + ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); + + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; + } + + PopID(); + EndGroup(); + + // Drag and Drop Target + // NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test. + if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropTarget()) + { + bool accepted_drag_drop = false; + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + { + memcpy((float*)col, payload->Data, sizeof(float) * 3); // Preserve alpha if any //-V512 + value_changed = accepted_drag_drop = true; + } + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + { + memcpy((float*)col, payload->Data, sizeof(float) * components); + value_changed = accepted_drag_drop = true; + } + + // Drag-drop payloads are always RGB + if (accepted_drag_drop && (flags & ImGuiColorEditFlags_InputHSV)) + ColorConvertRGBtoHSV(col[0], col[1], col[2], col[0], col[1], col[2]); + EndDragDropTarget(); + } + + // When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4(). + if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window) + g.LastItemData.ID = g.ActiveId; + + if (value_changed) + MarkItemEdited(g.LastItemData.ID); + + return value_changed; +} + +bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) +{ + float col4[4] = { col[0], col[1], col[2], 1.0f }; + if (!ColorPicker4(label, col4, flags | ImGuiColorEditFlags_NoAlpha)) + return false; + col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; + return true; +} + +// Helper for ColorPicker4() +static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, float bar_w, float alpha) +{ + ImU32 alpha8 = IM_F32_TO_INT8_SAT(alpha); + ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32(0,0,0,alpha8)); + ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32(255,255,255,alpha8)); + ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32(0,0,0,alpha8)); + ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32(255,255,255,alpha8)); +} + +// Note: ColorPicker4() only accesses 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +// (In C++ the 'float col[4]' notation for a function argument is equivalent to 'float* col', we only specify a size to facilitate understanding of the code.) +// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) +// FIXME: this is trying to be aware of style.Alpha but not fully correct. Also, the color wheel will have overlapping glitches with (style.Alpha < 1.0) +bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImDrawList* draw_list = window->DrawList; + ImGuiStyle& style = g.Style; + ImGuiIO& io = g.IO; + + const float width = CalcItemWidth(); + g.NextItemData.ClearFlags(); + + PushID(label); + BeginGroup(); + + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + flags |= ImGuiColorEditFlags_NoSmallPreview; + + // Context menu: display and store options. + if (!(flags & ImGuiColorEditFlags_NoOptions)) + ColorPickerOptionsPopup(col, flags); + + // Read stored options + if (!(flags & ImGuiColorEditFlags_PickerMask_)) + flags |= ((g.ColorEditOptions & ImGuiColorEditFlags_PickerMask_) ? g.ColorEditOptions : ImGuiColorEditFlags_DefaultOptions_) & ImGuiColorEditFlags_PickerMask_; + if (!(flags & ImGuiColorEditFlags_InputMask_)) + flags |= ((g.ColorEditOptions & ImGuiColorEditFlags_InputMask_) ? g.ColorEditOptions : ImGuiColorEditFlags_DefaultOptions_) & ImGuiColorEditFlags_InputMask_; + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_PickerMask_)); // Check that only 1 is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_InputMask_)); // Check that only 1 is selected + if (!(flags & ImGuiColorEditFlags_NoOptions)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); + + // Setup + int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; + bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); + ImVec2 picker_pos = window->DC.CursorPos; + float square_sz = GetFrameHeight(); + float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars + float sv_picker_size = ImMax(bars_width * 1, width - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; + float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; + float bars_triangles_half_sz = IM_FLOOR(bars_width * 0.20f); + + float backup_initial_col[4]; + memcpy(backup_initial_col, col, components * sizeof(float)); + + float wheel_thickness = sv_picker_size * 0.08f; + float wheel_r_outer = sv_picker_size * 0.50f; + float wheel_r_inner = wheel_r_outer - wheel_thickness; + ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width)*0.5f, picker_pos.y + sv_picker_size * 0.5f); + + // Note: the triangle is displayed rotated with triangle_pa pointing to Hue, but most coordinates stays unrotated for logic. + float triangle_r = wheel_r_inner - (int)(sv_picker_size * 0.027f); + ImVec2 triangle_pa = ImVec2(triangle_r, 0.0f); // Hue point. + ImVec2 triangle_pb = ImVec2(triangle_r * -0.5f, triangle_r * -0.866025f); // Black point. + ImVec2 triangle_pc = ImVec2(triangle_r * -0.5f, triangle_r * +0.866025f); // White point. + + float H = col[0], S = col[1], V = col[2]; + float R = col[0], G = col[1], B = col[2]; + if (flags & ImGuiColorEditFlags_InputRGB) + { + // Hue is lost when converting from greyscale rgb (saturation=0). Restore it. + ColorConvertRGBtoHSV(R, G, B, H, S, V); + ColorEditRestoreHS(col, &H, &S, &V); + } + else if (flags & ImGuiColorEditFlags_InputHSV) + { + ColorConvertHSVtoRGB(H, S, V, R, G, B); + } + + bool value_changed = false, value_changed_h = false, value_changed_sv = false; + + PushItemFlag(ImGuiItemFlags_NoNav, true); + if (flags & ImGuiColorEditFlags_PickerHueWheel) + { + // Hue wheel + SV triangle logic + InvisibleButton("hsv", ImVec2(sv_picker_size + style.ItemInnerSpacing.x + bars_width, sv_picker_size)); + if (IsItemActive()) + { + ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center; + ImVec2 current_off = g.IO.MousePos - wheel_center; + float initial_dist2 = ImLengthSqr(initial_off); + if (initial_dist2 >= (wheel_r_inner - 1) * (wheel_r_inner - 1) && initial_dist2 <= (wheel_r_outer + 1) * (wheel_r_outer + 1)) + { + // Interactive with Hue wheel + H = ImAtan2(current_off.y, current_off.x) / IM_PI * 0.5f; + if (H < 0.0f) + H += 1.0f; + value_changed = value_changed_h = true; + } + float cos_hue_angle = ImCos(-H * 2.0f * IM_PI); + float sin_hue_angle = ImSin(-H * 2.0f * IM_PI); + if (ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, ImRotate(initial_off, cos_hue_angle, sin_hue_angle))) + { + // Interacting with SV triangle + ImVec2 current_off_unrotated = ImRotate(current_off, cos_hue_angle, sin_hue_angle); + if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated)) + current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated); + float uu, vv, ww; + ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated, uu, vv, ww); + V = ImClamp(1.0f - vv, 0.0001f, 1.0f); + S = ImClamp(uu / V, 0.0001f, 1.0f); + value_changed = value_changed_sv = true; + } + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) + { + // SV rectangle logic + InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); + if (IsItemActive()) + { + S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1)); + V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + + // Greatly reduces hue jitter and reset to 0 when hue == 255 and color is rapidly modified using SV square. + if (g.ColorEditLastColor == ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) + H = g.ColorEditLastHue; + value_changed = value_changed_sv = true; + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + + // Hue bar logic + SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); + InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); + if (IsItemActive()) + { + H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + value_changed = value_changed_h = true; + } + } + + // Alpha bar logic + if (alpha_bar) + { + SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y)); + InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size)); + if (IsItemActive()) + { + col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + value_changed = true; + } + } + PopItemFlag(); // ImGuiItemFlags_NoNav + + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + SameLine(0, style.ItemInnerSpacing.x); + BeginGroup(); + } + + if (!(flags & ImGuiColorEditFlags_NoLabel)) + { + const char* label_display_end = FindRenderedTextEnd(label); + if (label != label_display_end) + { + if ((flags & ImGuiColorEditFlags_NoSidePreview)) + SameLine(0, style.ItemInnerSpacing.x); + TextEx(label, label_display_end); + } + } + + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + PushItemFlag(ImGuiItemFlags_NoNavDefaultFocus, true); + ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + if ((flags & ImGuiColorEditFlags_NoLabel)) + Text("Current"); + + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip; + ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2)); + if (ref_col != NULL) + { + Text("Original"); + ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); + if (ColorButton("##original", ref_col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2))) + { + memcpy(col, ref_col, components * sizeof(float)); + value_changed = true; + } + } + PopItemFlag(); + EndGroup(); + } + + // Convert back color to RGB + if (value_changed_h || value_changed_sv) + { + if (flags & ImGuiColorEditFlags_InputRGB) + { + ColorConvertHSVtoRGB(H, S, V, col[0], col[1], col[2]); + g.ColorEditLastHue = H; + g.ColorEditLastSat = S; + g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)); + } + else if (flags & ImGuiColorEditFlags_InputHSV) + { + col[0] = H; + col[1] = S; + col[2] = V; + } + } + + // R,G,B and H,S,V slider color editor + bool value_changed_fix_hue_wrap = false; + if ((flags & ImGuiColorEditFlags_NoInputs) == 0) + { + PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; + if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags_DisplayMask_) == 0) + if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB)) + { + // FIXME: Hackily differentiating using the DragInt (ActiveId != 0 && !ActiveIdAllowOverlap) vs. using the InputText or DropTarget. + // For the later we don't want to run the hue-wrap canceling code. If you are well versed in HSV picker please provide your input! (See #2050) + value_changed_fix_hue_wrap = (g.ActiveId != 0 && !g.ActiveIdAllowOverlap); + value_changed = true; + } + if (flags & ImGuiColorEditFlags_DisplayHSV || (flags & ImGuiColorEditFlags_DisplayMask_) == 0) + value_changed |= ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_DisplayHSV); + if (flags & ImGuiColorEditFlags_DisplayHex || (flags & ImGuiColorEditFlags_DisplayMask_) == 0) + value_changed |= ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_DisplayHex); + PopItemWidth(); + } + + // Try to cancel hue wrap (after ColorEdit4 call), if any + if (value_changed_fix_hue_wrap && (flags & ImGuiColorEditFlags_InputRGB)) + { + float new_H, new_S, new_V; + ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); + if (new_H <= 0 && H > 0) + { + if (new_V <= 0 && V != new_V) + ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); + else if (new_S <= 0) + ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); + } + } + + if (value_changed) + { + if (flags & ImGuiColorEditFlags_InputRGB) + { + R = col[0]; + G = col[1]; + B = col[2]; + ColorConvertRGBtoHSV(R, G, B, H, S, V); + ColorEditRestoreHS(col, &H, &S, &V); // Fix local Hue as display below will use it immediately. + } + else if (flags & ImGuiColorEditFlags_InputHSV) + { + H = col[0]; + S = col[1]; + V = col[2]; + ColorConvertHSVtoRGB(H, S, V, R, G, B); + } + } + + const int style_alpha8 = IM_F32_TO_INT8_SAT(style.Alpha); + const ImU32 col_black = IM_COL32(0,0,0,style_alpha8); + const ImU32 col_white = IM_COL32(255,255,255,style_alpha8); + const ImU32 col_midgrey = IM_COL32(128,128,128,style_alpha8); + const ImU32 col_hues[6 + 1] = { IM_COL32(255,0,0,style_alpha8), IM_COL32(255,255,0,style_alpha8), IM_COL32(0,255,0,style_alpha8), IM_COL32(0,255,255,style_alpha8), IM_COL32(0,0,255,style_alpha8), IM_COL32(255,0,255,style_alpha8), IM_COL32(255,0,0,style_alpha8) }; + + ImVec4 hue_color_f(1, 1, 1, style.Alpha); ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); + ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); + ImU32 user_col32_striped_of_alpha = ColorConvertFloat4ToU32(ImVec4(R, G, B, style.Alpha)); // Important: this is still including the main rendering/style alpha!! + + ImVec2 sv_cursor_pos; + + if (flags & ImGuiColorEditFlags_PickerHueWheel) + { + // Render Hue Wheel + const float aeps = 0.5f / wheel_r_outer; // Half a pixel arc length in radians (2pi cancels out). + const int segment_per_arc = ImMax(4, (int)wheel_r_outer / 12); + for (int n = 0; n < 6; n++) + { + const float a0 = (n) /6.0f * 2.0f * IM_PI - aeps; + const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps; + const int vert_start_idx = draw_list->VtxBuffer.Size; + draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc); + draw_list->PathStroke(col_white, 0, wheel_thickness); + const int vert_end_idx = draw_list->VtxBuffer.Size; + + // Paint colors over existing vertices + ImVec2 gradient_p0(wheel_center.x + ImCos(a0) * wheel_r_inner, wheel_center.y + ImSin(a0) * wheel_r_inner); + ImVec2 gradient_p1(wheel_center.x + ImCos(a1) * wheel_r_inner, wheel_center.y + ImSin(a1) * wheel_r_inner); + ShadeVertsLinearColorGradientKeepAlpha(draw_list, vert_start_idx, vert_end_idx, gradient_p0, gradient_p1, col_hues[n], col_hues[n + 1]); + } + + // Render Cursor + preview on Hue Wheel + float cos_hue_angle = ImCos(H * 2.0f * IM_PI); + float sin_hue_angle = ImSin(H * 2.0f * IM_PI); + ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f); + float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; + int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); + draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad + 1, col_midgrey, hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, col_white, hue_cursor_segments); + + // Render SV triangle (rotated according to hue) + ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); + ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); + ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); + ImVec2 uv_white = GetFontTexUvWhitePixel(); + draw_list->PrimReserve(6, 6); + draw_list->PrimVtx(tra, uv_white, hue_color32); + draw_list->PrimVtx(trb, uv_white, hue_color32); + draw_list->PrimVtx(trc, uv_white, col_white); + draw_list->PrimVtx(tra, uv_white, 0); + draw_list->PrimVtx(trb, uv_white, col_black); + draw_list->PrimVtx(trc, uv_white, 0); + draw_list->AddTriangle(tra, trb, trc, col_midgrey, 1.5f); + sv_cursor_pos = ImLerp(ImLerp(trc, tra, ImSaturate(S)), trb, ImSaturate(1 - V)); + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) + { + // Render SV Square + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), col_white, hue_color32, hue_color32, col_white); + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0, 0, col_black, col_black); + RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0.0f); + sv_cursor_pos.x = ImClamp(IM_ROUND(picker_pos.x + ImSaturate(S) * sv_picker_size), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much + sv_cursor_pos.y = ImClamp(IM_ROUND(picker_pos.y + ImSaturate(1 - V) * sv_picker_size), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); + + // Render Hue Bar + for (int i = 0; i < 6; ++i) + draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), col_hues[i], col_hues[i], col_hues[i + 1], col_hues[i + 1]); + float bar0_line_y = IM_ROUND(picker_pos.y + H * sv_picker_size); + RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha); + } + + // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) + float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f; + draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, user_col32_striped_of_alpha, 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, col_midgrey, 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, col_white, 12); + + // Render alpha bar + if (alpha_bar) + { + float alpha = ImSaturate(col[3]); + ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); + RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); + draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK); + float bar1_line_y = IM_ROUND(picker_pos.y + (1.0f - alpha) * sv_picker_size); + RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha); + } + + EndGroup(); + + if (value_changed && memcmp(backup_initial_col, col, components * sizeof(float)) == 0) + value_changed = false; + if (value_changed) + MarkItemEdited(g.LastItemData.ID); + + PopID(); + + return value_changed; +} + +// A little color square. Return true when clicked. +// FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. +// 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. +// Note that 'col' may be encoded in HSV if ImGuiColorEditFlags_InputHSV is set. +bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, ImVec2 size) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiID id = window->GetID(desc_id); + float default_size = GetFrameHeight(); + if (size.x == 0.0f) + size.x = default_size; + if (size.y == 0.0f) + size.y = default_size; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); + if (!ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + if (flags & ImGuiColorEditFlags_NoAlpha) + flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf); + + ImVec4 col_rgb = col; + if (flags & ImGuiColorEditFlags_InputHSV) + ColorConvertHSVtoRGB(col_rgb.x, col_rgb.y, col_rgb.z, col_rgb.x, col_rgb.y, col_rgb.z); + + ImVec4 col_rgb_without_alpha(col_rgb.x, col_rgb.y, col_rgb.z, 1.0f); + float grid_step = ImMin(size.x, size.y) / 2.99f; + float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); + ImRect bb_inner = bb; + float off = 0.0f; + if ((flags & ImGuiColorEditFlags_NoBorder) == 0) + { + off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. + bb_inner.Expand(off); + } + if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f) + { + float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f); + RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight); + window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft); + } + else + { + // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha + ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col_rgb : col_rgb_without_alpha; + if (col_source.w < 1.0f) + RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); + else + window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding); + } + RenderNavHighlight(bb, id); + if ((flags & ImGuiColorEditFlags_NoBorder) == 0) + { + if (g.Style.FrameBorderSize > 0.0f) + RenderFrameBorder(bb.Min, bb.Max, rounding); + else + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + } + + // Drag and Drop Source + // NB: The ActiveId test is merely an optional micro-optimization, BeginDragDropSource() does the same test. + if (g.ActiveId == id && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropSource()) + { + if (flags & ImGuiColorEditFlags_NoAlpha) + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, &col_rgb, sizeof(float) * 3, ImGuiCond_Once); + else + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col_rgb, sizeof(float) * 4, ImGuiCond_Once); + ColorButton(desc_id, col, flags); + SameLine(); + TextEx("Color"); + EndDragDropSource(); + } + + // Tooltip + if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) + ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); + + return pressed; +} + +// Initialize/override default color options +void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags) +{ + ImGuiContext& g = *GImGui; + if ((flags & ImGuiColorEditFlags_DisplayMask_) == 0) + flags |= ImGuiColorEditFlags_DefaultOptions_ & ImGuiColorEditFlags_DisplayMask_; + if ((flags & ImGuiColorEditFlags_DataTypeMask_) == 0) + flags |= ImGuiColorEditFlags_DefaultOptions_ & ImGuiColorEditFlags_DataTypeMask_; + if ((flags & ImGuiColorEditFlags_PickerMask_) == 0) + flags |= ImGuiColorEditFlags_DefaultOptions_ & ImGuiColorEditFlags_PickerMask_; + if ((flags & ImGuiColorEditFlags_InputMask_) == 0) + flags |= ImGuiColorEditFlags_DefaultOptions_ & ImGuiColorEditFlags_InputMask_; + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_DisplayMask_)); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_DataTypeMask_)); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_PickerMask_)); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags_InputMask_)); // Check only 1 option is selected + g.ColorEditOptions = flags; +} + +// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags) +{ + ImGuiContext& g = *GImGui; + + BeginTooltipEx(ImGuiTooltipFlags_OverridePreviousTooltip, ImGuiWindowFlags_None); + const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; + if (text_end > text) + { + TextEx(text, text_end); + Separator(); + } + + ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2); + ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + ColorButton("##preview", cf, (flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz); + SameLine(); + if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_)) + { + if (flags & ImGuiColorEditFlags_NoAlpha) + Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); + else + Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); + } + else if (flags & ImGuiColorEditFlags_InputHSV) + { + if (flags & ImGuiColorEditFlags_NoAlpha) + Text("H: %.3f, S: %.3f, V: %.3f", col[0], col[1], col[2]); + else + Text("H: %.3f, S: %.3f, V: %.3f, A: %.3f", col[0], col[1], col[2], col[3]); + } + EndTooltip(); +} + +void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) +{ + bool allow_opt_inputs = !(flags & ImGuiColorEditFlags_DisplayMask_); + bool allow_opt_datatype = !(flags & ImGuiColorEditFlags_DataTypeMask_); + if ((!allow_opt_inputs && !allow_opt_datatype) || !BeginPopup("context")) + return; + ImGuiContext& g = *GImGui; + ImGuiColorEditFlags opts = g.ColorEditOptions; + if (allow_opt_inputs) + { + if (RadioButton("RGB", (opts & ImGuiColorEditFlags_DisplayRGB) != 0)) opts = (opts & ~ImGuiColorEditFlags_DisplayMask_) | ImGuiColorEditFlags_DisplayRGB; + if (RadioButton("HSV", (opts & ImGuiColorEditFlags_DisplayHSV) != 0)) opts = (opts & ~ImGuiColorEditFlags_DisplayMask_) | ImGuiColorEditFlags_DisplayHSV; + if (RadioButton("Hex", (opts & ImGuiColorEditFlags_DisplayHex) != 0)) opts = (opts & ~ImGuiColorEditFlags_DisplayMask_) | ImGuiColorEditFlags_DisplayHex; + } + if (allow_opt_datatype) + { + if (allow_opt_inputs) Separator(); + if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) != 0)) opts = (opts & ~ImGuiColorEditFlags_DataTypeMask_) | ImGuiColorEditFlags_Uint8; + if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) != 0)) opts = (opts & ~ImGuiColorEditFlags_DataTypeMask_) | ImGuiColorEditFlags_Float; + } + + if (allow_opt_inputs || allow_opt_datatype) + Separator(); + if (Button("Copy as..", ImVec2(-1, 0))) + OpenPopup("Copy"); + if (BeginPopup("Copy")) + { + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + char buf[64]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + if (Selectable(buf)) + SetClipboardText(buf); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca); + if (Selectable(buf)) + SetClipboardText(buf); + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", cr, cg, cb); + if (Selectable(buf)) + SetClipboardText(buf); + if (!(flags & ImGuiColorEditFlags_NoAlpha)) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", cr, cg, cb, ca); + if (Selectable(buf)) + SetClipboardText(buf); + } + EndPopup(); + } + + g.ColorEditOptions = opts; + EndPopup(); +} + +void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags) +{ + bool allow_opt_picker = !(flags & ImGuiColorEditFlags_PickerMask_); + bool allow_opt_alpha_bar = !(flags & ImGuiColorEditFlags_NoAlpha) && !(flags & ImGuiColorEditFlags_AlphaBar); + if ((!allow_opt_picker && !allow_opt_alpha_bar) || !BeginPopup("context")) + return; + ImGuiContext& g = *GImGui; + if (allow_opt_picker) + { + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + PushItemWidth(picker_size.x); + for (int picker_type = 0; picker_type < 2; picker_type++) + { + // Draw small/thumbnail version of each picker type (over an invisible button for selection) + if (picker_type > 0) Separator(); + PushID(picker_type); + ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoSidePreview | (flags & ImGuiColorEditFlags_NoAlpha); + if (picker_type == 0) picker_flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_type == 1) picker_flags |= ImGuiColorEditFlags_PickerHueWheel; + ImVec2 backup_pos = GetCursorScreenPos(); + if (Selectable("##selectable", false, 0, picker_size)) // By default, Selectable() is closing popup + g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags_PickerMask_) | (picker_flags & ImGuiColorEditFlags_PickerMask_); + SetCursorScreenPos(backup_pos); + ImVec4 previewing_ref_col; + memcpy(&previewing_ref_col, ref_col, sizeof(float) * ((picker_flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4)); + ColorPicker4("##previewing_picker", &previewing_ref_col.x, picker_flags); + PopID(); + } + PopItemWidth(); + } + if (allow_opt_alpha_bar) + { + if (allow_opt_picker) Separator(); + CheckboxFlags("Alpha Bar", &g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar); + } + EndPopup(); +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: TreeNode, CollapsingHeader, etc. +//------------------------------------------------------------------------- +// - TreeNode() +// - TreeNodeV() +// - TreeNodeEx() +// - TreeNodeExV() +// - TreeNodeBehavior() [Internal] +// - TreePush() +// - TreePop() +// - GetTreeNodeToLabelSpacing() +// - SetNextItemOpen() +// - CollapsingHeader() +//------------------------------------------------------------------------- + +bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, 0, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, 0, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNode(const char* label) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + return TreeNodeBehavior(window->GetID(label), 0, label, NULL); +} + +bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) +{ + return TreeNodeExV(str_id, 0, fmt, args); +} + +bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args) +{ + return TreeNodeExV(ptr_id, 0, fmt, args); +} + +bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + return TreeNodeBehavior(window->GetID(label), flags, label, NULL); +} + +bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, flags, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, flags, fmt, args); + va_end(args); + return is_open; +} + +bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); +} + +bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); +} + +bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) +{ + if (flags & ImGuiTreeNodeFlags_Leaf) + return true; + + // We only write to the tree storage if the user clicks (or explicitly use the SetNextItemOpen function) + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiStorage* storage = window->DC.StateStorage; + + bool is_open; + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasOpen) + { + if (g.NextItemData.OpenCond & ImGuiCond_Always) + { + is_open = g.NextItemData.OpenVal; + storage->SetInt(id, is_open); + } + else + { + // We treat ImGuiCond_Once and ImGuiCond_FirstUseEver the same because tree node state are not saved persistently. + const int stored_value = storage->GetInt(id, -1); + if (stored_value == -1) + { + is_open = g.NextItemData.OpenVal; + storage->SetInt(id, is_open); + } + else + { + is_open = stored_value != 0; + } + } + } + else + { + is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0; + } + + // When logging is enabled, we 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 && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && (window->DC.TreeDepth - g.LogDepthRef) < g.LogDepthToExpand) + is_open = true; + + return is_open; +} + +bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; + const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y)); + + if (!label_end) + label_end = FindRenderedTextEnd(label); + const ImVec2 label_size = CalcTextSize(label, label_end, false); + + // We vertically grow up to current line height up the typical widget height. + const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); + ImRect frame_bb; + frame_bb.Min.x = (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; + frame_bb.Min.y = window->DC.CursorPos.y; + frame_bb.Max.x = window->WorkRect.Max.x; + frame_bb.Max.y = window->DC.CursorPos.y + frame_height; + if (display_frame) + { + // Framed header expand a little outside the default padding, to the edge of InnerClipRect + // (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f) + frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); + frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); + } + + const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing + const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it + const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser + ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); + ItemSize(ImVec2(text_width, frame_height), padding.y); + + // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing + ImRect interact_bb = frame_bb; + if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth)) == 0) + interact_bb.Max.x = frame_bb.Min.x + text_width + style.ItemSpacing.x * 2.0f; + + // Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child. + // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). + // This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero. + const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0; + bool is_open = TreeNodeBehaviorIsOpen(id, flags); + if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + window->DC.TreeJumpToParentOnPopMask |= (1 << window->DC.TreeDepth); + + bool item_add = ItemAdd(interact_bb, id); + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; + g.LastItemData.DisplayRect = frame_bb; + + if (!item_add) + { + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushOverrideID(id); + IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0)); + return is_open; + } + + ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None; + if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) + button_flags |= ImGuiButtonFlags_AllowItemOverlap; + if (!is_leaf) + button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; + + // We allow clicking on the arrow section with keyboard modifiers held, in order to easily + // allow browsing a tree while preserving selection with code implementing multi-selection patterns. + // When clicking on the rest of the tree node we always disallow keyboard modifiers. + const float arrow_hit_x1 = (text_pos.x - text_offset_x) - style.TouchExtraPadding.x; + const float arrow_hit_x2 = (text_pos.x - text_offset_x) + (g.FontSize + padding.x * 2.0f) + style.TouchExtraPadding.x; + const bool is_mouse_x_over_arrow = (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2); + if (window != g.HoveredWindow || !is_mouse_x_over_arrow) + button_flags |= ImGuiButtonFlags_NoKeyModifiers; + + // Open behaviors can be altered with the _OpenOnArrow and _OnOnDoubleClick flags. + // Some alteration have subtle effects (e.g. toggle on MouseUp vs MouseDown events) due to requirements for multi-selection and drag and drop support. + // - Single-click on label = Toggle on MouseUp (default, when _OpenOnArrow=0) + // - Single-click on arrow = Toggle on MouseDown (when _OpenOnArrow=0) + // - Single-click on arrow = Toggle on MouseDown (when _OpenOnArrow=1) + // - Double-click on label = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1) + // - Double-click on arrow = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1 and _OpenOnArrow=0) + // It is rather standard that arrow click react on Down rather than Up. + // We set ImGuiButtonFlags_PressedOnClickRelease on OpenOnDoubleClick because we want the item to be active on the initial MouseDown in order for drag and drop to work. + if (is_mouse_x_over_arrow) + button_flags |= ImGuiButtonFlags_PressedOnClick; + else if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; + else + button_flags |= ImGuiButtonFlags_PressedOnClickRelease; + + bool selected = (flags & ImGuiTreeNodeFlags_Selected) != 0; + const bool was_selected = selected; + + bool hovered, held; + bool pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); + bool toggled = false; + if (!is_leaf) + { + if (pressed && g.DragDropHoldJustPressedId != id) + { + if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id)) + toggled = true; + if (flags & ImGuiTreeNodeFlags_OpenOnArrow) + toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job + if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseClickedCount[0] == 2) + toggled = true; + } + else if (pressed && g.DragDropHoldJustPressedId == id) + { + IM_ASSERT(button_flags & ImGuiButtonFlags_PressedOnDragDropHold); + if (!is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. + toggled = true; + } + + if (g.NavId == id && g.NavMoveDir == ImGuiDir_Left && is_open) + { + toggled = true; + NavMoveRequestCancel(); + } + if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? + { + toggled = true; + NavMoveRequestCancel(); + } + + if (toggled) + { + is_open = !is_open; + window->DC.StateStorage->SetInt(id, is_open); + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen; + } + } + if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) + SetItemAllowOverlap(); + + // In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger. + if (selected != was_selected) //-V547 + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; + + // Render + const ImU32 text_col = GetColorU32(ImGuiCol_Text); + ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_TypeThin; + if (display_frame) + { + // Framed type + const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding); + RenderNavHighlight(frame_bb, id, nav_highlight_flags); + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col); + else if (!is_leaf) + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); + else // Leaf without bullet, left-adjusted text + text_pos.x -= text_offset_x; + if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) + frame_bb.Max.x -= g.FontSize + style.FramePadding.x; + + if (g.LogEnabled) + LogSetNextTextDecoration("###", "###"); + RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); + } + else + { + // Unframed typed for tree nodes + if (hovered || selected) + { + const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false); + } + RenderNavHighlight(frame_bb, id, nav_highlight_flags); + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col); + else if (!is_leaf) + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); + if (g.LogEnabled) + LogSetNextTextDecoration(">", NULL); + RenderText(text_pos, label, label_end, false); + } + + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushOverrideID(id); + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0)); + return is_open; +} + +void ImGui::TreePush(const char* str_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(str_id); +} + +void ImGui::TreePush(const void* ptr_id) +{ + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(ptr_id); +} + +void ImGui::TreePushOverrideID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + Indent(); + window->DC.TreeDepth++; + PushOverrideID(id); +} + +void ImGui::TreePop() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + Unindent(); + + window->DC.TreeDepth--; + ImU32 tree_depth_mask = (1 << window->DC.TreeDepth); + + // Handle Left arrow to move to parent tree node (when ImGuiTreeNodeFlags_NavLeftJumpsBackHere is enabled) + if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) + if (g.NavIdIsAlive && (window->DC.TreeJumpToParentOnPopMask & tree_depth_mask)) + { + SetNavID(window->IDStack.back(), g.NavLayer, 0, ImRect()); + NavMoveRequestCancel(); + } + window->DC.TreeJumpToParentOnPopMask &= tree_depth_mask - 1; + + IM_ASSERT(window->IDStack.Size > 1); // There should always be 1 element in the IDStack (pushed during window creation). If this triggers you called TreePop/PopID too much. + PopID(); +} + +// Horizontal distance preceding label when using TreeNode() or Bullet() +float ImGui::GetTreeNodeToLabelSpacing() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + (g.Style.FramePadding.x * 2.0f); +} + +// Set next TreeNode/CollapsingHeader open state. +void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + if (g.CurrentWindow->SkipItems) + return; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen; + g.NextItemData.OpenVal = is_open; + g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always; +} + +// CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag). +// This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode(). +bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label); +} + +// p_visible == NULL : regular collapsing header +// p_visible != NULL && *p_visible == true : show a small close button on the corner of the header, clicking the button will set *p_visible = false +// p_visible != NULL && *p_visible == false : do not show the header at all +// Do not mistake this with the Open state of the header itself, which you can adjust with SetNextItemOpen() or ImGuiTreeNodeFlags_DefaultOpen. +bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + if (p_visible && !*p_visible) + return false; + + ImGuiID id = window->GetID(label); + flags |= ImGuiTreeNodeFlags_CollapsingHeader; + if (p_visible) + flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton; + bool is_open = TreeNodeBehavior(id, flags, label); + if (p_visible != NULL) + { + // Create a small overlapping close button + // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. + // FIXME: CloseButton can overlap into text, need find a way to clip the text somehow. + ImGuiContext& g = *GImGui; + ImGuiLastItemData last_item_backup = g.LastItemData; + float button_size = g.FontSize; + float button_x = ImMax(g.LastItemData.Rect.Min.x, g.LastItemData.Rect.Max.x - g.Style.FramePadding.x * 2.0f - button_size); + float button_y = g.LastItemData.Rect.Min.y; + ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id); + if (CloseButton(close_button_id, ImVec2(button_x, button_y))) + *p_visible = false; + g.LastItemData = last_item_backup; + } + + return is_open; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Selectable +//------------------------------------------------------------------------- +// - Selectable() +//------------------------------------------------------------------------- + +// Tip: pass a non-visible label (e.g. "##hello") 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 or use ##unique_id. +// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags. +// FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported. +bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + // Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle. + ImGuiID id = window->GetID(label); + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); + ImVec2 pos = window->DC.CursorPos; + pos.y += window->DC.CurrLineTextBaseOffset; + ItemSize(size, 0.0f); + + // Fill horizontal space + // We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitly right-aligned sizes not visibly match other widgets. + const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0; + const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x; + const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x; + if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth)) + size.x = ImMax(label_size.x, max_x - min_x); + + // Text stays at the submission position, but bounding box may be extended on both sides + const ImVec2 text_min = pos; + const ImVec2 text_max(min_x + size.x, pos.y + size.y); + + // Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable. + ImRect bb(min_x, pos.y, text_max.x, text_max.y); + if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0) + { + const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x; + const float spacing_y = style.ItemSpacing.y; + const float spacing_L = IM_FLOOR(spacing_x * 0.50f); + const float spacing_U = IM_FLOOR(spacing_y * 0.50f); + bb.Min.x -= spacing_L; + bb.Min.y -= spacing_U; + bb.Max.x += (spacing_x - spacing_L); + bb.Max.y += (spacing_y - spacing_U); + } + //if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); } + + // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackground for every Selectable.. + const float backup_clip_rect_min_x = window->ClipRect.Min.x; + const float backup_clip_rect_max_x = window->ClipRect.Max.x; + if (span_all_columns) + { + window->ClipRect.Min.x = window->ParentWorkRect.Min.x; + window->ClipRect.Max.x = window->ParentWorkRect.Max.x; + } + + const bool disabled_item = (flags & ImGuiSelectableFlags_Disabled) != 0; + const bool item_add = ItemAdd(bb, id, NULL, disabled_item ? ImGuiItemFlags_Disabled : ImGuiItemFlags_None); + if (span_all_columns) + { + window->ClipRect.Min.x = backup_clip_rect_min_x; + window->ClipRect.Max.x = backup_clip_rect_max_x; + } + + if (!item_add) + return false; + + const bool disabled_global = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; + if (disabled_item && !disabled_global) // Only testing this as an optimization + BeginDisabled(); + + // FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only, + // which would be advantageous since most selectable are not selected. + if (span_all_columns && window->DC.CurrentColumns) + PushColumnsBackground(); + else if (span_all_columns && g.CurrentTable) + TablePushBackgroundChannel(); + + // We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries + ImGuiButtonFlags button_flags = 0; + if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; } + if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; } + if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; } + if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; } + if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; } + + const bool was_selected = selected; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); + + // Auto-select when moved into + // - This will be more fully fleshed in the range-select branch + // - This is not exposed as it won't nicely work with some user side handling of shift/control + // - We cannot do 'if (g.NavJustMovedToId != id) { selected = false; pressed = was_selected; }' for two reasons + // - (1) it would require focus scope to be set, need exposing PushFocusScope() or equivalent (e.g. BeginSelection() calling PushFocusScope()) + // - (2) usage will fail with clipped items + // The multi-select API aim to fix those issues, e.g. may be replaced with a BeginSelection() API. + if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == window->DC.NavFocusScopeIdCurrent) + if (g.NavJustMovedToId == id) + selected = pressed = true; + + // Update NavId when clicking or when Hovering (this doesn't happen on most widgets), so navigation can be resumed with gamepad/keyboard + if (pressed || (hovered && (flags & ImGuiSelectableFlags_SetNavIdOnHover))) + { + if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent) + { + SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, WindowRectAbsToRel(window, bb)); // (bb == NavRect) + g.NavDisableHighlight = true; + } + } + if (pressed) + MarkItemEdited(id); + + if (flags & ImGuiSelectableFlags_AllowItemOverlap) + SetItemAllowOverlap(); + + // In this branch, Selectable() cannot toggle the selection so this will never trigger. + if (selected != was_selected) //-V547 + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; + + // Render + if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld)) + hovered = true; + if (hovered || selected) + { + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(bb.Min, bb.Max, col, false, 0.0f); + } + RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); + + if (span_all_columns && window->DC.CurrentColumns) + PopColumnsBackground(); + else if (span_all_columns && g.CurrentTable) + TablePopBackgroundChannel(); + + RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb); + + // Automatically close popups + if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.LastItemData.InFlags & ImGuiItemFlags_SelectableDontClosePopup)) + CloseCurrentPopup(); + + if (disabled_item && !disabled_global) + EndDisabled(); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + return pressed; //-V1020 +} + +bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) +{ + if (Selectable(label, *p_selected, flags, size_arg)) + { + *p_selected = !*p_selected; + return true; + } + return false; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: ListBox +//------------------------------------------------------------------------- +// - BeginListBox() +// - EndListBox() +// - ListBox() +//------------------------------------------------------------------------- + +// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty" +// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height). +bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + // Size default to hold ~7.25 items. + // Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + ImVec2 size = ImFloor(CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.25f + style.FramePadding.y * 2.0f)); + ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); + ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + g.NextItemData.ClearFlags(); + + if (!IsRectVisible(bb.Min, bb.Max)) + { + ItemSize(bb.GetSize(), style.FramePadding.y); + ItemAdd(bb, 0, &frame_bb); + return false; + } + + // FIXME-OPT: We could omit the BeginGroup() if label_size.x but would need to omit the EndGroup() as well. + BeginGroup(); + if (label_size.x > 0.0f) + { + ImVec2 label_pos = ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y); + RenderText(label_pos, label); + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, label_pos + label_size); + } + + BeginChildFrame(id, frame_bb.GetSize()); + return true; +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// OBSOLETED in 1.81 (from February 2021) +bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) +{ + // If height_in_items == -1, default height is maximum 7. + ImGuiContext& g = *GImGui; + float height_in_items_f = (height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f; + ImVec2 size; + size.x = 0.0f; + size.y = GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f; + return BeginListBox(label, size); +} +#endif + +void ImGui::EndListBox() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched BeginListBox/EndListBox calls. Did you test the return value of BeginListBox?"); + IM_UNUSED(window); + + EndChildFrame(); + EndGroup(); // This is only required to be able to do IsItemXXX query on the whole ListBox including label +} + +bool ImGui::ListBox(const char* label, int* current_item, const char* const 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; +} + +// This is merely a helper around BeginListBox(), EndListBox(). +// Considering using those directly to submit custom data or store selection differently. +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) +{ + ImGuiContext& g = *GImGui; + + // Calculate size from "height_in_items" + if (height_in_items < 0) + height_in_items = ImMin(items_count, 7); + float height_in_items_f = height_in_items + 0.25f; + ImVec2 size(0.0f, ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f)); + + if (!BeginListBox(label, size)) + return false; + + // Assume all items have even height (= 1 line of text). If you need items of different height, + // you can create a custom version of ListBox() in your code without using the clipper. + bool value_changed = false; + ImGuiListClipper clipper; + clipper.Begin(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + { + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + + PushID(i); + const bool item_selected = (i == *current_item); + if (Selectable(item_text, item_selected)) + { + *current_item = i; + value_changed = true; + } + if (item_selected) + SetItemDefaultFocus(); + PopID(); + } + EndListBox(); + + if (value_changed) + MarkItemEdited(g.LastItemData.ID); + + return value_changed; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: PlotLines, PlotHistogram +//------------------------------------------------------------------------- +// - PlotEx() [Internal] +// - PlotLines() +// - PlotHistogram() +//------------------------------------------------------------------------- +// Plot/Graph widgets are not very good. +// Consider writing your own, or using a third-party one, see: +// - ImPlot https://github.com/epezent/implot +// - others https://github.com/ocornut/imgui/wiki/Useful-Extensions +//------------------------------------------------------------------------- + +int ImGui::PlotEx(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 frame_size) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return -1; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + + const ImVec2 label_size = CalcTextSize(label, NULL, true); + if (frame_size.x == 0.0f) + frame_size.x = CalcItemWidth(); + if (frame_size.y == 0.0f) + frame_size.y = label_size.y + (style.FramePadding.y * 2); + + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + 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, 0, &frame_bb)) + return -1; + const bool hovered = ItemHoverable(frame_bb, id); + + // 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); + if (v != v) // Ignore NaN values + continue; + 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, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + + const int values_count_min = (plot_type == ImGuiPlotType_Lines) ? 2 : 1; + int idx_hovered = -1; + if (values_count >= values_count_min) + { + int res_w = ImMin((int)frame_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + + // Tooltip on hover + if (hovered && inner_bb.Contains(g.IO.MousePos)) + { + 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 * item_count); + 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) + SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx + 1, v1); + else if (plot_type == ImGuiPlotType_Histogram) + SetTooltip("%d: %8.4g", v_idx, v0); + idx_hovered = v_idx; + } + + const float t_step = 1.0f / (float)res_w; + const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); + + float v0 = values_getter(data, (0 + values_offset) % values_count); + float t0 = 0.0f; + ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) ); // Point in the normalized space of our target rectangle + float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (1 + scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands + + const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); + const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); + + for (int n = 0; n < res_w; n++) + { + const float t1 = t0 + t_step; + const int v1_idx = (int)(t0 * item_count + 0.5f); + IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); + const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); + const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale) ); + + // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. + ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); + ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, histogram_zero_line_t)); + if (plot_type == ImGuiPlotType_Lines) + { + window->DrawList->AddLine(pos0, pos1, idx_hovered == v1_idx ? col_hovered : col_base); + } + else if (plot_type == ImGuiPlotType_Histogram) + { + if (pos1.x >= pos0.x + 2.0f) + pos1.x -= 1.0f; + window->DrawList->AddRectFilled(pos0, pos1, idx_hovered == v1_idx ? col_hovered : col_base); + } + + t0 = t1; + tp0 = tp1; + } + } + + // Text overlay + if (overlay_text) + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f, 0.0f)); + + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + + // Return hovered index or -1 if none are hovered. + // This is currently not exposed in the public API because we need a larger redesign of the whole thing, but in the short-term we are making it available in PlotEx(). + return idx_hovered; +} + +struct ImGuiPlotArrayGetterData +{ + const float* Values; + int Stride; + + ImGuiPlotArrayGetterData(const float* values, int stride) { Values = values; Stride = stride; } +}; + +static float Plot_ArrayGetter(void* data, int idx) +{ + ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; + const float v = *(const float*)(const void*)((const 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, int stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(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) +{ + PlotEx(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, int stride) +{ + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(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) +{ + PlotEx(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Value helpers +// Those is not very useful, legacy API. +//------------------------------------------------------------------------- +// - Value() +//------------------------------------------------------------------------- + +void ImGui::Value(const char* prefix, bool b) +{ + Text("%s: %s", prefix, (b ? "true" : "false")); +} + +void ImGui::Value(const char* prefix, int v) +{ + Text("%s: %d", prefix, v); +} + +void ImGui::Value(const char* prefix, unsigned int v) +{ + 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); + Text(fmt, prefix, v); + } + else + { + Text("%s: %.3f", prefix, v); + } +} + +//------------------------------------------------------------------------- +// [SECTION] MenuItem, BeginMenu, EndMenu, etc. +//------------------------------------------------------------------------- +// - ImGuiMenuColumns [Internal] +// - BeginMenuBar() +// - EndMenuBar() +// - BeginMainMenuBar() +// - EndMainMenuBar() +// - BeginMenu() +// - EndMenu() +// - MenuItemEx() [Internal] +// - MenuItem() +//------------------------------------------------------------------------- + +// Helpers for internal use +void ImGuiMenuColumns::Update(float spacing, bool window_reappearing) +{ + if (window_reappearing) + memset(Widths, 0, sizeof(Widths)); + Spacing = (ImU16)spacing; + CalcNextTotalWidth(true); + memset(Widths, 0, sizeof(Widths)); + TotalWidth = NextTotalWidth; + NextTotalWidth = 0; +} + +void ImGuiMenuColumns::CalcNextTotalWidth(bool update_offsets) +{ + ImU16 offset = 0; + bool want_spacing = false; + for (int i = 0; i < IM_ARRAYSIZE(Widths); i++) + { + ImU16 width = Widths[i]; + if (want_spacing && width > 0) + offset += Spacing; + want_spacing |= (width > 0); + if (update_offsets) + { + if (i == 1) { OffsetLabel = offset; } + if (i == 2) { OffsetShortcut = offset; } + if (i == 3) { OffsetMark = offset; } + } + offset += width; + } + NextTotalWidth = offset; +} + +float ImGuiMenuColumns::DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark) +{ + Widths[0] = ImMax(Widths[0], (ImU16)w_icon); + Widths[1] = ImMax(Widths[1], (ImU16)w_label); + Widths[2] = ImMax(Widths[2], (ImU16)w_shortcut); + Widths[3] = ImMax(Widths[3], (ImU16)w_mark); + CalcNextTotalWidth(false); + return (float)ImMax(TotalWidth, NextTotalWidth); +} + +// FIXME: Provided a rectangle perhaps e.g. a BeginMenuBarEx() could be used anywhere.. +// Currently the main responsibility of this function being to setup clip-rect + horizontal layout + menu navigation layer. +// Ideally we also want this to be responsible for claiming space out of the main window scrolling rectangle, in which case ImGuiWindowFlags_MenuBar will become unnecessary. +// Then later the same system could be used for multiple menu-bars, scrollbars, side-bars. +bool ImGui::BeginMenuBar() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + if (!(window->Flags & ImGuiWindowFlags_MenuBar)) + return false; + + IM_ASSERT(!window->DC.MenuBarAppending); + BeginGroup(); // Backup position on layer 0 // FIXME: Misleading to use a group for that backup/restore + PushID("##menubar"); + + // We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect. + // We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy. + ImRect bar_rect = window->MenuBarRect(); + ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize))), IM_ROUND(bar_rect.Max.y)); + clip_rect.ClipWith(window->OuterRectClipped); + PushClipRect(clip_rect.Min, clip_rect.Max, false); + + // We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags). + window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y); + window->DC.LayoutType = ImGuiLayoutType_Horizontal; + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; + window->DC.MenuBarAppending = true; + AlignTextToFramePadding(); + return true; +} + +void ImGui::EndMenuBar() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; + + // Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings. + if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) + { + // Try to find out if the request is for one of our child menu + ImGuiWindow* nav_earliest_child = g.NavWindow; + while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) + nav_earliest_child = nav_earliest_child->ParentWindow; + if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0) + { + // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. + // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) + const ImGuiNavLayer layer = ImGuiNavLayer_Menu; + IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check + FocusWindow(window); + SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); + g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. + g.NavDisableMouseHover = g.NavMousePosDirty = true; + NavMoveRequestForward(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags, g.NavMoveScrollFlags); // Repeat + } + } + + IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'" + IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar); + IM_ASSERT(window->DC.MenuBarAppending); + PopClipRect(); + PopID(); + window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos. + g.GroupStack.back().EmitItem = false; + EndGroup(); // Restore position on layer 0 + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + window->DC.MenuBarAppending = false; +} + +// Important: calling order matters! +// FIXME: Somehow overlapping with docking tech. +// FIXME: The "rect-cut" aspect of this could be formalized into a lower-level helper (rect-cut: https://halt.software/dead-simple-layouts) +bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, ImGuiDir dir, float axis_size, ImGuiWindowFlags window_flags) +{ + IM_ASSERT(dir != ImGuiDir_None); + + ImGuiWindow* bar_window = FindWindowByName(name); + ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)(viewport_p ? viewport_p : GetMainViewport()); + if (bar_window == NULL || bar_window->BeginCount == 0) + { + // Calculate and set window size/position + ImRect avail_rect = viewport->GetBuildWorkRect(); + ImGuiAxis axis = (dir == ImGuiDir_Up || dir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; + ImVec2 pos = avail_rect.Min; + if (dir == ImGuiDir_Right || dir == ImGuiDir_Down) + pos[axis] = avail_rect.Max[axis] - axis_size; + ImVec2 size = avail_rect.GetSize(); + size[axis] = axis_size; + SetNextWindowPos(pos); + SetNextWindowSize(size); + + // Report our size into work area (for next frame) using actual window size + if (dir == ImGuiDir_Up || dir == ImGuiDir_Left) + viewport->BuildWorkOffsetMin[axis] += axis_size; + else if (dir == ImGuiDir_Down || dir == ImGuiDir_Right) + viewport->BuildWorkOffsetMax[axis] -= axis_size; + } + + window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking; + SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set. + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint + bool is_open = Begin(name, NULL, window_flags); + PopStyleVar(2); + + return is_open; +} + +bool ImGui::BeginMainMenuBar() +{ + ImGuiContext& g = *GImGui; + ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport(); + + // Notify of viewport change so GetFrameHeight() can be accurate in case of DPI change + SetCurrentViewport(NULL, viewport); + + // For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set. + // FIXME: This could be generalized as an opt-in way to clamp window->DC.CursorStartPos to avoid SafeArea? + // FIXME: Consider removing support for safe area down the line... it's messy. Nowadays consoles have support for TV calibration in OS settings. + g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f)); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar; + float height = GetFrameHeight(); + bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags); + g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); + + if (is_open) + BeginMenuBar(); + else + End(); + return is_open; +} + +void ImGui::EndMainMenuBar() +{ + EndMenuBar(); + + // When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window + // FIXME: With this strategy we won't be able to restore a NULL focus. + ImGuiContext& g = *GImGui; + if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest) + FocusTopMostWindowUnderOne(g.NavWindow, NULL); + + End(); +} + +static bool IsRootOfOpenMenuSet() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if ((g.OpenPopupStack.Size <= g.BeginPopupStack.Size) || (window->Flags & ImGuiWindowFlags_ChildMenu)) + return false; + + // Initially we used 'OpenParentId' to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) based on parent ID. + // This would however prevent the use of e.g. PuhsID() user code submitting menus. + // Previously this worked between popup and a first child menu because the first child menu always had the _ChildWindow flag, + // making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects. + // Instead we don't treat Popup specifically (in order to consistently support menu features in them), maybe the first child menu of a Popup + // doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first chilld menu. + const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size]; + return (/*upper_popup->OpenParentId == window->IDStack.back() &&*/ upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu)); +} + +bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None); + + // Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu) + // The first menu in a hierarchy isn't so hovering doesn't get accross (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation. + ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus; + if (window->Flags & ImGuiWindowFlags_ChildMenu) + flags |= ImGuiWindowFlags_ChildWindow; + + // If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin(). + // We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame. + // If somehow this is ever becoming a problem we can switch to use e.g. ImGuiStorage mapping key to last frame used. + if (g.MenusIdSubmittedThisFrame.contains(id)) + { + if (menu_is_open) + menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + else + g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values + return menu_is_open; + } + + // Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu + g.MenusIdSubmittedThisFrame.push_back(id); + + ImVec2 label_size = CalcTextSize(label, NULL, true); + + // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window) + const bool menuset_is_open = IsRootOfOpenMenuSet(); + ImGuiWindow* backed_nav_window = g.NavWindow; + if (menuset_is_open) + g.NavWindow = window; + + // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu, + // However the final position is going to be different! It is chosen by FindBestWindowPosForPopup(). + // e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering. + ImVec2 popup_pos, pos = window->DC.CursorPos; + PushID(label); + if (!enabled) + BeginDisabled(); + const ImGuiMenuColumns* offsets = &window->DC.MenuColumns; + bool pressed; + const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + { + // Menu inside an horizontal menu bar + // Selectable extend their highlight by half ItemSpacing in each direction. + // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() + popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight()); + window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); + float w = label_size.x; + ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); + pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, 0.0f)); + RenderText(text_pos, label); + PopStyleVar(); + window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). + } + else + { + // Menu inside a regular/vertical menu + // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. + // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. + popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); + float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; + float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); + float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); + ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); + pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); + RenderText(text_pos, label); + if (icon_w > 0.0f) + RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); + RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right); + } + if (!enabled) + EndDisabled(); + + const bool hovered = (g.HoveredId == id) && enabled; + if (menuset_is_open) + g.NavWindow = backed_nav_window; + + bool want_open = false; + bool want_close = false; + if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) + { + // Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu + // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. + bool moving_toward_other_child_menu = false; + ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL; + if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar)) + { + float ref_unit = g.FontSize; // FIXME-DPI + ImRect next_window_rect = child_menu_window->Rect(); + ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta); + ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); + ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); + float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // add a bit of extra slack. + ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues (FIXME: ??) + tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? + tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +ref_unit * 8.0f); + moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); + //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_other_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG] + } + if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu) + want_close = true; + + // Open + if (!menu_is_open && pressed) // Click/activate to open + want_open = true; + else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open + want_open = true; + if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open + { + want_open = true; + NavMoveRequestCancel(); + } + } + else + { + // Menu bar + if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it + { + want_close = true; + want_open = menu_is_open = false; + } + else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others + { + want_open = true; + } + else if (g.NavId == id && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open + { + want_open = true; + NavMoveRequestCancel(); + } + } + + if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' + want_close = true; + if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None)) + ClosePopupToLevel(g.BeginPopupStack.Size, true); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); + PopID(); + + if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) + { + // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. + OpenPopup(label); + return false; + } + + menu_is_open |= want_open; + if (want_open) + OpenPopup(label); + + if (menu_is_open) + { + SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos. + PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding + menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + PopStyleVar(); + } + else + { + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values + } + + return menu_is_open; +} + +bool ImGui::BeginMenu(const char* label, bool enabled) +{ + return BeginMenuEx(label, NULL, enabled); +} + +void ImGui::EndMenu() +{ + // Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu). + // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. + // However, it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) + if (g.NavWindow && (g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow == window) + { + ClosePopupToLevel(g.BeginPopupStack.Size, true); + NavMoveRequestCancel(); + } + + EndPopup(); +} + +bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut, bool selected, bool enabled) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImVec2 pos = window->DC.CursorPos; + ImVec2 label_size = CalcTextSize(label, NULL, true); + + const bool menuset_is_open = IsRootOfOpenMenuSet(); + ImGuiWindow* backed_nav_window = g.NavWindow; + if (menuset_is_open) + g.NavWindow = window; + + // We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73), + // but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only. + bool pressed; + PushID(label); + if (!enabled) + BeginDisabled(); + + const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover; + const ImGuiMenuColumns* offsets = &window->DC.MenuColumns; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + { + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark. + float w = label_size.x; + window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); + ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); + PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); + pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f)); + PopStyleVar(); + RenderText(text_pos, label); + window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). + } + else + { + // Menu item inside a vertical menu + // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. + // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. + float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f; + float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f; + float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); + float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame + float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); + pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); + RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label); + if (icon_w > 0.0f) + RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); + if (shortcut_w > 0.0f) + { + PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f); + } + IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0)); + if (!enabled) + EndDisabled(); + PopID(); + if (menuset_is_open) + g.NavWindow = backed_nav_window; + + return pressed; +} + +bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) +{ + return MenuItemEx(label, NULL, shortcut, selected, enabled); +} + +bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) +{ + if (MenuItemEx(label, NULL, shortcut, p_selected ? *p_selected : false, enabled)) + { + if (p_selected) + *p_selected = !*p_selected; + return true; + } + return false; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: BeginTabBar, EndTabBar, etc. +//------------------------------------------------------------------------- +// - BeginTabBar() +// - BeginTabBarEx() [Internal] +// - EndTabBar() +// - TabBarLayout() [Internal] +// - TabBarCalcTabID() [Internal] +// - TabBarCalcMaxTabWidth() [Internal] +// - TabBarFindTabById() [Internal] +// - TabBarAddTab() [Internal] +// - TabBarRemoveTab() [Internal] +// - TabBarCloseTab() [Internal] +// - TabBarScrollClamp() [Internal] +// - TabBarScrollToTab() [Internal] +// - TabBarQueueChangeTabOrder() [Internal] +// - TabBarScrollingButtons() [Internal] +// - TabBarTabListPopupButton() [Internal] +//------------------------------------------------------------------------- + +struct ImGuiTabBarSection +{ + int TabCount; // Number of tabs in this section. + float Width; // Sum of width of tabs in this section (after shrinking down) + float Spacing; // Horizontal spacing at the end of the section. + + ImGuiTabBarSection() { memset(this, 0, sizeof(*this)); } +}; + +namespace ImGui +{ + static void TabBarLayout(ImGuiTabBar* tab_bar); + static ImU32 TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window); + static float TabBarCalcMaxTabWidth(); + static float TabBarScrollClamp(ImGuiTabBar* tab_bar, float scrolling); + static void TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGuiTabBarSection* sections); + static ImGuiTabItem* TabBarScrollingButtons(ImGuiTabBar* tab_bar); + static ImGuiTabItem* TabBarTabListPopupButton(ImGuiTabBar* tab_bar); +} + +ImGuiTabBar::ImGuiTabBar() +{ + memset(this, 0, sizeof(*this)); + CurrFrameVisible = PrevFrameVisible = -1; + LastTabItemIdx = -1; +} + +static inline int TabItemGetSectionIdx(const ImGuiTabItem* tab) +{ + return (tab->Flags & ImGuiTabItemFlags_Leading) ? 0 : (tab->Flags & ImGuiTabItemFlags_Trailing) ? 2 : 1; +} + +static int IMGUI_CDECL TabItemComparerBySection(const void* lhs, const void* rhs) +{ + const ImGuiTabItem* a = (const ImGuiTabItem*)lhs; + const ImGuiTabItem* b = (const ImGuiTabItem*)rhs; + const int a_section = TabItemGetSectionIdx(a); + const int b_section = TabItemGetSectionIdx(b); + if (a_section != b_section) + return a_section - b_section; + return (int)(a->IndexDuringLayout - b->IndexDuringLayout); +} + +static int IMGUI_CDECL TabItemComparerByBeginOrder(const void* lhs, const void* rhs) +{ + const ImGuiTabItem* a = (const ImGuiTabItem*)lhs; + const ImGuiTabItem* b = (const ImGuiTabItem*)rhs; + return (int)(a->BeginOrder - b->BeginOrder); +} + +static ImGuiTabBar* GetTabBarFromTabBarRef(const ImGuiPtrOrIndex& ref) +{ + ImGuiContext& g = *GImGui; + return ref.Ptr ? (ImGuiTabBar*)ref.Ptr : g.TabBars.GetByIndex(ref.Index); +} + +static ImGuiPtrOrIndex GetTabBarRefFromTabBar(ImGuiTabBar* tab_bar) +{ + ImGuiContext& g = *GImGui; + if (g.TabBars.Contains(tab_bar)) + return ImGuiPtrOrIndex(g.TabBars.GetIndex(tab_bar)); + return ImGuiPtrOrIndex(tab_bar); +} + +bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + ImGuiID id = window->GetID(str_id); + ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id); + ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2); + tab_bar->ID = id; + return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused, NULL); +} + +bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + if ((flags & ImGuiTabBarFlags_DockNode) == 0) + PushOverrideID(tab_bar->ID); + + // Add to stack + g.CurrentTabBarStack.push_back(GetTabBarRefFromTabBar(tab_bar)); + g.CurrentTabBar = tab_bar; + + // Append with multiple BeginTabBar()/EndTabBar() pairs. + tab_bar->BackupCursorPos = window->DC.CursorPos; + if (tab_bar->CurrFrameVisible == g.FrameCount) + { + window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.y + tab_bar->ItemSpacingY); + tab_bar->BeginCount++; + return true; + } + + // Ensure correct ordering when toggling ImGuiTabBarFlags_Reorderable flag, or when a new tab was added while being not reorderable + if ((flags & ImGuiTabBarFlags_Reorderable) != (tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (tab_bar->TabsAddedNew && !(flags & ImGuiTabBarFlags_Reorderable))) + if ((flags & ImGuiTabBarFlags_DockNode) == 0) // FIXME: TabBar with DockNode can now be hybrid + ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder); + tab_bar->TabsAddedNew = false; + + // Flags + if ((flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) + flags |= ImGuiTabBarFlags_FittingPolicyDefault_; + + tab_bar->Flags = flags; + tab_bar->BarRect = tab_bar_bb; + tab_bar->WantLayout = true; // Layout will be done on the first call to ItemTab() + tab_bar->PrevFrameVisible = tab_bar->CurrFrameVisible; + tab_bar->CurrFrameVisible = g.FrameCount; + tab_bar->PrevTabsContentsHeight = tab_bar->CurrTabsContentsHeight; + tab_bar->CurrTabsContentsHeight = 0.0f; + tab_bar->ItemSpacingY = g.Style.ItemSpacing.y; + tab_bar->FramePadding = g.Style.FramePadding; + tab_bar->TabsActiveCount = 0; + tab_bar->BeginCount = 1; + + // Set cursor pos in a way which only be used in the off-chance the user erroneously submits item before BeginTabItem(): items will overlap + window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.y + tab_bar->ItemSpacingY); + + // Draw separator + const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive); + const float y = tab_bar->BarRect.Max.y - 1.0f; + if (dock_node != NULL) + { + const float separator_min_x = dock_node->Pos.x + window->WindowBorderSize; + const float separator_max_x = dock_node->Pos.x + dock_node->Size.x - window->WindowBorderSize; + window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f); + } + else + { + const float separator_min_x = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f); + const float separator_max_x = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f); + window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f); + } + return true; +} + +void ImGui::EndTabBar() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + ImGuiTabBar* tab_bar = g.CurrentTabBar; + if (tab_bar == NULL) + { + IM_ASSERT_USER_ERROR(tab_bar != NULL, "Mismatched BeginTabBar()/EndTabBar()!"); + return; + } + + // Fallback in case no TabItem have been submitted + if (tab_bar->WantLayout) + TabBarLayout(tab_bar); + + // Restore the last visible height if no tab is visible, this reduce vertical flicker/movement when a tabs gets removed without calling SetTabItemClosed(). + const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount); + if (tab_bar->VisibleTabWasSubmitted || tab_bar->VisibleTabId == 0 || tab_bar_appearing) + { + tab_bar->CurrTabsContentsHeight = ImMax(window->DC.CursorPos.y - tab_bar->BarRect.Max.y, tab_bar->CurrTabsContentsHeight); + window->DC.CursorPos.y = tab_bar->BarRect.Max.y + tab_bar->CurrTabsContentsHeight; + } + else + { + window->DC.CursorPos.y = tab_bar->BarRect.Max.y + tab_bar->PrevTabsContentsHeight; + } + if (tab_bar->BeginCount > 1) + window->DC.CursorPos = tab_bar->BackupCursorPos; + + if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0) + PopID(); + + g.CurrentTabBarStack.pop_back(); + g.CurrentTabBar = g.CurrentTabBarStack.empty() ? NULL : GetTabBarFromTabBarRef(g.CurrentTabBarStack.back()); +} + +// This is called only once a frame before by the first call to ItemTab() +// The reason we're not calling it in BeginTabBar() is to leave a chance to the user to call the SetTabItemClosed() functions. +static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) +{ + ImGuiContext& g = *GImGui; + tab_bar->WantLayout = false; + + // Garbage collect by compacting list + // Detect if we need to sort out tab list (e.g. in rare case where a tab changed section) + int tab_dst_n = 0; + bool need_sort_by_section = false; + ImGuiTabBarSection sections[3]; // Layout sections: Leading, Central, Trailing + for (int tab_src_n = 0; tab_src_n < tab_bar->Tabs.Size; tab_src_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_src_n]; + if (tab->LastFrameVisible < tab_bar->PrevFrameVisible || tab->WantClose) + { + // Remove tab + if (tab_bar->VisibleTabId == tab->ID) { tab_bar->VisibleTabId = 0; } + if (tab_bar->SelectedTabId == tab->ID) { tab_bar->SelectedTabId = 0; } + if (tab_bar->NextSelectedTabId == tab->ID) { tab_bar->NextSelectedTabId = 0; } + continue; + } + if (tab_dst_n != tab_src_n) + tab_bar->Tabs[tab_dst_n] = tab_bar->Tabs[tab_src_n]; + + tab = &tab_bar->Tabs[tab_dst_n]; + tab->IndexDuringLayout = (ImS16)tab_dst_n; + + // We will need sorting if tabs have changed section (e.g. moved from one of Leading/Central/Trailing to another) + int curr_tab_section_n = TabItemGetSectionIdx(tab); + if (tab_dst_n > 0) + { + ImGuiTabItem* prev_tab = &tab_bar->Tabs[tab_dst_n - 1]; + int prev_tab_section_n = TabItemGetSectionIdx(prev_tab); + if (curr_tab_section_n == 0 && prev_tab_section_n != 0) + need_sort_by_section = true; + if (prev_tab_section_n == 2 && curr_tab_section_n != 2) + need_sort_by_section = true; + } + + sections[curr_tab_section_n].TabCount++; + tab_dst_n++; + } + if (tab_bar->Tabs.Size != tab_dst_n) + tab_bar->Tabs.resize(tab_dst_n); + + if (need_sort_by_section) + ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerBySection); + + // Calculate spacing between sections + sections[0].Spacing = sections[0].TabCount > 0 && (sections[1].TabCount + sections[2].TabCount) > 0 ? g.Style.ItemInnerSpacing.x : 0.0f; + sections[1].Spacing = sections[1].TabCount > 0 && sections[2].TabCount > 0 ? g.Style.ItemInnerSpacing.x : 0.0f; + + // Setup next selected tab + ImGuiID scroll_to_tab_id = 0; + if (tab_bar->NextSelectedTabId) + { + tab_bar->SelectedTabId = tab_bar->NextSelectedTabId; + tab_bar->NextSelectedTabId = 0; + scroll_to_tab_id = tab_bar->SelectedTabId; + } + + // Process order change request (we could probably process it when requested but it's just saner to do it in a single spot). + if (tab_bar->ReorderRequestTabId != 0) + { + if (TabBarProcessReorder(tab_bar)) + if (tab_bar->ReorderRequestTabId == tab_bar->SelectedTabId) + scroll_to_tab_id = tab_bar->ReorderRequestTabId; + tab_bar->ReorderRequestTabId = 0; + } + + // Tab List Popup (will alter tab_bar->BarRect and therefore the available width!) + const bool tab_list_popup_button = (tab_bar->Flags & ImGuiTabBarFlags_TabListPopupButton) != 0; + if (tab_list_popup_button) + if (ImGuiTabItem* tab_to_select = TabBarTabListPopupButton(tab_bar)) // NB: Will alter BarRect.Min.x! + scroll_to_tab_id = tab_bar->SelectedTabId = tab_to_select->ID; + + // Leading/Trailing tabs will be shrink only if central one aren't visible anymore, so layout the shrink data as: leading, trailing, central + // (whereas our tabs are stored as: leading, central, trailing) + int shrink_buffer_indexes[3] = { 0, sections[0].TabCount + sections[2].TabCount, sections[0].TabCount }; + g.ShrinkWidthBuffer.resize(tab_bar->Tabs.Size); + + // Compute ideal tabs widths + store them into shrink buffer + ImGuiTabItem* most_recently_selected_tab = NULL; + int curr_section_n = -1; + bool found_selected_tab_id = false; + for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + IM_ASSERT(tab->LastFrameVisible >= tab_bar->PrevFrameVisible); + + if ((most_recently_selected_tab == NULL || most_recently_selected_tab->LastFrameSelected < tab->LastFrameSelected) && !(tab->Flags & ImGuiTabItemFlags_Button)) + most_recently_selected_tab = tab; + if (tab->ID == tab_bar->SelectedTabId) + found_selected_tab_id = true; + if (scroll_to_tab_id == 0 && g.NavJustMovedToId == tab->ID) + scroll_to_tab_id = tab->ID; + + // Refresh tab width immediately, otherwise changes of style e.g. style.FramePadding.x would noticeably lag in the tab bar. + // Additionally, when using TabBarAddTab() to manipulate tab bar order we occasionally insert new tabs that don't have a width yet, + // and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window. + const char* tab_name = tab_bar->GetTabName(tab); + const bool has_close_button = (tab->Flags & ImGuiTabItemFlags_NoCloseButton) == 0; + tab->ContentWidth = TabItemCalcSize(tab_name, has_close_button).x; + + int section_n = TabItemGetSectionIdx(tab); + ImGuiTabBarSection* section = §ions[section_n]; + section->Width += tab->ContentWidth + (section_n == curr_section_n ? g.Style.ItemInnerSpacing.x : 0.0f); + curr_section_n = section_n; + + // Store data so we can build an array sorted by width if we need to shrink tabs down + IM_MSVC_WARNING_SUPPRESS(6385); + int shrink_buffer_index = shrink_buffer_indexes[section_n]++; + g.ShrinkWidthBuffer[shrink_buffer_index].Index = tab_n; + g.ShrinkWidthBuffer[shrink_buffer_index].Width = tab->ContentWidth; + + IM_ASSERT(tab->ContentWidth > 0.0f); + tab->Width = tab->ContentWidth; + } + + // Compute total ideal width (used for e.g. auto-resizing a window) + tab_bar->WidthAllTabsIdeal = 0.0f; + for (int section_n = 0; section_n < 3; section_n++) + tab_bar->WidthAllTabsIdeal += sections[section_n].Width + sections[section_n].Spacing; + + // Horizontal scrolling buttons + // (note that TabBarScrollButtons() will alter BarRect.Max.x) + if ((tab_bar->WidthAllTabsIdeal > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll)) + if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar)) + { + scroll_to_tab_id = scroll_and_select_tab->ID; + if ((scroll_and_select_tab->Flags & ImGuiTabItemFlags_Button) == 0) + tab_bar->SelectedTabId = scroll_to_tab_id; + } + + // Shrink widths if full tabs don't fit in their allocated space + float section_0_w = sections[0].Width + sections[0].Spacing; + float section_1_w = sections[1].Width + sections[1].Spacing; + float section_2_w = sections[2].Width + sections[2].Spacing; + bool central_section_is_visible = (section_0_w + section_2_w) < tab_bar->BarRect.GetWidth(); + float width_excess; + if (central_section_is_visible) + width_excess = ImMax(section_1_w - (tab_bar->BarRect.GetWidth() - section_0_w - section_2_w), 0.0f); // Excess used to shrink central section + else + width_excess = (section_0_w + section_2_w) - tab_bar->BarRect.GetWidth(); // Excess used to shrink leading/trailing section + + // With ImGuiTabBarFlags_FittingPolicyScroll policy, we will only shrink leading/trailing if the central section is not visible anymore + if (width_excess > 0.0f && ((tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown) || !central_section_is_visible)) + { + int shrink_data_count = (central_section_is_visible ? sections[1].TabCount : sections[0].TabCount + sections[2].TabCount); + int shrink_data_offset = (central_section_is_visible ? sections[0].TabCount + sections[2].TabCount : 0); + ShrinkWidths(g.ShrinkWidthBuffer.Data + shrink_data_offset, shrink_data_count, width_excess); + + // Apply shrunk values into tabs and sections + for (int tab_n = shrink_data_offset; tab_n < shrink_data_offset + shrink_data_count; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index]; + float shrinked_width = IM_FLOOR(g.ShrinkWidthBuffer[tab_n].Width); + if (shrinked_width < 0.0f) + continue; + + int section_n = TabItemGetSectionIdx(tab); + sections[section_n].Width -= (tab->Width - shrinked_width); + tab->Width = shrinked_width; + } + } + + // Layout all active tabs + int section_tab_index = 0; + float tab_offset = 0.0f; + tab_bar->WidthAllTabs = 0.0f; + for (int section_n = 0; section_n < 3; section_n++) + { + ImGuiTabBarSection* section = §ions[section_n]; + if (section_n == 2) + tab_offset = ImMin(ImMax(0.0f, tab_bar->BarRect.GetWidth() - section->Width), tab_offset); + + for (int tab_n = 0; tab_n < section->TabCount; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[section_tab_index + tab_n]; + tab->Offset = tab_offset; + tab->NameOffset = -1; + tab_offset += tab->Width + (tab_n < section->TabCount - 1 ? g.Style.ItemInnerSpacing.x : 0.0f); + } + tab_bar->WidthAllTabs += ImMax(section->Width + section->Spacing, 0.0f); + tab_offset += section->Spacing; + section_tab_index += section->TabCount; + } + + // Clear name buffers + tab_bar->TabsNames.Buf.resize(0); + + // If we have lost the selected tab, select the next most recently active one + if (found_selected_tab_id == false) + tab_bar->SelectedTabId = 0; + if (tab_bar->SelectedTabId == 0 && tab_bar->NextSelectedTabId == 0 && most_recently_selected_tab != NULL) + scroll_to_tab_id = tab_bar->SelectedTabId = most_recently_selected_tab->ID; + + // Lock in visible tab + tab_bar->VisibleTabId = tab_bar->SelectedTabId; + tab_bar->VisibleTabWasSubmitted = false; + + // CTRL+TAB can override visible tab temporarily + if (g.NavWindowingTarget != NULL && g.NavWindowingTarget->DockNode && g.NavWindowingTarget->DockNode->TabBar == tab_bar) + tab_bar->VisibleTabId = scroll_to_tab_id = g.NavWindowingTarget->ID; + + // Update scrolling + if (scroll_to_tab_id != 0) + TabBarScrollToTab(tab_bar, scroll_to_tab_id, sections); + tab_bar->ScrollingAnim = TabBarScrollClamp(tab_bar, tab_bar->ScrollingAnim); + tab_bar->ScrollingTarget = TabBarScrollClamp(tab_bar, tab_bar->ScrollingTarget); + if (tab_bar->ScrollingAnim != tab_bar->ScrollingTarget) + { + // Scrolling speed adjust itself so we can always reach our target in 1/3 seconds. + // Teleport if we are aiming far off the visible line + tab_bar->ScrollingSpeed = ImMax(tab_bar->ScrollingSpeed, 70.0f * g.FontSize); + tab_bar->ScrollingSpeed = ImMax(tab_bar->ScrollingSpeed, ImFabs(tab_bar->ScrollingTarget - tab_bar->ScrollingAnim) / 0.3f); + const bool teleport = (tab_bar->PrevFrameVisible + 1 < g.FrameCount) || (tab_bar->ScrollingTargetDistToVisibility > 10.0f * g.FontSize); + tab_bar->ScrollingAnim = teleport ? tab_bar->ScrollingTarget : ImLinearSweep(tab_bar->ScrollingAnim, tab_bar->ScrollingTarget, g.IO.DeltaTime * tab_bar->ScrollingSpeed); + } + else + { + tab_bar->ScrollingSpeed = 0.0f; + } + tab_bar->ScrollingRectMinX = tab_bar->BarRect.Min.x + sections[0].Width + sections[0].Spacing; + tab_bar->ScrollingRectMaxX = tab_bar->BarRect.Max.x - sections[2].Width - sections[1].Spacing; + + // Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame) + ImGuiWindow* window = g.CurrentWindow; + window->DC.CursorPos = tab_bar->BarRect.Min; + ItemSize(ImVec2(tab_bar->WidthAllTabs, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y); + window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal); +} + +// Dockable uses Name/ID in the global namespace. Non-dockable items use the ID stack. +static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window) +{ + if (docked_window != NULL) + { + IM_UNUSED(tab_bar); + IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode); + ImGuiID id = docked_window->TabId; + KeepAliveID(id); + return id; + } + else + { + ImGuiWindow* window = GImGui->CurrentWindow; + return window->GetID(label); + } +} + +static float ImGui::TabBarCalcMaxTabWidth() +{ + ImGuiContext& g = *GImGui; + return g.FontSize * 20.0f; +} + +ImGuiTabItem* ImGui::TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id) +{ + if (tab_id != 0) + for (int n = 0; n < tab_bar->Tabs.Size; n++) + if (tab_bar->Tabs[n].ID == tab_id) + return &tab_bar->Tabs[n]; + return NULL; +} + +// FIXME: See references to #2304 in TODO.txt +ImGuiTabItem* ImGui::TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar) +{ + ImGuiTabItem* most_recently_selected_tab = NULL; + for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + if (most_recently_selected_tab == NULL || most_recently_selected_tab->LastFrameSelected < tab->LastFrameSelected) + if (tab->Window && tab->Window->WasActive) + most_recently_selected_tab = tab; + } + return most_recently_selected_tab; +} + +// The purpose of this call is to register tab in advance so we can control their order at the time they appear. +// Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function. +void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(TabBarFindTabByID(tab_bar, window->TabId) == NULL); + IM_ASSERT(g.CurrentTabBar != tab_bar); // Can't work while the tab bar is active as our tab doesn't have an X offset yet, in theory we could/should test something like (tab_bar->CurrFrameVisible < g.FrameCount) but we'd need to solve why triggers the commented early-out assert in BeginTabBarEx() (probably dock node going from implicit to explicit in same frame) + + if (!window->HasCloseButton) + tab_flags |= ImGuiTabItemFlags_NoCloseButton; // Set _NoCloseButton immediately because it will be used for first-frame width calculation. + + ImGuiTabItem new_tab; + new_tab.ID = window->TabId; + new_tab.Flags = tab_flags; + new_tab.LastFrameVisible = tab_bar->CurrFrameVisible; // Required so BeginTabBar() doesn't ditch the tab + if (new_tab.LastFrameVisible == -1) + new_tab.LastFrameVisible = g.FrameCount - 1; + new_tab.Window = window; // Required so tab bar layout can compute the tab width before tab submission + tab_bar->Tabs.push_back(new_tab); +} + +// The *TabId fields be already set by the docking system _before_ the actual TabItem was created, so we clear them regardless. +void ImGui::TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id) +{ + if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id)) + tab_bar->Tabs.erase(tab); + if (tab_bar->VisibleTabId == tab_id) { tab_bar->VisibleTabId = 0; } + if (tab_bar->SelectedTabId == tab_id) { tab_bar->SelectedTabId = 0; } + if (tab_bar->NextSelectedTabId == tab_id) { tab_bar->NextSelectedTabId = 0; } +} + +// Called on manual closure attempt +void ImGui::TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) +{ + IM_ASSERT(!(tab->Flags & ImGuiTabItemFlags_Button)); + if (!(tab->Flags & ImGuiTabItemFlags_UnsavedDocument)) + { + // This will remove a frame of lag for selecting another tab on closure. + // However we don't run it in the case where the 'Unsaved' flag is set, so user gets a chance to fully undo the closure + tab->WantClose = true; + if (tab_bar->VisibleTabId == tab->ID) + { + tab->LastFrameVisible = -1; + tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = 0; + } + } + else + { + // Actually select before expecting closure attempt (on an UnsavedDocument tab user is expect to e.g. show a popup) + if (tab_bar->VisibleTabId != tab->ID) + tab_bar->NextSelectedTabId = tab->ID; + } +} + +static float ImGui::TabBarScrollClamp(ImGuiTabBar* tab_bar, float scrolling) +{ + scrolling = ImMin(scrolling, tab_bar->WidthAllTabs - tab_bar->BarRect.GetWidth()); + return ImMax(scrolling, 0.0f); +} + +// Note: we may scroll to tab that are not selected! e.g. using keyboard arrow keys +static void ImGui::TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGuiTabBarSection* sections) +{ + ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id); + if (tab == NULL) + return; + if (tab->Flags & ImGuiTabItemFlags_SectionMask_) + return; + + ImGuiContext& g = *GImGui; + float margin = g.FontSize * 1.0f; // When to scroll to make Tab N+1 visible always make a bit of N visible to suggest more scrolling area (since we don't have a scrollbar) + int order = tab_bar->GetTabOrder(tab); + + // Scrolling happens only in the central section (leading/trailing sections are not scrolling) + // FIXME: This is all confusing. + float scrollable_width = tab_bar->BarRect.GetWidth() - sections[0].Width - sections[2].Width - sections[1].Spacing; + + // We make all tabs positions all relative Sections[0].Width to make code simpler + float tab_x1 = tab->Offset - sections[0].Width + (order > sections[0].TabCount - 1 ? -margin : 0.0f); + float tab_x2 = tab->Offset - sections[0].Width + tab->Width + (order + 1 < tab_bar->Tabs.Size - sections[2].TabCount ? margin : 1.0f); + tab_bar->ScrollingTargetDistToVisibility = 0.0f; + if (tab_bar->ScrollingTarget > tab_x1 || (tab_x2 - tab_x1 >= scrollable_width)) + { + // Scroll to the left + tab_bar->ScrollingTargetDistToVisibility = ImMax(tab_bar->ScrollingAnim - tab_x2, 0.0f); + tab_bar->ScrollingTarget = tab_x1; + } + else if (tab_bar->ScrollingTarget < tab_x2 - scrollable_width) + { + // Scroll to the right + tab_bar->ScrollingTargetDistToVisibility = ImMax((tab_x1 - scrollable_width) - tab_bar->ScrollingAnim, 0.0f); + tab_bar->ScrollingTarget = tab_x2 - scrollable_width; + } +} + +void ImGui::TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset) +{ + IM_ASSERT(offset != 0); + IM_ASSERT(tab_bar->ReorderRequestTabId == 0); + tab_bar->ReorderRequestTabId = tab->ID; + tab_bar->ReorderRequestOffset = (ImS16)offset; +} + +void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* src_tab, ImVec2 mouse_pos) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(tab_bar->ReorderRequestTabId == 0); + if ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) == 0) + return; + + const bool is_central_section = (src_tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0; + const float bar_offset = tab_bar->BarRect.Min.x - (is_central_section ? tab_bar->ScrollingTarget : 0); + + // Count number of contiguous tabs we are crossing over + const int dir = (bar_offset + src_tab->Offset) > mouse_pos.x ? -1 : +1; + const int src_idx = tab_bar->Tabs.index_from_ptr(src_tab); + int dst_idx = src_idx; + for (int i = src_idx; i >= 0 && i < tab_bar->Tabs.Size; i += dir) + { + // Reordered tabs must share the same section + const ImGuiTabItem* dst_tab = &tab_bar->Tabs[i]; + if (dst_tab->Flags & ImGuiTabItemFlags_NoReorder) + break; + if ((dst_tab->Flags & ImGuiTabItemFlags_SectionMask_) != (src_tab->Flags & ImGuiTabItemFlags_SectionMask_)) + break; + dst_idx = i; + + // Include spacing after tab, so when mouse cursor is between tabs we would not continue checking further tabs that are not hovered. + const float x1 = bar_offset + dst_tab->Offset - g.Style.ItemInnerSpacing.x; + const float x2 = bar_offset + dst_tab->Offset + dst_tab->Width + g.Style.ItemInnerSpacing.x; + //GetForegroundDrawList()->AddRect(ImVec2(x1, tab_bar->BarRect.Min.y), ImVec2(x2, tab_bar->BarRect.Max.y), IM_COL32(255, 0, 0, 255)); + if ((dir < 0 && mouse_pos.x > x1) || (dir > 0 && mouse_pos.x < x2)) + break; + } + + if (dst_idx != src_idx) + TabBarQueueReorder(tab_bar, src_tab, dst_idx - src_idx); +} + +bool ImGui::TabBarProcessReorder(ImGuiTabBar* tab_bar) +{ + ImGuiTabItem* tab1 = TabBarFindTabByID(tab_bar, tab_bar->ReorderRequestTabId); + if (tab1 == NULL || (tab1->Flags & ImGuiTabItemFlags_NoReorder)) + return false; + + //IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_Reorderable); // <- this may happen when using debug tools + int tab2_order = tab_bar->GetTabOrder(tab1) + tab_bar->ReorderRequestOffset; + if (tab2_order < 0 || tab2_order >= tab_bar->Tabs.Size) + return false; + + // Reordered tabs must share the same section + // (Note: TabBarQueueReorderFromMousePos() also has a similar test but since we allow direct calls to TabBarQueueReorder() we do it here too) + ImGuiTabItem* tab2 = &tab_bar->Tabs[tab2_order]; + if (tab2->Flags & ImGuiTabItemFlags_NoReorder) + return false; + if ((tab1->Flags & ImGuiTabItemFlags_SectionMask_) != (tab2->Flags & ImGuiTabItemFlags_SectionMask_)) + return false; + + ImGuiTabItem item_tmp = *tab1; + ImGuiTabItem* src_tab = (tab_bar->ReorderRequestOffset > 0) ? tab1 + 1 : tab2; + ImGuiTabItem* dst_tab = (tab_bar->ReorderRequestOffset > 0) ? tab1 : tab2 + 1; + const int move_count = (tab_bar->ReorderRequestOffset > 0) ? tab_bar->ReorderRequestOffset : -tab_bar->ReorderRequestOffset; + memmove(dst_tab, src_tab, move_count * sizeof(ImGuiTabItem)); + *tab2 = item_tmp; + + if (tab_bar->Flags & ImGuiTabBarFlags_SaveSettings) + MarkIniSettingsDirty(); + return true; +} + +static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const ImVec2 arrow_button_size(g.FontSize - 2.0f, g.FontSize + g.Style.FramePadding.y * 2.0f); + const float scrolling_buttons_width = arrow_button_size.x * 2.0f; + + const ImVec2 backup_cursor_pos = window->DC.CursorPos; + //window->DrawList->AddRect(ImVec2(tab_bar->BarRect.Max.x - scrolling_buttons_width, tab_bar->BarRect.Min.y), ImVec2(tab_bar->BarRect.Max.x, tab_bar->BarRect.Max.y), IM_COL32(255,0,0,255)); + + int select_dir = 0; + ImVec4 arrow_col = g.Style.Colors[ImGuiCol_Text]; + arrow_col.w *= 0.5f; + + PushStyleColor(ImGuiCol_Text, arrow_col); + PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + const float backup_repeat_delay = g.IO.KeyRepeatDelay; + const float backup_repeat_rate = g.IO.KeyRepeatRate; + g.IO.KeyRepeatDelay = 0.250f; + g.IO.KeyRepeatRate = 0.200f; + float x = ImMax(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.x - scrolling_buttons_width); + window->DC.CursorPos = ImVec2(x, tab_bar->BarRect.Min.y); + if (ArrowButtonEx("##<", ImGuiDir_Left, arrow_button_size, ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_Repeat)) + select_dir = -1; + window->DC.CursorPos = ImVec2(x + arrow_button_size.x, tab_bar->BarRect.Min.y); + if (ArrowButtonEx("##>", ImGuiDir_Right, arrow_button_size, ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_Repeat)) + select_dir = +1; + PopStyleColor(2); + g.IO.KeyRepeatRate = backup_repeat_rate; + g.IO.KeyRepeatDelay = backup_repeat_delay; + + ImGuiTabItem* tab_to_scroll_to = NULL; + if (select_dir != 0) + if (ImGuiTabItem* tab_item = TabBarFindTabByID(tab_bar, tab_bar->SelectedTabId)) + { + int selected_order = tab_bar->GetTabOrder(tab_item); + int target_order = selected_order + select_dir; + + // Skip tab item buttons until another tab item is found or end is reached + while (tab_to_scroll_to == NULL) + { + // If we are at the end of the list, still scroll to make our tab visible + tab_to_scroll_to = &tab_bar->Tabs[(target_order >= 0 && target_order < tab_bar->Tabs.Size) ? target_order : selected_order]; + + // Cross through buttons + // (even if first/last item is a button, return it so we can update the scroll) + if (tab_to_scroll_to->Flags & ImGuiTabItemFlags_Button) + { + target_order += select_dir; + selected_order += select_dir; + tab_to_scroll_to = (target_order < 0 || target_order >= tab_bar->Tabs.Size) ? tab_to_scroll_to : NULL; + } + } + } + window->DC.CursorPos = backup_cursor_pos; + tab_bar->BarRect.Max.x -= scrolling_buttons_width + 1.0f; + + return tab_to_scroll_to; +} + +static ImGuiTabItem* ImGui::TabBarTabListPopupButton(ImGuiTabBar* tab_bar) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + // We use g.Style.FramePadding.y to match the square ArrowButton size + const float tab_list_popup_button_width = g.FontSize + g.Style.FramePadding.y; + const ImVec2 backup_cursor_pos = window->DC.CursorPos; + window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x - g.Style.FramePadding.y, tab_bar->BarRect.Min.y); + tab_bar->BarRect.Min.x += tab_list_popup_button_width; + + ImVec4 arrow_col = g.Style.Colors[ImGuiCol_Text]; + arrow_col.w *= 0.5f; + PushStyleColor(ImGuiCol_Text, arrow_col); + PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + bool open = BeginCombo("##v", NULL, ImGuiComboFlags_NoPreview | ImGuiComboFlags_HeightLargest); + PopStyleColor(2); + + ImGuiTabItem* tab_to_select = NULL; + if (open) + { + for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + if (tab->Flags & ImGuiTabItemFlags_Button) + continue; + + const char* tab_name = tab_bar->GetTabName(tab); + if (Selectable(tab_name, tab_bar->SelectedTabId == tab->ID)) + tab_to_select = tab; + } + EndCombo(); + } + + window->DC.CursorPos = backup_cursor_pos; + return tab_to_select; +} + +//------------------------------------------------------------------------- +// [SECTION] Widgets: BeginTabItem, EndTabItem, etc. +//------------------------------------------------------------------------- +// - BeginTabItem() +// - EndTabItem() +// - TabItemButton() +// - TabItemEx() [Internal] +// - SetTabItemClosed() +// - TabItemCalcSize() [Internal] +// - TabItemBackground() [Internal] +// - TabItemLabelAndCloseButton() [Internal] +//------------------------------------------------------------------------- + +bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + ImGuiTabBar* tab_bar = g.CurrentTabBar; + if (tab_bar == NULL) + { + IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!"); + return false; + } + IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead! + + bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL); + if (ret && !(flags & ImGuiTabItemFlags_NoPushId)) + { + ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx]; + PushOverrideID(tab->ID); // We already hashed 'label' so push into the ID stack directly instead of doing another hash through PushID(label) + } + return ret; +} + +void ImGui::EndTabItem() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; + + ImGuiTabBar* tab_bar = g.CurrentTabBar; + if (tab_bar == NULL) + { + IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!"); + return; + } + IM_ASSERT(tab_bar->LastTabItemIdx >= 0); + ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx]; + if (!(tab->Flags & ImGuiTabItemFlags_NoPushId)) + PopID(); +} + +bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + ImGuiTabBar* tab_bar = g.CurrentTabBar; + if (tab_bar == NULL) + { + IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!"); + return false; + } + return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL); +} + +bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window) +{ + // Layout whole tab bar if not already done + if (tab_bar->WantLayout) + TabBarLayout(tab_bar); + + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + const ImGuiID id = TabBarCalcTabID(tab_bar, label, docked_window); + + // If the user called us with *p_open == false, we early out and don't render. + // We make a call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID. + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + if (p_open && !*p_open) + { + ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); + return false; + } + + IM_ASSERT(!p_open || !(flags & ImGuiTabItemFlags_Button)); + IM_ASSERT((flags & (ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing)) != (ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing)); // Can't use both Leading and Trailing + + // Store into ImGuiTabItemFlags_NoCloseButton, also honor ImGuiTabItemFlags_NoCloseButton passed by user (although not documented) + if (flags & ImGuiTabItemFlags_NoCloseButton) + p_open = NULL; + else if (p_open == NULL) + flags |= ImGuiTabItemFlags_NoCloseButton; + + // Calculate tab contents size + ImVec2 size = TabItemCalcSize(label, p_open != NULL); + + // Acquire tab data + ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, id); + bool tab_is_new = false; + if (tab == NULL) + { + tab_bar->Tabs.push_back(ImGuiTabItem()); + tab = &tab_bar->Tabs.back(); + tab->ID = id; + tab->Width = size.x; + tab_bar->TabsAddedNew = true; + tab_is_new = true; + } + tab_bar->LastTabItemIdx = (ImS16)tab_bar->Tabs.index_from_ptr(tab); + tab->ContentWidth = size.x; + tab->BeginOrder = tab_bar->TabsActiveCount++; + + const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount); + const bool tab_bar_focused = (tab_bar->Flags & ImGuiTabBarFlags_IsFocused) != 0; + const bool tab_appearing = (tab->LastFrameVisible + 1 < g.FrameCount); + const bool is_tab_button = (flags & ImGuiTabItemFlags_Button) != 0; + tab->LastFrameVisible = g.FrameCount; + tab->Flags = flags; + tab->Window = docked_window; + + // Append name with zero-terminator + // (regular tabs are permitted in a DockNode tab bar, but window tabs not permitted in a non-DockNode tab bar) + if (tab->Window != NULL) + { + IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode); + tab->NameOffset = -1; + } + else + { + IM_ASSERT(tab->Window == NULL); + tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); + tab_bar->TabsNames.append(label, label + strlen(label) + 1); // Append name _with_ the zero-terminator. + } + + // Update selected tab + if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0) + if (!tab_bar_appearing || tab_bar->SelectedTabId == 0) + if (!is_tab_button) + tab_bar->NextSelectedTabId = id; // New tabs gets activated + if ((flags & ImGuiTabItemFlags_SetSelected) && (tab_bar->SelectedTabId != id)) // SetSelected can only be passed on explicit tab bar + if (!is_tab_button) + tab_bar->NextSelectedTabId = id; + + // Lock visibility + // (Note: tab_contents_visible != tab_selected... because CTRL+TAB operations may preview some tabs without selecting them!) + bool tab_contents_visible = (tab_bar->VisibleTabId == id); + if (tab_contents_visible) + tab_bar->VisibleTabWasSubmitted = true; + + // On the very first frame of a tab bar we let first tab contents be visible to minimize appearing glitches + if (!tab_contents_visible && tab_bar->SelectedTabId == 0 && tab_bar_appearing && docked_window == NULL) + if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs)) + tab_contents_visible = true; + + // Note that tab_is_new is not necessarily the same as tab_appearing! When a tab bar stops being submitted + // and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'. + if (tab_appearing && (!tab_bar_appearing || tab_is_new)) + { + ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); + if (is_tab_button) + return false; + return tab_contents_visible; + } + + if (tab_bar->SelectedTabId == id) + tab->LastFrameSelected = g.FrameCount; + + // Backup current layout position + const ImVec2 backup_main_cursor_pos = window->DC.CursorPos; + + // Layout + const bool is_central_section = (tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0; + size.x = tab->Width; + if (is_central_section) + window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(IM_FLOOR(tab->Offset - tab_bar->ScrollingAnim), 0.0f); + else + window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(tab->Offset, 0.0f); + ImVec2 pos = window->DC.CursorPos; + ImRect bb(pos, pos + size); + + // We don't have CPU clipping primitives to clip the CloseButton (until it becomes a texture), so need to add an extra draw call (temporary in the case of vertical animation) + const bool want_clip_rect = is_central_section && (bb.Min.x < tab_bar->ScrollingRectMinX || bb.Max.x > tab_bar->ScrollingRectMaxX); + if (want_clip_rect) + PushClipRect(ImVec2(ImMax(bb.Min.x, tab_bar->ScrollingRectMinX), bb.Min.y - 1), ImVec2(tab_bar->ScrollingRectMaxX, bb.Max.y), true); + + ImVec2 backup_cursor_max_pos = window->DC.CursorMaxPos; + ItemSize(bb.GetSize(), style.FramePadding.y); + window->DC.CursorMaxPos = backup_cursor_max_pos; + + if (!ItemAdd(bb, id)) + { + if (want_clip_rect) + PopClipRect(); + window->DC.CursorPos = backup_main_cursor_pos; + return tab_contents_visible; + } + + // Click to Select a tab + ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowItemOverlap); + if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this + button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); + if (pressed && !is_tab_button) + tab_bar->NextSelectedTabId = id; + + // Transfer active id window so the active id is not owned by the dock host (as StartMouseMovingWindow() + // will only do it on the drag). This allows FocusWindow() to be more conservative in how it clears active id. + if (held && docked_window && g.ActiveId == id && g.ActiveIdIsJustActivated) + g.ActiveIdWindow = docked_window; + + // Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered) + if (g.ActiveId != id) + SetItemAllowOverlap(); + + // Drag and drop a single floating window node moves it + ImGuiDockNode* node = docked_window ? docked_window->DockNode : NULL; + const bool single_floating_window_node = node && node->IsFloatingNode() && (node->Windows.Size == 1); + if (held && single_floating_window_node && IsMouseDragging(0, 0.0f)) + { + // Move + StartMouseMovingWindow(docked_window); + } + else if (held && !tab_appearing && IsMouseDragging(0)) + { + // Drag and drop: re-order tabs + int drag_dir = 0; + float drag_distance_from_edge_x = 0.0f; + if (!g.DragDropActive && ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (docked_window != NULL))) + { + // While moving a tab it will jump on the other side of the mouse, so we also test for MouseDelta.x + if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < bb.Min.x) + { + drag_dir = -1; + drag_distance_from_edge_x = bb.Min.x - g.IO.MousePos.x; + TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos); + } + else if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > bb.Max.x) + { + drag_dir = +1; + drag_distance_from_edge_x = g.IO.MousePos.x - bb.Max.x; + TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos); + } + } + + // Extract a Dockable window out of it's tab bar + if (docked_window != NULL && !(docked_window->Flags & ImGuiWindowFlags_NoMove)) + { + // We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar + bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id); + if (!undocking_tab) //&& (!g.IO.ConfigDockingWithShift || g.IO.KeyShift) + { + float threshold_base = g.FontSize; + float threshold_x = (threshold_base * 2.2f); + float threshold_y = (threshold_base * 1.5f) + ImClamp((ImFabs(g.IO.MouseDragMaxDistanceAbs[0].x) - threshold_base * 2.0f) * 0.20f, 0.0f, threshold_base * 4.0f); + //GetForegroundDrawList()->AddRect(ImVec2(bb.Min.x - threshold_x, bb.Min.y - threshold_y), ImVec2(bb.Max.x + threshold_x, bb.Max.y + threshold_y), IM_COL32_WHITE); // [DEBUG] + + float distance_from_edge_y = ImMax(bb.Min.y - g.IO.MousePos.y, g.IO.MousePos.y - bb.Max.y); + if (distance_from_edge_y >= threshold_y) + undocking_tab = true; + if (drag_distance_from_edge_x > threshold_x) + if ((drag_dir < 0 && tab_bar->GetTabOrder(tab) == 0) || (drag_dir > 0 && tab_bar->GetTabOrder(tab) == tab_bar->Tabs.Size - 1)) + undocking_tab = true; + } + + if (undocking_tab) + { + // Undock + // FIXME: refactor to share more code with e.g. StartMouseMovingWindow + DockContextQueueUndockWindow(&g, docked_window); + g.MovingWindow = docked_window; + SetActiveID(g.MovingWindow->MoveId, g.MovingWindow); + g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min; + g.ActiveIdNoClearOnFocusLoss = true; + SetActiveIdUsingNavAndKeys(); + } + } + } + +#if 0 + if (hovered && g.HoveredIdNotActiveTimer > TOOLTIP_DELAY && bb.GetWidth() < tab->ContentWidth) + { + // Enlarge tab display when hovering + bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->ContentWidth, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f))); + display_draw_list = GetForegroundDrawList(window); + TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive)); + } +#endif + + // Render tab shape + ImDrawList* display_draw_list = window->DrawList; + const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabUnfocused)); + TabItemBackground(display_draw_list, bb, flags, tab_col); + RenderNavHighlight(bb, id); + + // Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget. + const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup); + if (hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1))) + if (!is_tab_button) + tab_bar->NextSelectedTabId = id; + + if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton) + flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton; + + // Render tab label, process close button + const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0; + bool just_closed; + bool text_clipped; + TabItemLabelAndCloseButton(display_draw_list, bb, flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped); + if (just_closed && p_open != NULL) + { + *p_open = false; + TabBarCloseTab(tab_bar, tab); + } + + // Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent) + // That state is copied to window->DockTabItemStatusFlags by our caller. + if (docked_window && (hovered || g.HoveredId == close_button_id)) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; + + // Restore main window position so user can draw there + if (want_clip_rect) + PopClipRect(); + window->DC.CursorPos = backup_main_cursor_pos; + + // Tooltip + // (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok) + // (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores) + // FIXME: This is a mess. + // FIXME: We may want disabled tab to still display the tooltip? + if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered()) + if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip)) + SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label); + + IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected + if (is_tab_button) + return pressed; + return tab_contents_visible; +} + +// [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed. +// To use it to need to call the function SetTabItemClosed() between BeginTabBar() and EndTabBar(). +// Tabs closed by the close button will automatically be flagged to avoid this issue. +void ImGui::SetTabItemClosed(const char* label) +{ + ImGuiContext& g = *GImGui; + bool is_within_manual_tab_bar = g.CurrentTabBar && !(g.CurrentTabBar->Flags & ImGuiTabBarFlags_DockNode); + if (is_within_manual_tab_bar) + { + ImGuiTabBar* tab_bar = g.CurrentTabBar; + ImGuiID tab_id = TabBarCalcTabID(tab_bar, label, NULL); + if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id)) + tab->WantClose = true; // Will be processed by next call to TabBarLayout() + } + else if (ImGuiWindow* window = FindWindowByName(label)) + { + if (window->DockIsActive) + if (ImGuiDockNode* node = window->DockNode) + { + ImGuiID tab_id = TabBarCalcTabID(node->TabBar, label, window); + TabBarRemoveTab(node->TabBar, tab_id); + window->DockTabWantClose = true; + } + } +} + +ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button) +{ + ImGuiContext& g = *GImGui; + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size = ImVec2(label_size.x + g.Style.FramePadding.x, label_size.y + g.Style.FramePadding.y * 2.0f); + if (has_close_button) + size.x += g.Style.FramePadding.x + (g.Style.ItemInnerSpacing.x + g.FontSize); // We use Y intentionally to fit the close button circle. + else + size.x += g.Style.FramePadding.x + 1.0f; + return ImVec2(ImMin(size.x, TabBarCalcMaxTabWidth()), size.y); +} + +void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col) +{ + // While rendering tabs, we trim 1 pixel off the top of our bounding box so they can fit within a regular frame height while looking "detached" from it. + ImGuiContext& g = *GImGui; + const float width = bb.GetWidth(); + IM_UNUSED(flags); + IM_ASSERT(width > 0.0f); + const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f)); + const float y1 = bb.Min.y + 1.0f; + const float y2 = bb.Max.y + ((flags & ImGuiTabItemFlags_Preview) ? 0.0f : -1.0f); + draw_list->PathLineTo(ImVec2(bb.Min.x, y2)); + draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9); + draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12); + draw_list->PathLineTo(ImVec2(bb.Max.x, y2)); + draw_list->PathFillConvex(col); + if (g.Style.TabBorderSize > 0.0f) + { + draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2)); + draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9); + draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding - 0.5f, y1 + rounding + 0.5f), rounding, 9, 12); + draw_list->PathLineTo(ImVec2(bb.Max.x - 0.5f, y2)); + draw_list->PathStroke(GetColorU32(ImGuiCol_Border), 0, g.Style.TabBorderSize); + } +} + +// Render text label (with custom clipping) + Unsaved Document marker + Close Button logic +// We tend to lock style.FramePadding for a given tab-bar, hence the 'frame_padding' parameter. +void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped) +{ + ImGuiContext& g = *GImGui; + ImVec2 label_size = CalcTextSize(label, NULL, true); + + if (out_just_closed) + *out_just_closed = false; + if (out_text_clipped) + *out_text_clipped = false; + + if (bb.GetWidth() <= 1.0f) + return; + + // In Style V2 we'll have full override of all colors per state (e.g. focused, selected) + // But right now if you want to alter text color of tabs this is what you need to do. +#if 0 + const float backup_alpha = g.Style.Alpha; + if (!is_contents_visible) + g.Style.Alpha *= 0.7f; +#endif + + // Render text label (with clipping + alpha gradient) + unsaved marker + ImRect text_pixel_clip_bb(bb.Min.x + frame_padding.x, bb.Min.y + frame_padding.y, bb.Max.x - frame_padding.x, bb.Max.y); + ImRect text_ellipsis_clip_bb = text_pixel_clip_bb; + + // Return clipped state ignoring the close button + if (out_text_clipped) + { + *out_text_clipped = (text_ellipsis_clip_bb.Min.x + label_size.x) > text_pixel_clip_bb.Max.x; + //draw_list->AddCircle(text_ellipsis_clip_bb.Min, 3.0f, *out_text_clipped ? IM_COL32(255, 0, 0, 255) : IM_COL32(0, 255, 0, 255)); + } + + const float button_sz = g.FontSize; + const ImVec2 button_pos(ImMax(bb.Min.x, bb.Max.x - frame_padding.x * 2.0f - button_sz), bb.Min.y); + + // Close Button & Unsaved Marker + // We are relying on a subtle and confusing distinction between 'hovered' and 'g.HoveredId' which happens because we are using ImGuiButtonFlags_AllowOverlapMode + SetItemAllowOverlap() + // 'hovered' will be true when hovering the Tab but NOT when hovering the close button + // 'g.HoveredId==id' will be true when hovering the Tab including when hovering the close button + // 'g.ActiveId==close_button_id' will be true when we are holding on the close button, in which case both hovered booleans are false + bool close_button_pressed = false; + bool close_button_visible = false; + if (close_button_id != 0) + if (is_contents_visible || bb.GetWidth() >= ImMax(button_sz, g.Style.TabMinWidthForCloseButton)) + if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == tab_id || g.ActiveId == close_button_id) + close_button_visible = true; + bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x); + + if (close_button_visible) + { + ImGuiLastItemData last_item_backup = g.LastItemData; + PushStyleVar(ImGuiStyleVar_FramePadding, frame_padding); + if (CloseButton(close_button_id, button_pos)) + close_button_pressed = true; + PopStyleVar(); + g.LastItemData = last_item_backup; + + // Close with middle mouse button + if (!(flags & ImGuiTabItemFlags_NoCloseWithMiddleMouseButton) && IsMouseClicked(2)) + close_button_pressed = true; + } + else if (unsaved_marker_visible) + { + const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz) + g.Style.FramePadding * 2.0f); + RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text)); + } + + // This is all rather complicated + // (the main idea is that because the close button only appears on hover, we don't want it to alter the ellipsis position) + // FIXME: if FramePadding is noticeably large, ellipsis_max_x will be wrong here (e.g. #3497), maybe for consistency that parameter of RenderTextEllipsis() shouldn't exist.. + float ellipsis_max_x = close_button_visible ? text_pixel_clip_bb.Max.x : bb.Max.x - 1.0f; + if (close_button_visible || unsaved_marker_visible) + { + text_pixel_clip_bb.Max.x -= close_button_visible ? (button_sz) : (button_sz * 0.80f); + text_ellipsis_clip_bb.Max.x -= unsaved_marker_visible ? (button_sz * 0.80f) : 0.0f; + ellipsis_max_x = text_pixel_clip_bb.Max.x; + } + RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, text_pixel_clip_bb.Max.x, ellipsis_max_x, label, NULL, &label_size); + +#if 0 + if (!is_contents_visible) + g.Style.Alpha = backup_alpha; +#endif + + if (out_just_closed) + *out_just_closed = close_button_pressed; +} + + +#endif // #ifndef IMGUI_DISABLE diff --git a/libultraship/libultraship/Lib/ImGui/imstb_rectpack.h b/libultraship/libultraship/Lib/ImGui/imstb_rectpack.h new file mode 100644 index 000000000..395895216 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imstb_rectpack.h @@ -0,0 +1,639 @@ +// [DEAR IMGUI] +// This is a slightly modified version of stb_rect_pack.h 1.00. +// Those changes would need to be pushed into nothings/stb: +// - Added STBRP__CDECL +// Grep for [DEAR IMGUI] to find the changes. + +// stb_rect_pack.h - v1.00 - 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. +// Can override those by defining STBRP_SORT and STBRP_ASSERT. +// +// 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. +// +// Credits +// +// Library +// Sean Barrett +// Minor features +// Martins Mozeiko +// github:IntellectualKitty +// +// Bugfixes / warning fixes +// Jeremy Jaussaud +// Fabian Giesen +// +// Version history: +// +// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles +// 0.99 (2019-02-07) warning fixes +// 0.11 (2017-03-03) return packing success/fail result +// 0.10 (2016-10-25) remove cast-away-const to avoid warnings +// 0.09 (2016-08-27) fix compiler warnings +// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) +// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) +// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort +// 0.05: added STBRP_ASSERT to allow replacing assert +// 0.04: fixed minor bug in STBRP_LARGE_RECTS support +// 0.01: initial release +// +// LICENSE +// +// See end of file for license information. + +////////////////////////////////////////////////////////////////////////////// +// +// 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 int 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. +// +// The function returns 1 if all of the rectangles were successfully +// packed and 0 otherwise. + +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 +#ifndef STBRP_SORT +#include +#define STBRP_SORT qsort +#endif + +#ifndef STBRP_ASSERT +#include +#define STBRP_ASSERT assert +#endif + +// [DEAR IMGUI] Added STBRP__CDECL +#ifdef _MSC_VER +#define STBRP__NOTUSED(v) (void)(v) +#define STBRP__CDECL __cdecl +#else +#define STBRP__NOTUSED(v) (void)sizeof(v) +#define STBRP__CDECL +#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) +{ + stbrp_node *node = first; + int x1 = x0 + width; + int min_y, visited_width, waste_area; + + STBRP__NOTUSED(c); + + 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); + + // if it can't possibly fit, bail immediately + if (width > c->width || height > c->height) { + fr.prev_link = NULL; + fr.x = fr.y = 0; + return fr; + } + + 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); + + { + int count=0; + cur = context->active_head; + while (cur) { + cur = cur->next; + ++count; + } + cur = context->free_head; + while (cur) { + cur = cur->next; + ++count; + } + STBRP_ASSERT(count == context->num_nodes+2); + } +#endif + + return res; +} + +// [DEAR IMGUI] Added STBRP__CDECL +static int STBRP__CDECL rect_height_compare(const void *a, const void *b) +{ + const stbrp_rect *p = (const stbrp_rect *) a; + const stbrp_rect *q = (const 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); +} + +// [DEAR IMGUI] Added STBRP__CDECL +static int STBRP__CDECL rect_original_order(const void *a, const void *b) +{ + const stbrp_rect *p = (const stbrp_rect *) a; + const stbrp_rect *q = (const 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 int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) +{ + int i, all_rects_packed = 1; + + // we use the 'was_packed' field internally to allow sorting/unsorting + for (i=0; i < num_rects; ++i) { + rects[i].was_packed = i; + } + + // sort according to heuristic + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); + + for (i=0; i < num_rects; ++i) { + if (rects[i].w == 0 || rects[i].h == 0) { + rects[i].x = rects[i].y = 0; // empty rect needs no space + } else { + 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 + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); + + // set was_packed flags and all_rects_packed status + for (i=0; i < num_rects; ++i) { + rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); + if (!rects[i].was_packed) + all_rects_packed = 0; + } + + // return the all_rects_packed status + return all_rects_packed; +} +#endif + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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/libultraship/libultraship/Lib/ImGui/imstb_textedit.h b/libultraship/libultraship/Lib/ImGui/imstb_textedit.h new file mode 100644 index 000000000..2c635b27d --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imstb_textedit.h @@ -0,0 +1,1449 @@ +// [DEAR IMGUI] +// This is a slightly modified version of stb_textedit.h 1.13. +// Those changes would need to be pushed into nothings/stb: +// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) +// Grep for [DEAR IMGUI] to find the changes. + +// stb_textedit.h - v1.13 - 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 +// +// See end of file for license information. +// +// +// DEPENDENCIES +// +// Uses the C runtime function 'memmove', which you can override +// by defining STB_TEXTEDIT_memmove before the implementation. +// Uses no other functions. Performs no runtime allocations. +// +// +// VERSION HISTORY +// +// 1.13 (2019-02-07) fix bug in undo size management +// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash +// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield +// 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual +// 1.9 (2016-08-27) customizable move-by-word +// 1.8 (2016-04-02) better keyboard handling when mouse button is down +// 1.7 (2015-09-13) change y range handling in case baseline is non-0 +// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove +// 1.5 (2014-09-10) add support for secondary keys for OS X +// 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 +// Fabian Giesen: secondary key inputs in 1.5 +// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6 +// +// Bugfixes: +// Scott Graham +// Daniel Keller +// Omar Cornut +// Dan Thompson +// +// 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 + 3 * 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 is 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_PGUP keyboard input to move cursor up a page +// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page +// 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 default WORDLEFT/WORDRIGHT handlers +// STB_TEXTEDIT_MOVEWORDLEFT(obj,i) custom handler for WORDLEFT, returns index to move cursor to +// STB_TEXTEDIT_MOVEWORDRIGHT(obj,i) custom handler for WORDRIGHT, returns index to move cursor to +// 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 +// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line +// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line +// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text +// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text +// +// 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_TEXTEDIT_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, STB_TEXEDIT_KEYTYPE 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. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to +// anything other type you wante before including. +// +// +// 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; + STB_TEXTEDIT_POSITIONTYPE insert_length; + STB_TEXTEDIT_POSITIONTYPE delete_length; + int 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; + int 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 + + int row_count_per_page; + // page size in number of row. + // this value MUST be set to >0 for pageup or pagedown in multilines documents. + + ///////////////////// + // + // 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 + +#ifndef STB_TEXTEDIT_memmove +#include +#define STB_TEXTEDIT_memmove memmove +#endif + + +///////////////////////////////////////////////////////////////////////////// +// +// 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; + + 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 (i==0 && y < base_y + r.ymin) + return 0; + + 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' + prev_x = r.x0; + for (k=0; k < r.num_chars; ++k) { + float w = STB_TEXTEDIT_GETWIDTH(str, i, k); + 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) +{ + // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse + // goes off the top or bottom of the text + if( state->single_line ) + { + StbTexteditRow r; + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + y = r.ymin; + } + + 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 = 0; + + // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse + // goes off the top or bottom of the text + if( state->single_line ) + { + StbTexteditRow r; + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + y = r.ymin; + } + + if (state->select_start == state->select_end) + state->select_start = state->cursor; + + 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; + 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; +} + +#ifndef STB_TEXTEDIT_MOVEWORDLEFT +static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c ) +{ + --c; // always move at least one character + while( c >= 0 && !is_word_boundary( str, c ) ) + --c; + + if( c < 0 ) + c = 0; + + return c; +} +#define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous +#endif + +#ifndef STB_TEXTEDIT_MOVEWORDRIGHT +static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c ) +{ + const int len = STB_TEXTEDIT_STRINGLEN(str); + ++c; // always move at least one character + while( c < len && !is_word_boundary( str, c ) ) + ++c; + + if( c > len ) + c = len; + + return c; +} +#define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next +#endif + +#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); // implicitly clamps + state->has_preferred_x = 0; + return 1; + } + return 0; +} + +// API paste: replace existing selection with passed-in text +static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len) +{ + // 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; + } + // [DEAR IMGUI] + //// remove the undo since we didn't actually insert the characters + //if (state->undostate.undo_point) + // --state->undostate.undo_point; + // note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details) + return 0; +} + +#ifndef STB_TEXTEDIT_KEYTYPE +#define STB_TEXTEDIT_KEYTYPE int +#endif + +// API key: process a keyboard input +static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE 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); // implicitly 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_MOVEWORDLEFT + case STB_TEXTEDIT_K_WORDLEFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else { + state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); + 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_MOVEWORDLEFT(str, state->cursor); + state->select_end = state->cursor; + + stb_textedit_clamp( str, state ); + break; +#endif + +#ifdef STB_TEXTEDIT_MOVEWORDRIGHT + case STB_TEXTEDIT_K_WORDRIGHT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else { + state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, 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_MOVEWORDRIGHT(str, state->cursor); + 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: + case STB_TEXTEDIT_K_PGDOWN: + case STB_TEXTEDIT_K_PGDOWN | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, j, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGDOWN; + int row_count = is_page ? state->row_count_per_page : 1; + + if (!is_page && 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); + + for (j = 0; j < row_count; ++j) { + float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x; + int start = find.first_char + find.length; + + if (find.length == 0) + break; + + // [DEAR IMGUI] + // going down while being on the last line shouldn't bring us to that line end + if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE) + break; + + // now find character position down a row + 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; + + // go to next line + find.first_char = find.first_char + find.length; + find.length = row.num_chars; + } + break; + } + + case STB_TEXTEDIT_K_UP: + case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: + case STB_TEXTEDIT_K_PGUP: + case STB_TEXTEDIT_K_PGUP | STB_TEXTEDIT_K_SHIFT: { + StbFindState find; + StbTexteditRow row; + int i, j, prev_scan, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGUP; + int row_count = is_page ? state->row_count_per_page : 1; + + if (!is_page && 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); + + for (j = 0; j < row_count; ++j) { + float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x; + + // can only go up if there's a previous row + if (find.prev_first == find.first_char) + break; + + // now find character position up a row + 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; + + // go to previous line + // (we need to scan previous line the hard way. maybe we could expose this as a new API function?) + prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0; + while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE) + --prev_scan; + find.first_char = find.prev_first; + find.prev_first = prev_scan; + } + 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; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2: +#endif + case STB_TEXTEDIT_K_TEXTSTART: + state->cursor = state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2: +#endif + case STB_TEXTEDIT_K_TEXTEND: + state->cursor = STB_TEXTEDIT_STRINGLEN(str); + state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_TEXTSTART2 + case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + 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; + +#ifdef STB_TEXTEDIT_K_TEXTEND2 + case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + 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; + + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2: +#endif + case STB_TEXTEDIT_K_LINESTART: + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + if (state->single_line) + state->cursor = 0; + else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2: +#endif + case STB_TEXTEDIT_K_LINEEND: { + int n = STB_TEXTEDIT_STRINGLEN(str); + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + if (state->single_line) + state->cursor = n; + else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) + ++state->cursor; + state->has_preferred_x = 0; + break; + } + +#ifdef STB_TEXTEDIT_K_LINESTART2 + case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + if (state->single_line) + state->cursor = 0; + else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; + break; + +#ifdef STB_TEXTEDIT_K_LINEEND2 + case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: +#endif + case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { + int n = STB_TEXTEDIT_STRINGLEN(str); + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + if (state->single_line) + state->cursor = n; + else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) + ++state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; + break; + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// +// 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 -= n; + STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (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 -= n; // @OPTIMIZE: get rid of char_storage and infer it + } + --state->undo_point; + STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (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; + // move the remaining redo character data to the end of the buffer + state->redo_char_point += n; + STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); + // adjust the position of all the other records to account for above memmove + for (i=state->redo_point; i < k; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage += n; + } + // now move all the redo records towards the end of the buffer; the first one is at 'redo_point' + // [DEAR IMGUI] + size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0])); + const char* buf_begin = (char*)state->undo_rec; (void)buf_begin; + const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end; + IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin); + IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end); + STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size); + + // now move redo_point to point to the new one + ++state->redo_point; + } +} + +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 = (STB_TEXTEDIT_POSITIONTYPE) insert_len; + r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len; + + if (insert_len == 0) { + r->char_storage = -1; + return NULL; + } else { + r->char_storage = state->undo_char_point; + state->undo_char_point += 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) { + // should never happen: + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + // there's currently not enough room, so discard a redo record + stb_textedit_discard_redo(s); + } + 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 - 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); + s->redo_char_point += 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; + state->row_count_per_page = 0; +} + +// API initialize +static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) +{ + stb_textedit_clear_state(state, is_single_line); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) +{ + return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif//STB_TEXTEDIT_IMPLEMENTATION + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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/libultraship/libultraship/Lib/ImGui/imstb_truetype.h b/libultraship/libultraship/Lib/ImGui/imstb_truetype.h new file mode 100644 index 000000000..48c202617 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/imstb_truetype.h @@ -0,0 +1,4903 @@ +// [DEAR IMGUI] +// This is a slightly modified version of stb_truetype.h 1.20. +// Mostly fixing for compiler and static analyzer warnings. +// Grep for [DEAR IMGUI] to find the changes. + +// stb_truetype.h - v1.20 - public domain +// authored from 2009-2016 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) +// render glyphs to one-channel SDF bitmaps (signed-distance field/function) +// +// 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 +// Dougall Johnson: OpenType / Type 2 font handling +// Daniel Ribeiro Maciel: basic GPOS-based kerning +// +// Misc other: +// Ryan Gordon +// Simon Glass +// github:IntellectualKitty +// Imanol Celaya +// Daniel Ribeiro Maciel +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket Fabian "ryg" Giesen +// Cass Everitt Martins Mozeiko +// stoiko (Haemimont Games) Cap Petschulat +// Brian Hook Omar Cornut +// Walter van Niftrik github:aloucks +// David Gow Peter LaValle +// David Given Sergey Popov +// Ivan-Assen Ivanov Giumo X. Clanjor +// Anthony Pesch Higor Euripedes +// Johan Duparc Thomas Fields +// Hou Qiming Derek Vinyard +// Rob Loach Cort Stratton +// Kenney Phillis Jr. github:oyvindjam +// Brian Costabile github:vassvik +// +// VERSION HISTORY +// +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() +// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// variant PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// +// Full history can be found at the end of this file. +// +// LICENSE +// +// See end of file for license information. +// +// USAGE +// +// Include this file in whatever places need 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. +// +// To make the implementation private to the file that generates the implementation, +// #define STBTT_STATIC +// +// 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_PackSetOversampling() -- 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() -- indexing for TTC font collections +// stbtt_GetNumberOfFonts() -- number of fonts 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_GetFontVMetricsOS2() +// stbtt_GetCodepointKernAdvance() +// +// Starting with version 1.06, the rasterizer was replaced with a new, +// faster and generally-more-precise rasterizer. The new rasterizer more +// accurately measures pixel coverage for anti-aliasing, except in the case +// where multiple shapes overlap, in which case it overestimates the AA pixel +// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If +// this turns out to be a problem, you can re-enable the old rasterizer with +// #define STBTT_RASTERIZER_VERSION 1 +// which will incur about a 15% speed hit. +// +// 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 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. +// +// DETAILED USAGE: +// +// Scale: +// Select how high you want the font to be, in points or pixels. +// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute +// a scale factor SF that will be used by all other functions. +// +// Baseline: +// You need to select a y-coordinate that is the baseline of where +// your text will appear. Call GetFontBoundingBox to get the baseline-relative +// bounding box for all characters. SF*-y0 will be the distance in pixels +// that the worst-case character could extend above the baseline, so if +// you want the top edge of characters to appear at the top of the +// screen where y=0, then you would set the baseline to SF*-y0. +// +// Current point: +// Set the current point where the first character will appear. The +// first character could extend left of the current point; this is font +// dependent. You can either choose a current point that is the leftmost +// point and hope, or add some padding, or check the bounding box or +// left-side-bearing of the first character to be displayed and set +// the current point based on that. +// +// Displaying a character: +// Compute the bounding box of the character. It will contain signed values +// relative to . I.e. if it returns x0,y0,x1,y1, +// then the character should be displayed in the rectangle from +// to = 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!"; // intentionally misspelled to show 'lj' brokenness + + 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, e.g. if you don't +//// link with the C runtime library. + +#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]; + + // e.g. #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) + #define STBTT_pow(x,y) pow(x,y) + #endif + + #ifndef STBTT_fmod + #include + #define STBTT_fmod(x,y) fmod(x,y) + #endif + + #ifndef STBTT_cos + #include + #define STBTT_cos(x) cos(x) + #define STBTT_acos(x) acos(x) + #endif + + #ifndef STBTT_fabs + #include + #define STBTT_fabs(x) fabs(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 STBTT_STATIC +#define STBTT_DEF static +#else +#define STBTT_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// private structure +typedef struct +{ + unsigned char *data; + int cursor; + int size; +} stbtt__buf; + +////////////////////////////////////////////////////////////////////////////// +// +// 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(const 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. + +STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap); +// Query the font vertical metrics without having to create a font first. + + +////////////////////////////////////////////////////////////////////////////// +// +// 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 width * 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, const 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_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar *chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally +} stbtt_pack_range; + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const 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. Note that you can call this multiple +// times within a single PackBegin/PackEnd. + +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) or stbtt_PackFontRangesGatherRects for a given +// pack context. The default (no oversampling) is achieved by h_oversample=1 +// and 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 +// +// To use with PackFontRangesGather etc., you must set it before calls +// call to PackFontRangesGatherRects. + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip); +// If skip != 0, this tells stb_truetype to skip any codepoints for which +// there is no corresponding glyph. If skip=0, which is the default, then +// codepoints without a glyph recived the font's "missing character" glyph, +// typically an empty box by convention. + +STBTT_DEF void stbtt_GetPackedQuad(const 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); + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +// Calling these functions in sequence is roughly equivalent to calling +// stbtt_PackFontRanges(). If you more control over the packing of multiple +// fonts, or if you want to pack custom data into a font texture, take a look +// at the source to of stbtt_PackFontRanges() and create a custom version +// using these functions, e.g. call GatherRects multiple times, +// building up a single array of rects, then call PackRects once, +// then call RenderIntoRects repeatedly. This may result in a +// better packing than calling PackFontRanges multiple times +// (or it may not). + +// 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; + int skip_missing; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// + +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); +// This function will determine the number of fonts in a font file. TrueType +// collection (.ttc) files may contain multiple fonts, while TrueType font +// (.ttf) files only contain one font. The number of fonts can be used for +// indexing with the previous function where the index is between zero and one +// less than the total fonts. If an error occurs, -1 is returned. + +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. + +// The following structure is defined publicly so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +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,gpos; // 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__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict +}; + +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. +// Returns 0 if the character codepoint is not defined in the font. + + +////////////////////////////////////////////////////////////////////////////// +// +// 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 int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); +// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 +// table (specific to MS/Windows TTF files). +// +// Returns 1 on success (table present), 0 on failure. + +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, + STBTT_vcubic + }; +#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,cx1,cy1; + 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 contours. 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_MakeCodepointBitmapSubpixelPrefilter(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 oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint); +// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering +// is performed (see stbtt_PackSetOversampling) + +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_MakeGlyphBitmapSubpixelPrefilter(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 oversample_x, int oversample_y, float *sub_x, float *sub_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; + +// rasterize a shape with quadratic beziers into a bitmap +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex *vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void *userdata); // context for to STBTT_MALLOC + +////////////////////////////////////////////////////////////////////////////// +// +// Signed Distance Function (or Field) rendering + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata); +// frees the SDF bitmap allocated below + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +// These functions compute a discretized SDF field for a single character, suitable for storing +// in a single-channel texture, sampling with bilinear filtering, and testing against +// larger than some threshold to produce scalable fonts. +// info -- the font +// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap +// glyph/codepoint -- the character to generate the SDF for +// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), +// which allows effects like bit outlines +// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) +// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) +// if positive, > onedge_value is inside; if negative, < onedge_value is inside +// width,height -- output height & width of the SDF bitmap (including padding) +// xoff,yoff -- output origin of the character +// return value -- a 2D array of bytes 0..255, width*height in size +// +// pixel_dist_scale & onedge_value are a scale & bias that allows you to make +// optimal use of the limited 0..255 for your application, trading off precision +// and special effects. SDF values outside the range 0..255 are clamped to 0..255. +// +// Example: +// scale = stbtt_ScaleForPixelHeight(22) +// padding = 5 +// onedge_value = 180 +// pixel_dist_scale = 180/5.0 = 36.0 +// +// This will create an SDF bitmap in which the character is about 22 pixels +// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled +// shape, sample the SDF at each pixel and fill the pixel if the SDF value +// is greater than or equal to 180/255. (You'll actually want to antialias, +// which is beyond the scope of this example.) Additionally, you can compute +// offset outlines (e.g. to stroke the character border inside & outside, +// or only outside). For example, to fill outside the character up to 3 SDF +// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above +// choice of variables maps a range from 5 pixels outside the shape to +// 2 pixels inside the shape to 0..255; this is intended primarily for apply +// outside effects only (the interior range is needed to allow proper +// antialiasing of the font at *smaller* sizes) +// +// The function computes the SDF analytically at each SDF pixel, not by e.g. +// building a higher-res bitmap and approximating it. In theory the quality +// should be as high as possible for an SDF of this size & representation, but +// unclear if this is true in practice (perhaps building a higher-res bitmap +// and computing from that can allow drop-out prevention). +// +// The algorithm has not been optimized at all, so expect it to be slow +// if computing lots of characters or very large sizes. + + + +////////////////////////////////////////////////////////////////////////////// +// +// 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 + +#if STBTT_MAX_OVERSAMPLE > 255 +#error "STBTT_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +#ifndef STBTT_RASTERIZER_VERSION +#define STBTT_RASTERIZER_VERSION 2 +#endif + +#ifdef _MSC_VER +#define STBTT__NOTUSED(v) (void)(v) +#else +#define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +////////////////////////////////////////////////////////////////////////// +// +// stbtt__buf helpers to parse data from file +// + +static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; +} + +static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; +} + +static void stbtt__buf_seek(stbtt__buf *b, int o) +{ + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +static void stbtt__buf_skip(stbtt__buf *b, int o) +{ + stbtt__buf_seek(b, b->cursor + o); +} + +static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) +{ + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; +} + +static stbtt__buf stbtt__new_buf(const void *p, size_t size) +{ + stbtt__buf r; + STBTT_assert(size < 0x40000000); + r.data = (stbtt_uint8*) p; + r.size = (int) size; + r.cursor = 0; + return r; +} + +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) + +static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) +{ + stbtt__buf r = stbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; +} + +static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) +{ + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if (count) { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); +} + +static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) +{ + int b0 = stbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) return b0 - 139; + else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108; + else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108; + else if (b0 == 28) return stbtt__buf_get16(b); + else if (b0 == 29) return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; +} + +static void stbtt__cff_skip_operand(stbtt__buf *b) { + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if (b0 == 30) { + stbtt__buf_skip(b, 1); + while (b->cursor < b->size) { + v = stbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } else { + stbtt__cff_int(b); + } +} + +static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) +{ + stbtt__buf_seek(b, 0); + while (b->cursor < b->size) { + int start = b->cursor, end, op; + while (stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if (op == 12) op = stbtt__buf_get8(b) | 0x100; + if (op == key) return stbtt__buf_range(b, start, end-start); + } + return stbtt__buf_range(b, 0, 0); +} + +static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) +{ + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); +} + +static int stbtt__cff_index_count(stbtt__buf *b) +{ + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); +} + +static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) +{ + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i*offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); +} + +////////////////////////////////////////////////////////////////////////// +// +// 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) + +static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } +static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + +#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(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 + if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts + 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; +} + +static int stbtt_GetFontOffsetForIndex_internal(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*4); + } + } + return -1; +} + +static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) +{ + // if it's just a font, there's only one valid font + if (stbtt__isfont(font_collection)) + return 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) { + return ttLONG(font_collection+8); + } + } + return 0; +} + +static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) +{ + stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1]+subrsoff); + return stbtt__cff_get_index(&cff); +} + +static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) +{ + stbtt_uint32 cmap, t; + stbtt_int32 i,numTables; + + info->data = data; + info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); + + 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 + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required + + if (!cmap || !info->head || !info->hhea || !info->hmtx) + return 0; + if (info->glyf) { + // required for truetype + if (!info->loca) return 0; + } else { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; + + cff = stbtt__find_table(data, fontstart, "CFF "); + if (!cff) return 0; + + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); + + // @TODO this should use size from table (not 512MB) + info->cff = stbtt__new_buf(data+cff, 512*1024*1024); + b = info->cff; + + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); + + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); + + // we only support Type 2 charstrings + if (cstype != 2) return 0; + if (charstrings == 0) return 0; + + if (fdarrayoff) { + // looks like a CID font + if (!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff); + } + + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } + + 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; + + // 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) { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + { + stbtt_uint16 offset, start; + stbtt_uint16 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); + 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; + + STBTT_assert(!info->cff.size); + + 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 +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + if (info->cff.size) { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } else { + 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; + if (info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + 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; +} + +static int stbtt__GetGlyphShapeTT(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)); //-V595 + 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; +} + +typedef struct +{ + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; + + stbtt_vertex *pvertices; + int num_vertices; +} stbtt__csctx; + +#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) +{ + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) +{ + if (c->bounds) { + stbtt__track_vertex(c, x, y); + if (type == STBTT_vcubic) { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } else { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1; + } + c->num_vertices++; +} + +static void stbtt__csctx_close_shape(stbtt__csctx *ctx) +{ + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) +{ + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) +{ + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); +} + +static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if (fmt == 0) { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } else if (fmt == 3) { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); +} + +static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define STBTT__CSERR(s) (0) + + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch (b0) { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if (in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; + + case 0x15: // rmoveto + in_header = 0; + if (sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); + break; + case 0x04: // vmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp-1]); + break; + case 0x16: // hmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-1], 0); + break; + + case 0x05: // rlineto + if (sp < 2) return STBTT__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. + + case 0x07: // vlineto + if (sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if (sp < 1) return STBTT__CSERR("hlineto stack"); + for (;;) { + if (i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: // hvcurveto + if (sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if (sp < 4) return STBTT__CSERR("vhcurveto stack"); + for (;;) { + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); + i += 4; + } + break; + + case 0x08: // rrcurveto + if (sp < 6) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x18: // rcurveline + if (sp < 8) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + case 0x19: // rlinecurve + if (sp < 8) return STBTT__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) { f = s[i]; i++; } + for (; i + 3 < sp; i += 4) { + if (b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); + f = 0.0; + } + break; + + case 0x0A: // callsubr + if (!has_subrs) { + if (info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // fallthrough + case 0x1D: // callgsubr + if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int) s[--sp]; + if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: // return + if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch (b1) { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if (sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: // flex + if (sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: // hflex1 + if (sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); + break; + + case 0x25: // flex1 + if (sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1+dx2+dx3+dx4+dx5; + dy = dy1+dy2+dy3+dy4+dy5; + if (STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return STBTT__CSERR("unimplemented"); + } + } break; + + default: + if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) //-V560 + return STBTT__CSERR("reserved operator"); + + // push immediate + if (b0 == 255) { + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; + } else { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if (sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); + +#undef STBTT__CSERR +} + +static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; + return r ? c.num_vertices : 0; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + if (!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + +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)); + } +} + +static int stbtt__GetGlyphKernInfoAdvance(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; +} + +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +{ + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch(coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + + // Binary search. + stbtt_int32 l=0, r=glyphCount-1, m; + int straw, needle=glyph; + while (l <= r) { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; + } + } + } break; + + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; + + // Binary search. + stbtt_int32 l=0, r=rangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) +{ + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch(classDefFormat) + { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + + // [DEAR IMGUI] Commented to fix static analyzer warning + //classDefTable = classDef1ValueArray + 2 * glyphCount; + } break; + + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; + + // Binary search. + stbtt_int32 l=0, r=classRangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } + + // [DEAR IMGUI] Commented to fix static analyzer warning + //classDefTable = classRangeRecords + 6 * classRangeCount; + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +// Define to STBTT_assert(x) if you want to break on unimplemented formats. +#define STBTT_GPOS_TODO_assert(x) + +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i; + + if (!info->gpos) return 0; + + data = info->data + info->gpos; + + if (ttUSHORT(data+0) != 1) return 0; // Major version 1 + if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data+8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); + + for (i=0; i> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } break; + + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + STBTT_assert(glyph1class < class1Count); + STBTT_assert(glyph2class < class2Count); + + // TODO: Support more formats. + STBTT_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + STBTT_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { + stbtt_uint8 *class1Records = table + 16; + stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); + stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + break; + } // [DEAR IMGUI] removed ; + } + } + break; + } // [DEAR IMGUI] removed ; + + default: + // TODO: Implement other stuff. + break; + } + } + + return 0; +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) +{ + int xAdvance = 0; + + if (info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + + if (info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +{ + if (!info->kern && !info->gpos) // 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 int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) +{ + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if (!tab) + return 0; + if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68); + if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70); + if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72); + return 1; +} + +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=0,y0=0,x1,y1; // =0 suppresses compiler warning + 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); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Rasterizer + +typedef struct stbtt__hheap_chunk +{ + struct stbtt__hheap_chunk *next; +} stbtt__hheap_chunk; + +typedef struct stbtt__hheap +{ + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; +} stbtt__hheap; + +static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) +{ + if (hh->first_free) { + void *p = hh->first_free; + hh->first_free = * (void **) p; + return p; + } else { + if (hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; + } +} + +static void stbtt__hheap_free(stbtt__hheap *hh, void *p) +{ + *(void **) p = hh->first_free; + hh->first_free = p; +} + +static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) +{ + stbtt__hheap_chunk *c = hh->head; + while (c) { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } +} + +typedef struct stbtt__edge { + float x0,y0, x1,y1; + int invert; +} stbtt__edge; + + +typedef struct stbtt__active_edge +{ + struct stbtt__active_edge *next; + #if STBTT_RASTERIZER_VERSION==1 + int x,dx; + float ey; + int direction; + #elif STBTT_RASTERIZER_VERSION==2 + float fx,fdx,fdy; + float direction; + float sy; + float ey; + #else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" + #endif +} stbtt__active_edge; + +#if STBTT_RASTERIZER_VERSION == 1 +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX-1) + +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if (!z) return z; + + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; +} +#elif STBTT_RASTERIZER_VERSION == 2 +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#if STBTT_RASTERIZER_VERSION == 1 +// 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->direction; + } else { + int x1 = e->x; w += e->direction; + // if we went to zero, we need to draw + if (w == 0) { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_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 >> STBTT_FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_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__hheap hh = { 0, 0, 0 }; + 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->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } 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 = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if (z != NULL) { + // 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; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +#elif STBTT_RASTERIZER_VERSION == 2 + +// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 +// (i.e. it has already been clipped to those) +static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) +{ + if (y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) { + x0 += (x1-x0) * (e->sy - y0) / (y1-y0); + y0 = e->sy; + } + if (y1 > e->ey) { + x1 += (x1-x0) * (e->ey - y1) / (y1-y0); + y1 = e->ey; + } + + if (x0 == x) + STBTT_assert(x1 <= x+1); + else if (x0 == x+1) + STBTT_assert(x1 >= x); + else if (x0 <= x) + STBTT_assert(x1 <= x); + else if (x0 >= x+1) + STBTT_assert(x1 >= x+1); + else + STBTT_assert(x1 >= x && x1 <= x+1); + + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1-y0); + else if (x0 >= x+1 && x1 >= x+1) + ; + else { + STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); + scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position + } +} + +static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) +{ + float y_bottom = y_top+1; + + while (e) { + // brute force every pixel + + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); + + if (e->fdx == 0) { + float x0 = e->fx; + if (x0 < len) { + if (x0 >= 0) { + stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); + stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); + } else { + stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); + } + } + } else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0,sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } else { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } else { + x_bottom = xb; + sy1 = y_bottom; + } + + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + // from here on, we don't have to range check x values + + if ((int) x_top == (int) x_bottom) { + float height; + // simple case, only spans one pixel + int x = (int) x_top; + height = sy1 - sy0; + STBTT_assert(x >= 0 && x < len); + scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; + scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + } else { + int x,x1,x2; + float y_crossing, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + // [DEAR IMGUI] Fix static analyzer warning + (void)dx; // [ImGui: fix static analyzer warning] + } + + x1 = (int) x_top; + x2 = (int) x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = (x1+1 - x0) * dy + y_top; + + sign = e->direction; + // area of the rectangle covered from y0..y_crossing + area = sign * (y_crossing-sy0); + // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) + scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); + + step = sign * dy; + for (x = x1+1; x < x2; ++x) { + scanline[x] += area + step/2; + area += step; + } + y_crossing += dy * (x2 - (x1+1)); + + STBTT_assert(STBTT_fabs(area) <= 1.01f); + + scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); + + scanline_fill[x2] += sign * (sy1-sy0); + } + } else { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + int x; + for (x=0; x < len; ++x) { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. + + // rename variables to clearly-defined pairs + float y0 = y_top; + float x1 = (float) (x); + float x2 = (float) (x+1); + float x3 = xb; + float y3 = y_bottom; + + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + float y1 = (x - x0) / dx + y_top; + float y2 = (x+1 - x0) / dx + y_top; + + if (x0 < x1 && x3 > x2) { // three segments descending down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x1 && x0 > x2) { // three segments descending down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else { // one segment + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); + } + } + } + } + e = e->next; + } +} + +// directly AA rasterize edges w/o supersampling +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__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0, i; + float scanline_data[129], *scanline, *scanline2; + + STBTT__NOTUSED(vsubsample); + + if (result->w > 64) + scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float) (off_y + result->h) + 1; + + while (j < result->h) { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; + + STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y_top) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + step = &((*step)->next); // advance through list + } + } + + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) { + if (e->y0 != e->y1) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if (z != NULL) { + if (j == 0 && off_y != 0) { + if (z->ey < scan_y_top) { + // this can happen due to subpixel positioning and some kind of fp rounding error i think + z->ey = scan_y_top; + } + } + STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds + // insert at front + z->next = active; + active = z; + } + } + ++e; + } + + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + + { + float sum = 0; + for (i=0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float) STBTT_fabs(k)*255 + 0.5f; + m = (int) k; + if (m > 255) m = 255; + result->pixels[j*result->stride + i] = (unsigned char) m; + } + } + // advance all the edges + step = &active; + while (*step) { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + + ++y; + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) + +static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) +{ + int i,j; + for (i=1; i < n; ++i) { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) { + stbtt__edge *b = &p[j-1]; + int c = STBTT__COMPARE(a,b); + if (!c) break; + p[j] = p[j-1]; + --j; + } + if (i != j) + p[j] = t; + } +} + +static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) +{ + /* threshold for transitioning to insertion sort */ + while (n > 12) { + stbtt__edge t; + int c01,c12,c,m,i,j; + + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0],&p[m]); + c12 = STBTT__COMPARE(&p[m],&p[n-1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0],&p[n-1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n-1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i=1; + j=n-1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;;++i) { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;;--j) { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n-i)) { + stbtt__sort_edges_quicksort(p,j); + p = p+i; + n = n-i; + } else { + stbtt__sort_edges_quicksort(p+i, n-i); + n = j; + } + } +} + +static void stbtt__sort_edges(stbtt__edge *p, int n) +{ + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); +} + +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; +#if STBTT_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif STBTT_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + // 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); + stbtt__sort_edges(e, n); + + // 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; +} + +// tessellate until threshold 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; +} + +static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1-x0; + float dy0 = y1-y0; + float dx1 = x2-x1; + float dy1 = y2-y1; + float dx2 = x3-x2; + float dy2 = y3-y2; + float dx = x3-x0; + float dy = y3-y0; + float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2)); + float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy); + float flatness_squared = longlen*longlen-shortlen*shortlen; + + if (n > 16) // 65536 segments on one curve better be enough! + return; + + if (flatness_squared > objspace_flatness_squared) { + float x01 = (x0+x1)/2; + float y01 = (y0+y1)/2; + float x12 = (x1+x2)/2; + float y12 = (y1+y2)/2; + float x23 = (x2+x3)/2; + float y23 = (y2+y3)/2; + + float xa = (x01+x12)/2; + float ya = (y01+y12)/2; + float xb = (x12+x23)/2; + float yb = (y12+y23)/2; + + float mx = (xa+xb)/2; + float my = (ya+yb)/2; + + stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x3,y3); + *num_points = *num_points+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; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + 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 = 0; + int *winding_lengths = NULL; + 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) { + STBTT_free(vertices, info->userdata); + 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_MakeCodepointBitmapSubpixelPrefilter(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 oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +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 + +static int stbtt_BakeFontBitmap_internal(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; + f.userdata = NULL; + 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(const 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; + const stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + + 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 + +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; + spc->skip_missing = 0; + + 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; +} + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) +{ + spc->skip_missing = skip; +} + +#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; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < h; ++j) { + int i; + unsigned int total; + STBTT_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; + case 5: + 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 / 5); + } + 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; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < w; ++j) { + int i; + unsigned int total; + STBTT_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; + case 5: + 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 / 5); + } + 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, const 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); + ranges[i].h_oversample = (unsigned char) spc->h_oversample; + ranges[i].v_oversample = (unsigned char) spc->v_oversample; + for (j=0; j < ranges[i].num_chars; ++j) { + int x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + if (glyph == 0 && spc->skip_missing) { + rects[k].w = rects[k].h = 0; + } else { + 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); + } + ++k; + } + } + + return k; +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(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 prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, + output, + out_w - (prefilter_x - 1), + out_h - (prefilter_y - 1), + out_stride, + scale_x, + scale_y, + shift_x, + shift_y, + glyph); + + if (prefilter_x > 1) + stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); + + if (prefilter_y > 1) + stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); + + *sub_x = stbtt__oversample_shift(prefilter_x); + *sub_y = stbtt__oversample_shift(prefilter_y); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k, return_value = 1; + + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; + + 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); + float recip_h,recip_v,sub_x,sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for (j=0; j < ranges[i].num_chars; ++j) { + stbrp_rect *r = &rects[k]; + if (r->was_packed && r->w != 0 && r->h != 0) { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + 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; + } + } + + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; + + return return_value; +} + +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) +{ + stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); +} + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +{ + stbtt_fontinfo info; + int i,j,n, return_value; // [DEAR IMGUI] removed = 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; ++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; + + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; + + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; +} + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) +{ + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = 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_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap) +{ + int i_ascent, i_descent, i_lineGap; + float scale; + stbtt_fontinfo info; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); + scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size); + stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap); + *ascent = (float) i_ascent * scale; + *descent = (float) i_descent * scale; + *lineGap = (float) i_lineGap * scale; +} + +STBTT_DEF void stbtt_GetPackedQuad(const 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; + const stbtt_packedchar *b = chardata + char_index; + + if (align_to_integer) { + float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); + 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; +} + +////////////////////////////////////////////////////////////////////////////// +// +// sdf computation +// + +#define STBTT_min(a,b) ((a) < (b) ? (a) : (b)) +#define STBTT_max(a,b) ((a) < (b) ? (b) : (a)) + +static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) +{ + float q0perp = q0[1]*ray[0] - q0[0]*ray[1]; + float q1perp = q1[1]*ray[0] - q1[0]*ray[1]; + float q2perp = q2[1]*ray[0] - q2[0]*ray[1]; + float roperp = orig[1]*ray[0] - orig[0]*ray[1]; + + float a = q0perp - 2*q1perp + q2perp; + float b = q1perp - q0perp; + float c = q0perp - roperp; + + float s0 = 0., s1 = 0.; + int num_s = 0; + + if (a != 0.0) { + float discr = b*b - a*c; + if (discr > 0.0) { + float rcpna = -1 / a; + float d = (float) STBTT_sqrt(discr); + s0 = (b+d) * rcpna; + s1 = (b-d) * rcpna; + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { + if (num_s == 0) s0 = s1; + ++num_s; + } + } + } else { + // 2*b*s + c = 0 + // s = -c / (2*b) + s0 = c / (-2 * b); + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + } + + if (num_s == 0) + return 0; + else { + float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]); + float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; + + float q0d = q0[0]*rayn_x + q0[1]*rayn_y; + float q1d = q1[0]*rayn_x + q1[1]*rayn_y; + float q2d = q2[0]*rayn_x + q2[1]*rayn_y; + float rod = orig[0]*rayn_x + orig[1]*rayn_y; + + float q10d = q1d - q0d; + float q20d = q2d - q0d; + float q0rd = q0d - rod; + + hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d; + hits[0][1] = a*s0+b; + + if (num_s > 1) { + hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d; + hits[1][1] = a*s1+b; + return 2; + } else { + return 1; + } + } +} + +static int equal(float *a, float *b) +{ + return (a[0] == b[0] && a[1] == b[1]); +} + +static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) +{ + int i; + float orig[2], ray[2] = { 1, 0 }; + float y_frac; + int winding = 0; + + orig[0] = x; + //orig[1] = y; // [DEAR IMGUI] commented double assignment + + // make sure y never passes through a vertex of the shape + y_frac = (float) STBTT_fmod(y, 1.0f); + if (y_frac < 0.01f) + y += 0.01f; + else if (y_frac > 0.99f) + y -= 0.01f; + orig[1] = y; + + // test a ray from (-infinity,y) to (x,y) + for (i=0; i < nverts; ++i) { + if (verts[i].type == STBTT_vline) { + int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y; + int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + if (verts[i].type == STBTT_vcurve) { + int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ; + int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy; + int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ; + int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2)); + int by = STBTT_max(y0,STBTT_max(y1,y2)); + if (y > ay && y < by && x > ax) { + float q0[2],q1[2],q2[2]; + float hits[2][2]; + q0[0] = (float)x0; + q0[1] = (float)y0; + q1[0] = (float)x1; + q1[1] = (float)y1; + q2[0] = (float)x2; + q2[1] = (float)y2; + if (equal(q0,q1) || equal(q1,q2)) { + x0 = (int)verts[i-1].x; + y0 = (int)verts[i-1].y; + x1 = (int)verts[i ].x; + y1 = (int)verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } else { + int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); + if (num_hits >= 1) + if (hits[0][0] < 0) + winding += (hits[0][1] < 0 ? -1 : 1); + if (num_hits >= 2) + if (hits[1][0] < 0) + winding += (hits[1][1] < 0 ? -1 : 1); + } + } + } + } + return winding; +} + +static float stbtt__cuberoot( float x ) +{ + if (x<0) + return -(float) STBTT_pow(-x,1.0f/3.0f); + else + return (float) STBTT_pow( x,1.0f/3.0f); +} + +// x^3 + c*x^2 + b*x + a = 0 +static int stbtt__solve_cubic(float a, float b, float c, float* r) +{ + float s = -a / 3; + float p = b - a*a / 3; + float q = a * (2*a*a - 9*b) / 27 + c; + float p3 = p*p*p; + float d = q*q + 4*p3 / 27; + if (d >= 0) { + float z = (float) STBTT_sqrt(d); + float u = (-q + z) / 2; + float v = (-q - z) / 2; + u = stbtt__cuberoot(u); + v = stbtt__cuberoot(v); + r[0] = s + u + v; + return 1; + } else { + float u = (float) STBTT_sqrt(-p/3); + float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float) STBTT_cos(v); + float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f; + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); + + //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? + //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); + //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); + return 3; + } +} + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + float scale_x = scale, scale_y = scale; + int ix0,iy0,ix1,iy1; + int w,h; + unsigned char *data; + + // if one scale is 0, use same scale for both + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) return NULL; // if both scales are 0, return NULL + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); + + // if empty, return NULL + if (ix0 == ix1 || iy0 == iy1) + return NULL; + + ix0 -= padding; + iy0 -= padding; + ix1 += padding; + iy1 += padding; + + w = (ix1 - ix0); + h = (iy1 - iy0); + + if (width ) *width = w; + if (height) *height = h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + // invert for y-downwards bitmaps + scale_y = -scale_y; + + { + int x,y,i,j; + float *precompute; + stbtt_vertex *verts; + int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); + data = (unsigned char *) STBTT_malloc(w * h, info->userdata); + precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata); + + for (i=0,j=num_verts-1; i < num_verts; j=i++) { + if (verts[i].type == STBTT_vline) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y; + float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)); + precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y; + float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y; + float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float len2 = bx*bx + by*by; + if (len2 != 0.0f) + precompute[i] = 1.0f / (bx*bx + by*by); + else + precompute[i] = 0.0f; + } else + precompute[i] = 0.0f; + } + + for (y=iy0; y < iy1; ++y) { + for (x=ix0; x < ix1; ++x) { + float val; + float min_dist = 999999.0f; + float sx = (float) x + 0.5f; + float sy = (float) y + 0.5f; + float x_gspace = (sx / scale_x); + float y_gspace = (sy / scale_y); + + int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path + + for (i=0; i < num_verts; ++i) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + + // check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve + float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + + if (verts[i].type == STBTT_vline) { + float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y; + + // coarse culling against bbox + //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && + // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) + float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; + STBTT_assert(i != 0); + if (dist < min_dist) { + // check position along line + // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) + // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) + float dx = x1-x0, dy = y1-y0; + float px = x0-sx, py = y0-sy; + // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy + // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve + float t = -(px*dx + py*dy) / (dx*dx + dy*dy); + if (t >= 0.0f && t <= 1.0f) + min_dist = dist; + } + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y; + float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y; + float box_x0 = STBTT_min(STBTT_min(x0,x1),x2); + float box_y0 = STBTT_min(STBTT_min(y0,y1),y2); + float box_x1 = STBTT_max(STBTT_max(x0,x1),x2); + float box_y1 = STBTT_max(STBTT_max(y0,y1),y2); + // coarse culling against bbox to avoid computing cubic unnecessarily + if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) { + int num=0; + float ax = x1-x0, ay = y1-y0; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float mx = x0 - sx, my = y0 - sy; + float res[3],px,py,t,it; + float a_inv = precompute[i]; + if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula + float a = 3*(ax*bx + ay*by); + float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by); + float c = mx*ax+my*ay; + if (a == 0.0) { // if a is 0, it's linear + if (b != 0.0) { + res[num++] = -c/b; + } + } else { + float discriminant = b*b - 4*a*c; + if (discriminant < 0) + num = 0; + else { + float root = (float) STBTT_sqrt(discriminant); + res[0] = (-b - root)/(2*a); + res[1] = (-b + root)/(2*a); + num = 2; // don't bother distinguishing 1-solution case, as code below will still work + } + } + } else { + float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv; + float d = (mx*ax+my*ay) * a_inv; + num = stbtt__solve_cubic(b, c, d, res); + } + if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { + t = res[0], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { + t = res[1], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { + t = res[2], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + } + } + } + if (winding == 0) + min_dist = -min_dist; // if outside the shape, value is negative + val = onedge_value + pixel_dist_scale * min_dist; + if (val < 0) + val = 0; + else if (val > 255) + val = 255; + data[(y-iy0)*w+(x-ix0)] = (unsigned char) val; + } + } + STBTT_free(precompute, info->userdata); + STBTT_free(verts, info->userdata); + } + return data; +} + +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// 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(stbtt_uint8 *s1, stbtt_int32 len1, 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; +} + +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (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_internal((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; +} + +static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, 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; + } +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, + float pixel_height, unsigned char *pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar *chardata) +{ + return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) +{ + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); +} + +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) +{ + return stbtt_GetNumberOfFonts_internal((unsigned char *) data); +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) +{ + return stbtt_InitFont_internal(info, (unsigned char *) data, offset); +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) +{ + return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags); +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif // STB_TRUETYPE_IMPLEMENTATION + + +// FULL VERSION HISTORY +// +// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) allow user-defined fabs() replacement +// fix memory leak if fontsize=0.0 +// fix warning from duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// allow PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// 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 +// + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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/libultraship/libultraship/Lib/ImGui/misc/README.txt b/libultraship/libultraship/Lib/ImGui/misc/README.txt new file mode 100644 index 000000000..b4ce89f03 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/README.txt @@ -0,0 +1,23 @@ + +misc/cpp/ + InputText() wrappers for C++ standard library (STL) type: std::string. + This is also an example of how you may wrap your own similar types. + +misc/debuggers/ + Helper files for popular debuggers. + With the .natvis file, types like ImVector<> will be displayed nicely in Visual Studio debugger. + +misc/fonts/ + Fonts loading/merging instructions (e.g. How to handle glyph ranges, how to merge icons fonts). + Command line tool "binary_to_compressed_c" to create compressed arrays to embed data in source code. + Suggested fonts and links. + +misc/freetype/ + Font atlas builder/rasterizer using FreeType instead of stb_truetype. + Benefit from better FreeType rasterization, in particular for small fonts. + +misc/single_file/ + Single-file header stub. + We use this to validate compiling all *.cpp files in a same compilation unit. + Users of that technique (also called "Unity builds") can generally provide this themselves, + so we don't really recommend you use this in your projects. diff --git a/libultraship/libultraship/Lib/ImGui/misc/cpp/README.txt b/libultraship/libultraship/Lib/ImGui/misc/cpp/README.txt new file mode 100644 index 000000000..429159029 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/cpp/README.txt @@ -0,0 +1,13 @@ + +imgui_stdlib.h + imgui_stdlib.cpp + InputText() wrappers for C++ standard library (STL) type: std::string. + This is also an example of how you may wrap your own similar types. + +imgui_scoped.h + [Experimental, not currently in main repository] + Additional header file with some RAII-style wrappers for common Dear ImGui functions. + Try by merging: https://github.com/ocornut/imgui/pull/2197 + Discuss at: https://github.com/ocornut/imgui/issues/2096 + +See more C++ related extension on Wiki + https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness diff --git a/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.cpp b/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.cpp new file mode 100644 index 000000000..dd6bd8a52 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.cpp @@ -0,0 +1,72 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +#include "imgui.h" +#include "imgui_stdlib.h" + +struct InputTextCallback_UserData +{ + std::string* Str; + ImGuiInputTextCallback ChainCallback; + void* ChainCallbackUserData; +}; + +static int InputTextCallback(ImGuiInputTextCallbackData* data) +{ + InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData; + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + // Resize string callback + // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want. + std::string* str = user_data->Str; + IM_ASSERT(data->Buf == str->c_str()); + str->resize(data->BufTextLen); + data->Buf = (char*)str->c_str(); + } + else if (user_data->ChainCallback) + { + // Forward to user callback, if any + data->UserData = user_data->ChainCallbackUserData; + return user_data->ChainCallback(data); + } + return 0; +} + +bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} diff --git a/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.h b/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.h new file mode 100644 index 000000000..61afc098e --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/cpp/imgui_stdlib.h @@ -0,0 +1,18 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +#pragma once + +#include + +namespace ImGui +{ + // ImGui::InputText() with std::string + // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity + IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); +} diff --git a/libultraship/libultraship/Lib/ImGui/misc/debuggers/README.txt b/libultraship/libultraship/Lib/ImGui/misc/debuggers/README.txt new file mode 100644 index 000000000..3f4ba83e3 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/debuggers/README.txt @@ -0,0 +1,16 @@ + +HELPER FILES FOR POPULAR DEBUGGERS + +imgui.gdb + GDB: disable stepping into trivial functions. + (read comments inside file for details) + +imgui.natstepfilter + Visual Studio Debugger: disable stepping into trivial functions. + (read comments inside file for details) + +imgui.natvis + Visual Studio Debugger: describe Dear ImGui types for better display. + With this, types like ImVector<> will be displayed nicely in the debugger. + (read comments inside file for details) + diff --git a/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.gdb b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.gdb new file mode 100644 index 000000000..000ff6eb9 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.gdb @@ -0,0 +1,12 @@ +# GDB configuration to aid debugging experience + +# To enable these customizations edit $HOME/.gdbinit (or ./.gdbinit if local gdbinit is enabled) and add: +# add-auto-load-safe-path /path/to/imgui.gdb +# source /path/to/imgui.gdb +# +# More Information at: +# * https://sourceware.org/gdb/current/onlinedocs/gdb/gdbinit-man.html +# * https://sourceware.org/gdb/current/onlinedocs/gdb/Init-File-in-the-Current-Directory.html#Init-File-in-the-Current-Directory + +# Disable stepping into trivial functions +skip -rfunction Im(Vec2|Vec4|Strv|Vector|Span)::.+ diff --git a/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natstepfilter b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natstepfilter new file mode 100644 index 000000000..efd1957b2 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natstepfilter @@ -0,0 +1,30 @@ + + + + + + + + (ImVec2|ImVec4|ImStrv)::.+ + NoStepInto + + + (ImVector|ImSpan).*::operator.+ + NoStepInto + + + diff --git a/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natvis b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natvis new file mode 100644 index 000000000..94d17a8f6 --- /dev/null +++ b/libultraship/libultraship/Lib/ImGui/misc/debuggers/imgui.natvis @@ -0,0 +1,62 @@ + + + + + + + {{Size={Size} Capacity={Capacity}}} + + + Size + Data + + + + + + {{Size={DataEnd-Data} }} + + + DataEnd-Data + Data + + + + + + {{x={x,g} y={y,g}}} + + + + {{x={x,g} y={y,g} z={z,g} w={w,g}}} + + + + {{Min=({Min.x,g} {Min.y,g}) Max=({Max.x,g} {Max.y,g}) Size=({Max.x-Min.x,g} {Max.y-Min.y,g})}} + + Min + Max + Max.x - Min.x + Max.y - Min.y + + + + + {{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags & 0x01000000)?1:0,d} Popup {(Flags & 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}} + + + + {{ID {ID,x} Pos=({Pos.x,g} {Pos.y,g}) Size=({Size.x,g} {Size.y,g}) Parent {(ParentNode==0)?0:ParentNode->ID,x} Childs {(ChildNodes[0] != 0)+(ChildNodes[1] != 0)} Windows {Windows.Size} } + + + diff --git a/libultraship/libultraship/Lib/ImGui/misc/fonts/Cousine-Regular.ttf b/libultraship/libultraship/Lib/ImGui/misc/fonts/Cousine-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..70a0bf902e1482724d7706f7a0f40d94fe51f4c3 GIT binary patch literal 43912 zcmb@uc|coLzBqo)x%Xx#xgiM&gph=gumlJY_AQqsArvTqLd#MLv_SVl3v{!#Si90y z?Wm*GR;`Xpou;+gR;%r(EPWf!SHXE=U9CTWIk*!& z*9hmf=6RmHf4UxRhDRQR^S&jk`$u|Y&mTjG2_r-{FIhikYl>U+BD~-@oR<%cEL}bN z69-(AWFjQxmiCX1AQO^9fBEn{zjW26p^~f1*9(_H zgK{HT4Cifdp0aH9*v4i>;9WTX2W;n84KL|mmC*EKgmfRm`I*)I8%NkJWGNhPg!^r4 z`d1HX|5*G_gdY7VLW;bR;nA^AwoLy3p=V?;zKoG|gCqa`;C~-MCh+pFHV zCwn#JpCc>W2A_9^vwk-FJ^e+bg#EeXX*ic5LR;Yj&q$t``Zo0O{`42q|IPkf>?wLJ zx@X0fU!YBhLn{EH1o6m&x&U%nxD_#Qm0{ndx-NwmzL-^(~pKotc)X4R!#^< zSoSy~rv$X|tJ&^ztLD`p0ojt{+5d=aB`(P`WN9Bl$3FT$FrHG*5BJ#+X5U8?$1uX^ zMi^{Bg{T^u-1rMTABWIC&=_X$Tznm^LtD@hbQn#brLaAK9z{FR0el_zp)v7q5dwUo z$I)8Y9!IZ>-|wO@9A86s!G36FYetReAX31+Deza1A3~#8jdo6dh3|!aUqIW@B=kIq z4xtOMjiXP{F0@2!e*s$mhQ5PdgDZYyK#O3c_o3et9ki_?3_Mi~qsoW#W4IYv(T~tJ z7?~A%u7g<=<2-o7VYChAvH@Gr@6bwQMp~pqfTPaW!5rw{Bk-Ps zGk+;?x39wlNk9z)aU+37Fv z0elGepws9KI)g*F3$H=%p>BY+6Mc#PjJ^+}WoEWSpc44NlayY7KM{*N;5!-cODSqA zn#Q?!9(jxWl6+{>+Y)R^wq#qWt=4uj*^nGRJq`ET&~dn@b><$O&16f2drEHIGyQvn zrVmXIPfbnzdFnr}zHl{s_0-jqSMR@i;Hv947k~4z_+}gQ^#Ar@&|<*j02%}cE=9}G za-jK@XcbxwRKErdqY;4nIy4H<8At2U2DB0QVl%n}sP0af#WsNOT>!hg(GGy^F0>o% zL3@E7_M!dg0ASz{VD=t#FVMpg^euEh(C34I*N4!<=qTXpQFII)M~?xno{-;?*N=AW+`adn`;R_$ z{P7b{Jo%kxo__YZ=TCn3)ae(_oPFuVmoL0>5sfSvSoWj!$JVSsW6RO52LYyNXj~lR z%FXDh^V=4$rYEcJK+MG5-}>I`Z~fqh@4fxbIhfwR{rH0`aAm{0@1yOLckSDA;NYSC z_Z>m^KJ@UnFTe5qVT9hK;u9gk-`UaLHm|iM)I7JTv0+YqurA=Qt*NdOe3cdDWu+y> zMTG^qIiBpS%(PUOGsTf?x0>`?UZajtD&#V$gku?kQKsJ!=(B}gePPz+2nMt0xuYK% z`fqFK3)`S6@b!DbHu_vYT>9Fb0^B+DjXQfnJI8?$>IL$F~8mCoa@qncHOHUIdi=nR#Gfsd1KseOW;jcB@?VVYf^ysR>KPE^W)hFm$xfb~^L&=U#@s7#UD%IqOA0UiE9bpXZFYhyl1N%F}eBUx$Iy2coYeQJq z(%lgz&VX%MKTIF~eGYrE*{+2NhyV$|^Z(D65dZ?f0Wh`O>BRS)7tmrj2~V_iM9*z# zvH1)VJnqgg>7!RJ&t5UK(<>9RS8hJu=KyRr%04x(Deh$ZDGz8me8kee*mbEJ~9bAK!W;<=+`wfyuhW6wUs!a z8`_WG;qROIU%$)*Z?t7)hJ)@X>f1WPLM=c;=$|1A|LGhLJkj3=C|XW2+0qgAI7Y&H zM|G5Lpn(p{zkFVY_(-(XAJ*4|!3djqD(vyYvq0?rNlIIE2(&LpOUDJ|oxXZH-)4Tn zi}F!tEi{MYYJjd>{>hGkp|G{jJOG?FWa}{7!$Kz@xYN-w*hvWuAe4R;UI!nTR+!YZ zbu`R#G_-Ve09Ngt;uU&vX-{{8CVUBhKBo~%BWws7tW;)?U9vW-`IB-;#!#*r^ z%3$LG;9@H!)#`Fv2R5VGyI~mNben&$cIG~M{hIx||6ONe< z5sbV(j3@~U#afs)@H*vZN1)$f^dcY_4E)4Z9! zI~FzIhPLXgOb}+(ryY1t%V`1cnb*~Efd>;}Pg}0CD1*GXv{#Q{X%ABVA{5}@O#JdKG&6;?O~tHVl1HEs9Nc3-qz zLffT|>M)MOS(%$BdB5XxQx<}`4agaG3V$9-v;HlRX8o@~hV^=&z`F0R5C8SKzcMR7 z-S;VZhl#$_Q7zg@LO9ll3Cjqe>i$+ObYhRWR)zRs6dBHx(bYzfvW~aR8Av z*bl%)rZ3~T7gTWp&}eaIz&g1IjXb@84QD>Au%5?SVF@#B<$rDaweaiEuP1&T{&R=^_FB$smtSK>UYmH0 zXf9eW63<27#o>#mE`D^8yYRfrYCE5EK6HNM{KR?g{PblZ@w_fQz@NjmbD?t+=fdaM zi5J5!63q*~7e0M~Igeum_p?FkMEG!+gu|D^SHg_vl3Sfs(cV8EfHeMd)*GT*-6WqmNJV0O^ zFWeuO7@*_HxL>Uee9Js-)f_o>3I+nwPN( z4P%vHBljL~S?`%QZT;vl&N+;&hdqbM@ZoKT2|C0dvK?Y*zqUiB#DMK!&Oy?Ap!dM= z0VZcZ*6g?L_v~kc{k$%~U&2ZltP%u^;wHv;>;9Hj$+s*MpSDc55TT`@I3Tn*(*hra@JEffF<`Ma1cKJkd2ANC z@EibnJq#=eTODkt0{ElArvWk%z;Stob}iPl^Ld(fF!|as!d9!sr|H#f)36$iN7Jks z)*RA&q?y)8ebDx)h8afSx#8n+n8WAs;nQvN-0p_+(rK_FIp%tEhvoZI$xOb1z_EETnK8@f7(DmpT9KfsG zqj(gK;L7M2eIYyvZW^4^hemrx#W%xPUSNp+#dKf&kfBm@t{cI60A3?qU`ZoMD_=p?9dwUyvzysiyEy9zSK{Wbs z7x-$IQHVXwz7c6ef5B(a8(5C+z;1FsjN$%&(dWJ30j>m(@f_?QruUG)p?gUsT0@>> z{NP(2M}34wxZVK4GZ&q}-4Jh>0IwBXAvjt_pSbyPF>}Bpy#vn2Z@2pwRoFq`j!*GWJ7#69dJ&oCq8B9TD^=^prNg1-R}^>=|M z`*dVk`J#j(mZPXfx+0O-MEUSMEWw54`C{@U;WzPpFpDLRXnHe{E_YZlPQ}gP)^qoAC%Ior7D}F$CQJV$%adJ{56B-?tWc_z`N~G+QRUB7F4fVP z57m|G*EMaL?`rR~b;pgUs=HDbPOMKh1-ttzGB&jRuM@bRu5$m6Ab8SDjFSLh~ ztCJr}{>-r`Wp2v5&iT#rARXwKDb1v_v_M-`^>BIZt))W zKJC5i{e|~$`HKAH{L=ik{44o?DnJFMf}Db2!Qz7V3O5(tTlj3@>xCZ{epb|4tSC+{ zE-r2@9x2{me4=DW$%7@~lDA4eEcvXIFLjmHmM$wxD9b4emMtn9E1N8PyzH;#C(GX~ z|7H2#DpVE86;D;XR`J)$Wj>oP=zCkR3Hd@$SR*_ryj7*BnqPII>T0#Ry1aT(4XR15 z8K}8fJE!(>z!;%%IWoYtLsUnKvQJ~=DL*4+6R+i+mT(`IpJ50bqSFj*=4kU7sl;-l z927qsd$o40)2_AG5?dq%KNwlYwSW0sEsgOZLMe{C!_|uYrV9o}`XE6p&q4@MCdZg? zkFaoy&vQ*%;?c(95>Jo!T3&7rb}(M1z-u6vep9Irrtociy4a1=Ga51k#C) zGgZ(t_Y)$Q-tUoMB*796$QXhoKCjo4hdn(#*J4XN*P^|NJ?=l4b~R!+kbaeEBHO0! zA`tYYb1#Hw%zBVv_Xj_&f>B#60pQvn2FV>m8?Q1vm_c=y`04; zo;7iC)+8w_G3rk0xswv(NmGJ{@iBx+U`#m@K@yTMyvb%FS54PVL@zO!Bzi_+*J@QN z`AMX}3K^?96=T6MiHJX?jW=kUwYXW^tNm2VXa#F>a9hlwm}41$q(7eHx*8{iIl-P7aYuhBo+di$1})6?U| zjNM>o96Gu=3cRq{bzX*UUTC-Ln8#}{8~J0$n)#7$wXJD;=eITgg{7TqI`GPlH61^h z68v~Y4O10)V^w4s#XWv-6|PtnJ&G(_6?p?!0E`(_Jw3{9<=#XkKxxf5Uid+6MOy_K zoQv1g;lXme!h^>%c4mATX&`s7{7WKfMaDfTMJCiz}D*~IK+$Y$%Lm1GWQW%(Pt zsS;m`Rw}iQgGwMEBK^GI=I`^5_&Iuz0|$rw$Ngcy)bDRm4J(CMTkxO~E0v|g$SPO~ zvhvpJR>qnqjHb+q9rgNrDOp*mDNezb8gvS=#-P)gB5BZ$%8-gz3968)PsP!%3t(g|prprrO}yt?50IqS>wQ0u z;>>fcCpQQ6-1^`itXC7M!BLQnQ;U)qqt=xQe~xUfAit6n0Y^ZaG@D7)CUIDwM2uQB zgY&aVs^xsva`Z~%= z*DdX+O1TkE^Y;|iEiN~c6FH$3rBy4N+;~gFL~jZA*kjTQ-*Fap*QT@hKM6QmSY=5q zs_*x;ZfH(pwr^)ML*tG1oaPcc8=0@Rx=UMDk;1|{Pm&rx!q^M^Q;U2p`F2etolPnR z^#hDK{Tcfst_3K;h}_7B=ArLhK$X+K5Y%#YusBVw3g**Y_W9{wyZ|k6@GV~AX{(Cv zB(y0Gu5BWF2?&QlGQD#7c<-GD1F|@7ibA=!QM8(*mM;ro?Z`YwqG= ztrzf25jJbBc^%m6%u6B$z?maCn@}9-02_{EHMAuWZ(b$A|I77X-@}}^@5b@crA=8` zbC;EuFQ1#4HFw2Zu@0}@QJ4~|ODRaUc~f*m_P^c1)yu3+cP;7L9&$LE@9tZ2SCcgo zuI?x>#1$;478Vp5jfD#$zxZEop}gvz{)ByuYeE&M87!pF1k>o;yXTTkEqhzYV8?jJ z&JJezJY3?$w)4|}qR2`VzeVI-7b*Z%&R8sojf*A0`gliuWlkl|DZ^!Dx%D|KLs+Fx z)UVPrX$|xAY-Ls`pJU@kDkmxrS2C5AIq}rb@$tH#F9(Af&*`5Z)CfvrP}7$+k~NXV z42E!e2y>zQELM@@Z)k5AY+xGnIcf8_?wXb)rl`9GDdK=7ffKKRuU{6pIR5FTO2x#qrEQq*qfX-AkGmF)tY=$D&JA+IqaA74bGODpO348Mj ziwtT^*)WRuIAbNl0RO7-ED^9d>5Vm|afx;FmzJ%5bSO7#?#fDy*`RVS*wN`5- z-FGQw&%|2e5|^Ckxl5YO06r; zRT&(fg!nv{sdQ*E)U0vbRQlZf$O7gLc+P;*gg9PuU8~`&9N{=4x{g2q^GIR_PNRB? zVj`;SsUUMiAzb8DGen!-vA6HFg}Xc5?#|r{U+df3kxpVKKl}K%>(~D3z4FZWG$WMp(q_FZ1MyCZ|>4}bOXuf#V@?iJtq?|+2!Ek^$!H<+JtKSXMDN-%ay zR)Vd;gqS{t(a3w{!*WK+NM)3O8o70`BN5Fs`juamhPzkGKk4E3jU*h*GimD=>WW)v+M%)QOH`>3r?jP!(>=FepZkG zMJO0TR58#X<K-e@-6Zrc7sGJ5mMzS9*B=uYlCtU5AvTL;ct@% zn1?)||F^+S=qP@eMf?{azk9At0kYjaz|cB7#>_KV9(f0PyMGGu>yTZ(!fYiY@Q6jw zFbq&NPwDz)55{2l_R!}6dN9rcy8+K7Irz%);3Uq445 zVB(=ykwc2}dgwTcy*;3GjM$6UF$HICe4yv9erW>$F=z|)-OP0%9ZChAx=Cm)wBdku zzLo@H=EsnFX{VIbGo1|KGi(_|$OvT+l#VmfGt!gL8bKe@6Qsv_eOA&iQt&{U&1twf ztv8LNrKdaMM>SH%C>M`>pb=pZ@As^o<=M3}qO@o2tnGsJM2$gIV$guGl^_t4aIEyE zIE?B+C)h4*bJNbVLrc%x-O#Y(?25tDI~vcW&0QO89BWQXZ(dhlx31Y8>G%tI;*H3E zpQx*Q0xRBl537y|!m-F_?;ZQ;*8GC4KRNc$k0*+YCw`p#PvA%jE~uMeSAgvvi#ml8 zs43BE`C%fHSuxgt70`@(A+vo9pTbg%)jYvG86gt{=vJqfjmqVWTEaun1e8Cu-M}7; zqH!%Xn%8>4Yz769o8tvq1zk`8>b!{3>?8P`uJ6u+)pHJQ=}UMD_us=zrPbwIk0e*L z<$cw7k2tQwFs^dIjSKA-7LH4HN=S(fkC}Iv$@+v{31ov|w}EVk+Z{)iEAUDlck-A^ zz%G|%jaBB8kzv^-8O#Eu#jermP+!VO%0vp2lJWtiI7+Lru`#12DNdOkI#`&1o*o!A zH7Z5ZWi5<-7D1wc=`E-PD>AC2q^Xt6j51@TcEjP!!%sZ9vn{o*zpSt)kSRSc7lt2S zvHUyZmGgI>I67e?KN;^oanFvscFrkZP-0Fh?<~_c?iwu3>6z?Y^w{C;6L$rGV=m!Xe^CF3PKOURNEER=*w$j1CV`D9f-ZpiP>Cu5!+9wNzJpS>%a*^s_Fovd== zE+<|Riw9zGdko$r+bbiRqXPY6Q$_F_|b#}KGWrLjAlytQBF`ERua0qu4I%-O5IVr-3Rca zK)Y5#p$I1wgkUa!f5pSuTJTQ42Fh83ooW+mB2ZHu%m4~qH!h%NUqQahku13l%wW_f zF>Hfx)0wgDXU9tAFU#C>R@d)&*uQj>cWAM9O?TPOyEojYdQlm=xbvG z-r45H>$>k5D6Cq!w_aPkusUVyrrNH8xTEn!oxT+tHV>>sH`fF zYFNdpR9GpIU}_SBrwLjb)aNYs(_@h-dZJPsgZ?qdv7LG5?9@7P#}6(>4o6h@Gwh3e z5Bv5rn{Vtn$ka?Vh&&Oc4?jeQ4hoBw%P5|i>H7#M>gTe;@C0#hWDD2knc8etoRt*_iM{N%bC^-Ib$|6nk%t|c=A zRe>?=VeC^oEjfpmEPr~vfG-X_cSj(#E|q zf>mUU4%?tC!A4mr-!!T@WWWZ4Mw&k(?13S8(KHj)AP5mk0Bfl*0o`_+t2zs^S&2`; zEd?C_j!zU?-<1Dsux#|%;XBT6uJCVvWqok#(z(WyiFdTj+1QqqduFunk>T=lDZv$i z+<_KvTEmL!s--~}er@2nI|Dr@KY#Ev=Fj&g)vO6wyIcIbzJFJDZ{@nM zRl&O!mt?h$QM$)ad4t$2pnEkc5O{8lL;?vGC77My#}gG57)reGz>)4~X463_Qc2Zdn zbzp$Q0N^kkJf;@(lCX6=ZD$%;uiB*|8_6C*Hp=$M$Og-93)z&sH<@gV-4jbz1n>$0 zgFiDkhsHk!3vmi>&0k}%uE{XKp8_;=B}SE(E3Z(;XkKs)#U8nh@KbocX0)WFNmM7E z(FExxZZAigqG;^#iGhY|C0g%olpj^x)ZYQ=_BCu$AL%wHwy5A6{tn14<{JwAn~p9U zC>ek8&Mhx)DDgB87MAt+>?I>ltsZ@5xX|wFsi;`i=m+B^G7O8d6f<`1-0s8~fo z+gjrFw3a&@<*goPt3NB--#Yb5R%cyiX0XdsHaI6Ey#a(Dm4OEUFTNSxdQ#Z1SvDyn zo28RdvedT0w%f)mOW2sOCn3sI{@nK4nMwyHs#nYC&>Elfkn@=Hl#`__MVwAcsd9}% z;aPLla@|5cuwZ22EyR*Psxt|?xS+|T&KOOWsz=#7(^If|J=PjLAKrWq*{Ow$iJuuR2?ryK$@#bBgIbL(^=4S?%J+rYo zayDFl_mZ-#d82{q(FJ+QHG^R1i*_$$eHe(jrUHPEmBC9+er(W5thwM(?rDL;>)hrs`M7D>>C z7ZGmdSdM0Nc?r@>5GR4SR4W7eOHA{o5da@%h(yLltt5=V_u_n#VaYZLBN1W^K?$P) zM;2`Ss3TQU0kJr2f>ZuCKmFcr*3Dya|EBnDa_@G(nVX|4z@Xp^W6bYwJjHa8viI@h z4@K^c+(WB43DkLZunU+^MA$S6MN%S%Dq9}L#XWCjx3S0AQ|u)c9KqPQAd8;Q!6Dp- zM=%?L-2~+RuV4V6=ygDt(Boc9$-~S42wcb&(v8A|<@7Aau(yCB;UIRV0hnRmjNe2711^la2lTr4CP?0dQSko? zCPf8u3}6{!x&S7>f9TtI7_WIKvWSNK0Va?^WOIS#vOJii5H$LrLg7e%ByGsC-m%NUSS+ST9V}Sspq{`u z1J@Q}bW}6Z9ato@VN?)e5^(ROHx>AdoeM^pfz5SRHn%qWQt>I0S~)k=RPIb~T3uT^ z+?ppnubQ(pJhJNa*4n88km0AFtn8&usG@@)4f^_iZh~%y7oGj6)d=Y0l`)AmY<2iZ&Nb z7BS0PaD%4N+DIB3=cAt#rF(v&=u1lXfH)Vf})7oTm_-I7r~&a z`pJB%{9Hy`aDLwK&kY*Ru;l0Vw6u5^cG)!stHEP9W;kWw4%?60iJjhRgrGx%!EQG+ zFoAL&x+woyHwyf$N5(hrUv+*Cj1xDppQZi+pYx+z9)k(W_327O%Awic~3d^5%hfjAneqwZ${E)?BQ zj@sX9b~XT41mW=~)90=WCgrEbVJy*Pm(^$Z<`)=^nN=-|i!&8-9GKY^bxvRp;&>-dexyy@O3{kNxNUcfT>=i!2V5IfeW*vs!7+ zw58USX2&oPbSHm5{OQR)-dUbWlqv<2T32YTTDfmd3-;Vra{fgC@4FhX8 zl$0-Ra2E|6TA<4>%oXVmcI9$`rd9% zl#Fl!lAeLQ5%$V43IXNdWy^BWuj!VK4RuY@mo0ynx?v*m>y%LyG)DsZh zyQoD=}I(~kl#$Gc} z+kSUPcI2-QJn+$PTh;~bE#98(p&M9He`mKBZ&`Y{JA?DPnzzg^9&9O7%ZnGRC21?W zBYoDA(A2;CI!Y2E$;M(3m{hK>1$$+^Xh)t9vPx2Mz%t)5WMPI9Axea8)*LJ8vyNEF zaVwOy*aS;T5S$~WG7OnS%CLT5ScSq(lOhCl=NJS-$iN^2Zy<(1!u$l{>`eeyiRBeG zMUJ9RF{0pdAR>81aTS~bMLpli6Rwxn0jy{kVJ&#Z{51%igIc22F@zmGKnQMnY26IS zXaY*KQEstcH2On*0bocq!KGL;yT6&BhedEi~~ky8&vrav&OAisbTV!IA4Lw7z~6GbDTzA3S&QJqqJ^9bi`hH!)Vu_WJNPh?Oxu(B;P< zKq(l~gBWuNV8p?j#VDY==hmBnC}<>?z7V3h27DJeF}3g#a|ioOB=*s%-@|)v(lm`x zrlUQ=92w;AlblK8NjsC+_E?;ns&Jm7?k9MzU7~rt4UBDqoY?7f7edL#F3U?6*3zA$ z5EP-=m`-YMTAED*(NaMTO3Bo#0q>Qy^>UPQMWS`X$S8cGgbPRn-xbJ~#&@Eqb>7q# zx5zc>y7I9iJ=5Sc+mzBfws-EXx3&wF+uz(@JW4s)Pj?dBnNCKdN1wy&9OJ+qL z$b!Z?t!&CQg{;79K;g_$7_;?p+0Ehy{(J2%|kOzYIQiSB{5ugvY zOC$Hm56O?o*=ERSY=grOF{emm?Vu@lai_o>BL5aydmdl}|p=T#n+FGB4m4BL1Qy>za+p zQDic|^bX#?___BSuP8D~>(iGlkGz9F$0r7!7_B^W*(&suTMkV!av<0!ul`Vk&jUjK zm|};51QhcXLkeauD7+(W?H^O{4wqjH2wl53a9anAqM0ud&6K_3m!M<)9A1(XB`(gA{8Nrg!y z!vsg^86_DswsKvF2SCK|bf-#5Nz7cBfrR)(@GY{F=+zj77BwcB7otQykwDJ)@(XEM zGL1P(^qP>b& z)*3){{|V>?2uQkcM20D$AD4w?tZYBVn=vGduolaiyOnrciH9J8iew;+seRTH-HU=w zgh&sB>AY?#2=L8`V^?Z6E}#OTcIqE2%W%*BhVUHAawpjp?krbl>Ww3S<%4P2sf)c# zpEw1ejUli@hCpU(kp;3!^Qjyr`4+rBepfunkH?#gdyS;bh&So>>PVRm&*!n9$KS{~ zq3+&T94n$9zGJPX?vMiWpzsX68rD1`uA?Fhu-OBi@9laQrZ=N|Z_6qnhKFc7(NZZL z%MJy0T-vzp@`O;k{nD2I#`#!ClanpuT-LLd#@ea#cA2G z-mbT2r*?y^7e zGIzyNnNtX9q;0W>Vj;B#)M|-~3hSs2=1H$LZd)Aj#SOG8m zeiQdl>jh#P+}%7;f`f20mQ|Gy&^JgiZMs zcy$(Tuyk7p?+5#!ZMOUcMcVL=NE@(^gd8C489 z15qJET$zI5=RMIJF0cViOAF00)3#;!j{ zzDl{E%4yr&9^BBLQ?+7eZQjtLmWt%y){_HcPpqxgUsSs525LjAsx1ZGoBTy1OFOGw zcwPIUWu@o8>n!T3N->vq`2roq4sDDjwV+|Jrf=_pwDi_ZA-gwJm}oDVn^oSBYl~G| zGfG<5Q20VMw&<5i(HtQc6br3=z+D>RBZtT_a*2FEB+aCkY=hGe$VX6bLW^W%a>N30 zz#1BwT)1f>eY5z%K)(N4#Lwol&wRCjedegBXAc5CseK-g774Y3hH=AA12d=@*X*PM zX~KBec*S_tc-_ePjQBDflWoRBMq)IYW4aD0jwwzlm=6>#`FD? z9cgKuhnF$|k^aEBVPA*w@@TuzuA%Iet|`$Fw+63gb}^)l8DK~u6JSURcwe|xBiAhA zk)G$Fl%kc9GmB>8wQ|B!evGAXgp4F%+U2+wtUg3xNL8JWCNZL62r>LXLlL`8d^9{8 zr6(`|APj+T>3QrW@4OX}zJmqcqEg4G)T$&NSH8pfZ*0!$&&cs)<)kn6FuTNgz)p;z zv&OAivL4a4&wPjXFK)RZe;)kC9r)j_3AqEdqzlTG5D zSD+?p83GmA=tEH8arJDBdgef`K#d@Ht_vWK;3$n=h)tudTH2A0K9?-dgI`;KY8wET z!|gZ^%WPC~te1l%!L7*&$+RIT*XreREkHNdox3Ox>GSeHg0<=s^ow+{diw8{Conob z59j6O>*Su~=H%XFCOJ7FSI4*$5Kc+J30f#_21pxed81Y=E(Y0!sk`3;F}`m?dS~#i<5-@Tsx@lK>Qk%1Qd3KTR3r+OWZA3uZe4zvFDcO26iD)wd36z3 zuX5wnsx7%CUVn|HqP)n64@K6-6_-_5Y67)Gn+us5%F`);>t}#wmFR6@p!U_QiNqnRw*G;IhH9n1(eW2Odnw>WE!wcD#MG2R8NSMQ{Yx51ooAS6r5hc zDWQVKrXU2$Xc!5CVlI|y6_X+n%D-Y{g3=t6Avr9Bz%n*g0n12y6wXEvmSERy5Xkc6x#1r>4$BcKrKLyQlg4)9~6B2g?TfQo{fg0bYS zp1f#b7$iNQQmj|h4-hE^bx9}YC2wAgB)*T=lBuaj$P(za9_Da2%t4OE z1=n5~UM|B6WE*58T~;EimocnN56X)sLzqQUnO-Vmq!cSJKym??@v>ln(p46mUl^K_ zmJByT)I&;TH<9&H(Ifh}Ab9{gG|=t7$q6FlVVLQV0|D>SfbHzvU%kcTO&OWjZ~Tbq zKg1>+-S^e+D4g*_P@niJM*tW*j$u&Fs4|4roDm`m5;_ z_TQ#=z-!fK8H8Se!asmML=dEaP>%iihkbn_{_bT@Go{>F@ShU|^%%2*Armxr#_We* z{-F4JAKnJ#l?7g-fxH&^>Gyxnp8nYKsUDssVm;Izb}q_8Rp?2?!h%Agvq98W0)miOC)z$S7qu1VwUjy~7ZpVV53GFqos6kp&fDCQ_FB27Qt z0NB0&^j{71X@g%A=ohNRl9^g>n|Hv=G&s5)D; z(qfm`Z8Fywlp_u=`&k4JldO@J@f?d(sr18 zG0>G0JtDLY#Nh!RZ%W#mLA2Xjab03&L zGEbYCJ~K9(Q+0KeGe^uAnR#=cdBi+nzHFA5sccL%Ck4%BQ^+2t4sli`Elp;W0yIKJ z0}pfs34thGL5Uotsi=8*yS)#}NjFn6f3q}5v^5K7(sg9}`~zou7e6!{h`G#9te-z# zXSLRix34;=eNA4w?$Lq0mo^lVq$hqcQINM_eXY8CdC~HR2L_I?F(T z0vRY2ix0;hhip=8fvt`%A4@RAB2P#ux zE8jI^ON)ix@lW3EE#2!&iO&K^qOxe!k)E6D^+TJV%zKvz*30My@#d(dF} zEg(^6Zx$A_Sf5=-VZj(OL{fV;gR5PQYv&a8%*j(d$_pzVTsHdB)|%#Br~2-Gah*5f z%pROy#*m;aziBc4@AgAWOX4#tV6|3vy(f6^X9te{bbE2z13#TG;U8P(Y+Jl&Yom?I zZTO`o8ndKyvFHL)fC4E5L2JPQ;^Q#KNk~$X)&q{*u;{&UM9@2fbd7_SXl-_5NCi)a zEKr(Z0F4PkGFsgNW&nsuFxWuL&@wqNSYWj_b?Xc4v(qvfqNy(nhT8Vpvym^cBx~T< zI!h>2XNV0p2X)np1uOmwbMi(TbMj#P;Gyme1`1a0VIcdeFI?21I0(ZBoF0mFut{tK z%0+&3RH)pXGnqq%eAusQR}HF|hSKiRm8DF99dj0gg`$^L7!!<}jgv;!6Ua*rsqta; zaWyPFNT`zpIJ!KF1FlZf7=j#EUKdWlDB(&1Nl4Qag_5m&RS2>u@({8~a$wnngc>8D z7pPA!{sV*4HEiw~t?@NJ=)uwYSFu{D0^ds9Lu!z61}&Ke9RcF8TY~GsS(BXw{ckhF1)_x}oisCu^9A%ZC!a}pbf||ubQj)K~x?m`j8|iSt zvbFezmgI(w^IuPEEOk`xdUyBT?;V)4yg$COD2)L@TAzC3t>6EV`C#p%OER;TJhFED z=%Q42-@`x~7XZ6anc)*sN7NH)!p7)h#$tBFu-ZUuteqoC0c4$kh=)~cFoie>;?t6R z3JfaiMCA}Aa)>5_9`Mc-Qv)T;7RhNH7haSwj7ex+F3j8B<$2Lw7Ro7G+LU>gdoQv% zZ!p`_SYXLqczAHiL(YYkR+zHd?`)YmFoSy--yqPg9MbkdAr00ULc~@%2g-6W3LK~O ztJWxK4p(GGX-K94YGr^_DWL+cqRVq=%_cA-kSlO#ZjN&%AyZ&ar3-8S6K}bZfuDjZ z-M_#6_Q8V(nWTe1zI-|Q{&BGVYT^Cy5dUouGRJj0b>P+{FvMh17!u}KEU?y_rtOlf zikt*I0WPH37&2-25M6Eq5`iu}1^-c0p>zb|`@zQGW=afG3uw7CM13gZ(9tlpb?cAL zPj79kGR2h#o70N>gXxjwq~Yzi6IVabn;}(c7wvJq=>+umo4m*UH;yAPXH+ zo>E>?GSPeuFJ^24kSh~i2CFkDe#e=`Zvj^02E{}U z$QMIRJ~g+zwBC|hSO5jO#O!N1oO>hp?l^lE|LP}^di*2&_r;N6?!6oRBqrjSdH@iD zA)$}hg(5w8g#?+5Qo~J3P$&WaaQ!C!MaPQb{(mB#T%AGsNBC!eayBf=8u*zTczyu% zM+rK30cA{Ic|ooT!rHzoLZ>_?m|Ox0oS5w3CC>+*X%Exq8SxM+_(MJq)9mT>Z1WuQ zu)N3S$?-5APg%SwD6Vh19)mS8z8LaB%ttYVhvJd~Nhm%!jj{4NjVDF~7r@I1q7^s_ z;!^9PVRJYVLsi#kc`8H@ZsR9yEGP`Z|e3xF#@O+EP4ib~% z4P3DL<$=L(^~ zsOX@|Qna`K_0(WJsg@bIDKF?Gp2gG+GF7#&sGc{mAnSICF+1|ik}~}*nG)q=YA4pi zST)E2+1`qQWE@DIpG*c4v6vB9X~OlUP7_%fi|b=MA@p5$ipPlO`97ZEd1pc$txqt7 zVt8wa1AQNLPiLatQJ(<_dNz~`!9+1H^FM6i`kJjTu3LTj&f2LzefHN^-AyZmsx{47 zp62BxRl}hyl63GV`~9{1e{u*LaeU;@k&m~YSe%-^ zN<-ynP^cX!!-2B-Wn`rr*SkC2MB<8bt#|EmvH5mfCd1-daj^E&ae8{CH%S{nu@hkA zWrvbdc#}qJE)FT^bf{$qyPE?2Hf#UZoKhV?a8a>-i}q+9C%Qghw!Dn3PFr~YnxcXE zHAdh}j9;WkI|V)*!^ZnU1C?v;Uzql?sjR=gY*|wlSbDYfi_79k@*P+1Z`WrA@`yFN z)Dr3Bn6x=%8FI#%U!IWPm}?B(_oF)pj;<_r_MhB6`bd99$(qNbc%1}zB(QVDH3LIJ zT|-uP*2*lVHn%NzAeSjk#060Hkzz<0PuZEmDr^b1&9+G!8yj$PAss%fI}WaouGCXU z%ck-}@z%Ilb4G}RAg(VDKoW%r72RJ`^H{9HyQ$4V(a~(HsO@P&?$+YhXh{&!Ru45- zn7{$z01g0*7b#dsysu@j>fP7gAhBt4mRHsGS6C9u`}}3g=4P>T;x=)BTuVc zT=P{SK9^9Mkd)}1TaW<17-WFWGIe#sql?nK%O6{_;@FD9)FsaWKmHB)(Ev1VMFGLR zQL;xu*aUq7VdM4jpuX*K@_>Tpt%_mAHpL+*bc$nI6M0@Er*>VGC%s!dCNSk@byN?Y zS;lY+>rqh?XJieYrIl^F7UrH+@v)NUq#Ct?aEX=eW39!jGMM{i%G&Xx9TAqiT0FM2 z)nuxyskKxN1Y8OTF=6x_;KdZM=Zeuzp<|UPnnYb?#48H%Xzty)q%L#KJ+Q7R_L!=mVR1?6l3=>G zV^f{5bxFlf-)Wv)Rj+HV4K&^Nl*PBiug@yBs~*TMahbJzMqo9C(QDJ!nSXL^V19N8g)2;(O_L_Zlm<~c zi3Di&bc&%gw|mA;2jqIA#UVQQ zg^OsVRJ4{9R&F!k*%xSEd$x2V4o5=m{b}vZep6gv!BFAjkAsPh6CxiUoEmFxlqyu* zUJ0*O>^(w`iF)}0;M5AW>`vqtGPflkN+x&M_t}ZUo?y?gGbM>QUL8;>p^gv1@;#D5 zHA0-;paOYJjfJR2pb7z&>Cy-cggkF0W9XsiOU_!s``bHB?-(<*3 z!K^~mgPJKaR@XB{5c&P#&mzt5VwEgbua!vPr)_0e{|-!4 zi1XF@3=1`|@-z|>1nXQ)fn3@m?+ zq1{<&cQM!*QxG#AvonUpVmBCP;8LjBpi6nL3M25C0VtyYF^~{|h-fPx$2VxyddP0X z;MT;r#71e1UK#_r9gD-#D8+gywm|ZsHQkZkkb(3W$RUkmH2RFOj2#(FMn8Fy!800-BW^ryXB>%(!ALEF82}9l93zd#dLfPu)w^H>()e|>diQ3|X17?t zdmHe@YHYAi>Ax5VjD`d0A+#c( z1^PNidUjG*@BDZ|f1eAB>j_o^ewFBgFjB`xtEWm}8TDSwte4?NWucRw>V8}5X$4C`m z_``}wsGp_0>ZO?)u>h8q!2&$LM!^3cax}Qd9?j2)xf zicjE+ky?^T)RAud;G--OTgnQu5_#F_A0g1-DUuV`OjZi?zbC^*pUmvpaJd#lL>q9NDBY{COHoP{8zekR&MN~Ze4Ki zX#So4#XcqXPU(VY$9boCeEx{CcD_%1|D=+2`sBwymHv$P(KngclNH1F6f;TC>3P(h7-w3rtcmwF2RU7xA1vv7;Wenbz457%c#{@!ZoM7XVT&hj*36D>sv zzjv{s1-A;C7DgAE!sQMUI#b;t(Of}8l*}$=a!*u7_Gq%SdYv-<(oRNd1niNKz6N|* zN%ecyW+qD_)CgBKg6fffW!RHf*P`->F!DEr(s7`J` zvB{y}F5!5D+*afQLccuD+y~f0<+6y zOUdv?YC8mLOGJ*GY_SqRlSPa4N8jGsom1bFpWCxKH#V={_ck|Q-GuOLZQjMVR`)mf z&@Kgy+p74M@;1NobYACFQ~1GEeHF4D%Qx1AA8MHFDp2KikI2;xD%s4#`UCDbU6!s~ zH>UfX?h&2AR%DKa>tDVCEBQ(wlisJw_fcuKWS;DLDvAZ-0j3NCYKyjvZG?%QAS&|sU+|2xKxL!!0ofddz|O8{PYZPX@vhEFbAXGjjSNx z6uR@cvJpHPz!#<%?l)Qycoq#gppYNc%Zq-1IDlHr0b(nWC@I~u{qv#{MMm! zWOTVwy+^#~5Q^eWM3|L_#+OY$sGrgw)xV-Q==H2C+JzsB6(~0ggLO&<_fup)@uz9V zT-ped{NPh*v67XhWf>=o0zw=lE0?4JTIAt^3%~&PmpEM6-%@D4WUd~*b<5F-hxe9O zPkm|pXy5Un+Nc-pHyyg~p~pb-R^DB1Sryv0%5?d%srTdy6SLnu)oXs?1!G0uWL@;u zJ>UNN>)%FORAMCE2~1ZxtiC%Gm&Mv*h~(0ieIVDT+0U9^3dK*$U- z4%|TYZ!ZyJ8NCog-JNDnd3W{4=ki-hlfU-0((wy>+CDSd62qfisrKxWxP9vm9U#s) zYX+jGHq}%`{x-j_A^+aEqNcI-GiU#K+nr+-$<=*T1|Tvlwz|N~4L?46x@NFrWqer~ z>;n(5_jHB28CW?g*slWjx2A1Q6TYsFIJ?*mc)uC zTc1s&*-C7pDY7q8q(zoQiYCk?BF$I=<`l762%o5h$a@Vb78fk!t`x71MaRX(JTd9# zHb3|KS(VP?$#{a$)JHKSEC#FM^tw_~ynuR`6XR1;bDs&ovnJ}`Z^OEx^cgeU%tX*9 zLx2H-03ja)kbX%1@Qt*Zk{6{EEL98N5&m1S{JdgeN1<6PF6Cy9j1QL|X>I;Y`Ox@aW`04|$k=H4XPR4%t_Y5eW#-=N zTRT==HP%s3&@on3J+{^-o@_o+KC*K(J3lXLC^%Stq`CQM*+_6SGdC|Q7#u@UNL5gP zT-9nWRoAV69G{23KaM>YnCy4*cI@Dtxy~x5(&OMtz`mA>L(-90Xg1VjZ-_G8-cNZ6;@o zLI7!vArV6x)23a%NPZqkWl;j6Bo%UU1^7Hn6Y@o+O6phfCsKGRib48zhzdZ3qI}Hj z!#DCH;Ttc8Z{jxyTnECV--3~O@3+LGXHVYt2}ba3C(nup=07ijQeQg4RhTEgBK2iv zz^)j-jG$zb8S7J^7~pwDU8OdXno?Di=yeL7#@zYHBjRBt;^RO3`EDih8Ylqik|Y~&We=ksfTy>-@C8V@sOor-7tnmM?uxV;rjZU#_K&b z>&x=mtGsXW_sTY1S6jV#WomKHo|WbO4cYqdrqu0#t)n*6zPZ^K@Oz?d{?=VK4V{Kx# z^F*hZZ9ma2LQTh-#Noi{fH>HAvQZqYKUpu7E=QM8+8k}d5|b2D5CbQe!vD!Z0Bqr**>x9y4=sWUvVqUZF5h#k0Ra?7ahSh2iKfj zqpW$Oij8&5cAV%?I^HP!0rmhYQ3g47uOr7U2^*~n5M55dynei@JU}F%P$dY7T$Di- zefKv!+zU~V`u_$!7C)O*xxO;DuFz|laja+?UbE%+#{B%g&u&~Z+)`|tj_~+bW>@!? zB`B#|A9(xVfwwMf+xEa)2M@mez}9UYCoYbSUOd*(aqQyg*u@ha;?FGy`ic^Ll}YLO z-E~=k=?Av&xNov1qozIE>n_QP_xH}Wy%hfF;)V?ux&5V=xc%9_zGuT9z4YjB&Nnxo z|IMS1eRRI5>HJ5~HQy7bm3jSnmIp?sLob406Ks!iZ}Vg9ZQvQoK@3E$i~u5j&Xkn+ zf5|YgGLAX9HtPN8==}H9C?j{#m7MY`dc7mVn}gE==Axn^t~g#G!w}jU#v!O+G`qyl zYilp5rlrA-aHIqyAqdhEqml$5smohA)uqcBZ(**JsHE>z4}Z4#o7?-=Z;QO!RJ8tJ z=RJ?4=3A1?@s;sC?TRk{j~ao$QI%;^<##@{0|xmu-3gL z7oYM1K3f0`iCxL*UAO?G?JKh$eDObd5+c1zfK@J+b^IEGRYrnS6=`4E6V$GpyHeVpQH

    6. n40n}CwP^;np&pc|6JEN?+dW|hL7_fBS$ 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

      ELiajr9{p$UVkjwYR~Zr&SI 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 yt$2XdE+cR-qf7T`pBxx_i5d2(`a;prfPMhf&yz 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